@@ -248,6 +248,35 @@ static bool maybe_start_compound_statement(THD *thd)
248
248
return 0 ;
249
249
}
250
250
251
+ static bool push_sp_label (THD *thd, LEX_STRING label)
252
+ {
253
+ sp_pcontext *ctx= thd->lex ->spcont ;
254
+ sp_label *lab= ctx->find_label (label);
255
+
256
+ if (lab)
257
+ {
258
+ my_error (ER_SP_LABEL_REDEFINE, MYF (0 ), label.str );
259
+ return 1 ;
260
+ }
261
+ else
262
+ {
263
+ lab= thd->lex ->spcont ->push_label (thd, label,
264
+ thd->lex ->sphead ->instructions ());
265
+ lab->type = sp_label::ITERATION;
266
+ }
267
+ return 0 ;
268
+ }
269
+
270
+ static bool push_sp_empty_label (THD *thd)
271
+ {
272
+ if (maybe_start_compound_statement (thd))
273
+ return 1 ;
274
+ /* Unlabeled controls get an empty label. */
275
+ thd->lex ->spcont ->push_label (thd, empty_lex_str,
276
+ thd->lex ->sphead ->instructions ());
277
+ return 0 ;
278
+ }
279
+
251
280
/* *
252
281
Helper action for a case expression statement (the expr in 'CASE expr').
253
282
This helper is used for 'searched' cases only.
@@ -997,7 +1026,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
997
1026
Currently there are 160 shift/reduce conflicts.
998
1027
We should not introduce new conflicts any more.
999
1028
*/
1000
- %expect 160
1029
+ %expect 162
1001
1030
1002
1031
/*
1003
1032
Comments for TOKENS.
@@ -1934,6 +1963,7 @@ END_OF_INPUT
1934
1963
%type <NONE> sp_proc_stmt_iterate
1935
1964
%type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close
1936
1965
%type <NONE> case_stmt_specification
1966
+ %type <NONE> loop_body while_body repeat_body
1937
1967
1938
1968
%type <num> sp_decl_idents sp_handler_type sp_hcond_list
1939
1969
%type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
@@ -3768,20 +3798,6 @@ sp_proc_stmt_return:
3768
3798
}
3769
3799
;
3770
3800
3771
- sp_unlabeled_control:
3772
- {
3773
- if (maybe_start_compound_statement (thd))
3774
- MYSQL_YYABORT;
3775
- /* Unlabeled controls get an empty label. */
3776
- Lex->spcont ->push_label (thd, empty_lex_str,
3777
- Lex->sphead ->instructions ());
3778
- }
3779
- sp_control_content
3780
- {
3781
- Lex->sphead ->backpatch (Lex->spcont ->pop_label ());
3782
- }
3783
- ;
3784
-
3785
3801
sp_proc_stmt_leave:
3786
3802
LEAVE_SYM label_ident
3787
3803
{
@@ -4200,41 +4216,6 @@ else_clause_opt:
4200
4216
| ELSE sp_proc_stmts1
4201
4217
;
4202
4218
4203
- sp_labeled_control:
4204
- label_ident ' :'
4205
- {
4206
- LEX *lex= Lex;
4207
- sp_pcontext *ctx= lex->spcont ;
4208
- sp_label *lab= ctx->find_label ($1 );
4209
-
4210
- if (lab)
4211
- {
4212
- my_error (ER_SP_LABEL_REDEFINE, MYF (0 ), $1 .str );
4213
- MYSQL_YYABORT;
4214
- }
4215
- else
4216
- {
4217
- lab= lex->spcont ->push_label (thd, $1 , lex->sphead ->instructions ());
4218
- lab->type = sp_label::ITERATION;
4219
- }
4220
- }
4221
- sp_control_content sp_opt_label
4222
- {
4223
- LEX *lex= Lex;
4224
- sp_label *lab= lex->spcont ->pop_label ();
4225
-
4226
- if ($5 .str )
4227
- {
4228
- if (my_strcasecmp (system_charset_info, $5 .str , lab->name .str ) != 0 )
4229
- {
4230
- my_error (ER_SP_LABEL_MISMATCH, MYF (0 ), $5 .str );
4231
- MYSQL_YYABORT;
4232
- }
4233
- }
4234
- lex->sphead ->backpatch (lab);
4235
- }
4236
- ;
4237
-
4238
4219
sp_opt_label:
4239
4220
/* Empty */ { $$= null_lex_str; }
4240
4221
| label_ident { $$= $1 ; }
@@ -4327,8 +4308,7 @@ sp_block_content:
4327
4308
}
4328
4309
;
4329
4310
4330
- sp_control_content:
4331
- LOOP_SYM
4311
+ loop_body:
4332
4312
sp_proc_stmts1 END LOOP_SYM
4333
4313
{
4334
4314
LEX *lex= Lex;
@@ -4340,15 +4320,16 @@ sp_control_content:
4340
4320
lex->sphead ->add_instr (i))
4341
4321
MYSQL_YYABORT;
4342
4322
}
4343
- | WHILE_SYM
4344
- { Lex->sphead ->reset_lex (thd); }
4323
+ ;
4324
+
4325
+ while_body:
4345
4326
expr DO_SYM
4346
4327
{
4347
4328
LEX *lex= Lex;
4348
4329
sp_head *sp= lex->sphead ;
4349
4330
uint ip= sp->instructions ();
4350
4331
sp_instr_jump_if_not *i= new (lex->thd ->mem_root )
4351
- sp_instr_jump_if_not (ip, lex->spcont , $3 , lex);
4332
+ sp_instr_jump_if_not (ip, lex->spcont , $1 , lex);
4352
4333
if (i == NULL ||
4353
4334
/* Jumping forward */
4354
4335
sp->push_backpatch (i, lex->spcont ->last_label ()) ||
@@ -4370,15 +4351,18 @@ sp_control_content:
4370
4351
MYSQL_YYABORT;
4371
4352
lex->sphead ->do_cont_backpatch ();
4372
4353
}
4373
- | REPEAT_SYM sp_proc_stmts1 UNTIL_SYM
4354
+ ;
4355
+
4356
+ repeat_body:
4357
+ sp_proc_stmts1 UNTIL_SYM
4374
4358
{ Lex->sphead ->reset_lex (thd); }
4375
4359
expr END REPEAT_SYM
4376
4360
{
4377
4361
LEX *lex= Lex;
4378
4362
uint ip= lex->sphead ->instructions ();
4379
4363
sp_label *lab= lex->spcont ->last_label (); /* Jumping back */
4380
4364
sp_instr_jump_if_not *i= new (lex->thd ->mem_root )
4381
- sp_instr_jump_if_not (ip, lex->spcont , $5 , lab->ip , lex);
4365
+ sp_instr_jump_if_not (ip, lex->spcont , $4 , lab->ip , lex);
4382
4366
if (i == NULL ||
4383
4367
lex->sphead ->add_instr (i))
4384
4368
MYSQL_YYABORT;
@@ -4389,6 +4373,84 @@ sp_control_content:
4389
4373
}
4390
4374
;
4391
4375
4376
+ pop_sp_label:
4377
+ sp_opt_label
4378
+ {
4379
+ sp_label *lab;
4380
+ Lex->sphead ->backpatch (lab= Lex->spcont ->pop_label ());
4381
+ if ($1 .str )
4382
+ {
4383
+ if (my_strcasecmp (system_charset_info, $1 .str ,
4384
+ lab->name .str ) != 0 )
4385
+ {
4386
+ my_error (ER_SP_LABEL_MISMATCH, MYF (0 ), $1 .str );
4387
+ MYSQL_YYABORT;
4388
+ }
4389
+ }
4390
+ }
4391
+ ;
4392
+
4393
+ pop_sp_empty_label:
4394
+ {
4395
+ sp_label *lab;
4396
+ Lex->sphead ->backpatch (lab= Lex->spcont ->pop_label ());
4397
+ DBUG_ASSERT (lab->name .length == 0 );
4398
+ }
4399
+ ;
4400
+
4401
+ sp_labeled_control:
4402
+ label_ident ' :' LOOP_SYM
4403
+ {
4404
+ if (push_sp_label (thd, $1 ))
4405
+ MYSQL_YYABORT;
4406
+ }
4407
+ loop_body pop_sp_label
4408
+ { }
4409
+ | label_ident ' :' WHILE_SYM
4410
+ {
4411
+ if (push_sp_label (thd, $1 ))
4412
+ MYSQL_YYABORT;
4413
+ Lex->sphead ->reset_lex (thd);
4414
+ }
4415
+ while_body pop_sp_label
4416
+ { }
4417
+ | label_ident ' :' REPEAT_SYM
4418
+ {
4419
+ if (push_sp_label (thd, $1 ))
4420
+ MYSQL_YYABORT;
4421
+ }
4422
+ repeat_body pop_sp_label
4423
+ { }
4424
+ ;
4425
+
4426
+ sp_unlabeled_control:
4427
+ LOOP_SYM
4428
+ {
4429
+ if (push_sp_empty_label (thd))
4430
+ MYSQL_YYABORT;
4431
+ }
4432
+ loop_body
4433
+ pop_sp_empty_label
4434
+ { }
4435
+ | WHILE_SYM
4436
+ {
4437
+ if (push_sp_empty_label (thd))
4438
+ MYSQL_YYABORT;
4439
+ Lex->sphead ->reset_lex (thd);
4440
+ }
4441
+ while_body
4442
+ pop_sp_empty_label
4443
+ { }
4444
+ | REPEAT_SYM
4445
+ {
4446
+ if (push_sp_empty_label (thd))
4447
+ MYSQL_YYABORT;
4448
+ }
4449
+ repeat_body
4450
+ pop_sp_empty_label
4451
+ { }
4452
+ ;
4453
+
4392
4454
trg_action_time:
4393
4455
BEFORE_SYM
4394
4456
{ Lex->trg_chistics .action_time = TRG_ACTION_BEFORE; }
0 commit comments