← Back to team overview

maria-developers team mailing list archive

GSoC2015: facing errors working on udf's for table valued functions.

 

hii i have been stuck on some shift/reduce conflict since past few days. It
is giving the error for the code i have added for select query using the
udf. I think the rule that I defined under table_factor is conflicting with
the first rule defined under it.

regards
diff --git a/sql/sp.h b/sql/sp.h
index eb3291f..149077f 100644
--- a/sql/sp.h
+++ b/sql/sp.h
@@ -45,7 +45,8 @@ enum stored_procedure_type
   TYPE_ENUM_FUNCTION=1,
   TYPE_ENUM_PROCEDURE=2,
   TYPE_ENUM_TRIGGER=3,
-  TYPE_ENUM_PROXY=4
+  TYPE_ENUM_PROXY=4,
+  TYPE_ENUM_TABLE=5
 };
 
 /* Tells what SP_DEFAULT_ACCESS should be mapped to */
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 8efeeab..09920c5 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -2360,7 +2360,34 @@ void sp_head::recursion_level_error(THD *thd)
   return FALSE;
 }
 
-
+bool
+sp_head::fill_resultset_definition(THD *thd, List<Create_field> *create_list)
+{
+    List_iterator_fast<Create_field> it(*create_list);
+    Create_field *field;
+    while ((field= it++))
+    {
+      Create_field *new_field = field->clone(thd->mem_root);
+      switch (new_field->sql_type) {
+        case MYSQL_TYPE_DATE:
+        case MYSQL_TYPE_NEWDATE:
+        case MYSQL_TYPE_TIME:
+        case MYSQL_TYPE_DATETIME:
+        case MYSQL_TYPE_TIMESTAMP:
+          new_field->charset= &my_charset_bin;
+        default: break;
+      }
+      if (!new_field->charset)
+         new_field->charset= default_charset_info;
+      if (!new_field->charset)
+         new_field->charset= system_charset_info;
+      if (new_field->interval_list.elements)
+          new_field->interval= create_typelib(thd->mem_root, new_field, &new_field->interval_list);
+      sp_prepare_create_field(thd, new_field);
+      if(m_cols_list.push_back(new_field, thd->mem_root))
+          return TRUE;
+    }
+}
 int
 sp_head::new_cont_backpatch(sp_instr_opt_meta *i)
 {
diff --git a/sql/sp_head.h b/sql/sp_head.h
index dbdb957..7246052 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -182,6 +182,7 @@ class sp_head :private Query_arena
   uint m_flags;                 // Boolean attributes of a stored routine
 
   Create_field m_return_field_def; /**< This is used for FUNCTIONs only. */
+  List<Create_field> m_cols_list; /**< Used for TABLE FUNCTIONs only. */
 
   const char *m_tmp_query;	///< Temporary pointer to sub query string
   st_sp_chistics *m_chistics;
@@ -196,7 +197,7 @@ class sp_head :private Query_arena
   LEX_STRING m_defstr;
   LEX_STRING m_definer_user;
   LEX_STRING m_definer_host;
-
+  LEX_STRING m_table_alias;
   /**
     Is this routine being executed?
   */
@@ -420,7 +421,7 @@ class sp_head :private Query_arena
   bool fill_field_definition(THD *thd, LEX *lex,
                              enum enum_field_types field_type,
                              Create_field *field_def);
-
+  bool fill_resultset_definition(THD *thd, List<Create_field> *create_list);
   void set_info(longlong created, longlong modified,
 		st_sp_chistics *chistics, ulonglong sql_mode);
 
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index cf933e0b..1dd2ad2 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1202,6 +1202,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
 %token  ENCLOSED
 %token  END                           /* SQL-2003-R */
 %token  ENDS_SYM
+%token  END_SYM
 %token  END_OF_INPUT                  /* INTERNAL */
 %token  ENGINES_SYM
 %token  ENGINE_SYM
@@ -1965,7 +1966,7 @@ END_OF_INPUT
 %type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
 %type <spblock> sp_decls sp_decl
 %type <lex> sp_cursor_stmt
-%type <spname> sp_name
+%type <spname> sp_name table_function
 %type <splabel> sp_block_content
 %type <spvar> sp_param_name_and_type
 %type <spvar_mode> sp_opt_inout
@@ -6629,22 +6630,33 @@ attribute:
           }
         ;
 
-
 type_with_opt_collate:
-        field_type opt_collate
-        {
-          $$= $1;
+          field_type opt_collate
+          {
+            $$= $1;
 
-          if ($2)
+            if ($2)
+            {
+              if (!(Lex->charset= merge_charset_and_collation(Lex->charset, $2)))
+                MYSQL_YYABORT;
+            }
+            Lex->set_last_field_type($1);
+          }
+        | TABLE_SYM ident '(' field_list ')'
           {
-            if (!(Lex->charset= merge_charset_and_collation(Lex->charset, $2)))
+            Lex->sphead->m_table_alias= $2;
+            // table functions, we need to store the return types
+            Lex->sphead->m_type= TYPE_ENUM_TABLE;
+            if(Lex->sphead->fill_resultset_definition(thd, &Lex->alter_info.create_list))
+              MYSQL_YYABORT;
+            if (Lex->sphead->m_cols_list.is_empty())
+            {
+              my_parse_error(ER(ER_SYNTAX_ERROR));
               MYSQL_YYABORT;
+            }
           }
-          Lex->set_last_field_type($1);
-        }
         ;
 
-
 now_or_signed_literal:
           NOW_SYM opt_default_time_precision
           {
@@ -10873,6 +10885,25 @@ table_factor:
               $$= $3;
             }
           }
+        | table_function '(' table_function_args ')' opt_table_alias
+          {
+            LEX *lex=Lex;
+            SELECT_LEX *sel= lex->current_select;
+            SELECT_LEX_UNIT *unit= sel->master_unit();
+            lex->current_select= sel= unit->outer_select();
+            Table_ident *ti= new Table_ident(unit);
+            if (ti == NULL)
+              MYSQL_YYABORT;
+            unit->spname= $1;
+            unit->sparg_list= unit->item_list;
+            unit->item_list.empty();
+            if (!($$= sel->add_table_to_list(lex->thd,
+                                             ti, $5, 0,
+                                             TL_READ)))
+              MYSQL_YYABORT;
+            sel->add_joined_table($$);
+            lex->pop_context();
+          }
         ;
 
 /*
@@ -11012,6 +11043,38 @@ select_derived2:
           opt_select_from
         ;
 
+table_function:
+          sp_name
+          {
+            LEX *lex= Lex;
+            lex->derived_tables|= DERIVED_SUBQUERY;
+            if (!lex->expr_allows_subselect ||
+                lex->sql_command == (int)SQLCOM_PURGE)
+            {
+              my_parse_error(ER(ER_SYNTAX_ERROR));
+              MYSQL_YYABORT;
+            }
+            if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE ||
+                mysql_new_select(lex, 1))
+              MYSQL_YYABORT;
+            mysql_init_select(lex);
+            lex->current_select->linkage= TABLE_FUNCTION_TYPE;
+            lex->current_select->parsing_place= NO_MATTER;
+            sp_add_used_routine(lex, YYTHD, $1, TYPE_ENUM_FUNCTION);
+            $$= $1;
+          }
+        ;
+
+table_function_args:
+          /* empty */
+        | '(' table_function_arg_items ')'
+        ;
+
+table_function_arg_items:
+          table_function_arg_items ',' select_item
+        | select_item
+        ;
+        
 get_select_lex:
           /* Empty */ { $$= Select; }
         ;
@@ -16285,9 +16348,13 @@ sf_tail:
           }
           type_with_opt_collate /* $11 */
           { /* $12 */
-            if (Lex->sphead->fill_field_definition(thd, Lex, $11,
-                                                   Lex->last_field))
-              MYSQL_YYABORT;
+            if (!(Lex->sphead->m_type== TYPE_ENUM_TABLE))
+            {
+                Lex->sphead->m_type = TYPE_ENUM_FUNCTION;
+                if (Lex->sphead->fill_field_definition(thd, Lex, $11,
+                                                       Lex->last_field))
+                  MYSQL_YYABORT;
+            }
           }
           sp_c_chistics /* $13 */
           { /* $14 */
@@ -16306,12 +16373,13 @@ sf_tail:
 
             lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
             sp->set_stmt_end(thd);
-            if (!(sp->m_flags & sp_head::HAS_RETURN))
+            if (!(sp->m_flags & sp_head::HAS_RETURN) && !(Lex->sphead->m_type== TYPE_ENUM_TABLE))
             {
               my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str);
               MYSQL_YYABORT;
             }
-            if (is_native_function(thd, & sp->m_name))
+            if ((Lex->sphead->m_type == TYPE_ENUM_FUNCTION) &&
+                is_native_function(thd, & sp->m_name))
             {
               /*
                 This warning will be printed when
@@ -16451,7 +16519,7 @@ begin_or_start:
           BEGIN_SYM {}
         | START_SYM {}
         ;
-
+        
 opt_join_or_resume:
           /* nothing */ { Lex->xa_opt=XA_NONE;        }
         | JOIN_SYM      { Lex->xa_opt=XA_JOIN;        }

Attachment: error_log
Description: Binary data

Attachment: tree
Description: Binary data


Follow ups