Below is the list of changes that have just been committed into a local
4.1 repository of kostja. When kostja does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.2359 05/07/15 23:13:29 konstantin@stripped +7 -0
A fix and a test case for Bug#9359 "Prepared statements take snapshot
of system vars at PREPARE time": implement a special Item
to handle system variables. This item substitutes itself with
a basic constant containing variable value at fix_fields.
sql/set_var.h
1.59 05/07/15 23:13:25 konstantin@stripped +0 -5
- declaration of enum_var_type moved to mysql_priv.h
sql/set_var.cc
1.172 05/07/15 23:13:24 konstantin@stripped +3 -3
- we should not print to network from get_system_var: if it's called
from prepared statement prepare, we get packets out of order when using
the binary protocol. Instead report the error to be sent to the user later.
This is a backport from 5.0.
sql/mysql_priv.h
1.356 05/07/15 23:13:24 konstantin@stripped +6 -4
Move necessary declarations to make set_var.h objects visible in
item_func.h
sql/item_func.h
1.125 05/07/15 23:13:24 konstantin@stripped +23 -0
Add a new item, Item_func_get_system_var
sql/item_func.cc
1.254 05/07/15 23:13:24 konstantin@stripped +38 -30
- implement Item_func_get_system_var: we should not evaluate system
variables in the parser, but instead should create an item which
is evaluated to a constant at execute.
- remove an unused function
mysql-test/t/ps.test
1.41 05/07/15 23:13:24 konstantin@stripped +17 -1
- add a test case for Bug#9359 "Prepared statements take snapshot
of system vars at PREPARE time"
mysql-test/r/ps.result
1.41 05/07/15 23:13:24 konstantin@stripped +25 -0
- test results fixed (Bug#9359).
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: konstantin
# Host: dragonfly.local
# Root: /opt/local/work/mysql-4.1-root
--- 1.253/sql/item_func.cc 2005-07-14 20:02:29 +04:00
+++ 1.254/sql/item_func.cc 2005-07-15 23:13:24 +04:00
@@ -3031,6 +3031,36 @@
}
+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)
+{
+ /* 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, TABLE_LIST *tables, Item **ref)
+{
+ Item *item= var->item(thd, var_type, &component);
+ 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 == 0)
+ 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);
+}
+
+
longlong Item_func_inet_aton::val_int()
{
DBUG_ASSERT(fixed == 1);
@@ -3375,22 +3405,21 @@
0 error
# constant item
*/
-
+
Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
LEX_STRING component)
{
+ sys_var *var;
+ char buff[MAX_SYS_VAR_LENGTH*2+4+8], *pos;
+ LEX_STRING *base_name, *component_name;
+
if (component.str == 0 &&
!my_strcasecmp(system_charset_info, name.str, "VERSION"))
return new Item_string("@@VERSION", server_version,
(uint) strlen(server_version),
system_charset_info, DERIVATION_SYSCONST);
- Item *item;
- sys_var *var;
- char buff[MAX_SYS_VAR_LENGTH*2+4+8], *pos;
- LEX_STRING *base_name, *component_name;
-
if (component.str)
{
base_name= &component;
@@ -3412,9 +3441,8 @@
return 0;
}
}
- if (!(item=var->item(thd, var_type, component_name)))
- return 0; // Impossible
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
+
buff[0]='@';
buff[1]='@';
pos=buff+2;
@@ -3435,28 +3463,8 @@
memcpy(pos, base_name->str, base_name->length);
pos+= base_name->length;
- // set_name() will allocate the name
- item->set_name(buff,(uint) (pos-buff), system_charset_info);
- return item;
-}
-
-
-Item *get_system_var(THD *thd, enum_var_type var_type, const char *var_name,
- uint length, const char *item_name)
-{
- Item *item;
- sys_var *var;
- LEX_STRING null_lex_string;
-
- null_lex_string.str= 0;
-
- var= find_sys_var(var_name, length);
- DBUG_ASSERT(var != 0);
- if (!(item=var->item(thd, var_type, &null_lex_string)))
- return 0; // Impossible
- thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
- item->set_name(item_name, 0, system_charset_info); // Will use original name
- return item;
+ return new Item_func_get_system_var(var, var_type, component_name,
+ buff, pos - buff);
}
--- 1.124/sql/item_func.h 2005-05-09 13:33:15 +04:00
+++ 1.125/sql/item_func.h 2005-07-15 23:13:24 +04:00
@@ -988,6 +988,29 @@
};
+/* A system variable */
+
+class Item_func_get_system_var :public Item_func
+{
+ sys_var *var;
+ enum_var_type var_type;
+ LEX_STRING component;
+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, TABLE_LIST *tables, Item **ref);
+ /*
+ Stubs for pure virtual methods. Should never be called: this
+ item is always substituted with a constant in fix_fields().
+ */
+ double val() { 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); }
+};
+
+
class Item_func_inet_aton : public Item_int_func
{
public:
--- 1.355/sql/mysql_priv.h 2005-07-13 17:39:43 +04:00
+++ 1.356/sql/mysql_priv.h 2005-07-15 23:13:24 +04:00
@@ -358,6 +358,11 @@
#include "protocol.h"
#include "sql_udf.h"
class user_var_entry;
+enum enum_var_type
+{
+ OPT_DEFAULT, OPT_SESSION, OPT_GLOBAL
+};
+class sys_var;
#include "item.h"
typedef Comp_creator* (*chooser_compare_func_creator)(bool invert);
/* sql_parse.cc */
@@ -1119,12 +1124,9 @@
extern void sql_cache_free();
extern int sql_cache_hit(THD *thd, char *inBuf, uint length);
-/* item.cc */
+/* item_func.cc */
Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
LEX_STRING component);
-Item *get_system_var(THD *thd, enum_var_type var_type, const char *var_name,
- uint length, const char *item_name);
-/* item_func.cc */
int get_var_with_binlog(THD *thd, LEX_STRING &name,
user_var_entry **out_entry);
/* log.cc */
--- 1.171/sql/set_var.cc 2005-06-21 19:18:50 +04:00
+++ 1.172/sql/set_var.cc 2005-07-15 23:13:24 +04:00
@@ -1568,8 +1568,8 @@
{
if (var_type != OPT_DEFAULT)
{
- net_printf(thd, ER_INCORRECT_GLOBAL_LOCAL_VAR,
- name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
+ 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 */
@@ -1613,7 +1613,7 @@
return tmp;
}
default:
- net_printf(thd, ER_VAR_CANT_BE_READ, name);
+ my_error(ER_VAR_CANT_BE_READ, MYF(0), name);
}
return 0;
}
--- 1.58/sql/set_var.h 2005-05-04 17:05:53 +04:00
+++ 1.59/sql/set_var.h 2005-07-15 23:13:25 +04:00
@@ -30,11 +30,6 @@
typedef struct system_variables SV;
extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib;
-enum enum_var_type
-{
- OPT_DEFAULT, OPT_SESSION, OPT_GLOBAL
-};
-
typedef int (*sys_check_func)(THD *, set_var *);
typedef bool (*sys_update_func)(THD *, set_var *);
typedef void (*sys_after_update_func)(THD *,enum_var_type);
--- 1.40/mysql-test/r/ps.result 2005-07-15 00:01:41 +04:00
+++ 1.41/mysql-test/r/ps.result 2005-07-15 23:13:24 +04:00
@@ -676,3 +676,28 @@
select ? from t1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to
your MySQL server version for the right syntax to use near '? from t1' at line 1
drop table t1;
+prepare stmt from "select @@time_zone";
+execute stmt;
+@@time_zone
+SYSTEM
+set @@time_zone:='Japan';
+execute stmt;
+@@time_zone
+Japan
+prepare stmt from "select @@tx_isolation";
+execute stmt;
+@@tx_isolation
+REPEATABLE-READ
+set transaction isolation level read committed;
+execute stmt;
+@@tx_isolation
+READ-COMMITTED
+set transaction isolation level serializable;
+execute stmt;
+@@tx_isolation
+SERIALIZABLE
+set @@tx_isolation=default;
+execute stmt;
+@@tx_isolation
+REPEATABLE-READ
+deallocate prepare stmt;
--- 1.40/mysql-test/t/ps.test 2005-07-15 02:11:00 +04:00
+++ 1.41/mysql-test/t/ps.test 2005-07-15 23:13:24 +04:00
@@ -702,4 +702,20 @@
select ? from t1;
--enable_ps_protocol
drop table t1;
-#
+#
+# Bug#9359 "Prepared statements take snapshot of system vars at PREPARE
+# time"
+#
+prepare stmt from "select @@time_zone";
+execute stmt;
+set @@time_zone:='Japan';
+execute stmt;
+prepare stmt from "select @@tx_isolation";
+execute stmt;
+set transaction isolation level read committed;
+execute stmt;
+set transaction isolation level serializable;
+execute stmt;
+set @@tx_isolation=default;
+execute stmt;
+deallocate prepare stmt;
| Thread |
|---|
| • bk commit into 4.1 tree (konstantin:1.2359) BUG#9359 | konstantin | 15 Jul |