summaryrefslogtreecommitdiff
path: root/sql/sql_yacc.yy
diff options
context:
space:
mode:
authorpem@mysql.com <>2002-12-11 14:24:29 +0100
committerpem@mysql.com <>2002-12-11 14:24:29 +0100
commitf0137bcd686fbfe51fadb681713f61e0559c84da (patch)
treec0a89d8aee02a69b9c85212ad22f3f7a5e31ca64 /sql/sql_yacc.yy
parentaae07a4d45989b1b2a57ee01002e4a101511b512 (diff)
downloadmariadb-git-f0137bcd686fbfe51fadb681713f61e0559c84da.tar.gz
Fixed bugs in the parameter evaluation and modified the execution engine
for better jump support. Some flow control support added too (but not complete).
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r--sql/sql_yacc.yy152
1 files changed, 129 insertions, 23 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 33f928f2efe..bc19560ea77 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -526,6 +526,16 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token SQL_SMALL_RESULT
%token SQL_BUFFER_RESULT
+%token CURSOR_SYM
+%token ELSEIF_SYM
+%token ITERATE_SYM
+%token LEAVE_SYM
+%token LOOP_SYM
+%token UNTIL_SYM
+%token WHILE_SYM
+%token ASENSITIVE_SYM
+%token INSENSITIVE_SYM
+%token SENSITIVE_SYM
/* QQ This is a dummy, until we have solved the SET syntax problem. */
%token SPSET_SYM
@@ -680,7 +690,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
statement
END_OF_INPUT
-%type <NONE> call sp_proc_body sp_proc_stmts sp_proc_stmt
+%type <NONE> call sp_proc_stmts sp_proc_stmt
%type <num> sp_decls sp_decl sp_decl_idents sp_opt_inout
%type <NONE>
@@ -906,7 +916,7 @@ create:
{
Lex->spcont->set_params();
}
- sp_proc_body
+ sp_proc_stmt
{
Lex->sql_command= SQLCOM_CREATE_PROCEDURE;
}
@@ -974,26 +984,9 @@ sp_opt_locator:
| AS LOCATOR_SYM
;
-sp_proc_body:
- {
- Lex->sphead->reset_lex(YYTHD);
- }
- sp_proc_stmt
- {
- Lex->sphead->restore_lex(YYTHD);
- }
- | begin
- sp_decls
- sp_proc_stmts
- END
- {
- Lex->spcont->pop($2);
- }
- ;
-
sp_proc_stmts:
- sp_proc_body ';'
- | sp_proc_stmts sp_proc_body ';'
+ sp_proc_stmt ';'
+ | sp_proc_stmts sp_proc_stmt ';'
;
sp_decls:
@@ -1037,14 +1030,69 @@ sp_decl_idents:
/* Dummy for the spset thing. Will go away when the SET problem is fixed. */
sp_proc_stmt:
+ {
+ Lex->sphead->reset_lex(YYTHD);
+ }
statement
{
LEX *lex= Lex;
- sp_instr_stmt *i= new sp_instr_stmt();
+ sp_instr_stmt *i= new sp_instr_stmt(lex->sphead->instructions());
i->set_lex(lex);
lex->sphead->add_instr(i);
+ lex->sphead->restore_lex(YYTHD);
}
+/* | sp_if
+ | sp_case */
+ | sp_labeled_control
+ {}
+ | { /* Unlabeled controls get a secret label. */
+ LEX *lex= Lex;
+
+ Lex->spcont->push_gen_label(lex->sphead->instructions());
+ }
+ sp_unlabeled_control
+ {
+ /* QQ backpatch here */
+ Lex->spcont->pop_label();
+ }
+ | LEAVE_SYM IDENT
+ {
+ LEX *lex= Lex;
+ sp_label_t *lab= lex->spcont->find_label($2.str);
+
+ if (! lab)
+ {
+ printf("QQ LEAVE with no matching label\n");
+ YYABORT;
+ }
+ else
+ {
+ uint ip= lex->sphead->instructions();
+ sp_instr_jump *i= new sp_instr_jump(ip, 0);
+
+ lex->sphead->push_backpatch(ip);
+ lex->sphead->add_instr(i);
+ }
+ }
+ | ITERATE_SYM IDENT
+ {
+ LEX *lex= Lex;
+ sp_label_t *lab= lex->spcont->find_label($2.str);
+
+ if (! lab)
+ {
+ printf("QQ ITERATE with no matching label\n");
+ YYABORT;
+ }
+ else
+ {
+ uint ip= lex->sphead->instructions();
+ sp_instr_jump *i= new sp_instr_jump(ip, lab->ip);
+
+ lex->sphead->add_instr(i);
+ }
+ }
|
/* QQ Dummy. We need to fix the old SET syntax to make it work for
local SP variables as well. */
@@ -1059,7 +1107,8 @@ sp_proc_stmt:
else
{
/* QQ Check type match! */
- sp_instr_set *i = new sp_instr_set(spv->offset, $4, spv->type);
+ sp_instr_set *i = new sp_instr_set(lex->sphead->instructions(),
+ spv->offset, $4, spv->type);
lex->sphead->add_instr(i);
spv->isset= TRUE;
@@ -1067,6 +1116,63 @@ sp_proc_stmt:
}
;
+sp_labeled_control:
+ IDENT ':'
+ {
+ LEX *lex= Lex;
+ sp_label_t *lab= lex->spcont->find_label($1.str);
+
+ if (lab)
+ {
+ printf("QQ Redefining label\n");
+ YYABORT;
+ }
+ else
+ lex->spcont->push_label($1.str,
+ lex->sphead->instructions());
+ }
+ sp_unlabeled_control IDENT
+ {
+ LEX *lex= Lex;
+ sp_label_t *lab= lex->spcont->find_label($5.str);
+
+ if (! lab)
+ {
+ printf("QQ end-label without match\n");
+ YYABORT;
+ }
+ else if (strcasecmp($5.str, lab->name) != 0)
+ {
+ printf("QQ mismatching labels\n");
+ YYABORT;
+ }
+ else
+ {
+ /* QQ backpatch here */
+ lex->spcont->pop_label();
+ }
+ }
+ ;
+
+sp_unlabeled_control:
+ begin
+ sp_decls
+ sp_proc_stmts
+ END
+ {
+ Lex->spcont->pop($2);
+ }
+ | LOOP_SYM
+ sp_proc_stmts
+ END LOOP_SYM
+ | WHILE_SYM expr DO_SYM
+ sp_proc_stmts
+ END WHILE_SYM
+ | FUNC_ARG2 /* "REPEAT" actually... */
+ sp_proc_stmts
+ UNTIL_SYM expr END FUNC_ARG2
+ ;
+
create2:
'(' field_list ')' opt_create_table_options create3 {}
| opt_create_table_options create3 {}