| Thread Previous • Date Previous • Date Next • Thread Next |
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
| Thread Previous • Date Previous • Date Next • Thread Next |