1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Bug #32124: crash if prepared statements refer to variables in the where clause

The code to get read the value of a system variable was extracting its value 
on PREPARE stage and was substituting the value (as a constant) into the parse tree.
Note that this must be a reversible transformation, i.e. it must be reversed before
each re-execution.
Unfortunately this cannot be reliably done using the current code, because there are
other non-reversible source tree transformations that can interfere with this
reversible transformation.
Fixed by not resolving the value at PREPARE, but at EXECUTE (as the rest of the 
functions operate). Added a cache of the value (so that it's constant throughout
the execution of the query). Note that the cache also caches NULL values.
Updated an obsolete related test suite (variables-big) and the code to test the 
result type of system variables (as per bug 74).
This commit is contained in:
Georgi Kodinov
2008-10-08 14:23:53 +03:00
parent 7fa30b2858
commit 489ad44ab5
16 changed files with 542 additions and 266 deletions

View File

@ -7201,9 +7201,6 @@ static void test_field_misc()
{
MYSQL_STMT *stmt;
MYSQL_RES *result;
MYSQL_BIND my_bind[1];
char table_type[NAME_LEN];
ulong type_length;
int rc;
myheader("test_field_misc");
@ -7246,53 +7243,6 @@ static void test_field_misc()
mysql_free_result(result);
mysql_stmt_close(stmt);
stmt= mysql_simple_prepare(mysql, "SELECT @@table_type");
check_stmt(stmt);
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
bzero((char*) my_bind, sizeof(my_bind));
my_bind[0].buffer_type= MYSQL_TYPE_STRING;
my_bind[0].buffer= table_type;
my_bind[0].length= &type_length;
my_bind[0].buffer_length= NAME_LEN;
rc= mysql_stmt_bind_result(stmt, my_bind);
check_execute(stmt, rc);
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
if (!opt_silent)
fprintf(stdout, "\n default table type: %s(%ld)", table_type, type_length);
rc= mysql_stmt_fetch(stmt);
DIE_UNLESS(rc == MYSQL_NO_DATA);
mysql_stmt_close(stmt);
stmt= mysql_simple_prepare(mysql, "SELECT @@table_type");
check_stmt(stmt);
result= mysql_stmt_result_metadata(stmt);
mytest(result);
DIE_UNLESS(mysql_stmt_field_count(stmt) == mysql_num_fields(result));
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
DIE_UNLESS(1 == my_process_stmt_result(stmt));
verify_prepare_field(result, 0,
"@@table_type", "", /* field and its org name */
mysql_get_server_version(mysql) <= 50000 ?
MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
"", "", /* table and its org name */
"", type_length, 0); /* db name, length */
mysql_free_result(result);
mysql_stmt_close(stmt);
stmt= mysql_simple_prepare(mysql, "SELECT @@max_error_count");
check_stmt(stmt);
@ -7309,7 +7259,8 @@ static void test_field_misc()
"@@max_error_count", "", /* field and its org name */
MYSQL_TYPE_LONGLONG, /* field type */
"", "", /* table and its org name */
"", 10, 0); /* db name, length */
/* db name, length */
"", MY_INT64_NUM_DECIMAL_DIGITS , 0);
mysql_free_result(result);
mysql_stmt_close(stmt);
@ -7329,7 +7280,8 @@ static void test_field_misc()
"@@max_allowed_packet", "", /* field and its org name */
MYSQL_TYPE_LONGLONG, /* field type */
"", "", /* table and its org name */
"", 10, 0); /* db name, length */
/* db name, length */
"", MY_INT64_NUM_DECIMAL_DIGITS, 0);
mysql_free_result(result);
mysql_stmt_close(stmt);