A lot of fixes for prepared statements (PS):

New mysqltest that can run mysqltest with PS
Added support for ZEROFILL in PS
Fixed crash when one called mysql_stmt_store_result() without a preceding mysql_stmt_bind_result()
Updated test cases to support --ps-protocol
(Some tests are still run using old protocol)
Fixed crash in PS when using SELECT * FROM t1 NATURAL JOIN t2...
Fixed crash in PS when using sub queries
Create table didn't signal when table was created. This could cause a "DROP TABLE created_table" in another thread to wait "forever"
Fixed wrong permissions check in PS and multi-table updates (one could get permission denied for legal quries)
Fix for PS and SELECT ... PROCEDURE
Reset all warnings when executing a new PS query
group_concat(...ORDER BY) didn't work with PS
Fixed problem with test suite when not using innodb
This commit is contained in:
monty@mysql.com 2004-10-26 19:30:01 +03:00
parent 8b6839e644
commit 6fbc869d18
56 changed files with 934 additions and 196 deletions

View File

@ -17,7 +17,8 @@
# This file is public domain and comes with NO WARRANTY of any kind
#AUTOMAKE_OPTIONS = nostdinc
INCLUDES = -I$(top_srcdir)/include $(openssl_includes)
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/regex \
$(openssl_includes)
LIBS = @CLIENT_LIBS@
DEPLIB= ../libmysql/libmysqlclient.la
LDADD = @CLIENT_EXTRA_LDFLAGS@ $(DEPLIB)
@ -36,6 +37,7 @@ mysqldump_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB)
mysqlimport_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB)
mysqltest_SOURCES= mysqltest.c ../mysys/my_getsystime.c
mysqltest_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB)
mysqltest_LDADD = $(LDADD) $(top_builddir)/regex/libregex.a
mysqlbinlog_SOURCES = mysqlbinlog.cc ../mysys/mf_tempdir.c
mysqlbinlog_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB)
mysqlmanagerc_SOURCES = mysqlmanagerc.c

View File

@ -42,7 +42,7 @@
**********************************************************************/
#define MTEST_VERSION "2.2"
#define MTEST_VERSION "2.3"
#include <my_global.h>
#include <mysql_embed.h>
@ -53,12 +53,13 @@
#include <mysqld_error.h>
#include <m_ctype.h>
#include <my_dir.h>
#include <errmsg.h> /* Error codes */
#include <hash.h>
#include <my_getopt.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <violite.h>
#include <regex.h> /* Our own version of lib */
#define MAX_QUERY 131072
#define MAX_VAR_NAME 256
#define MAX_COLUMNS 256
@ -93,7 +94,7 @@
enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT, OPT_SKIP_SAFEMALLOC,
OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH,
OPT_SSL_CIPHER};
OPT_SSL_CIPHER,OPT_PS_PROTOCOL};
/* ************************************************************************ */
/*
@ -131,8 +132,8 @@ static int record = 0, opt_sleep=0;
static char *db = 0, *pass=0;
const char* user = 0, *host = 0, *unix_sock = 0, *opt_basedir="./";
static int port = 0;
static my_bool opt_big_test= 0, opt_compress= 0, silent= 0, verbose = 0,
tty_password= 0;
static my_bool opt_big_test= 0, opt_compress= 0, silent= 0, verbose = 0;
static my_bool tty_password= 0, ps_protocol= 0, ps_protocol_enabled= 0;
static uint start_lineno, *lineno;
const char* manager_user="root",*manager_host=0;
char *manager_pass=0;
@ -157,7 +158,7 @@ static int block_stack[BLOCK_STACK_DEPTH];
static int block_ok_stack[BLOCK_STACK_DEPTH];
static CHARSET_INFO *charset_info= &my_charset_latin1; /* Default charset */
static char *charset_name = "latin1"; /* Default character set name */
static const char *charset_name= "latin1"; /* Default character set name */
static int embedded_server_arg_count=0;
static char *embedded_server_args[MAX_SERVER_ARGS];
@ -171,6 +172,12 @@ static int got_end_timer= FALSE;
static void timer_output(void);
static ulonglong timer_now(void);
static regex_t ps_re; /* Holds precompiled re for valid PS statements */
static void ps_init_re(void);
static int ps_match_re(char *);
static char *ps_eprint(int);
static void ps_free_reg(void);
static const char *embedded_server_groups[] = {
"server",
"embedded",
@ -270,7 +277,7 @@ Q_EXEC, Q_DELIMITER,
Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS,
Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL,
Q_START_TIMER, Q_END_TIMER,
Q_CHARACTER_SET,
Q_CHARACTER_SET, Q_DISABLE_PS_PROTOCOL, Q_ENABLE_PS_PROTOCOL,
Q_UNKNOWN, /* Unknown command. */
Q_COMMENT, /* Comments, ignored. */
@ -352,6 +359,8 @@ const char *command_names[]=
"start_timer",
"end_timer",
"character_set",
"disable_ps_protocol",
"enable_ps_protocol",
0
};
@ -523,6 +532,8 @@ static void free_used_memory()
my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
free_defaults(default_argv);
mysql_server_end();
if (ps_protocol)
ps_free_reg();
my_end(MY_CHECK_ERROR);
DBUG_VOID_RETURN;
}
@ -2089,6 +2100,9 @@ static struct my_option my_long_options[] =
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"port", 'P', "Port number to use for connection.", (gptr*) &port,
(gptr*) &port, 0, GET_INT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, 0},
{"ps-protocol", OPT_PS_PROTOCOL, "Use prepared statements protocol for communication",
(gptr*) &ps_protocol, (gptr*) &ps_protocol, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"quiet", 's', "Suppress all normal output.", (gptr*) &silent,
(gptr*) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"record", 'r', "Record output of test_file into result file.",
@ -2367,7 +2381,36 @@ static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
* the result will be read - for regular query, both bits must be on
*/
int run_query(MYSQL* mysql, struct st_query* q, int flags)
static int run_query_normal(MYSQL *mysql, struct st_query *q, int flags);
static int run_query_stmt (MYSQL *mysql, struct st_query *q, int flags);
static void run_query_stmt_handle_warnings(MYSQL *mysql, DYNAMIC_STRING *ds);
static int run_query_stmt_handle_error(char *query, struct st_query *q,
MYSQL_STMT *stmt, DYNAMIC_STRING *ds);
static void run_query_display_metadata(MYSQL_FIELD *field, uint num_fields,
DYNAMIC_STRING *ds);
static int run_query(MYSQL *mysql, struct st_query *q, int flags)
{
/*
Try to find out if we can run this statement using the prepared
statement protocol.
We don't have a mysql_stmt_send_execute() so we only handle
complete SEND+REAP.
If it is a '?' in the query it may be a SQL level prepared
statement already and we can't do it twice
*/
if (ps_protocol_enabled && disable_info &&
(flags & QUERY_SEND) && (flags & QUERY_REAP) && ps_match_re(q->query))
return run_query_stmt (mysql, q, flags);
return run_query_normal(mysql, q, flags);
}
static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags)
{
MYSQL_RES* res= 0;
uint i;
@ -2377,7 +2420,7 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
DYNAMIC_STRING eval_query;
char* query;
int query_len, got_error_on_send= 0;
DBUG_ENTER("run_query");
DBUG_ENTER("run_query_normal");
DBUG_PRINT("enter",("flags: %d", flags));
if (q->type != Q_EVAL)
@ -2520,56 +2563,14 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
{
if (res)
{
MYSQL_FIELD *field, *field_end;
MYSQL_FIELD *field= mysql_fetch_fields(res);
uint num_fields= mysql_num_fields(res);
if (display_metadata)
{
dynstr_append(ds,"Catalog\tDatabase\tTable\tTable_alias\tColumn\tColumn_alias\tName\tType\tLength\tMax length\tIs_null\tFlags\tDecimals\tCharsetnr\n");
for (field= mysql_fetch_fields(res), field_end= field+num_fields ;
field < field_end ;
field++)
{
char buff[22];
dynstr_append_mem(ds, field->catalog, field->catalog_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->db, field->db_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->org_table, field->org_table_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->table, field->table_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->org_name, field->org_name_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->name, field->name_length);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->type, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->length, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->max_length, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, (char*) (IS_NOT_NULL(field->flags) ?
"N" : "Y"), 1);
dynstr_append_mem(ds, "\t", 1);
run_query_display_metadata(field, num_fields, ds);
int10_to_str((int) field->flags, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->decimals, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->charsetnr, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\n", 1);
}
}
if (!display_result_vertically)
{
field= mysql_fetch_fields(res);
for (i = 0; i < num_fields; i++)
{
if (i)
@ -2645,6 +2646,576 @@ end:
}
/****************************************************************************\
* If --ps-protocol run ordinary statements using prepared statemnt C API
\****************************************************************************/
/*
We don't have a mysql_stmt_send_execute() so we only handle
complete SEND+REAP
*/
static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags)
{
int error= 0; /* Function return code if "goto end;" */
int err; /* Temporary storage of return code from calls */
int query_len, got_error_on_execute;
uint num_rows;
char *query;
MYSQL_RES *res= NULL; /* Note that here 'res' is meta data result set */
DYNAMIC_STRING *ds;
DYNAMIC_STRING ds_tmp;
DYNAMIC_STRING eval_query;
MYSQL_STMT *stmt;
DBUG_ENTER("run_query_stmt");
/*
We must allocate a new stmt for each query in this program becasue this
may be a new connection.
*/
if (!(stmt= mysql_stmt_init(mysql)))
die("At line %u: unable init stmt structure");
if (q->type != Q_EVAL)
{
query= q->query;
query_len= strlen(query);
}
else
{
init_dynamic_string(&eval_query, "", 16384, 65536);
do_eval(&eval_query, q->query);
query= eval_query.str;
query_len= eval_query.length;
}
DBUG_PRINT("query", ("'%-.60s'", query));
if (q->record_file[0])
{
init_dynamic_string(&ds_tmp, "", 16384, 65536);
ds= &ds_tmp;
}
else
ds= &ds_res;
/* Store the query into the output buffer if not disabled */
if (!disable_query_log)
{
replace_dynstr_append_mem(ds,query, query_len);
dynstr_append_mem(ds, delimiter, delimiter_length);
dynstr_append_mem(ds, "\n", 1);
}
/*
We use the prepared statement interface but there is actually no
'?' in the query. If unpreparable we fall back to use normal
C API.
*/
if ((err= mysql_stmt_prepare(stmt, query, query_len)) == CR_NO_PREPARE_STMT)
return run_query_normal(mysql, q, flags);
if (err != 0)
{
if (q->abort_on_error)
{
die("At line %u: unable to prepare statement '%s': "
"%s (mysql_stmt_errno=%d returned=%d)",
start_lineno, query,
mysql_stmt_error(stmt), mysql_stmt_errno(stmt), err);
}
else
{
/*
Preparing is part of normal execution and some errors may be expected
*/
error= run_query_stmt_handle_error(query, q, stmt, ds);
goto end;
}
}
/* We may have got warnings already, collect them if any */
/* FIXME we only want this if the statement succeeds I think */
run_query_stmt_handle_warnings(mysql, ds);
/*
No need to call mysql_stmt_bind_param() because we have no
parameter markers.
To optimize performance we use a global 'stmt' that is initiated
once. A new prepare will implicitely close the old one. When we
terminate we will lose the connection, this also closes the last
prepared statement.
*/
if ((got_error_on_execute= mysql_stmt_execute(stmt)) != 0) /* 0 == Success */
{
if (q->abort_on_error)
{
/* We got an error, unexpected */
die("At line %u: unable to execute statement '%s': "
"%s (mysql_stmt_errno=%d returned=%d)",
start_lineno, query, mysql_stmt_error(stmt),
mysql_stmt_errno(stmt), got_error_on_execute);
}
else
{
/* We got an error, maybe expected */
error= run_query_stmt_handle_error(query, q, stmt, ds);
goto end;
}
}
/*
We instruct that we want to update the "max_length" field in
mysql_stmt_store_result(), this is our only way to know how much
buffer to allocate for result data
*/
{
my_bool one= 1;
if (mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH,
(void*) &one) != 0)
die("At line %u: unable to set stmt attribute "
"'STMT_ATTR_UPDATE_MAX_LENGTH': %s (returned=%d)",
start_lineno, query, err);
}
/*
If we got here the statement succeeded and was expected to do so,
get data. Note that this can still give errors found during execution!
*/
if ((err= mysql_stmt_store_result(stmt)) != 0)
{
if (q->abort_on_error)
{
/* We got an error, unexpected */
die("At line %u: unable to execute statement '%s': "
"%s (mysql_stmt_errno=%d returned=%d)",
start_lineno, query, mysql_stmt_error(stmt),
mysql_stmt_errno(stmt), got_error_on_execute);
}
else
{
/* We got an error, maybe expected */
error= run_query_stmt_handle_error(query, q, stmt, ds);
goto end;
}
}
/* If we got here the statement was both executed and read succeesfully */
if (q->expected_errno[0].type == ERR_ERRNO &&
q->expected_errno[0].code.errnum != 0)
{
verbose_msg("query '%s' succeeded - should have failed with errno %d...",
q->query, q->expected_errno[0].code.errnum);
error= 1;
goto end;
}
num_rows= mysql_stmt_num_rows(stmt);
/*
Not all statements creates a result set. If there is one we can
now create another normal result set that contains the meta
data. This set can be handled almost like any other non prepared
statement result set.
*/
if (!disable_result_log && ((res= mysql_stmt_result_metadata(stmt)) != NULL))
{
/* Take the column count from meta info */
MYSQL_FIELD *field= mysql_fetch_fields(res);
uint num_fields= mysql_num_fields(res);
/* FIXME check error from the above? */
if (display_metadata)
run_query_display_metadata(field, num_fields, ds);
if (!display_result_vertically)
{
/* Display the table heading with the names tab separated */
uint col_idx;
for (col_idx= 0; col_idx < num_fields; col_idx++)
{
if (col_idx)
dynstr_append_mem(ds, "\t", 1);
replace_dynstr_append_mem(ds, field[col_idx].name,
strlen(field[col_idx].name));
}
dynstr_append_mem(ds, "\n", 1);
}
/* Now we are to put the real result into the output buffer */
/* FIXME when it works, create function append_stmt_result() */
{
MYSQL_BIND *bind;
my_bool *is_null;
unsigned long *length;
/* FIXME we don't handle vertical display ..... */
uint col_idx, row_idx;
/* Allocate array with bind structs, lengths and NULL flags */
bind= (MYSQL_BIND*) my_malloc(num_fields * sizeof(MYSQL_BIND),
MYF(MY_WME | MY_FAE));
length= (unsigned long*) my_malloc(num_fields * sizeof(unsigned long),
MYF(MY_WME | MY_FAE));
is_null= (my_bool*) my_malloc(num_fields * sizeof(my_bool),
MYF(MY_WME | MY_FAE));
for (col_idx= 0; col_idx < num_fields; col_idx++)
{
/* Allocate data for output */
/*
FIXME it may be a bug that for non string/blob types
'max_length' is 0, should try out 'length' in that case
*/
uint max_length= max(field[col_idx].max_length + 1, 1024);
char *str_data= (char *) my_malloc(max_length, MYF(MY_WME | MY_FAE));
bind[col_idx].buffer_type= MYSQL_TYPE_STRING;
bind[col_idx].buffer= (char *)str_data;
bind[col_idx].buffer_length= max_length;
bind[col_idx].is_null= &is_null[col_idx];
bind[col_idx].length= &length[col_idx];
}
/* Fill in the data into the structures created above */
if ((err= mysql_stmt_bind_result(stmt, bind)) != 0)
die("At line %u: unable to bind result to statement '%s': "
"%s (mysql_stmt_errno=%d returned=%d)",
start_lineno, query,
mysql_stmt_error(stmt), mysql_stmt_errno(stmt), err);
/* Read result from each row */
for (row_idx= 0; row_idx < num_rows; row_idx++)
{
if ((err= mysql_stmt_fetch(stmt)) != 0)
die("At line %u: unable to fetch all rows from statement '%s': "
"%s (mysql_stmt_errno=%d returned=%d)",
start_lineno, query,
mysql_stmt_error(stmt), mysql_stmt_errno(stmt), err);
/* Read result from each column */
for (col_idx= 0; col_idx < num_fields; col_idx++)
{
/* FIXME is string terminated? */
const char *val= (const char *)bind[col_idx].buffer;
ulonglong len= *bind[col_idx].length;
if (col_idx < max_replace_column && replace_column[col_idx])
{
val= replace_column[col_idx];
len= strlen(val);
}
if (*bind[col_idx].is_null)
{
val= "NULL";
len= 4;
}
if (!display_result_vertically)
{
if (col_idx) /* No tab before first col */
dynstr_append_mem(ds, "\t", 1);
replace_dynstr_append_mem(ds, val, len);
}
else
{
dynstr_append(ds, field[col_idx].name);
dynstr_append_mem(ds, "\t", 1);
replace_dynstr_append_mem(ds, val, len);
dynstr_append_mem(ds, "\n", 1);
}
}
if (!display_result_vertically)
dynstr_append_mem(ds, "\n", 1);
}
if ((err= mysql_stmt_fetch(stmt)) != MYSQL_NO_DATA)
die("At line %u: fetch didn't end with MYSQL_NO_DATA from statement "
"'%s': %s (mysql_stmt_errno=%d returned=%d)",
start_lineno, query,
mysql_stmt_error(stmt), mysql_stmt_errno(stmt), err);
free_replace_column();
for (col_idx= 0; col_idx < num_fields; col_idx++)
{
/* Free data for output */
my_free((gptr)bind[col_idx].buffer, MYF(MY_WME | MY_FAE));
}
/* Free array with bind structs, lengths and NULL flags */
my_free((gptr)bind , MYF(MY_WME | MY_FAE));
my_free((gptr)length , MYF(MY_WME | MY_FAE));
my_free((gptr)is_null , MYF(MY_WME | MY_FAE));
}
/* Add all warnings to the result */
run_query_stmt_handle_warnings(mysql, ds);
if (!disable_info)
{
char buf[40];
sprintf(buf,"affected rows: %lu\n",(ulong) mysql_affected_rows(mysql));
dynstr_append(ds, buf);
if (mysql_info(mysql))
{
dynstr_append(ds, "info: ");
dynstr_append(ds, mysql_info(mysql));
dynstr_append_mem(ds, "\n", 1);
}
}
}
run_query_stmt_handle_warnings(mysql, ds);
if (record)
{
if (!q->record_file[0] && !result_file)
die("At line %u: Missing result file", start_lineno);
if (!result_file)
str_to_file(q->record_file, ds->str, ds->length);
}
else if (q->record_file[0])
{
error= check_result(ds, q->record_file, q->require_file);
}
if (res)
mysql_free_result(res); /* Free normal result set with meta data */
last_result= 0; /* FIXME have no idea what this is about... */
if (err >= 1)
mysql_error(mysql); /* FIXME strange, has no effect... */
end:
free_replace();
last_result=0;
if (ds == &ds_tmp)
dynstr_free(&ds_tmp);
if (q->type == Q_EVAL)
dynstr_free(&eval_query);
mysql_stmt_close(stmt);
DBUG_RETURN(error);
}
/****************************************************************************\
* Broken out sub functions to run_query_stmt()
\****************************************************************************/
static void run_query_display_metadata(MYSQL_FIELD *field, uint num_fields,
DYNAMIC_STRING *ds)
{
MYSQL_FIELD *field_end;
dynstr_append(ds,"Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
"Column_alias\tName\tType\tLength\tMax length\tIs_null\t"
"Flags\tDecimals\tCharsetnr\n");
for (field_end= field+num_fields ;
field < field_end ;
field++)
{
char buff[22];
dynstr_append_mem(ds, field->catalog,
field->catalog_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->db, field->db_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->org_table,
field->org_table_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->table,
field->table_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->org_name,
field->org_name_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->name, field->name_length);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->type, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->length, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->max_length, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, (char*) (IS_NOT_NULL(field->flags) ?
"N" : "Y"), 1);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->flags, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->decimals, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->charsetnr, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\n", 1);
}
}
static void run_query_stmt_handle_warnings(MYSQL *mysql, DYNAMIC_STRING *ds)
{
uint count;
DBUG_ENTER("run_query_stmt_handle_warnings");
if (!disable_warnings && (count= mysql_warning_count(mysql)))
{
if (mysql_real_query(mysql, "SHOW WARNINGS", 13) == 0)
{
MYSQL_RES *warn_res= mysql_store_result(mysql);
if (!warn_res)
verbose_msg("Warning count is %u but didn't get any warnings\n",
count);
else
{
dynstr_append_mem(ds, "Warnings:\n", 10);
append_result(ds, warn_res);
mysql_free_result(warn_res);
}
}
}
DBUG_VOID_RETURN;
}
static int run_query_stmt_handle_error(char *query, struct st_query *q,
MYSQL_STMT *stmt, DYNAMIC_STRING *ds)
{
if (q->require_file) /* FIXME don't understand this one */
{
abort_not_supported_test();
}
if (q->abort_on_error)
die("At line %u: query '%s' failed: %d: %s", start_lineno, query,
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
else
{
int i;
for (i=0 ; (uint) i < q->expected_errors ; i++)
{
if (((q->expected_errno[i].type == ERR_ERRNO) &&
(q->expected_errno[i].code.errnum == mysql_stmt_errno(stmt))) ||
((q->expected_errno[i].type == ERR_SQLSTATE) &&
(strcmp(q->expected_errno[i].code.sqlstate,
mysql_stmt_sqlstate(stmt)) == 0)))
{
if (i == 0 && q->expected_errors == 1)
{
/* Only log error if there is one possible error */
dynstr_append_mem(ds,"ERROR ",6);
replace_dynstr_append_mem(ds, mysql_stmt_sqlstate(stmt),
strlen(mysql_stmt_sqlstate(stmt)));
dynstr_append_mem(ds, ": ", 2);
replace_dynstr_append_mem(ds,mysql_stmt_error(stmt),
strlen(mysql_stmt_error(stmt)));
dynstr_append_mem(ds,"\n",1);
}
/* Don't log error if we may not get an error */
else if (q->expected_errno[0].type == ERR_SQLSTATE ||
(q->expected_errno[0].type == ERR_ERRNO &&
q->expected_errno[0].code.errnum != 0))
dynstr_append(ds,"Got one of the listed errors\n");
return 0; /* Ok */
}
}
DBUG_PRINT("info",("i: %d expected_errors: %d", i,
q->expected_errors));
dynstr_append_mem(ds, "ERROR ",6);
replace_dynstr_append_mem(ds, mysql_stmt_sqlstate(stmt),
strlen(mysql_stmt_sqlstate(stmt)));
dynstr_append_mem(ds,": ",2);
replace_dynstr_append_mem(ds, mysql_stmt_error(stmt),
strlen(mysql_stmt_error(stmt)));
dynstr_append_mem(ds,"\n",1);
if (i)
{
verbose_msg("query '%s' failed with wrong errno %d instead of %d...",
q->query, mysql_stmt_errno(stmt), q->expected_errno[0]);
return 1; /* Error */
}
verbose_msg("query '%s' failed: %d: %s", q->query, mysql_stmt_errno(stmt),
mysql_stmt_error(stmt));
/*
if we do not abort on error, failure to run the query does
not fail the whole test case
*/
return 0;
}
return 0;
}
/****************************************************************************\
* Functions to match SQL statements that can be prepared
\****************************************************************************/
static void ps_init_re(void)
{
const char *ps_re_str =
"^("
"[[:space:]]*REPLACE[[:space:]]|"
"[[:space:]]*INSERT[[:space:]]|"
"[[:space:]]*UPDATE[[:space:]]|"
"[[:space:]]*DELETE[[:space:]]|"
"[[:space:]]*SELECT[[:space:]]|"
"[[:space:]]*CREATE[[:space:]]+TABLE[[:space:]]|"
"[[:space:]]*DO[[:space:]]|"
"[[:space:]]*SET[[:space:]]+OPTION[[:space:]]|"
"[[:space:]]*DELETE[[:space:]]+MULTI[[:space:]]|"
"[[:space:]]*UPDATE[[:space:]]+MULTI[[:space:]]|"
"[[:space:]]*INSERT[[:space:]]+SELECT[[:space:]])";
int err= regcomp(&ps_re, ps_re_str, (REG_EXTENDED | REG_ICASE | REG_NOSUB),
&my_charset_latin1);
if (err)
{
char erbuf[100];
int len= regerror(err, &ps_re, erbuf, sizeof(erbuf));
fprintf(stderr, "error %s, %d/%d `%s'\n",
ps_eprint(err), len, (int)sizeof(erbuf), erbuf);
exit(1);
}
}
static int ps_match_re(char *stmt_str)
{
int err= regexec(&ps_re, stmt_str, (size_t)0, NULL, 0);
if (err == 0)
return 1;
else if (err == REG_NOMATCH)
return 0;
else
{
char erbuf[100];
int len= regerror(err, &ps_re, erbuf, sizeof(erbuf));
fprintf(stderr, "error %s, %d/%d `%s'\n",
ps_eprint(err), len, (int)sizeof(erbuf), erbuf);
exit(1);
}
}
static char *ps_eprint(int err)
{
static char epbuf[100];
size_t len= regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, sizeof(epbuf));
assert(len <= sizeof(epbuf));
return(epbuf);
}
static void ps_free_reg(void)
{
regfree(&ps_re);
}
/****************************************************************************/
void get_query_type(struct st_query* q)
{
char save;
@ -2798,6 +3369,11 @@ int main(int argc, char **argv)
if (manager_host)
init_manager();
#endif
if (ps_protocol)
{
ps_protocol_enabled= 1;
ps_init_re();
}
if (!( mysql_init(&cur_con->mysql)))
die("Failed in mysql_init()");
if (opt_compress)
@ -2991,6 +3567,13 @@ int main(int argc, char **argv)
case Q_CHARACTER_SET:
set_charset(q);
break;
case Q_DISABLE_PS_PROTOCOL:
ps_protocol_enabled= 0;
break;
case Q_ENABLE_PS_PROTOCOL:
ps_protocol_enabled= ps_protocol;
break;
default: processed = 0; break;
}
}

View File

@ -2811,7 +2811,7 @@ thread_dirs=
dnl This probably should be cleaned up more - for now the threaded
dnl client is just using plain-old libs.
sql_client_dirs="libmysql client"
sql_client_dirs="libmysql strings regex client"
linked_client_targets="linked_libmysql_sources"
CLIENT_LIBS=$NON_THREADED_CLIENT_LIBS
if test "$THREAD_SAFE_CLIENT" != "no"

View File

@ -1880,6 +1880,7 @@ my_bool cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
}
stmt->field_count= (uint) field_count;
stmt->param_count= (ulong) param_count;
mysql->warning_count= 0;
DBUG_RETURN(0);
}
@ -3263,7 +3264,6 @@ static void read_binary_time(MYSQL_TIME *tm, uchar **pos)
tm->minute= (uint) to[6];
tm->second= (uint) to[7];
tm->second_part= (length > 8) ? (ulong) sint4korr(to+8) : 0;
tm->year= tm->month= 0;
*pos+= length;
@ -3489,7 +3489,16 @@ static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
char buff[22]; /* Enough for longlong */
char *end= longlong10_to_str(value, buff, field_is_unsigned ? 10: -10);
/* Resort to string conversion which supports all typecodes */
fetch_string_with_conversion(param, buff, (uint) (end - buff));
uint length= (uint) (end-buff);
if (field->flags & ZEROFILL_FLAG && length < field->length &&
field->length < 21)
{
bmove_upp((char*) buff+field->length,buff+length, length);
bfill((char*) buff, field->length - length,'0');
length= field->length;
}
fetch_string_with_conversion(param, buff, length);
break;
}
}
@ -3556,8 +3565,14 @@ static void fetch_float_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
if (field->decimals >= NOT_FIXED_DEC)
#undef NOT_FIXED_DEC
{
sprintf(buff, "%-*.*g", (int) min(sizeof(buff)-1, param->buffer_length),
width, value);
/*
The 14 below is to ensure that the server and client has the same
precisions. This will ensure that on the same machine you get the
same value as a string independent of the protocol you use.
*/
sprintf(buff, "%-*.*g", (int) min(sizeof(buff)-1,
param->buffer_length),
min(14,width), value);
end= strcend(buff, ' ');
*end= 0;
}
@ -3868,12 +3883,12 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
{
MYSQL_BIND *param, *end;
MYSQL_FIELD *field;
ulong bind_count;
ulong bind_count= stmt->field_count;
uint param_count= 0;
DBUG_ENTER("mysql_stmt_bind_result");
DBUG_ASSERT(stmt != 0);
DBUG_PRINT("enter",("field_count: %d", bind_count));
if (!stmt->field_count)
if (!bind_count)
{
if ((int) stmt->state < (int) MYSQL_STMT_PREPARE_DONE)
{
@ -3881,7 +3896,6 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
}
DBUG_RETURN(0);
}
bind_count= stmt->field_count;
/*
We only need to check that stmt->field_count - if it is not null
@ -3894,6 +3908,8 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
param < end ;
param++, field++)
{
DBUG_PRINT("info",("buffer_type: %u field_type: %u",
(uint) param->buffer_type, (uint) field->type));
/*
Set param->is_null to point to a dummy variable if it's not set.
This is to make the execute code easier
@ -4221,6 +4237,8 @@ int cli_read_binary_rows(MYSQL_STMT *stmt)
*prev_ptr= 0;
mysql->warning_count= uint2korr(cp+1);
mysql->server_status= uint2korr(cp+3);
DBUG_PRINT("info",("status: %u warning_count: %u",
mysql->server_status, mysql->warning_count));
DBUG_RETURN(0);
}
}
@ -4316,11 +4334,12 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
bind < end ;
bind++, field++)
{
bind->buffer_type= field->type;
bind->buffer_type= MYSQL_TYPE_NULL;
bind->buffer_length=1;
}
mysql_stmt_bind_result(stmt, stmt->bind);
if (mysql_stmt_bind_result(stmt, stmt->bind))
DBUG_RETURN(1);
stmt->bind_result_done= 0; /* No normal bind done */
}

View File

@ -14,13 +14,14 @@ link_sources:
DEFS = -DEMBEDDED_LIBRARY
INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include -I$(srcdir) \
-I$(top_srcdir) -I$(top_srcdir)/client $(openssl_includes)
-I$(top_srcdir) -I$(top_srcdir)/client -I$(top_srcdir)/regex \
$(openssl_includes)
LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@
LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS)
mysqltest_LINK = $(CXXLINK)
mysqltest_SOURCES = mysqltest.c
mysqltest_LDADD = $(LDADD) $(top_builddir)/regex/libregex.a
mysql_SOURCES = mysql.cc readline.cc completion_hash.cc \
my_readline.h sql_string.h completion_hash.h

View File

@ -1,4 +1,7 @@
-- require r/have_query_cache.require
# As PS are not cached we disable them to ensure the we get the right number
# of query cache hits
-- disable_ps_protocol
disable_query_log;
show variables like "have_query_cache";
enable_query_log;

View File

@ -73,7 +73,9 @@ create table t5 as select
show create table t5 ;
--vertical_results
--enable_metadata
--disable_ps_protocol
select * from t5 ;
--enable_ps_protocol
--disable_metadata
--horizontal_results
drop table t5 ;

View File

@ -321,6 +321,8 @@ while test $# -gt 0; do
EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT $1"
SLEEP_TIME_AFTER_RESTART=`$ECHO "$1" | $SED -e "s;--sleep=;;"`
;;
--ps-protocol)
EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT $1" ;;
--user-test=*)
USER_TEST=`$ECHO "$1" | $SED -e "s;--user-test=;;"`
;;

View File

@ -766,9 +766,7 @@ list_id smallint unsigned NOT NULL,
term text NOT NULL,
PRIMARY KEY(id),
INDEX(list_id, term(19))
) TYPE=MyISAM CHARSET=utf8;
Warnings:
Warning 1287 'TYPE=storage_engine' is deprecated; use 'ENGINE=storage_engine' instead
) ENGINE=MyISAM CHARSET=utf8;
INSERT INTO t1 set list_id = 1, term = "testétest";
INSERT INTO t1 set list_id = 1, term = "testetest";
INSERT INTO t1 set list_id = 1, term = "testètest";

View File

@ -21,17 +21,17 @@ INSERT INTO t2 VALUES (5,2,'um copo de Vodka');
INSERT INTO t2 VALUES (6,2,'um chocolate Snickers');
INSERT INTO t2 VALUES (7,1,'Bife');
INSERT INTO t2 VALUES (8,1,'Pizza de Salmao');
SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi')
SELECT t1.q, t2.item, t2.id, round(MATCH t2.item AGAINST ('sushi'),8)
as x FROM t1, t2 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
q item id x
aaaaaaaaa dsaass de sushi 1 1.92378664016724
aaaaaaaaa dsaass de Bolo de Chocolate 2 0
aaaaaaaaa dsaass de Feijoada 3 0
aaaaaaaaa dsaass de Mousse de Chocolate 4 0
ssde df s fsda sad er um copo de Vodka 5 0
ssde df s fsda sad er um chocolate Snickers 6 0
aaaaaaaaa dsaass de Bife 7 0
aaaaaaaaa dsaass de Pizza de Salmao 8 0
aaaaaaaaa dsaass de sushi 1 1.92378664
aaaaaaaaa dsaass de Bolo de Chocolate 2 0.00000000
aaaaaaaaa dsaass de Feijoada 3 0.00000000
aaaaaaaaa dsaass de Mousse de Chocolate 4 0.00000000
ssde df s fsda sad er um copo de Vodka 5 0.00000000
ssde df s fsda sad er um chocolate Snickers 6 0.00000000
aaaaaaaaa dsaass de Bife 7 0.00000000
aaaaaaaaa dsaass de Pizza de Salmao 8 0.00000000
SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi' IN BOOLEAN MODE)
as x FROM t1, t2 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
q item id x
@ -43,17 +43,17 @@ ssde df s fsda sad er um copo de Vodka 5 0
ssde df s fsda sad er um chocolate Snickers 6 0
aaaaaaaaa dsaass de Bife 7 0
aaaaaaaaa dsaass de Pizza de Salmao 8 0
SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi')
SELECT t1.q, t2.item, t2.id, round(MATCH t2.item AGAINST ('sushi'),8)
as x FROM t2, t1 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
q item id x
aaaaaaaaa dsaass de sushi 1 1.92378664016724
aaaaaaaaa dsaass de Bolo de Chocolate 2 0
aaaaaaaaa dsaass de Feijoada 3 0
aaaaaaaaa dsaass de Mousse de Chocolate 4 0
ssde df s fsda sad er um copo de Vodka 5 0
ssde df s fsda sad er um chocolate Snickers 6 0
aaaaaaaaa dsaass de Bife 7 0
aaaaaaaaa dsaass de Pizza de Salmao 8 0
aaaaaaaaa dsaass de sushi 1 1.92378664
aaaaaaaaa dsaass de Bolo de Chocolate 2 0.00000000
aaaaaaaaa dsaass de Feijoada 3 0.00000000
aaaaaaaaa dsaass de Mousse de Chocolate 4 0.00000000
ssde df s fsda sad er um copo de Vodka 5 0.00000000
ssde df s fsda sad er um chocolate Snickers 6 0.00000000
aaaaaaaaa dsaass de Bife 7 0.00000000
aaaaaaaaa dsaass de Pizza de Salmao 8 0.00000000
SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi' IN BOOLEAN MODE)
as x FROM t2, t1 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
q item id x

View File

@ -16,13 +16,13 @@ author VARCHAR(255) NOT NULL
INSERT INTO t2 VALUES('123', 'moi');
INSERT INTO t2 VALUES('123', 'lui');
INSERT INTO t2 VALUES('456', 'lui');
select match(t1.texte,t1.sujet,t1.motsclefs) against('droit')
select round(match(t1.texte,t1.sujet,t1.motsclefs) against('droit'),5)
from t1 left join t2 on t2.id=t1.id;
match(t1.texte,t1.sujet,t1.motsclefs) against('droit')
0
0
0.67003107070923
0
round(match(t1.texte,t1.sujet,t1.motsclefs) against('droit'),5)
0.00000
0.00000
0.67003
0.00000
select match(t1.texte,t1.sujet,t1.motsclefs) against('droit' IN BOOLEAN MODE)
from t1 left join t2 on t2.id=t1.id;
match(t1.texte,t1.sujet,t1.motsclefs) against('droit' IN BOOLEAN MODE)

View File

@ -11,19 +11,19 @@ FULLTEXT KEY a(b,c)
INSERT INTO t1 VALUES (1,'lala lolo lili','oooo aaaa pppp');
INSERT INTO t1 VALUES (2,'asdf fdsa','lkjh fghj');
INSERT INTO t1 VALUES (3,'qpwoei','zmxnvb');
SELECT a, MATCH b AGAINST ('lala lkjh') FROM t1;
a MATCH b AGAINST ('lala lkjh')
1 0.67003107070923
2 0
3 0
SELECT a, MATCH c AGAINST ('lala lkjh') FROM t1;
a MATCH c AGAINST ('lala lkjh')
1 0
2 0.67756325006485
3 0
SELECT a, MATCH b,c AGAINST ('lala lkjh') FROM t1;
a MATCH b,c AGAINST ('lala lkjh')
1 0.64840710163116
2 0.66266459226608
3 0
SELECT a, round(MATCH b AGAINST ('lala lkjh'),5) FROM t1;
a round(MATCH b AGAINST ('lala lkjh'),5)
1 0.67003
2 0.00000
3 0.00000
SELECT a, round(MATCH c AGAINST ('lala lkjh'),5) FROM t1;
a round(MATCH c AGAINST ('lala lkjh'),5)
1 0.00000
2 0.67756
3 0.00000
SELECT a, round(MATCH b,c AGAINST ('lala lkjh'),5) FROM t1;
a round(MATCH b,c AGAINST ('lala lkjh'),5)
1 0.64841
2 0.66266
3 0.00000
drop table t1;

View File

@ -1,3 +1,4 @@
set global innodb_table_locks=1;
select @@innodb_table_locks;
@@innodb_table_locks
1

View File

@ -272,8 +272,11 @@ insert into t2 values(10),(20);
create table t3 like t1;
show create table t3;
select * from t3;
# Disable PS becasue of @@warning_count
--disable_ps_protocol
create table if not exists t3 like t1;
select @@warning_count;
--enable_ps_protocol
create temporary table t3 like t2;
show create table t3;
select * from t3;

View File

@ -621,7 +621,7 @@ CREATE TABLE t1 (
term text NOT NULL,
PRIMARY KEY(id),
INDEX(list_id, term(19))
) TYPE=MyISAM CHARSET=utf8;
) ENGINE=MyISAM CHARSET=utf8;
INSERT INTO t1 set list_id = 1, term = "testétest";
INSERT INTO t1 set list_id = 1, term = "testetest";
INSERT INTO t1 set list_id = 1, term = "testètest";

View File

@ -118,8 +118,11 @@ SET datetime_format=default;
# Test of str_to_date
#
# PS doesn't support fraction of a seconds
--disable_ps_protocol
select str_to_date(concat('15-01-2001',' 2:59:58.999'),
concat('%d-%m-%Y',' ','%H:%i:%s.%f'));
--enable_ps_protocol
create table t1 (date char(30), format char(30) not null);
insert into t1 values
@ -153,7 +156,8 @@ insert into t1 values
('15-01-20', '%d-%m-%y'),
('15-2001-1', '%d-%Y-%c');
# Use through protocol functions
# PS doesn't support fractional seconds
--disable_ps_protocol
select date,format,str_to_date(date, format) as str_to_date from t1;
# Use as a string
select date,format,concat('',str_to_date(date, format)) as con from t1;
@ -198,6 +202,7 @@ select date,format,str_to_date(date, format) as str_to_date from t1;
select date,format,concat(str_to_date(date, format),'') as con from t1;
drop table t1;
--enable_ps_protocol
#
# Test of get_format
@ -221,6 +226,8 @@ insert into t1 values ('2004-07-14'),('2005-07-14');
select date_format(d,"%d") from t1 order by 1;
drop table t1;
# PS doesn't support fractional seconds
--disable_ps_protocol
select str_to_date("2003-....01ABCD-02 10:11:12.0012", "%Y-%.%m%@-%d %H:%i:%S.%f") as a;
@ -249,3 +256,4 @@ select str_to_date("2003-01-02 10:11:12.0012ABCD", "%Y-%m-%d %H:%i:%S.%f") as f1
select str_to_date("2003-04-05 g", "%Y-%m-%d") as f1,
str_to_date("2003-04-05 10:11:12.101010234567", "%Y-%m-%d %H:%i:%S.%f") as f2;
--enable_ps_protocol

View File

@ -29,13 +29,13 @@ INSERT INTO t2 VALUES (6,2,'um chocolate Snickers');
INSERT INTO t2 VALUES (7,1,'Bife');
INSERT INTO t2 VALUES (8,1,'Pizza de Salmao');
SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi')
SELECT t1.q, t2.item, t2.id, round(MATCH t2.item AGAINST ('sushi'),8)
as x FROM t1, t2 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi' IN BOOLEAN MODE)
as x FROM t1, t2 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi')
SELECT t1.q, t2.item, t2.id, round(MATCH t2.item AGAINST ('sushi'),8)
as x FROM t2, t1 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi' IN BOOLEAN MODE)

View File

@ -24,7 +24,7 @@ INSERT INTO t2 VALUES('123', 'moi');
INSERT INTO t2 VALUES('123', 'lui');
INSERT INTO t2 VALUES('456', 'lui');
select match(t1.texte,t1.sujet,t1.motsclefs) against('droit')
select round(match(t1.texte,t1.sujet,t1.motsclefs) against('droit'),5)
from t1 left join t2 on t2.id=t1.id;
select match(t1.texte,t1.sujet,t1.motsclefs) against('droit' IN BOOLEAN MODE)
from t1 left join t2 on t2.id=t1.id;

View File

@ -17,7 +17,7 @@ INSERT INTO t1 VALUES (1,'lala lolo lili','oooo aaaa pppp');
INSERT INTO t1 VALUES (2,'asdf fdsa','lkjh fghj');
INSERT INTO t1 VALUES (3,'qpwoei','zmxnvb');
SELECT a, MATCH b AGAINST ('lala lkjh') FROM t1;
SELECT a, MATCH c AGAINST ('lala lkjh') FROM t1;
SELECT a, MATCH b,c AGAINST ('lala lkjh') FROM t1;
SELECT a, round(MATCH b AGAINST ('lala lkjh'),5) FROM t1;
SELECT a, round(MATCH c AGAINST ('lala lkjh'),5) FROM t1;
SELECT a, round(MATCH b,c AGAINST ('lala lkjh'),5) FROM t1;
drop table t1;

View File

@ -30,7 +30,11 @@ select grp, sum(a)+count(a)+avg(a)+std(a)+variance(a)+bit_or(a)+bit_and(a)+min(a
create table t2 (grp int, a bigint unsigned, c char(10));
insert into t2 select grp,max(a)+max(grp),max(c) from t1 group by grp;
# REPLACE ... SELECT doesn't yet work with PS
--disable_ps_protocol
replace into t2 select grp, a, c from t1 limit 2,1;
--enable_ps_protocol
select * from t2;
drop table t1,t2;

View File

@ -47,17 +47,23 @@ select subtime("1997-12-31 23:59:59.999999", "1998-01-01 01:01:01.999999");
select subtime("01:00:00.999999", "02:00:00.999998");
select subtime("02:01:01.999999", "01:01:01.999999");
# PS doesn't support fractional seconds
--disable_ps_protocol
select timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002");
select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002");
select timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002");
select timediff("1997-12-31 23:59:59.000001","23:59:59.000001");
select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001");
--enable_ps_protocol
select maketime(10,11,12);
select maketime(25,11,12);
select maketime(-25,11,12);
# Extraction functions
# PS doesn't support fractional seconds
--disable_ps_protocol
select timestamp("2001-12-01", "01:01:01.999999");
select timestamp("2001-13-01", "01:01:01.000001");
select timestamp("2001-12-01", "25:01:01");
@ -69,6 +75,7 @@ select date("1997-13-31 23:59:59.000001");
select time("1997-12-31 23:59:59.000001");
select time("1997-12-31 25:59:59.000001");
select microsecond("1997-12-31 23:59:59.000001");
--enable_ps_protocol
create table t1
select makedate(1997,1) as f1,
@ -81,7 +88,10 @@ select makedate(1997,1) as f1,
date("1997-12-31 23:59:59.000001") as f8,
time("1997-12-31 23:59:59.000001") as f9;
describe t1;
# PS doesn't support fractional seconds
--disable_ps_protocol
select * from t1;
--enable_ps_protocol
create table test(t1 datetime, t2 time, t3 time, t4 datetime);
insert into test values
@ -94,7 +104,10 @@ insert into test values
('2001-01-01 01:01:01', '01:01:01', '1 01:01:01', '2001-01-01 01:01:01');
SELECT ADDTIME(t1,t2) As ttt, ADDTIME(t2, t3) As qqq from test;
# PS doesn't support fractional seconds
--disable_ps_protocol
SELECT TIMEDIFF(t1,t4) As ttt, TIMEDIFF(t2, t3) As qqq from test;
--enable_ps_protocol
drop table t1, test;
@ -102,4 +115,7 @@ select addtime("-01:01:01.01", "-23:59:59.1") as a;
select microsecond("1997-12-31 23:59:59.01") as a;
select microsecond(19971231235959.01) as a;
select date_add("1997-12-31",INTERVAL "10.09" SECOND_MICROSECOND) as a;
# PS doesn't support fractional seconds
--disable_ps_protocol
select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f");
--enable_ps_protocol

View File

@ -1 +0,0 @@
--innodb-table-lock=1

View File

@ -4,6 +4,8 @@
# Check and select innodb lock type
#
set global innodb_table_locks=1;
select @@innodb_table_locks;
#

View File

@ -92,6 +92,8 @@ drop database mysqltest;
# Test of wrong values for float data (bug #2082)
#
# PS gives sligthly different numbers for max-float/max-double
--disable_ps_protocol
use test;
create table t1(number int auto_increment primary key, original_value varchar(50), f_double double, f_float float, f_double_7_2 double(7,2), f_float_4_3 float (4,3), f_double_u double unsigned, f_float_u float unsigned, f_double_15_1_u double(15,1) unsigned, f_float_3_1_u float (3,1) unsigned);
@ -140,3 +142,4 @@ insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@val
--query_vertical select * from t1 where number =last_insert_id()
drop table t1;
--enable_ps_protocol

View File

@ -122,7 +122,10 @@ insert into t2 values (2,"t2:2"), (3,"t2:3");
--error 1062
insert into t1 select * from t2;
select * from t1;
# REPLACE .. SELECT is not yet supported by PS
--disable_ps_protocol
replace into t1 select * from t2;
--enable_ps_protocol
select * from t1;
drop table t1,t2;

View File

@ -35,10 +35,10 @@ create table t1(a int primary key, b int);
insert into t1 values(1,1),(2,2),(3,3),(4,4),(5,5);
select * from t1;
enable_info;
--enable_info
insert into t1 values(4,14),(5,15),(6,16),(7,17),(8,18)
on duplicate key update b=b+10;
disable_info;
--disable_info
select * from t1;

View File

@ -6,6 +6,8 @@
drop table if exists t1,t2;
--enable_warnings
--enable_metadata
# PS protocol gives slightly different metadata
--disable_ps_protocol
#
# First some simple tests

View File

@ -1,3 +1,6 @@
# PS doesn't support multi-statements
--disable_ps_protocol
select 1;
delimiter ||||;
select 2;

View File

@ -501,6 +501,8 @@ prepare stmt1 from ' KILL 0 ';
## simple explain
# cases derived from client_test.c: test_explain_bug()
prepare stmt1 from ' explain select a from t1 order by b ';
# PS protocol gives slightly different metadata
--disable_ps_protocol
--enable_metadata
execute stmt1;
--disable_metadata
@ -509,6 +511,7 @@ prepare stmt1 from ' explain select a from t1 where a > ? order by b ';
--enable_metadata
execute stmt1 using @arg00;
--disable_metadata
--enable_ps_protocol
## parameters with probably problematic characters (quote, double quote)
# cases derived from client_test.c: test_logs()

View File

@ -5,6 +5,8 @@
--disable_warnings
drop table if exists t1;
--enable_warnings
# PS doesn't work with BEGIN ... ROLLBACK
--disable_ps_protocol
create table t1 (n int not null primary key) engine=myisam;
begin work;

View File

@ -3,6 +3,8 @@
#
source include/master-slave.inc;
# We disable this for now as PS doesn't handle redirection
--disable_ps_protocol
#first, make sure the slave has had enough time to register
save_master_pos;

View File

@ -2,6 +2,9 @@
# Test of replicating user variables
#
source include/master-slave.inc;
# Disable PS as the log positions differs
--disable_ps_protocol
# Clean up old slave's binlogs.
# The slave is started with --log-slave-updates

View File

@ -1706,12 +1706,18 @@ select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.compan
select count(*) from t2;
select count(*) from t2 where fld1 < 098024;
# PS does correct pre-zero here. MySQL can't do it as it returns a number.
--disable_ps_protocol
select min(fld1) from t2 where fld1>= 098024;
--enable_ps_protocol
select max(fld1) from t2 where fld1>= 098024;
select count(*) from t3 where price2=76234234;
select count(*) from t3 where companynr=512 and price2=76234234;
explain select min(fld1),max(fld1),count(*) from t2;
# PS does correct pre-zero here. MySQL can't do it as it returns a number.
--disable_ps_protocol
select min(fld1),max(fld1),count(*) from t2;
--enable_ps_protocol
select min(t2nr),max(t2nr) from t3 where t2nr=2115 and price2=823742;
select count(*),min(t2nr),max(t2nr) from t3 where name='spates' and companynr=78;
select t2nr,count(*) from t3 where name='gems' group by t2nr limit 20;

View File

@ -5,6 +5,8 @@
# connection in a separate thread.
#
--source include/not_embedded.inc
# PS causes different statistics
--disable_ps_protocol
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);

View File

@ -16,7 +16,10 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7;
CREATE TABLE t1 (a blob, b text, c blob(250), d text(70000), e text(70000000));
show columns from t1;
# PS doesn't give errors on prepare yet
--disable_ps_protocol
CREATE TABLE t2 (a char(257), b varbinary(70000), c varchar(70000000));
--enable_ps_protocol
show columns from t2;
create table t3 (a long, b long byte);
show create TABLE t3;

View File

@ -39,7 +39,10 @@ create table t1 (c1 double, c2 varchar(20));
insert t1 values (121,"16");
select c1 + c1 * (c2 / 100) as col from t1;
create table t2 select c1 + c1 * (c2 / 100) as col1, round(c1, 5) as col2, round(c1, 35) as col3, sqrt(c1*1e-15) col4 from t1;
# Floats are a bit different in PS
--disable_ps_protocol
select * from t2;
--enable_ps_protocol
show create table t2;
drop table t1,t2;

View File

@ -5,6 +5,9 @@
--disable_warnings
drop table if exists t1,t2,t3,t4,t5,t6;
--enable_warnings
# PS doesn't work correctly with found_rows: to be fixed
--disable_ps_protocol
CREATE TABLE t1 (a int not null, b char (10) not null);
insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c');
@ -73,6 +76,7 @@ select * from t1 union select SQL_BUFFER_RESULT * from t2;
# Test CREATE, INSERT and REPLACE
create table t3 select a,b from t1 union all select a,b from t2;
insert into t3 select a,b from t1 union all select a,b from t2;
# PS can't handle REPLACE ... SELECT
replace into t3 select a,b as c from t1 union all select a,b from t2;
drop table t1,t2,t3;

View File

@ -26,8 +26,11 @@ show warnings limit 1;
drop database if exists not_exists_db;
show count(*) warnings;
create table t1(id int);
# PS doesn't give warnings on prepare
--disable_ps_protocol
create table if not exists t1(id int);
select @@warning_count;
--enable_ps_protocol
drop table t1;
#
@ -36,7 +39,10 @@ drop table t1;
create table t1(a tinyint, b int not null, c date, d char(5));
load data infile '../../std_data/warnings_loaddata.dat' into table t1 fields terminated by ',';
# PS doesn't work good with @@warning_count
--disable_ps_protocol
select @@warning_count;
--enable_ps_protocol
drop table t1;
#
@ -74,7 +80,9 @@ enable_query_log;
alter table t1 add b char;
set max_error_count=10;
update t1 set b=a;
--disable_ps_protocol
select @@warning_count;
--enable_ps_protocol
#
# Test for handler type
@ -87,12 +95,15 @@ drop table t1;
#
# Test for deprecated TYPE= syntax
#
# PS doesn't give warnings on prepare
--disable_ps_protocol
create table t1 (id int) type=heap;
alter table t1 type=myisam;
drop table t1;
--enable_ps_protocol
#
# Test for deprecated table_type variable
#
set table_type=MYISAM;

View File

@ -158,6 +158,8 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size)
next->next= mem_root->used;
next->size= Size;
mem_root->used= next;
DBUG_PRINT("exit",("ptr: 0x%lx", (((char*) next)+
ALIGN_SIZE(sizeof(USED_MEM)))));
DBUG_RETURN((gptr) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM))));
#else
uint get_size, block_size;

View File

@ -727,6 +727,7 @@ void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate)
static void cli_flush_use_result(MYSQL *mysql)
{
/* Clear the current execution status */
DBUG_ENTER("cli_flush_use_result");
DBUG_PRINT("warning",("Not all packets read, clearing them"));
for (;;)
{
@ -744,6 +745,7 @@ static void cli_flush_use_result(MYSQL *mysql)
break; /* End of data */
}
}
DBUG_VOID_RETURN;
}

View File

@ -742,9 +742,13 @@ void set_zero_time(MYSQL_TIME *tm)
int my_time_to_str(const MYSQL_TIME *l_time, char *to)
{
uint extra_hours= 0;
/* Get extra hours, if we are getting data from the server */
if (l_time->year == 0 && l_time->month == 0)
extra_hours= l_time->day*24;
return my_sprintf(to, (to, "%s%02d:%02d:%02d",
(l_time->neg ? "-" : ""),
l_time->hour,
extra_hours+ l_time->hour,
l_time->minute,
l_time->second));
}

View File

@ -3508,8 +3508,8 @@ bool Field_time::send_binary(Protocol *protocol)
{
TIME tm;
Field_time::get_time(&tm);
tm.day= tm.hour/3600; // Move hours to days
tm.hour-= tm.day*3600;
tm.day= tm.hour/24; // Move hours to days
tm.hour-= tm.day*24;
return protocol->store_time(&tm);
}

View File

@ -1760,6 +1760,7 @@ void Item_func_in::fix_length_and_dec()
{
Item **arg, **arg_end;
uint const_itm= 1;
THD *thd= current_thd;
agg_cmp_type(&cmp_type, args, arg_count);
@ -1797,6 +1798,9 @@ void Item_func_in::fix_length_and_dec()
Conversion is possible:
All IN arguments are constants.
*/
Item_arena *arena= thd->current_arena, backup;
if (arena->is_stmt_prepare())
thd->set_n_backup_item_arena(arena, &backup);
for (arg= args+1, arg_end= args+arg_count; arg < arg_end; arg++)
{
if (!my_charset_same(cmp_collation.collation,
@ -1812,6 +1816,8 @@ void Item_func_in::fix_length_and_dec()
arg[0]= conv;
}
}
if (arena->is_stmt_prepare())
thd->restore_backup_item_arena(arena, &backup);
}
}
@ -1839,7 +1845,7 @@ void Item_func_in::fix_length_and_dec()
DBUG_ASSERT(0);
return;
}
if (array && !(current_thd->is_fatal_error)) // If not EOM
if (array && !(thd->is_fatal_error)) // If not EOM
{
uint j=0;
for (uint i=1 ; i < arg_count ; i++)

View File

@ -365,9 +365,9 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
if (!(substitution= new Item_func_if(cond, substitution,
new Item_null())))
goto err;
}
if (arena->is_stmt_prepare())
thd->restore_backup_item_arena(arena, &backup);
}
return RES_REDUCE;
}
return RES_OK;

View File

@ -1693,8 +1693,7 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct,
SQL_LIST *is_order,
String *is_separator)
:Item_sum(), tmp_table_param(0), max_elements_in_tree(0), warning(0),
warning_available(0), key_length(0),
tree_mode(0), distinct(is_distinct), warning_for_row(0),
key_length(0), tree_mode(0), distinct(is_distinct), warning_for_row(0),
separator(is_separator), tree(&tree_base), table(0),
order(0), tables_list(0),
arg_count_order(0), arg_count_field(0),
@ -1752,7 +1751,6 @@ Item_func_group_concat::Item_func_group_concat(THD *thd,
tmp_table_param(item->tmp_table_param),
max_elements_in_tree(item->max_elements_in_tree),
warning(item->warning),
warning_available(item->warning_available),
key_length(item->key_length),
tree_mode(item->tree_mode),
distinct(item->distinct),
@ -1779,10 +1777,6 @@ void Item_func_group_concat::cleanup()
DBUG_ENTER("Item_func_group_concat::cleanup");
Item_sum::cleanup();
/* fix order list */
for (uint i= 0; i < arg_count_order ; i++)
order[i]->item= &order[i]->item_ptr;
/*
Free table and tree if they belong to this item (if item have not pointer
to original item from which was made copy => it own its objects )
@ -1802,6 +1796,13 @@ void Item_func_group_concat::cleanup()
tree_mode= 0;
delete_tree(tree);
}
if (warning)
{
char warn_buff[MYSQL_ERRMSG_SIZE];
sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
warning->set_msg(thd, warn_buff);
warning= 0;
}
}
DBUG_VOID_RETURN;
}
@ -1809,19 +1810,6 @@ void Item_func_group_concat::cleanup()
Item_func_group_concat::~Item_func_group_concat()
{
/*
Free table and tree if they belong to this item (if item have not pointer
to original item from which was made copy => it own its objects )
*/
if (!original)
{
if (warning_available)
{
char warn_buff[MYSQL_ERRMSG_SIZE];
sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
warning->set_msg(current_thd, warn_buff);
}
}
}
@ -2072,12 +2060,10 @@ String* Item_func_group_concat::val_str(String* str)
DBUG_ASSERT(fixed == 1);
if (null_value)
return 0;
if (count_cut_values && !warning_available)
{
warning_available= TRUE;
if (count_cut_values && !warning)
warning= push_warning(item_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_CUT_VALUE_GROUP_CONCAT, NULL);
}
ER_CUT_VALUE_GROUP_CONCAT,
ER(ER_CUT_VALUE_GROUP_CONCAT));
if (result.length())
return &result;
if (tree_mode)

View File

@ -674,7 +674,6 @@ class Item_func_group_concat : public Item_sum
TMP_TABLE_PARAM *tmp_table_param;
uint max_elements_in_tree;
MYSQL_ERROR *warning;
bool warning_available;
uint key_length;
bool tree_mode;
bool distinct;

View File

@ -1141,6 +1141,13 @@ bool Protocol_prep::store_time(TIME *tm)
field_pos++;
pos= buff+1;
pos[0]= tm->neg ? 1 : 0;
if (tm->hour >= 24)
{
/* Fix if we come from Item::send */
uint days= tm->hour/24;
tm->hour-= days*24;
tm->day+= days;
}
int4store(pos+1, tm->day);
pos[5]= (uchar) tm->hour;
pos[6]= (uchar) tm->minute;

View File

@ -2959,7 +2959,8 @@ void sys_var_thd_table_type::warn_deprecated(THD *thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DEPRECATED_SYNTAX,
ER(ER_WARN_DEPRECATED_SYNTAX), "table_type", "storage_engine");
ER(ER_WARN_DEPRECATED_SYNTAX), "table_type",
"storage_engine");
}
void sys_var_thd_table_type::set_default(THD *thd, enum_var_type type)

View File

@ -363,6 +363,7 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
{
bool found_old_table;
DBUG_ENTER("close_thread_tables");
if (thd->derived_tables && !skip_derived)
@ -385,8 +386,6 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
DBUG_VOID_RETURN; // LOCK TABLES in use
}
bool found_old_table=0;
if (thd->lock)
{
mysql_unlock_tables(thd, thd->lock);
@ -399,6 +398,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
DBUG_PRINT("info", ("thd->open_tables=%p", thd->open_tables));
found_old_table= 0;
while (thd->open_tables)
found_old_table|=close_thread_table(thd, &thd->open_tables);
thd->some_tables_deleted=0;
@ -2305,22 +2305,26 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
List<Item> *sum_func_list,
uint wild_num)
{
bool is_stmt_prepare;
DBUG_ENTER("setup_wild");
if (!wild_num)
return 0;
DBUG_RETURN(0);
Item_arena *arena= thd->current_arena, backup;
/*
If we are in preparing prepared statement phase then we have change
temporary mem_root to statement mem root to save changes of SELECT list
*/
if (arena->is_stmt_prepare())
if ((is_stmt_prepare= arena->is_stmt_prepare()))
thd->set_n_backup_item_arena(arena, &backup);
reg2 Item *item;
List_iterator<Item> it(fields);
while ( wild_num && (item= it++))
{
if (item->type() == Item::FIELD_ITEM && ((Item_field*) item)->field_name &&
if (item->type() == Item::FIELD_ITEM &&
((Item_field*) item)->field_name &&
((Item_field*) item)->field_name[0] == '*' &&
!((Item_field*) item)->field)
{
@ -2339,9 +2343,9 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
else if (insert_fields(thd,tables,((Item_field*) item)->db_name,
((Item_field*) item)->table_name, &it))
{
if (arena->is_stmt_prepare())
if (is_stmt_prepare)
thd->restore_backup_item_arena(arena, &backup);
return (-1);
DBUG_RETURN(-1);
}
if (sum_func_list)
{
@ -2355,9 +2359,9 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
wild_num--;
}
}
if (arena->is_stmt_prepare())
if (is_stmt_prepare)
thd->restore_backup_item_arena(arena, &backup);
return 0;
DBUG_RETURN(0);
}
/****************************************************************************
@ -2398,11 +2402,8 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
SYNOPSIS
setup_tables()
tables - tables list
tables table list
RETURN
0 ok; In this case *map will includes the choosed index
1 error
NOTE
Remap table numbers if INSERT ... SELECT
@ -2411,6 +2412,10 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
This has to be called for all tables that are used by items, as otherwise
table->map is not set and all Item_field will be regarded as const items.
RETURN
0 ok; In this case *map will includes the choosed index
1 error
*/
bool setup_tables(TABLE_LIST *tables)
@ -2584,7 +2589,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
{
table_map not_null_tables= 0;
Item_arena *arena= thd->current_arena, backup;
bool is_stmt_prepare= arena->is_stmt_prepare();
DBUG_ENTER("setup_conds");
thd->set_query_id=1;
@ -2622,11 +2627,11 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
!(specialflag & SPECIAL_NO_NEW_FUNC)))
{
table->outer_join= 0;
if (arena->is_stmt_prepare())
if (is_stmt_prepare)
thd->set_n_backup_item_arena(arena, &backup);
*conds= and_conds(*conds, table->on_expr);
table->on_expr=0;
if (arena->is_stmt_prepare())
if (is_stmt_prepare)
thd->restore_backup_item_arena(arena, &backup);
if ((*conds) && !(*conds)->fixed &&
(*conds)->fix_fields(thd, tables, conds))
@ -2635,7 +2640,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
}
if (table->natural_join)
{
if (arena->is_stmt_prepare())
if (is_stmt_prepare)
thd->set_n_backup_item_arena(arena, &backup);
/* Make a join of all fields with have the same name */
TABLE *t1= table->table;
@ -2677,7 +2682,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
{
*conds= and_conds(*conds, cond_and);
// fix_fields() should be made with temporary memory pool
if (arena->is_stmt_prepare())
if (is_stmt_prepare)
thd->restore_backup_item_arena(arena, &backup);
if (*conds && !(*conds)->fixed)
{
@ -2689,7 +2694,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
{
table->on_expr= and_conds(table->on_expr, cond_and);
// fix_fields() should be made with temporary memory pool
if (arena->is_stmt_prepare())
if (is_stmt_prepare)
thd->restore_backup_item_arena(arena, &backup);
if (table->on_expr && !table->on_expr->fixed)
{
@ -2698,10 +2703,12 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
}
}
}
else if (is_stmt_prepare)
thd->restore_backup_item_arena(arena, &backup);
}
}
if (arena->is_stmt_prepare())
if (is_stmt_prepare)
{
/*
We are in prepared statement preparation code => we should store
@ -2714,7 +2721,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
DBUG_RETURN(test(thd->net.report_error));
err:
if (arena->is_stmt_prepare())
if (is_stmt_prepare)
thd->restore_backup_item_arena(arena, &backup);
DBUG_RETURN(1);
}

View File

@ -841,7 +841,8 @@ bool select_send::send_eof()
/* Unlock tables before sending packet to gain some speed */
if (thd->lock)
{
mysql_unlock_tables(thd, thd->lock); thd->lock=0;
mysql_unlock_tables(thd, thd->lock);
thd->lock=0;
}
if (!thd->net.report_error)
{

View File

@ -102,12 +102,11 @@ void mysql_reset_errors(THD *thd)
MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
uint code, const char *msg)
{
MYSQL_ERROR *err= 0;
DBUG_ENTER("push_warning");
if (thd->query_id != thd->warn_id)
mysql_reset_errors(thd);
MYSQL_ERROR *err= NULL;
if (thd->warn_list.elements < thd->variables.max_error_count)
{
/*

View File

@ -1680,7 +1680,12 @@ bool select_create::send_eof()
We should be able to just keep the table in the table cache.
*/
if (!table->tmp_table)
{
hash_delete(&open_cache,(byte*) table);
/* Tell threads waiting for refresh that something has happened */
if (table->version != refresh_version)
VOID(pthread_cond_broadcast(&COND_refresh));
}
lock=0;
table=0;
VOID(pthread_mutex_unlock(&LOCK_open));
@ -1705,6 +1710,9 @@ void select_create::abort()
hash_delete(&open_cache,(byte*) table);
if (!create_info->table_existed)
quick_rm_table(table_type, db, name);
/* Tell threads waiting for refresh that something has happened */
if (table->version != refresh_version)
VOID(pthread_cond_broadcast(&COND_refresh));
}
else if (!create_info->table_existed)
close_temporary_table(thd, db, name);

View File

@ -290,6 +290,7 @@ class THD;
class select_result;
class JOIN;
class select_union;
class Procedure;
class st_select_lex_unit: public st_select_lex_node {
protected:
TABLE_LIST result_table_list;
@ -336,6 +337,7 @@ public:
st_select_lex *union_distinct; /* pointer to the last UNION DISTINCT */
bool describe; /* union exec() called for EXPLAIN */
Procedure *last_procedure; /* Pointer to procedure, if such exists */
void init_query();
bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result);

View File

@ -3590,8 +3590,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
bool dont_check_global_grants, bool no_errors)
{
DBUG_ENTER("check_access");
DBUG_PRINT("enter",("want_access: %lu master_access: %lu", want_access,
thd->master_access));
DBUG_PRINT("enter",("db: '%s' want_access: %lu master_access: %lu",
db ? db : "", want_access, thd->master_access));
#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong db_access;
#endif
@ -3645,7 +3645,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
thd->priv_user, db, test(want_access & GRANT_ACL));
else
db_access=thd->db_access;
// Remove SHOW attribute and access rights we already have
DBUG_PRINT("info",("db_access: %lu", db_access));
/* Remove SHOW attribute and access rights we already have */
want_access &= ~(thd->master_access | EXTRA_ACL);
db_access= ((*save_priv=(db_access | thd->master_access)) & want_access);
@ -4617,6 +4618,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ptr->db= empty_c_string;
ptr->db_length= 0;
}
if (thd->current_arena->is_stmt_prepare())
ptr->db= thd->strdup(ptr->db);
ptr->alias= alias_str;
if (lower_case_table_names && table->table.length)
@ -5142,9 +5145,12 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables)
*/
for (table= update_list; table; table= table->next)
{
if ((check_access(thd, UPDATE_ACL, table->db,
if (table->derived)
table->grant.privilege= SELECT_ACL;
else if ((check_access(thd, UPDATE_ACL, table->db,
&table->grant.privilege, 0, 1) ||
grant_option && check_grant(thd, UPDATE_ACL, table, 0, 1, 1)) &&
grant_option &&
check_grant(thd, UPDATE_ACL, table, 0, 1, 1)) &&
(check_access(thd, SELECT_ACL, table->db,
&table->grant.privilege, 0, 0) ||
grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0)))
@ -5162,6 +5168,7 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables)
*/
if (&lex->select_lex != lex->all_selects_list)
{
DBUG_PRINT("info",("Checking sub query list"));
for (table= tables; table; table= table->next)
{
if (table->table_in_update_from_clause)
@ -5174,7 +5181,7 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables)
if (table->table_list)
table->grant= table->table_list->grant;
}
else
else if (!table->derived)
{
if (check_access(thd, SELECT_ACL, table->db,
&table->grant.privilege, 0, 0) ||

View File

@ -1093,7 +1093,14 @@ static int mysql_test_select(Prepared_statement *stmt,
}
else
{
List<Item> &fields= lex->select_lex.item_list;
/* Make copy of item list, as change_columns may change it */
List<Item> fields(lex->select_lex.item_list);
/* Change columns if a procedure like analyse() */
if (unit->last_procedure &&
unit->last_procedure->change_columns(fields))
goto err_prep;
/*
We can use lex->result as it should've been
prepared in unit->prepare call above.
@ -1596,6 +1603,8 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
thd->current_arena= stmt;
mysql_init_query(thd, (uchar *) thd->query, thd->query_length);
/* Reset warnings from previous command */
mysql_reset_errors(thd);
lex= thd->lex;
lex->safe_to_cache_query= 0;

View File

@ -229,8 +229,12 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
(ORDER*) 0 : (ORDER *)sl->order_list.first,
(ORDER*) sl->group_list.first,
sl->having,
(ORDER*) NULL,
(is_union ? (ORDER*) 0 :
(ORDER*) thd_arg->lex->proc_list.first),
sl, this);
/* There are no * in the statement anymore (for PS) */
sl->with_wild= 0;
last_procedure= join->procedure;
if (res || thd_arg->is_fatal_error)
goto err;
if (sl == first_select)
@ -344,7 +348,8 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
0, 0,
fake_select_lex->order_list.elements,
(ORDER*) fake_select_lex->order_list.first,
(ORDER*) NULL, NULL, (ORDER*) NULL,
(ORDER*) NULL, NULL,
(ORDER*) NULL,
fake_select_lex, this);
fake_select_lex->table_list.empty();
}