[Commits] 1071348053f: MDEV-10355 Weird error message upon CREATE TABLE with DEFAULT

jacob.mathew at mariadb.com jacob.mathew at mariadb.com
Tue Mar 28 09:09:12 EEST 2017


revision-id: 1071348053fbcf0968acdef72e1dfeebd092e877 (mariadb-10.2.4-79-g1071348053f)
parent(s): bdcebf20e0dfa061e91fe4452caa9e927b2692c0
author: Jacob Mathew
committer: Jacob Mathew
timestamp: 2017-03-27 18:51:12 -0700
message:

MDEV-10355 Weird error message upon CREATE TABLE with DEFAULT

Allow temporal functions to be cached.  Clear the cached function values
when updating default values and when updating virtual column values.
Fixed date/time values that were previously unquoted.
Updated test result files that include date/time values that were
previously unquoted.

---
 mysql-test/r/derived_cond_pushdown.result |  6 +++---
 mysql-test/r/type_time.result             | 16 ++++++++--------
 sql/item.cc                               | 25 +++++++++++++++++--------
 sql/item.h                                | 10 ++++++++++
 sql/item_cmpfunc.cc                       |  6 ++----
 sql/table.cc                              | 10 ++++++++++
 6 files changed, 50 insertions(+), 23 deletions(-)

diff --git a/mysql-test/r/derived_cond_pushdown.result b/mysql-test/r/derived_cond_pushdown.result
index fd58ee038c7..5066d4649ab 100644
--- a/mysql-test/r/derived_cond_pushdown.result
+++ b/mysql-test/r/derived_cond_pushdown.result
@@ -8019,7 +8019,7 @@ EXPLAIN
       "access_type": "ALL",
       "rows": 3,
       "filtered": 100,
-      "attached_condition": "sq.i = 2007-05-28 00:00:00",
+      "attached_condition": "sq.i = '2007-05-28 00:00:00'",
       "materialized": {
         "query_block": {
           "select_id": 2,
@@ -8071,7 +8071,7 @@ EXPLAIN
       "access_type": "ALL",
       "rows": 3,
       "filtered": 100,
-      "attached_condition": "sq.i = 2007-05-28",
+      "attached_condition": "sq.i = '2007-05-28'",
       "materialized": {
         "query_block": {
           "select_id": 2,
@@ -8123,7 +8123,7 @@ EXPLAIN
       "access_type": "ALL",
       "rows": 3,
       "filtered": 100,
-      "attached_condition": "sq.i = 10:00:02",
+      "attached_condition": "sq.i = '10:00:02'",
       "materialized": {
         "query_block": {
           "select_id": 2,
diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result
index a827fb19943..2aabd98229d 100644
--- a/mysql-test/r/type_time.result
+++ b/mysql-test/r/type_time.result
@@ -989,7 +989,7 @@ SELECT * FROM t1 WHERE COALESCE(a)=TIME('00:00:00') AND COALESCE(a)=DATE('2015-0
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where
 Warnings:
-Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = 00:00:00
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = '00:00:00'
 # TIME cast + DATE literal
 SELECT * FROM t1 WHERE COALESCE(a)=TIME('00:00:00') AND COALESCE(a)=DATE'2015-09-11';
 a
@@ -999,7 +999,7 @@ SELECT * FROM t1 WHERE COALESCE(a)=TIME('00:00:00') AND COALESCE(a)=DATE'2015-09
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where
 Warnings:
-Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = 00:00:00
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = '00:00:00'
 # TIME literal + DATE cast
 SELECT * FROM t1 WHERE COALESCE(a)=TIME'00:00:00' AND COALESCE(a)=DATE('2015-09-11');
 a
@@ -1029,7 +1029,7 @@ SELECT * FROM t1 WHERE COALESCE(a)='00:00:00' AND COALESCE(a)=DATE('2015-09-11')
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where
 Warnings:
-Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = '00:00:00' and coalesce(`test`.`t1`.`a`) = 2015-09-11 00:00:00
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = '00:00:00' and coalesce(`test`.`t1`.`a`) = '2015-09-11 00:00:00'
 # TIME-alike string literal + DATE literal
 SELECT * FROM t1 WHERE COALESCE(a)='00:00:00' AND COALESCE(a)=DATE'2015-09-11';
 a
@@ -1049,7 +1049,7 @@ SELECT * FROM t1 WHERE COALESCE(a)=0 AND COALESCE(a)=DATE('2015-09-11');
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where
 Warnings:
-Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = 0 and coalesce(`test`.`t1`.`a`) = 2015-09-11 00:00:00
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = 0 and coalesce(`test`.`t1`.`a`) = '2015-09-11 00:00:00'
 # TIME-alike integer literal + DATE literal
 SELECT * FROM t1 WHERE COALESCE(a)=0 AND COALESCE(a)=DATE'2015-09-11';
 a
@@ -1069,7 +1069,7 @@ SELECT * FROM t1 WHERE COALESCE(a)=DATE('2015-09-11') AND COALESCE(a)=TIME('00:0
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where
 Warnings:
-Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = 2015-09-11 00:00:00
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = '2015-09-11 00:00:00'
 # DATE cast + TIME literal
 SELECT * FROM t1 WHERE COALESCE(a)=DATE('2015-09-11') AND COALESCE(a)=TIME'00:00:00';
 a
@@ -1079,7 +1079,7 @@ SELECT * FROM t1 WHERE COALESCE(a)=DATE('2015-09-11') AND COALESCE(a)=TIME'00:00
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where
 Warnings:
-Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = 2015-09-11 00:00:00
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = '2015-09-11 00:00:00'
 # DATE cast + TIME-alike string literal
 SELECT * FROM t1 WHERE COALESCE(a)=DATE('2015-09-11') AND COALESCE(a)='00:00:00';
 a
@@ -1089,7 +1089,7 @@ SELECT * FROM t1 WHERE COALESCE(a)=DATE('2015-09-11') AND COALESCE(a)='00:00:00'
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where
 Warnings:
-Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = 2015-09-11 00:00:00 and coalesce(`test`.`t1`.`a`) = '00:00:00'
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = '2015-09-11 00:00:00' and coalesce(`test`.`t1`.`a`) = '00:00:00'
 # DATE cast + TIME-alike integer literal
 SELECT * FROM t1 WHERE COALESCE(a)=DATE('2015-09-11') AND COALESCE(a)=0;
 a
@@ -1099,7 +1099,7 @@ SELECT * FROM t1 WHERE COALESCE(a)=DATE('2015-09-11') AND COALESCE(a)=0;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where
 Warnings:
-Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = 2015-09-11 00:00:00 and coalesce(`test`.`t1`.`a`) = 0
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = '2015-09-11 00:00:00' and coalesce(`test`.`t1`.`a`) = 0
 # DATE literal + TIME cast
 SELECT * FROM t1 WHERE COALESCE(a)=DATE'2015-09-11' AND COALESCE(a)=TIME('00:00:00');
 a
diff --git a/sql/item.cc b/sql/item.cc
index 25b30afec8d..ee3e43b60ad 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -9433,17 +9433,26 @@ void Item_cache::store(Item *item)
 
 void Item_cache::print(String *str, enum_query_type query_type)
 {
-  if (value_cached)
+  if ( example && ( example->type() == FUNC_ITEM ) &&       // There is a cached function item
+       ( query_type & QT_ITEM_IDENT_SKIP_TABLE_NAMES ) )    // Caller is show-create-table
   {
-    print_value(str);
-    return;
+      // Instead of "cache" or the cached value, print the function name
+      example->print( str, query_type );
   }
-  str->append(STRING_WITH_LEN("<cache>("));
-  if (example)
-    example->print(str, query_type);
   else
-    Item::print(str, query_type);
-  str->append(')');
+  {
+      if (value_cached)
+      {
+          print_value(str);
+          return;
+      }
+      str->append(STRING_WITH_LEN("<cache>("));
+      if (example)
+          example->print(str, query_type);
+      else
+          Item::print(str, query_type);
+      str->append(')');
+  }
 }
 
 /**
diff --git a/sql/item.h b/sql/item.h
index 9118b8b9699..222f8580cb4 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1653,6 +1653,7 @@ class Item: public Value_source,
   {
     return mark_unsupported_function(full_name(), arg, VCOL_IMPOSSIBLE);
   }
+  virtual bool clear_cached_function_value(void *arg) { return 0; }
   virtual bool check_field_expression_processor(void *arg) { return 0; }
   virtual bool check_func_default_processor(void *arg) { return 0; }
   /*
@@ -5456,6 +5457,15 @@ class Item_cache: public Item_basic_constant,
     }
     return mark_unsupported_function("cache", arg, VCOL_IMPOSSIBLE);
   }
+  bool clear_cached_function_value( void *arg )
+  {
+      if ( example && example->type() == Item::FUNC_ITEM )
+      {
+          // Clear the cached function value to trigger reevaluation
+          clear();
+      }
+      return false;
+  }
   /**
      Check if saved item has a non-NULL value.
      Will cache value of saved item if not already done. 
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 78b6a2b8c56..a3b9041aed4 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -739,10 +739,8 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
   value= item->val_temporal_packed(f_type);
   if ((*is_null= item->null_value))
     return ~(ulonglong) 0;
-  if ( cache_arg && item->const_item() &&
-       !( ( ( item->type() == Item::CACHE_ITEM ) ||     // item is already cached
-            ( item->type() == Item::FUNC_ITEM  ) ) &&   // item is a function: it should be evaluated each time
-          item->cmp_type() == TIME_RESULT ) )
+  if (cache_arg && item->const_item() &&
+      !(item->type() == Item::CACHE_ITEM && item->cmp_type() == TIME_RESULT))
   {
     if (!thd)
       thd= current_thd;
diff --git a/sql/table.cc b/sql/table.cc
index b19aa7e9da5..947a5a10880 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -7375,6 +7375,10 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode)
 
     if (update)
     {
+      // Clear any cached function values in the virtual field expression
+      // to trigger their reevaluation
+      vcol_info->expr->walk( &Item::clear_cached_function_value, 0, 0 );  // Always returns 0
+
       int field_error __attribute__((unused)) = 0;
       /* Compute the actual value of the virtual fields */
       if (vcol_info->expr->save_in_field(vf, 0))
@@ -7462,7 +7466,13 @@ int TABLE::update_default_fields(bool update_command, bool ignore_errors)
       {
         if (field->default_value &&
             (field->default_value->flags || field->flags & BLOB_FLAG))
+        {
+          // Clear any cached function values in the default value expression
+          // to trigger their reevaluation
+          field->default_value->expr->walk( &Item::clear_cached_function_value, 0, 0 );  // Always returns 0
+          // Store the default value in the field
           res|= (field->default_value->expr->save_in_field(field, 0) < 0);
+        }
       }
       else
         res|= field->evaluate_update_default_function();


More information about the commits mailing list