mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +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:
@ -442,8 +442,6 @@ SELECT f1();
|
||||
INSERT INTO t1 VALUES (NULL, f2()), (NULL, LAST_INSERT_ID()),
|
||||
(NULL, LAST_INSERT_ID()), (NULL, f2()), (NULL, f2());
|
||||
INSERT INTO t1 VALUES (NULL, f2());
|
||||
INSERT INTO t1 VALUES (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID(5)),
|
||||
(NULL, @@LAST_INSERT_ID);
|
||||
# Test replication of substitution "IS NULL" -> "= LAST_INSERT_ID".
|
||||
INSERT INTO t1 VALUES (NULL, 0), (NULL, LAST_INSERT_ID());
|
||||
UPDATE t1 SET j= -1 WHERE i IS NULL;
|
||||
|
@ -1,7 +1,7 @@
|
||||
'#---------------------BS_STVARS_025_01----------------------#'
|
||||
SELECT COUNT(@@GLOBAL.innodb_data_home_dir);
|
||||
COUNT(@@GLOBAL.innodb_data_home_dir)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
'#---------------------BS_STVARS_025_02----------------------#'
|
||||
SET @@GLOBAL.innodb_data_home_dir=1;
|
||||
@ -9,7 +9,7 @@ ERROR HY000: Variable 'innodb_data_home_dir' is a read only variable
|
||||
Expected error 'Read only variable'
|
||||
SELECT COUNT(@@GLOBAL.innodb_data_home_dir);
|
||||
COUNT(@@GLOBAL.innodb_data_home_dir)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
'#---------------------BS_STVARS_025_03----------------------#'
|
||||
SELECT @@GLOBAL.innodb_data_home_dir = VARIABLE_VALUE
|
||||
@ -20,7 +20,7 @@ NULL
|
||||
1 Expected
|
||||
SELECT COUNT(@@GLOBAL.innodb_data_home_dir);
|
||||
COUNT(@@GLOBAL.innodb_data_home_dir)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
SELECT COUNT(VARIABLE_VALUE)
|
||||
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
|
||||
@ -36,7 +36,7 @@ NULL
|
||||
'#---------------------BS_STVARS_025_05----------------------#'
|
||||
SELECT COUNT(@@innodb_data_home_dir);
|
||||
COUNT(@@innodb_data_home_dir)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
SELECT COUNT(@@local.innodb_data_home_dir);
|
||||
ERROR HY000: Variable 'innodb_data_home_dir' is a GLOBAL variable
|
||||
@ -46,7 +46,7 @@ ERROR HY000: Variable 'innodb_data_home_dir' is a GLOBAL variable
|
||||
Expected error 'Variable is a GLOBAL variable'
|
||||
SELECT COUNT(@@GLOBAL.innodb_data_home_dir);
|
||||
COUNT(@@GLOBAL.innodb_data_home_dir)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
SELECT innodb_data_home_dir = @@SESSION.innodb_data_home_dir;
|
||||
ERROR 42S22: Unknown column 'innodb_data_home_dir' in 'field list'
|
||||
|
@ -1,7 +1,7 @@
|
||||
'#---------------------BS_STVARS_029_01----------------------#'
|
||||
SELECT COUNT(@@GLOBAL.innodb_flush_method);
|
||||
COUNT(@@GLOBAL.innodb_flush_method)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
'#---------------------BS_STVARS_029_02----------------------#'
|
||||
SET @@GLOBAL.innodb_flush_method=1;
|
||||
@ -9,7 +9,7 @@ ERROR HY000: Variable 'innodb_flush_method' is a read only variable
|
||||
Expected error 'Read only variable'
|
||||
SELECT COUNT(@@GLOBAL.innodb_flush_method);
|
||||
COUNT(@@GLOBAL.innodb_flush_method)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
'#---------------------BS_STVARS_029_03----------------------#'
|
||||
SELECT @@GLOBAL.innodb_flush_method = VARIABLE_VALUE
|
||||
@ -20,7 +20,7 @@ NULL
|
||||
1 Expected
|
||||
SELECT COUNT(@@GLOBAL.innodb_flush_method);
|
||||
COUNT(@@GLOBAL.innodb_flush_method)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
SELECT COUNT(VARIABLE_VALUE)
|
||||
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
|
||||
@ -36,7 +36,7 @@ NULL
|
||||
'#---------------------BS_STVARS_029_05----------------------#'
|
||||
SELECT COUNT(@@innodb_flush_method);
|
||||
COUNT(@@innodb_flush_method)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
SELECT COUNT(@@local.innodb_flush_method);
|
||||
ERROR HY000: Variable 'innodb_flush_method' is a GLOBAL variable
|
||||
@ -46,7 +46,7 @@ ERROR HY000: Variable 'innodb_flush_method' is a GLOBAL variable
|
||||
Expected error 'Variable is a GLOBAL variable'
|
||||
SELECT COUNT(@@GLOBAL.innodb_flush_method);
|
||||
COUNT(@@GLOBAL.innodb_flush_method)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
SELECT innodb_flush_method = @@SESSION.innodb_flush_method;
|
||||
ERROR 42S22: Unknown column 'innodb_flush_method' in 'field list'
|
||||
|
@ -162,4 +162,32 @@ a b
|
||||
12 NULL
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
CREATE TABLE t1 (a INT);
|
||||
PREPARE stmt FROM 'select 1 from `t1` where `a` = any (select (@@tmpdir))';
|
||||
EXECUTE stmt;
|
||||
1
|
||||
DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t2 (a INT PRIMARY KEY);
|
||||
INSERT INTO t2 VALUES (400000), (400001);
|
||||
SET @@sort_buffer_size=400000;
|
||||
CREATE FUNCTION p1(i INT) RETURNS INT
|
||||
BEGIN
|
||||
SET @@sort_buffer_size= i;
|
||||
RETURN i + 1;
|
||||
END|
|
||||
SELECT * FROM t2 WHERE a = @@sort_buffer_size AND p1(@@sort_buffer_size + 1) > a - 1;
|
||||
a
|
||||
400000
|
||||
DROP TABLE t2;
|
||||
DROP FUNCTION p1;
|
||||
SELECT CONCAT(@@sort_buffer_size);
|
||||
CONCAT(@@sort_buffer_size)
|
||||
400001
|
||||
SELECT LEFT("12345", @@ft_boolean_syntax);
|
||||
LEFT("12345", @@ft_boolean_syntax)
|
||||
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect INTEGER value: '+ -><()~*:""&|'
|
||||
SET @@sort_buffer_size=DEFAULT;
|
||||
End of 5.0 tests.
|
||||
|
@ -1,7 +1,7 @@
|
||||
'#---------------------BS_STVARS_046_01----------------------#'
|
||||
SELECT COUNT(@@GLOBAL.ssl_capath);
|
||||
COUNT(@@GLOBAL.ssl_capath)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
'#---------------------BS_STVARS_046_02----------------------#'
|
||||
SET @@GLOBAL.ssl_capath=1;
|
||||
@ -9,7 +9,7 @@ ERROR HY000: Variable 'ssl_capath' is a read only variable
|
||||
Expected error 'Read only variable'
|
||||
SELECT COUNT(@@GLOBAL.ssl_capath);
|
||||
COUNT(@@GLOBAL.ssl_capath)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
'#---------------------BS_STVARS_046_03----------------------#'
|
||||
SELECT @@GLOBAL.ssl_capath = VARIABLE_VALUE
|
||||
@ -20,7 +20,7 @@ NULL
|
||||
1 Expected
|
||||
SELECT COUNT(@@GLOBAL.ssl_capath);
|
||||
COUNT(@@GLOBAL.ssl_capath)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
SELECT COUNT(VARIABLE_VALUE)
|
||||
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
|
||||
@ -36,7 +36,7 @@ NULL
|
||||
'#---------------------BS_STVARS_046_05----------------------#'
|
||||
SELECT COUNT(@@ssl_capath);
|
||||
COUNT(@@ssl_capath)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
SELECT COUNT(@@local.ssl_capath);
|
||||
ERROR HY000: Variable 'ssl_capath' is a GLOBAL variable
|
||||
@ -46,7 +46,7 @@ ERROR HY000: Variable 'ssl_capath' is a GLOBAL variable
|
||||
Expected error 'Variable is a GLOBAL variable'
|
||||
SELECT COUNT(@@GLOBAL.ssl_capath);
|
||||
COUNT(@@GLOBAL.ssl_capath)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
SELECT ssl_capath = @@SESSION.ssl_capath;
|
||||
ERROR 42S22: Unknown column 'ssl_capath' in 'field list'
|
||||
|
@ -1,7 +1,7 @@
|
||||
'#---------------------BS_STVARS_048_01----------------------#'
|
||||
SELECT COUNT(@@GLOBAL.ssl_cipher);
|
||||
COUNT(@@GLOBAL.ssl_cipher)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
'#---------------------BS_STVARS_048_02----------------------#'
|
||||
SET @@GLOBAL.ssl_cipher=1;
|
||||
@ -9,7 +9,7 @@ ERROR HY000: Variable 'ssl_cipher' is a read only variable
|
||||
Expected error 'Read only variable'
|
||||
SELECT COUNT(@@GLOBAL.ssl_cipher);
|
||||
COUNT(@@GLOBAL.ssl_cipher)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
'#---------------------BS_STVARS_048_03----------------------#'
|
||||
SELECT @@GLOBAL.ssl_cipher = VARIABLE_VALUE
|
||||
@ -20,7 +20,7 @@ NULL
|
||||
1 Expected
|
||||
SELECT COUNT(@@GLOBAL.ssl_cipher);
|
||||
COUNT(@@GLOBAL.ssl_cipher)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
SELECT COUNT(VARIABLE_VALUE)
|
||||
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
|
||||
@ -36,7 +36,7 @@ NULL
|
||||
'#---------------------BS_STVARS_048_05----------------------#'
|
||||
SELECT COUNT(@@ssl_cipher);
|
||||
COUNT(@@ssl_cipher)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
SELECT COUNT(@@local.ssl_cipher);
|
||||
ERROR HY000: Variable 'ssl_cipher' is a GLOBAL variable
|
||||
@ -46,7 +46,7 @@ ERROR HY000: Variable 'ssl_cipher' is a GLOBAL variable
|
||||
Expected error 'Variable is a GLOBAL variable'
|
||||
SELECT COUNT(@@GLOBAL.ssl_cipher);
|
||||
COUNT(@@GLOBAL.ssl_cipher)
|
||||
0
|
||||
1
|
||||
1 Expected
|
||||
SELECT ssl_cipher = @@SESSION.ssl_cipher;
|
||||
ERROR 42S22: Unknown column 'ssl_cipher' in 'field list'
|
||||
|
@ -157,7 +157,7 @@ explain extended select @@IDENTITY,last_insert_id(), @@identity;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1003 select 345 AS `@@IDENTITY`,last_insert_id() AS `last_insert_id()`,345 AS `@@identity`
|
||||
Note 1003 select @@IDENTITY AS `@@IDENTITY`,last_insert_id() AS `last_insert_id()`,@@identity AS `@@identity`
|
||||
set big_tables=OFF, big_tables=ON, big_tables=0, big_tables=1, big_tables="OFF", big_tables="ON";
|
||||
set global concurrent_insert=2;
|
||||
show variables like 'concurrent_insert';
|
||||
|
@ -398,8 +398,6 @@ f1()
|
||||
INSERT INTO t1 VALUES (NULL, f2()), (NULL, LAST_INSERT_ID()),
|
||||
(NULL, LAST_INSERT_ID()), (NULL, f2()), (NULL, f2());
|
||||
INSERT INTO t1 VALUES (NULL, f2());
|
||||
INSERT INTO t1 VALUES (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID(5)),
|
||||
(NULL, @@LAST_INSERT_ID);
|
||||
INSERT INTO t1 VALUES (NULL, 0), (NULL, LAST_INSERT_ID());
|
||||
UPDATE t1 SET j= -1 WHERE i IS NULL;
|
||||
INSERT INTO t1 (i) VALUES (NULL);
|
||||
@ -422,20 +420,17 @@ i j
|
||||
11 3
|
||||
12 3
|
||||
13 8
|
||||
14 13
|
||||
15 5
|
||||
16 13
|
||||
17 -1
|
||||
18 14
|
||||
19 0
|
||||
20 0
|
||||
14 -1
|
||||
15 13
|
||||
16 0
|
||||
17 0
|
||||
SELECT * FROM t2 ORDER BY i;
|
||||
i
|
||||
2
|
||||
3
|
||||
5
|
||||
6
|
||||
19
|
||||
16
|
||||
SELECT * FROM t1;
|
||||
i j
|
||||
1 -1
|
||||
@ -451,20 +446,17 @@ i j
|
||||
11 3
|
||||
12 3
|
||||
13 8
|
||||
14 13
|
||||
15 5
|
||||
16 13
|
||||
17 -1
|
||||
18 14
|
||||
19 0
|
||||
20 0
|
||||
14 -1
|
||||
15 13
|
||||
16 0
|
||||
17 0
|
||||
SELECT * FROM t2;
|
||||
i
|
||||
2
|
||||
3
|
||||
5
|
||||
6
|
||||
19
|
||||
16
|
||||
DROP PROCEDURE p1;
|
||||
DROP FUNCTION f1;
|
||||
DROP FUNCTION f2;
|
||||
|
@ -177,4 +177,41 @@ select * from t2;
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
|
||||
#
|
||||
# Bug #32124: crash if prepared statements refer to variables in the where
|
||||
# clause
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (a INT);
|
||||
PREPARE stmt FROM 'select 1 from `t1` where `a` = any (select (@@tmpdir))';
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t2 (a INT PRIMARY KEY);
|
||||
INSERT INTO t2 VALUES (400000), (400001);
|
||||
|
||||
SET @@sort_buffer_size=400000;
|
||||
|
||||
DELIMITER |;
|
||||
|
||||
CREATE FUNCTION p1(i INT) RETURNS INT
|
||||
BEGIN
|
||||
SET @@sort_buffer_size= i;
|
||||
RETURN i + 1;
|
||||
END|
|
||||
|
||||
DELIMITER ;|
|
||||
|
||||
SELECT * FROM t2 WHERE a = @@sort_buffer_size AND p1(@@sort_buffer_size + 1) > a - 1;
|
||||
|
||||
DROP TABLE t2;
|
||||
DROP FUNCTION p1;
|
||||
|
||||
|
||||
SELECT CONCAT(@@sort_buffer_size);
|
||||
SELECT LEFT("12345", @@ft_boolean_syntax);
|
||||
|
||||
SET @@sort_buffer_size=DEFAULT;
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
68
sql/item.cc
68
sql/item.cc
@ -2380,17 +2380,15 @@ void Item_string::print(String *str, enum_query_type query_type)
|
||||
}
|
||||
|
||||
|
||||
double Item_string::val_real()
|
||||
double
|
||||
double_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
int error;
|
||||
char *end, *org_end;
|
||||
char *org_end;
|
||||
double tmp;
|
||||
CHARSET_INFO *cs= str_value.charset();
|
||||
|
||||
org_end= (char*) str_value.ptr() + str_value.length();
|
||||
tmp= my_strntod(cs, (char*) str_value.ptr(), str_value.length(), &end,
|
||||
&error);
|
||||
org_end= end;
|
||||
tmp= my_strntod(cs, (char*) cptr, end - cptr, &end, &error);
|
||||
if (error || (end != org_end && !check_if_only_end_space(cs, end, org_end)))
|
||||
{
|
||||
/*
|
||||
@ -2400,7 +2398,39 @@ double Item_string::val_real()
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE), "DOUBLE",
|
||||
str_value.ptr());
|
||||
cptr);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
double Item_string::val_real()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
return double_from_string_with_check (str_value.charset(), str_value.ptr(),
|
||||
(char *) str_value.ptr() + str_value.length());
|
||||
}
|
||||
|
||||
|
||||
longlong
|
||||
longlong_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end)
|
||||
{
|
||||
int err;
|
||||
longlong tmp;
|
||||
char *org_end= end;
|
||||
|
||||
tmp= (*(cs->cset->strtoll10))(cs, cptr, &end, &err);
|
||||
/*
|
||||
TODO: Give error if we wanted a signed integer and we got an unsigned
|
||||
one
|
||||
*/
|
||||
if (err > 0 ||
|
||||
(end != org_end && !check_if_only_end_space(cs, end, org_end)))
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
|
||||
cptr);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
@ -2413,26 +2443,8 @@ double Item_string::val_real()
|
||||
longlong Item_string::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
int err;
|
||||
longlong tmp;
|
||||
char *end= (char*) str_value.ptr()+ str_value.length();
|
||||
char *org_end= end;
|
||||
CHARSET_INFO *cs= str_value.charset();
|
||||
|
||||
tmp= (*(cs->cset->strtoll10))(cs, str_value.ptr(), &end, &err);
|
||||
/*
|
||||
TODO: Give error if we wanted a signed integer and we got an unsigned
|
||||
one
|
||||
*/
|
||||
if (err > 0 ||
|
||||
(end != org_end && !check_if_only_end_space(cs, end, org_end)))
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
|
||||
str_value.ptr());
|
||||
}
|
||||
return tmp;
|
||||
return longlong_from_string_with_check(str_value.charset(), str_value.ptr(),
|
||||
(char *) str_value.ptr()+ str_value.length());
|
||||
}
|
||||
|
||||
|
||||
|
@ -1981,6 +1981,11 @@ private:
|
||||
};
|
||||
|
||||
|
||||
longlong
|
||||
longlong_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end);
|
||||
double
|
||||
double_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end);
|
||||
|
||||
class Item_static_string_func :public Item_string
|
||||
{
|
||||
const char *func_name;
|
||||
|
395
sql/item_func.cc
395
sql/item_func.cc
@ -4800,39 +4800,392 @@ Item_func_get_system_var::
|
||||
Item_func_get_system_var(sys_var *var_arg, enum_var_type var_type_arg,
|
||||
LEX_STRING *component_arg, const char *name_arg,
|
||||
size_t name_len_arg)
|
||||
:var(var_arg), var_type(var_type_arg), component(*component_arg)
|
||||
:var(var_arg), var_type(var_type_arg), component(*component_arg),
|
||||
cache_present(0)
|
||||
{
|
||||
/* set_name() will allocate the name */
|
||||
set_name(name_arg, name_len_arg, system_charset_info);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Item_func_get_system_var::fix_fields(THD *thd, Item **ref)
|
||||
{
|
||||
Item *item;
|
||||
DBUG_ENTER("Item_func_get_system_var::fix_fields");
|
||||
|
||||
/*
|
||||
Evaluate the system variable and substitute the result (a basic constant)
|
||||
instead of this item. If the variable can not be evaluated,
|
||||
the error is reported in sys_var::item().
|
||||
*/
|
||||
if (!(item= var->item(thd, var_type, &component)))
|
||||
DBUG_RETURN(1); // Impossible
|
||||
item->set_name(name, 0, system_charset_info); // don't allocate a new name
|
||||
thd->change_item_tree(ref, item);
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
bool Item_func_get_system_var::is_written_to_binlog()
|
||||
{
|
||||
return var->is_written_to_binlog(var_type);
|
||||
}
|
||||
|
||||
|
||||
void Item_func_get_system_var::fix_length_and_dec()
|
||||
{
|
||||
maybe_null=0;
|
||||
|
||||
if (var->check_type(var_type))
|
||||
{
|
||||
if (var_type != OPT_DEFAULT)
|
||||
{
|
||||
my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0),
|
||||
var->name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
|
||||
return;
|
||||
}
|
||||
/* As there was no local variable, return the global value */
|
||||
var_type= OPT_GLOBAL;
|
||||
}
|
||||
|
||||
switch (var->show_type())
|
||||
{
|
||||
case SHOW_LONG:
|
||||
case SHOW_INT:
|
||||
case SHOW_HA_ROWS:
|
||||
unsigned_flag= TRUE;
|
||||
max_length= MY_INT64_NUM_DECIMAL_DIGITS;
|
||||
decimals=0;
|
||||
break;
|
||||
case SHOW_LONGLONG:
|
||||
unsigned_flag= FALSE;
|
||||
max_length= MY_INT64_NUM_DECIMAL_DIGITS;
|
||||
decimals=0;
|
||||
break;
|
||||
case SHOW_CHAR:
|
||||
case SHOW_CHAR_PTR:
|
||||
collation.set(system_charset_info, DERIVATION_SYSCONST);
|
||||
max_length= MAX_BLOB_WIDTH;
|
||||
decimals=NOT_FIXED_DEC;
|
||||
break;
|
||||
case SHOW_MY_BOOL:
|
||||
unsigned_flag= FALSE;
|
||||
max_length= 1;
|
||||
decimals=0;
|
||||
break;
|
||||
case SHOW_DOUBLE:
|
||||
unsigned_flag= FALSE;
|
||||
decimals= 6;
|
||||
max_length= DBL_DIG + 6;
|
||||
break;
|
||||
default:
|
||||
my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Item_func_get_system_var::print(String *str, enum_query_type query_type)
|
||||
{
|
||||
str->append(name, name_length);
|
||||
}
|
||||
|
||||
|
||||
enum Item_result Item_func_get_system_var::result_type() const
|
||||
{
|
||||
switch (var->show_type())
|
||||
{
|
||||
case SHOW_MY_BOOL:
|
||||
case SHOW_INT:
|
||||
case SHOW_LONG:
|
||||
case SHOW_LONGLONG:
|
||||
case SHOW_HA_ROWS:
|
||||
return INT_RESULT;
|
||||
case SHOW_CHAR:
|
||||
case SHOW_CHAR_PTR:
|
||||
return STRING_RESULT;
|
||||
case SHOW_DOUBLE:
|
||||
return REAL_RESULT;
|
||||
default:
|
||||
my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
|
||||
return STRING_RESULT; // keep the compiler happy
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum_field_types Item_func_get_system_var::field_type() const
|
||||
{
|
||||
switch (var->show_type())
|
||||
{
|
||||
case SHOW_MY_BOOL:
|
||||
case SHOW_INT:
|
||||
case SHOW_LONG:
|
||||
case SHOW_LONGLONG:
|
||||
case SHOW_HA_ROWS:
|
||||
return MYSQL_TYPE_LONGLONG;
|
||||
case SHOW_CHAR:
|
||||
case SHOW_CHAR_PTR:
|
||||
return MYSQL_TYPE_VARCHAR;
|
||||
case SHOW_DOUBLE:
|
||||
return MYSQL_TYPE_DOUBLE;
|
||||
default:
|
||||
my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
|
||||
return MYSQL_TYPE_VARCHAR; // keep the compiler happy
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define get_sys_var_safe(type) \
|
||||
do { \
|
||||
type value; \
|
||||
pthread_mutex_lock(&LOCK_global_system_variables); \
|
||||
value= *(type*) var->value_ptr(thd, var_type, &component); \
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables); \
|
||||
cache_present |= GET_SYS_VAR_CACHE_LONG; \
|
||||
used_query_id= thd->query_id; \
|
||||
cached_llval= null_value ? 0 : (longlong) value; \
|
||||
cached_null_value= null_value; \
|
||||
return cached_llval; \
|
||||
} while (0)
|
||||
|
||||
|
||||
longlong Item_func_get_system_var::val_int()
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
|
||||
if (thd->query_id == used_query_id)
|
||||
{
|
||||
if (cache_present & GET_SYS_VAR_CACHE_LONG)
|
||||
{
|
||||
null_value= cached_null_value;
|
||||
return cached_llval;
|
||||
}
|
||||
else if (cache_present & GET_SYS_VAR_CACHE_DOUBLE)
|
||||
{
|
||||
null_value= cached_null_value;
|
||||
cached_llval= (longlong) cached_dval;
|
||||
cache_present|= GET_SYS_VAR_CACHE_LONG;
|
||||
return cached_llval;
|
||||
}
|
||||
else if (cache_present & GET_SYS_VAR_CACHE_STRING)
|
||||
{
|
||||
null_value= cached_null_value;
|
||||
if (!null_value)
|
||||
cached_llval= longlong_from_string_with_check (cached_strval.charset(),
|
||||
cached_strval.c_ptr(),
|
||||
cached_strval.c_ptr() +
|
||||
cached_strval.length());
|
||||
else
|
||||
cached_llval= 0;
|
||||
cache_present|= GET_SYS_VAR_CACHE_LONG;
|
||||
return cached_llval;
|
||||
}
|
||||
}
|
||||
|
||||
switch (var->show_type())
|
||||
{
|
||||
case SHOW_INT: get_sys_var_safe (uint);
|
||||
case SHOW_LONG: get_sys_var_safe (ulong);
|
||||
case SHOW_LONGLONG: get_sys_var_safe (longlong);
|
||||
case SHOW_HA_ROWS: get_sys_var_safe (ha_rows);
|
||||
case SHOW_MY_BOOL: get_sys_var_safe (my_bool);
|
||||
case SHOW_DOUBLE:
|
||||
{
|
||||
double dval= val_real();
|
||||
|
||||
used_query_id= thd->query_id;
|
||||
cached_llval= (longlong) dval;
|
||||
cache_present|= GET_SYS_VAR_CACHE_LONG;
|
||||
return cached_llval;
|
||||
}
|
||||
case SHOW_CHAR:
|
||||
case SHOW_CHAR_PTR:
|
||||
{
|
||||
String *str_val= val_str(NULL);
|
||||
|
||||
if (str_val && str_val->length())
|
||||
cached_llval= longlong_from_string_with_check (system_charset_info,
|
||||
str_val->c_ptr(),
|
||||
str_val->c_ptr() +
|
||||
str_val->length());
|
||||
else
|
||||
{
|
||||
null_value= TRUE;
|
||||
cached_llval= 0;
|
||||
}
|
||||
|
||||
cache_present|= GET_SYS_VAR_CACHE_LONG;
|
||||
return cached_llval;
|
||||
}
|
||||
|
||||
default:
|
||||
my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
|
||||
return 0; // keep the compiler happy
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String* Item_func_get_system_var::val_str(String* str)
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
|
||||
if (thd->query_id == used_query_id)
|
||||
{
|
||||
if (cache_present & GET_SYS_VAR_CACHE_STRING)
|
||||
{
|
||||
null_value= cached_null_value;
|
||||
return null_value ? NULL : &cached_strval;
|
||||
}
|
||||
else if (cache_present & GET_SYS_VAR_CACHE_LONG)
|
||||
{
|
||||
null_value= cached_null_value;
|
||||
if (!null_value)
|
||||
cached_strval.set (cached_llval, collation.collation);
|
||||
cache_present|= GET_SYS_VAR_CACHE_STRING;
|
||||
return null_value ? NULL : &cached_strval;
|
||||
}
|
||||
else if (cache_present & GET_SYS_VAR_CACHE_DOUBLE)
|
||||
{
|
||||
null_value= cached_null_value;
|
||||
if (!null_value)
|
||||
cached_strval.set_real (cached_dval, decimals, collation.collation);
|
||||
cache_present|= GET_SYS_VAR_CACHE_STRING;
|
||||
return null_value ? NULL : &cached_strval;
|
||||
}
|
||||
}
|
||||
|
||||
str= &cached_strval;
|
||||
switch (var->show_type())
|
||||
{
|
||||
case SHOW_CHAR:
|
||||
case SHOW_CHAR_PTR:
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
char *cptr= var->show_type() == SHOW_CHAR_PTR ?
|
||||
*(char**) var->value_ptr(thd, var_type, &component) :
|
||||
(char*) var->value_ptr(thd, var_type, &component);
|
||||
if (cptr)
|
||||
{
|
||||
if (str->copy(cptr, strlen(cptr), collation.collation))
|
||||
{
|
||||
null_value= TRUE;
|
||||
str= NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
null_value= TRUE;
|
||||
str= NULL;
|
||||
}
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
break;
|
||||
}
|
||||
|
||||
case SHOW_INT:
|
||||
case SHOW_LONG:
|
||||
case SHOW_LONGLONG:
|
||||
case SHOW_HA_ROWS:
|
||||
case SHOW_MY_BOOL:
|
||||
str->set (val_int(), collation.collation);
|
||||
break;
|
||||
case SHOW_DOUBLE:
|
||||
str->set_real (val_real(), decimals, collation.collation);
|
||||
break;
|
||||
|
||||
default:
|
||||
my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
|
||||
str= NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
cache_present|= GET_SYS_VAR_CACHE_STRING;
|
||||
used_query_id= thd->query_id;
|
||||
cached_null_value= null_value;
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
double Item_func_get_system_var::val_real()
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
|
||||
if (thd->query_id == used_query_id)
|
||||
{
|
||||
if (cache_present & GET_SYS_VAR_CACHE_DOUBLE)
|
||||
{
|
||||
null_value= cached_null_value;
|
||||
return cached_dval;
|
||||
}
|
||||
else if (cache_present & GET_SYS_VAR_CACHE_LONG)
|
||||
{
|
||||
null_value= cached_null_value;
|
||||
cached_dval= (double)cached_llval;
|
||||
cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
|
||||
return cached_dval;
|
||||
}
|
||||
else if (cache_present & GET_SYS_VAR_CACHE_STRING)
|
||||
{
|
||||
null_value= cached_null_value;
|
||||
if (!null_value)
|
||||
cached_dval= double_from_string_with_check (cached_strval.charset(),
|
||||
cached_strval.c_ptr(),
|
||||
cached_strval.c_ptr() +
|
||||
cached_strval.length());
|
||||
else
|
||||
cached_dval= 0;
|
||||
cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
|
||||
return cached_dval;
|
||||
}
|
||||
}
|
||||
|
||||
switch (var->show_type())
|
||||
{
|
||||
case SHOW_DOUBLE:
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
cached_dval= *(double*) var->value_ptr(thd, var_type, &component);
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
used_query_id= thd->query_id;
|
||||
cached_null_value= null_value;
|
||||
if (null_value)
|
||||
cached_dval= 0;
|
||||
cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
|
||||
return cached_dval;
|
||||
case SHOW_CHAR:
|
||||
case SHOW_CHAR_PTR:
|
||||
{
|
||||
char *cptr;
|
||||
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
cptr= var->show_type() == SHOW_CHAR ?
|
||||
(char*) var->value_ptr(thd, var_type, &component) :
|
||||
*(char**) var->value_ptr(thd, var_type, &component);
|
||||
if (cptr)
|
||||
cached_dval= double_from_string_with_check (system_charset_info,
|
||||
cptr, cptr + strlen (cptr));
|
||||
else
|
||||
{
|
||||
null_value= TRUE;
|
||||
cached_dval= 0;
|
||||
}
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
used_query_id= thd->query_id;
|
||||
cached_null_value= null_value;
|
||||
cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
|
||||
return cached_dval;
|
||||
}
|
||||
case SHOW_INT:
|
||||
case SHOW_LONG:
|
||||
case SHOW_LONGLONG:
|
||||
case SHOW_HA_ROWS:
|
||||
case SHOW_MY_BOOL:
|
||||
cached_dval= (double) val_int();
|
||||
cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
|
||||
used_query_id= thd->query_id;
|
||||
cached_null_value= null_value;
|
||||
return cached_dval;
|
||||
default:
|
||||
my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Item_func_get_system_var::eq(const Item *item, bool binary_cmp) const
|
||||
{
|
||||
/* Assume we don't have rtti */
|
||||
if (this == item)
|
||||
return 1; // Same item is same.
|
||||
/* Check if other type is also a get_user_var() object */
|
||||
if (item->type() != FUNC_ITEM ||
|
||||
((Item_func*) item)->functype() != functype())
|
||||
return 0;
|
||||
Item_func_get_system_var *other=(Item_func_get_system_var*) item;
|
||||
return (var == other->var && var_type == other->var_type);
|
||||
}
|
||||
|
||||
|
||||
longlong Item_func_inet_aton::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
NOW_FUNC, TRIG_COND_FUNC,
|
||||
SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
|
||||
EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC,
|
||||
NEG_FUNC };
|
||||
NEG_FUNC, GSYSVAR_FUNC };
|
||||
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
|
||||
OPTIMIZE_EQUAL };
|
||||
enum Type type() const { return FUNC_ITEM; }
|
||||
@ -1426,24 +1426,36 @@ public:
|
||||
|
||||
/* A system variable */
|
||||
|
||||
#define GET_SYS_VAR_CACHE_LONG 1
|
||||
#define GET_SYS_VAR_CACHE_DOUBLE 2
|
||||
#define GET_SYS_VAR_CACHE_STRING 4
|
||||
|
||||
class Item_func_get_system_var :public Item_func
|
||||
{
|
||||
sys_var *var;
|
||||
enum_var_type var_type;
|
||||
LEX_STRING component;
|
||||
longlong cached_llval;
|
||||
double cached_dval;
|
||||
String cached_strval;
|
||||
my_bool cached_null_value;
|
||||
query_id_t used_query_id;
|
||||
uchar cache_present;
|
||||
|
||||
public:
|
||||
Item_func_get_system_var(sys_var *var_arg, enum_var_type var_type_arg,
|
||||
LEX_STRING *component_arg, const char *name_arg,
|
||||
size_t name_len_arg);
|
||||
bool fix_fields(THD *thd, Item **ref);
|
||||
/*
|
||||
Stubs for pure virtual methods. Should never be called: this
|
||||
item is always substituted with a constant in fix_fields().
|
||||
*/
|
||||
double val_real() { DBUG_ASSERT(0); return 0.0; }
|
||||
longlong val_int() { DBUG_ASSERT(0); return 0; }
|
||||
String* val_str(String*) { DBUG_ASSERT(0); return 0; }
|
||||
void fix_length_and_dec() { DBUG_ASSERT(0); }
|
||||
enum Functype functype() const { return GSYSVAR_FUNC; }
|
||||
void fix_length_and_dec();
|
||||
void print(String *str, enum_query_type query_type);
|
||||
bool const_item() const { return true; }
|
||||
table_map used_tables() const { return 0; }
|
||||
enum Item_result result_type() const;
|
||||
enum_field_types field_type() const;
|
||||
double val_real();
|
||||
longlong val_int();
|
||||
String* val_str(String*);
|
||||
/* TODO: fix to support views */
|
||||
const char *func_name() const { return "get_system_var"; }
|
||||
/**
|
||||
@ -1455,6 +1467,7 @@ public:
|
||||
@return true if the variable is written to the binlog, false otherwise.
|
||||
*/
|
||||
bool is_written_to_binlog();
|
||||
bool eq(const Item *item, bool binary_cmp) const;
|
||||
};
|
||||
|
||||
|
||||
|
113
sql/set_var.cc
113
sql/set_var.cc
@ -1734,119 +1734,6 @@ err:
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Return an Item for a variable.
|
||||
|
||||
Used with @@[global.]variable_name.
|
||||
|
||||
If type is not given, return local value if exists, else global.
|
||||
*/
|
||||
|
||||
Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base)
|
||||
{
|
||||
if (check_type(var_type))
|
||||
{
|
||||
if (var_type != OPT_DEFAULT)
|
||||
{
|
||||
my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0),
|
||||
name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
|
||||
return 0;
|
||||
}
|
||||
/* As there was no local variable, return the global value */
|
||||
var_type= OPT_GLOBAL;
|
||||
}
|
||||
switch (show_type()) {
|
||||
case SHOW_INT:
|
||||
{
|
||||
uint value;
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
value= *(uint*) value_ptr(thd, var_type, base);
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
return new Item_uint((ulonglong) value);
|
||||
}
|
||||
case SHOW_LONG:
|
||||
{
|
||||
ulong value;
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
value= *(ulong*) value_ptr(thd, var_type, base);
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
return new Item_uint((ulonglong) value);
|
||||
}
|
||||
case SHOW_LONGLONG:
|
||||
{
|
||||
longlong value;
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
value= *(longlong*) value_ptr(thd, var_type, base);
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
return new Item_int(value);
|
||||
}
|
||||
case SHOW_DOUBLE:
|
||||
{
|
||||
double value;
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
value= *(double*) value_ptr(thd, var_type, base);
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
/* 6, as this is for now only used with microseconds */
|
||||
return new Item_float(value, 6);
|
||||
}
|
||||
case SHOW_HA_ROWS:
|
||||
{
|
||||
ha_rows value;
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
value= *(ha_rows*) value_ptr(thd, var_type, base);
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
return new Item_int((ulonglong) value);
|
||||
}
|
||||
case SHOW_MY_BOOL:
|
||||
{
|
||||
int32 value;
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
value= *(my_bool*) value_ptr(thd, var_type, base);
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
return new Item_int(value,1);
|
||||
}
|
||||
case SHOW_CHAR_PTR:
|
||||
{
|
||||
Item *tmp;
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
char *str= *(char**) value_ptr(thd, var_type, base);
|
||||
if (str)
|
||||
{
|
||||
uint length= strlen(str);
|
||||
tmp= new Item_string(thd->strmake(str, length), length,
|
||||
system_charset_info, DERIVATION_SYSCONST);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp= new Item_null();
|
||||
tmp->collation.set(system_charset_info, DERIVATION_SYSCONST);
|
||||
}
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
return tmp;
|
||||
}
|
||||
case SHOW_CHAR:
|
||||
{
|
||||
Item *tmp;
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
char *str= (char*) value_ptr(thd, var_type, base);
|
||||
if (str)
|
||||
tmp= new Item_string(str, strlen(str),
|
||||
system_charset_info, DERIVATION_SYSCONST);
|
||||
else
|
||||
{
|
||||
tmp= new Item_null();
|
||||
tmp->collation.set(system_charset_info, DERIVATION_SYSCONST);
|
||||
}
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
return tmp;
|
||||
}
|
||||
default:
|
||||
my_error(ER_VAR_CANT_BE_READ, MYF(0), name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool sys_var_thd_enum::update(THD *thd, set_var *var)
|
||||
{
|
||||
if (var->type == OPT_GLOBAL)
|
||||
|
@ -105,7 +105,6 @@ public:
|
||||
{ return type != INT_RESULT; } /* Assume INT */
|
||||
virtual bool check_default(enum_var_type type)
|
||||
{ return option_limits == 0; }
|
||||
Item *item(THD *thd, enum_var_type type, LEX_STRING *base);
|
||||
virtual bool is_struct() { return 0; }
|
||||
virtual bool is_readonly() const { return 0; }
|
||||
virtual sys_var_pluginvar *cast_pluginvar() { return 0; }
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user