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:
parent
8b6839e644
commit
6fbc869d18
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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 */
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 ;
|
||||
|
@ -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=;;"`
|
||||
;;
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -1,3 +1,4 @@
|
||||
set global innodb_table_locks=1;
|
||||
select @@innodb_table_locks;
|
||||
@@innodb_table_locks
|
||||
1
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -1 +0,0 @@
|
||||
--innodb-table-lock=1
|
@ -4,6 +4,8 @@
|
||||
# Check and select innodb lock type
|
||||
#
|
||||
|
||||
set global innodb_table_locks=1;
|
||||
|
||||
select @@innodb_table_locks;
|
||||
|
||||
#
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -1,3 +1,6 @@
|
||||
# PS doesn't support multi-statements
|
||||
--disable_ps_protocol
|
||||
|
||||
select 1;
|
||||
delimiter ||||;
|
||||
select 2;
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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,,);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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++)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) ||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user