From e7850f0ad908c1f88967a2ac2a6924ec7c477684 Mon Sep 17 00:00:00 2001
From: unknown <pappa@c-8b0ae253.1238-1-64736c10.cust.bredbandsbolaget.se>
Date: Fri, 22 Jul 2005 14:47:05 -0400
Subject: [PATCH] BUG #12097 patch

sql/handler.h:
  Fixed so that I store list of longlong's for list and
  a longlong value for range end instead of an item tree
  reference.
sql/sql_partition.cc:
  Fixed so that I store list of longlong's for list and
  a longlong value for range end instead of an item tree
  reference.
sql/sql_yacc.yy:
  Fixed so that I store list of longlong's for list and
  a longlong value for range end instead of an item tree
  reference.
---
 sql/handler.h        |  8 ++++----
 sql/sql_partition.cc | 46 ++++++++++++++------------------------------
 sql/sql_yacc.yy      | 27 +++++++++++++++++++++-----
 3 files changed, 40 insertions(+), 41 deletions(-)

diff --git a/sql/handler.h b/sql/handler.h
index 575210e8669..05327c3ad97 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -402,12 +402,12 @@ class Item;
 class partition_element :public Sql_alloc {
 public:
   List<partition_element> subpartitions;
-  List<Item> list_expr_list;
+  List<longlong> list_val_list;
   ulonglong part_max_rows;
   ulonglong part_min_rows;
   char *partition_name;
   char *tablespace_name;
-  Item* range_expr;
+  longlong range_value;
   char* part_comment;
   char* data_file_name;
   char* index_file_name;
@@ -416,12 +416,12 @@ class partition_element :public Sql_alloc {
   
   partition_element()
   : part_max_rows(0), part_min_rows(0), partition_name(NULL),
-    tablespace_name(NULL), range_expr(NULL), part_comment(NULL),
+    tablespace_name(NULL), range_value(0), part_comment(NULL),
     data_file_name(NULL), index_file_name(NULL),
     engine_type(DB_TYPE_UNKNOWN), nodegroup_id(UNDEF_NODEGROUP)
   {
     subpartitions.empty();
-    list_expr_list.empty();
+    list_val_list.empty();
   }
   ~partition_element() {}
 };
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index ffdf53ed287..0515579e42d 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -250,16 +250,7 @@ static bool check_range_constants(partition_info *part_info)
   {
     part_def= it++;
     if ((i != (no_parts - 1)) || !part_info->defined_max_value)
-    {
-      if (likely(part_def->range_expr->result_type() == INT_RESULT))
-        part_range_value_int= part_def->range_expr->val_int(); 
-      else
-      {
-        my_error(ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR, MYF(0),
-                 "LESS THAN");
-        goto end;
-      }
-    }
+      part_range_value_int= part_def->range_value; 
     else
       part_range_value_int= LONGLONG_MAX;
     if (likely(current_largest_int < part_range_value_int))
@@ -327,7 +318,7 @@ static int list_part_cmp(const void* a, const void* b)
 static bool check_list_constants(partition_info *part_info)
 {
   uint i, no_list_values= 0, no_parts, list_index= 0;
-  Item *list_expr;
+  longlong *list_value;
   bool not_first, result= TRUE;
   longlong curr_value, prev_value;
   partition_element* part_def;
@@ -342,8 +333,7 @@ static bool check_list_constants(partition_info *part_info)
 
     We use this number to allocate a properly sized array of structs
     to keep the partition id and the value to use in that partition.
-    In the second traversal we check that all Item trees are of the
-    same type (INT_RESULT) and assign them values in the struct array.
+    In the second traversal we assign them values in the struct array.
 
     Finally we sort the array of structs in order of values to enable
     a quick binary search for the proper value to discover the
@@ -357,7 +347,7 @@ static bool check_list_constants(partition_info *part_info)
   do
   {
     part_def= list_func_it++;
-    List_iterator<Item> list_val_it1(part_def->list_expr_list);
+    List_iterator<longlong> list_val_it1(part_def->list_val_list);
     while (list_val_it1++)
       no_list_values++;
   } while (++i < no_parts);
@@ -375,19 +365,11 @@ static bool check_list_constants(partition_info *part_info)
   do
   {
     part_def= list_func_it++;
-    List_iterator<Item> list_val_it2(part_def->list_expr_list);
-    while ((list_expr= list_val_it2++))
+    List_iterator<longlong> list_val_it2(part_def->list_val_list);
+    while ((list_value= list_val_it2++))
     {
-      if (likely(list_expr->result_type() == INT_RESULT))
-      {
-        part_info->list_array[list_index].list_value= list_expr->val_int();
-        part_info->list_array[list_index++].partition_id= i;
-      }
-      else
-      {
-        my_error(ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR, MYF(0), "IN");
-        goto end;
-      }
+      part_info->list_array[list_index].list_value= *list_value;
+      part_info->list_array[list_index++].partition_id= i;
     }
   } while (++i < no_parts);
 
@@ -1820,10 +1802,10 @@ static int add_partition_values(File fptr, partition_info *part_info,
   if (part_info->part_type == RANGE_PARTITION)
   {
     err+= add_string(fptr, "VALUES LESS THAN ");
-    if (p_elem->range_expr)
+    if (p_elem->range_value != LONGLONG_MAX)
     {
       err+= add_begin_parenthesis(fptr);
-      err+= add_int(fptr,p_elem->range_expr->val_int());
+      err+= add_int(fptr, p_elem->range_value);
       err+= add_end_parenthesis(fptr);
     }
     else
@@ -1832,15 +1814,15 @@ static int add_partition_values(File fptr, partition_info *part_info,
   else if (part_info->part_type == LIST_PARTITION)
   {
     uint i;
-    List_iterator<Item> list_expr_it(p_elem->list_expr_list);
+    List_iterator<longlong> list_val_it(p_elem->list_val_list);
     err+= add_string(fptr, "VALUES IN ");
-    uint no_items= p_elem->list_expr_list.elements;
+    uint no_items= p_elem->list_val_list.elements;
     err+= add_begin_parenthesis(fptr);
     i= 0;
     do
     {
-      Item *list_expr= list_expr_it++;
-      err+= add_int(fptr, list_expr->val_int());
+      longlong *list_value= list_val_it++;
+      err+= add_int(fptr, *list_value);
       if (i != (no_items-1))
         err+= add_comma(fptr);
     } while (++i < no_items);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index d4cd2bd6600..4e1983e1a2e 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -73,6 +73,7 @@ inline Item *is_truth_value(Item *A, bool v1, bool v2)
   int  num;
   ulong ulong_num;
   ulonglong ulonglong_number;
+  longlong longlong_number;
   LEX_STRING lex_str;
   LEX_STRING *lex_str_ptr;
   LEX_SYMBOL symbol;
@@ -716,6 +717,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
 %type <ulonglong_number>
 	ulonglong_num
 
+%type <longlong_number>
+        part_bit_expr
+
 %type <lock_type>
 	replace_lock_option opt_low_priority insert_lock_option load_data_lock
 
@@ -732,7 +736,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
 	sp_opt_default
 	simple_ident_nospvar simple_ident_q
         field_or_var limit_option
-        part_bit_expr part_func_expr
+        part_func_expr
 
 %type <item_num>
 	NUM_literal
@@ -2873,7 +2877,7 @@ part_func_max:
 part_range_func:
         '(' part_bit_expr ')' 
         {
-          Lex->part_info->curr_part_elem->range_expr= $2;
+          Lex->part_info->curr_part_elem->range_value= $2;
         };
 
 part_list_func:
@@ -2883,7 +2887,14 @@ part_list_func:
 part_list_item:
         part_bit_expr
         {
-          Lex->part_info->curr_part_elem->list_expr_list.push_back($1);
+          longlong *value_ptr;
+          if ((value_ptr= (longlong*)sql_alloc(sizeof(longlong))))
+          {
+            my_error(ER_OUTOFMEMORY, MYF(0), sizeof(longlong));
+            YYABORT;
+          }
+          *value_ptr= $1;
+          Lex->part_info->curr_part_elem->list_val_list.push_back(value_ptr);
         };
 
 part_bit_expr:
@@ -2892,6 +2903,7 @@ part_bit_expr:
           Item *part_expr= $1;
           bool not_corr_func;
           LEX *lex= Lex;
+          longlong item_value;
           Name_resolution_context *context= &lex->current_select->context;
           TABLE_LIST *save_list= context->table_list;
 
@@ -2900,13 +2912,18 @@ part_bit_expr:
           context->table_list= save_list;
           not_corr_func= !part_expr->const_item() ||
                          !lex->safe_to_cache_query;
-          lex->safe_to_cache_query= 1;
           if (not_corr_func)
           {
             yyerror(ER(ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR));
             YYABORT;
           }
-          $$= part_expr; 
+          if (part_expr->result_type() != INT_RESULT)
+          {
+            yyerror(ER(ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR));
+            YYABORT;
+          }
+          item_value= part_expr->val_int();
+          $$= item_value; 
         }
 
 opt_sub_partition:
-- 
2.30.9