[Commits] b14de6a: MDEV-6996: SET STATEMENT default_week_format = .. has no effect

sanja at mariadb.com sanja at mariadb.com
Thu Nov 20 12:32:21 EET 2014


revision-id: b14de6aa993a2d48848db34bda2fd5629043e6c2
parent(s): 7bf391c2059f452eafb424336faa30d402f92b67
committer: Oleksandr Byelkin
branch nick: work-maria-10.1-MDEV-6996
timestamp: 2014-11-20 11:32:18 +0100
message:

MDEV-6996: SET STATEMENT default_week_format = .. has no effect

default format is taken on fix_field and now will not be saved in the function print.

---
 mysql-test/r/func_time.result     |  2 +-
 mysql-test/r/set_statement.result |  3 +++
 mysql-test/t/set_statement.test   |  2 ++
 sql/item.cc                       | 12 ++++++++++++
 sql/item.h                        | 24 +++++++++++++++++++++++-
 sql/item_timefunc.cc              | 28 ++++++++++++++++++++++++++++
 sql/item_timefunc.h               |  5 ++++-
 sql/sql_yacc.yy                   |  5 ++---
 sql/sys_vars.cc                   |  2 +-
 9 files changed, 76 insertions(+), 7 deletions(-)

diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index bf07595..2d7b299 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -872,7 +872,7 @@ explain extended select period_add("9602",-12),period_diff(199505,"9404"),from_d
 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 period_add('9602',-(12)) AS `period_add("9602",-12)`,period_diff(199505,'9404') AS `period_diff(199505,"9404")`,from_days(to_days('960101')) AS `from_days(to_days("960101"))`,dayofmonth('1997-01-02') AS `dayofmonth("1997-01-02")`,month('1997-01-02') AS `month("1997-01-02")`,monthname('1972-03-04') AS `monthname("1972-03-04")`,dayofyear('0000-00-00') AS `dayofyear("0000-00-00")`,hour('1997-03-03 23:03:22') AS `HOUR("1997-03-03 23:03:22")`,minute('23:03:22') AS `MINUTE("23:03:22")`,second(230322) AS `SECOND(230322)`,quarter(980303) AS `QUARTER(980303)`,week('1998-03-03',0) AS `WEEK("1998-03-03")`,yearweek('2000-01-01',1) AS `yearweek("2000-01-01",1)`,week(19950101,1) AS `week(19950101,1)`,year('98-02-03') AS `year("98-02-03")`,(weekday(curdate()) - weekday(now())) AS `weekday(curdate())-weekday(now())`,dayname('1962-03-03') AS `dayname("1962-03-03")`,unix_timestamp() AS `unix_timestamp()`,sec_to_time((time_to_sec('0:30:47') / 6.21)) AS `sec_to_time(time_to_sec
 ("0:30:47")/6.21)`,curtime() AS `curtime()`,utc_time() AS `utc_time()`,curdate() AS `curdate()`,utc_date() AS `utc_date()`,utc_timestamp() AS `utc_timestamp()`,date_format('1997-01-02 03:04:05','%M %W %D %Y %y %m %d %h %i %s %w') AS `date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w")`,from_unixtime(unix_timestamp('1994-03-02 10:11:12')) AS `from_unixtime(unix_timestamp("1994-03-02 10:11:12"))`,('1997-12-31 23:59:59' + interval 1 second) AS `"1997-12-31 23:59:59" + INTERVAL 1 SECOND`,('1998-01-01 00:00:00' - interval 1 second) AS `"1998-01-01 00:00:00" - INTERVAL 1 SECOND`,('1997-12-31' + interval 1 day) AS `INTERVAL 1 DAY + "1997-12-31"`,extract(year from '1999-01-02 10:11:12') AS `extract(YEAR FROM "1999-01-02 10:11:12")`,('1997-12-31 23:59:59' + interval 1 second) AS `date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND)`
+Note	1003	select period_add('9602',-(12)) AS `period_add("9602",-12)`,period_diff(199505,'9404') AS `period_diff(199505,"9404")`,from_days(to_days('960101')) AS `from_days(to_days("960101"))`,dayofmonth('1997-01-02') AS `dayofmonth("1997-01-02")`,month('1997-01-02') AS `month("1997-01-02")`,monthname('1972-03-04') AS `monthname("1972-03-04")`,dayofyear('0000-00-00') AS `dayofyear("0000-00-00")`,hour('1997-03-03 23:03:22') AS `HOUR("1997-03-03 23:03:22")`,minute('23:03:22') AS `MINUTE("23:03:22")`,second(230322) AS `SECOND(230322)`,quarter(980303) AS `QUARTER(980303)`,week('1998-03-03') AS `WEEK("1998-03-03")`,yearweek('2000-01-01',1) AS `yearweek("2000-01-01",1)`,week(19950101,1) AS `week(19950101,1)`,year('98-02-03') AS `year("98-02-03")`,(weekday(curdate()) - weekday(now())) AS `weekday(curdate())-weekday(now())`,dayname('1962-03-03') AS `dayname("1962-03-03")`,unix_timestamp() AS `unix_timestamp()`,sec_to_time((time_to_sec('0:30:47') / 6.21)) AS `sec_to_time(time_to_sec("
 0:30:47")/6.21)`,curtime() AS `curtime()`,utc_time() AS `utc_time()`,curdate() AS `curdate()`,utc_date() AS `utc_date()`,utc_timestamp() AS `utc_timestamp()`,date_format('1997-01-02 03:04:05','%M %W %D %Y %y %m %d %h %i %s %w') AS `date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w")`,from_unixtime(unix_timestamp('1994-03-02 10:11:12')) AS `from_unixtime(unix_timestamp("1994-03-02 10:11:12"))`,('1997-12-31 23:59:59' + interval 1 second) AS `"1997-12-31 23:59:59" + INTERVAL 1 SECOND`,('1998-01-01 00:00:00' - interval 1 second) AS `"1998-01-01 00:00:00" - INTERVAL 1 SECOND`,('1997-12-31' + interval 1 day) AS `INTERVAL 1 DAY + "1997-12-31"`,extract(year from '1999-01-02 10:11:12') AS `extract(YEAR FROM "1999-01-02 10:11:12")`,('1997-12-31 23:59:59' + interval 1 second) AS `date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND)`
 SET @TMP='2007-08-01 12:22:49';
 CREATE TABLE t1 (d DATETIME);
 INSERT INTO t1 VALUES ('2007-08-01 12:22:59');
diff --git a/mysql-test/r/set_statement.result b/mysql-test/r/set_statement.result
index efe5286..e5ecd2b 100644
--- a/mysql-test/r/set_statement.result
+++ b/mysql-test/r/set_statement.result
@@ -1100,3 +1100,6 @@ set statement wait_timeout=default for select 1;
 ERROR 42000: The system variable wait_timeout cannot be set in SET STATEMENT.
 set statement interactive_timeout=default for select 1;
 ERROR 42000: The system variable interactive_timeout cannot be set in SET STATEMENT.
+SET STATEMENT default_week_format = 2 FOR SELECT WEEK('2000-01-01');
+WEEK('2000-01-01')
+52
diff --git a/mysql-test/t/set_statement.test b/mysql-test/t/set_statement.test
index a658071..85c9495 100644
--- a/mysql-test/t/set_statement.test
+++ b/mysql-test/t/set_statement.test
@@ -1047,3 +1047,5 @@ set statement wait_timeout=default for select 1;
 --error ER_SET_STATEMENT_NOT_SUPPORTED
 set statement interactive_timeout=default for select 1;
 
+# MDEV-6996: SET STATEMENT default_week_format = .. has no effect
+SET STATEMENT default_week_format = 2 FOR SELECT WEEK('2000-01-01');
diff --git a/sql/item.cc b/sql/item.cc
index 4fd1ddc..9b47b5c 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2733,6 +2733,18 @@ longlong Item_field::val_int_endpoint(bool left_endp, bool *incl_endp)
   return null_value? LONGLONG_MIN : res;
 }
 
+
+bool Item_ulong_def::fix_fields(THD *thd, Item **ref)
+{
+  Item *cnst= new (thd->mem_root)
+    Item_int((char*) "0", *value, 1);
+  if (!cnst)
+    return TRUE;
+  thd->change_item_tree(ref, cnst);
+  /* Item_int does not need fix_fields */
+  return FALSE;
+}
+
 /**
   Create an item from a string we KNOW points to a valid longlong
   end \\0 terminated number string.
diff --git a/sql/item.h b/sql/item.h
index e006622..c916c3f 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -667,7 +667,7 @@ class Item {
              PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM,
              XPATH_NODESET, XPATH_NODESET_CMP,
              VIEW_FIXER_ITEM, EXPR_CACHE_ITEM,
-             DATE_ITEM};
+             DATE_ITEM, ULONG_DEFAULT};
 
   enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
 
@@ -2599,6 +2599,28 @@ class Item_param :public Item_basic_value,
   Send_field *m_out_param_info;
 };
 
+/**
+  Item substitute constant from default value reference
+*/
+class Item_ulong_def :public Item
+{
+public:
+  ulong *value;
+  Item_ulong_def(ulong *ref) :value(ref)
+    {null_value= 1; name= (char*)"<default>";}
+  enum Type type() const { return ULONG_DEFAULT; }
+  enum Item_result result_type () const { return INT_RESULT; }
+  enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
+  longlong val_int() { DBUG_ASSERT(0); return 0; }
+  double val_real() { DBUG_ASSERT(0); return 0; }
+  my_decimal *val_decimal(my_decimal *) { DBUG_ASSERT(0); return 0; }
+  String *val_str(String*) { DBUG_ASSERT(0); return 0; }
+  int save_in_field(Field *field, bool no_conversions)
+  { DBUG_ASSERT(0); return 1; }
+  Item *clone_item() { return new Item_ulong_def(value); }
+
+  bool fix_fields(THD *, Item **);
+};
 
 class Item_int :public Item_num
 {
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 4a8bb4c..6c223c9 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1010,6 +1010,34 @@ uint week_mode(uint mode)
 }
 
 /**
+  Inserts default value (if it is needed) before calling general method
+
+  @param thd             Thread handle
+  @param ref             Reference to this item
+
+  @retval FALSE OK
+  @retval TRUE  Error
+*/
+
+bool Item_func_week::fix_fields(THD *thd, Item **ref)
+{
+  DBUG_ASSERT(arg_count == 2);
+  if (args[1]->type() == ULONG_DEFAULT)
+  {
+    deflt= 1;
+  }
+  return Item_int_func::fix_fields(thd, ref);
+}
+
+void Item_func_week::print(String *str, enum_query_type query_type)
+{
+  if (deflt)
+    arg_count= 1;
+  Item_int_func::print(str, query_type);
+  arg_count= 2;
+}
+
+/**
  @verbatim
   The bits in week_format(for calc_week() function) has the following meaning:
    WEEK_MONDAY_FIRST (0)  If not set	Sunday is first day of week
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index cb8b595..7b91723 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -303,10 +303,13 @@ class Item_func_second :public Item_int_func
 
 class Item_func_week :public Item_int_func
 {
+  bool deflt;
 public:
-  Item_func_week(Item *a,Item *b) :Item_int_func(a,b) {}
+  Item_func_week(Item *a,Item *b) :Item_int_func(a,b), deflt(0) {}
   longlong val_int();
   const char *func_name() const { return "week"; }
+  bool fix_fields(THD *, Item **);
+  void print(String *str, enum_query_type query_type);
   void fix_length_and_dec()
   { 
     decimals=0;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index d11ac48..21016b0 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -9812,9 +9812,8 @@ function_call_conflict:
           }
         | WEEK_SYM '(' expr ')'
           {
-            Item *i1= new (thd->mem_root) Item_int((char*) "0",
-                                           thd->variables.default_week_format,
-                                                   1);
+            Item *i1= new (thd->mem_root)
+              Item_ulong_def(&thd->variables.default_week_format);
             if (i1 == NULL)
               MYSQL_YYABORT;
             $$= new (thd->mem_root) Item_func_week($3, i1);
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index a7d5843..975b1f0 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -3741,7 +3741,7 @@ static Sys_var_session_special Sys_warning_count(
 static Sys_var_ulong Sys_default_week_format(
        "default_week_format",
        "The default week format used by WEEK() functions",
-       NO_SET_STMT SESSION_VAR(default_week_format), CMD_LINE(REQUIRED_ARG),
+       SESSION_VAR(default_week_format), CMD_LINE(REQUIRED_ARG),
        VALID_RANGE(0, 7), DEFAULT(0), BLOCK_SIZE(1));
 
 static Sys_var_ulonglong Sys_group_concat_max_len(


More information about the commits mailing list