兼容mysql的while和repeat语法

This commit is contained in:
qianxue21
2022-10-21 16:36:22 +08:00
parent 6e6fb41951
commit 90b876b9b8
7 changed files with 1277 additions and 15 deletions

View File

@ -884,7 +884,7 @@ static void setDelimiterName(core_yyscan_t yyscanner, char*input, VariableSetStm
QUERY QUOTE
RANDOMIZED RANGE RATIO RAW READ REAL REASSIGN REBUILD RECHECK RECURSIVE RECYCLEBIN REDISANYVALUE REF REFERENCES REFRESH REINDEX REJECT_P
RELATIVE_P RELEASE RELOPTIONS REMOTE_P REMOVE RENAME REPEATABLE REPLACE REPLICA
RELATIVE_P RELEASE RELOPTIONS REMOTE_P REMOVE RENAME REPEAT REPEATABLE REPLACE REPLICA
RESET RESIZE RESOURCE RESTART RESTRICT RETURN RETURNING RETURNS REUSE REVOKE RIGHT ROLE ROLES ROLLBACK ROLLUP
ROTATION ROW ROWNUM ROWS ROWTYPE_P RULE
@ -904,7 +904,7 @@ static void setDelimiterName(core_yyscan_t yyscanner, char*input, VariableSetStm
VACUUM VALID VALIDATE VALIDATION VALIDATOR VALUE_P VALUES VARCHAR VARCHAR2 VARIABLES VARIADIC VARRAY VARYING VCGROUP
VERBOSE VERIFY VERSION_P VIEW VOLATILE
WAIT WEAK WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WORKLOAD WRAPPER WRITE
WAIT WEAK WHEN WHERE WHILE_P WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WORKLOAD WRAPPER WRITE
XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLPARSE
XMLPI XMLROOT XMLSERIALIZE
@ -13855,7 +13855,7 @@ pkg_body_subprogram: {
}
continue;
}
if (tok == LOOP || tok == IF_P || tok == CASE)
if (tok == LOOP || tok == IF_P || tok == CASE || tok == WHILE_P || tok == REPEAT)
{
continue;
}
@ -14465,7 +14465,9 @@ subprogram_body: {
if (!(tok == ';' || (tok == 0 || tok == END_OF_PROC))
&& tok != IF_P
&& tok != CASE
&& tok != LOOP)
&& tok != LOOP
&& tok != WHILE_P
&& tok != REPEAT)
{
tok = END_P;
continue;
@ -26261,6 +26263,7 @@ unreserved_keyword:
| REMOTE_P
| REMOVE
| RENAME
| REPEAT
| REPEATABLE
| REPLACE
| REPLICA
@ -26377,6 +26380,7 @@ unreserved_keyword:
| VOLATILE
| WAIT
| WEAK
| WHILE_P
| WHITESPACE_P
| WITHIN
| WITHOUT

View File

@ -563,7 +563,7 @@ extern THR_LOCAL bool stmt_contains_operator_plus;
QUERY QUOTE
RANDOMIZED RANGE RATIO RAW READ REAL REASSIGN REBUILD RECHECK RECURSIVE RECYCLEBIN REDISANYVALUE REF REFERENCES REFRESH REINDEX REJECT_P
RELATIVE_P RELEASE RELOPTIONS REMOTE_P REMOVE RENAME REPEATABLE REPLACE REPLICA
RELATIVE_P RELEASE RELOPTIONS REMOTE_P REMOVE RENAME REPEAT REPEATABLE REPLACE REPLICA
RESET RESIZE RESOURCE RESTART RESTRICT RETURN RETURNING RETURNS REUSE REVOKE RIGHT ROLE ROLES ROLLBACK ROLLUP
ROTATION ROW ROWNUM ROWS ROWTYPE_P RULE
@ -583,7 +583,7 @@ extern THR_LOCAL bool stmt_contains_operator_plus;
VACUUM VALID VALIDATE VALIDATION VALIDATOR VALUE_P VALUES VARCHAR VARCHAR2 VARIABLES VARIADIC VARRAY VARYING VCGROUP
VERBOSE VERIFY VERSION_P VIEW VOLATILE
WAIT WEAK WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WORKLOAD WRAPPER WRITE
WAIT WEAK WHEN WHERE WHILE_P WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WORKLOAD WRAPPER WRITE
XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLPARSE
XMLPI XMLROOT XMLSERIALIZE
@ -3400,7 +3400,9 @@ subprogram_body: {
if (!(tok == ';' || tok == 0)
&& tok != IF_P
&& tok != CASE
&& tok != LOOP)
&& tok != LOOP
&& tok != WHILE_P
&& tok != REPEAT)
{
tok = END_P;
continue;
@ -11326,6 +11328,7 @@ unreserved_keyword:
| REMOTE_P
| REMOVE
| RENAME
| REPEAT
| REPEATABLE
| REPLACE
| REPLICA
@ -11435,6 +11438,7 @@ unreserved_keyword:
| VOLATILE
| WAIT
| WEAK
| WHILE_P
| WHITESPACE_P
| WITHIN
| WITHOUT

View File

@ -304,6 +304,23 @@ static void processFunctionRecordOutParam(int varno, Oid funcoid, int* outparam)
char *end_label;
int end_label_location;
} loop_body;
struct
{
List *stmts;
char *end_label;
int end_label_location;
} while_body;
struct
{
PLpgSQL_expr *expr;
char *end_label;
int end_label_location;
} repeat_condition;
struct
{
PLpgSQL_expr *expr;
int endtoken;
} expr_until_while_loop;
List *list;
PLpgSQL_type *dtype;
PLpgSQL_datum *datum;
@ -335,7 +352,9 @@ static void processFunctionRecordOutParam(int varno, Oid funcoid, int* outparam)
%type <expr> expr_until_semi expr_until_rightbracket
%type <expr> expr_until_then expr_until_loop opt_expr_until_when
%type <expr_until_while_loop> expr_until_while_loop
%type <expr> opt_exitcond
%type <expr> repeat_condition_expr
%type <ival> assign_var foreach_slice error_code cursor_variable
%type <datum> decl_cursor_arg
@ -347,6 +366,8 @@ static void processFunctionRecordOutParam(int varno, Oid funcoid, int* outparam)
%type <list> proc_sect proc_stmts stmt_elsifs stmt_else forall_body
%type <loop_body> loop_body
%type <while_body> while_body
%type <repeat_condition> repeat_condition
%type <stmt> proc_stmt pl_block
%type <stmt> stmt_assign stmt_if stmt_loop stmt_while stmt_exit stmt_goto label_stmts label_stmt
%type <stmt> stmt_return stmt_raise stmt_execsql
@ -453,6 +474,7 @@ static void processFunctionRecordOutParam(int varno, Oid funcoid, int* outparam)
%token <keyword> K_DETERMINISTIC
%token <keyword> K_DIAGNOSTICS
%token <keyword> K_DISTINCT
%token <keyword> K_DO
%token <keyword> K_DUMP
%token <keyword> K_ELSE
%token <keyword> K_ELSIF
@ -521,6 +543,7 @@ static void processFunctionRecordOutParam(int varno, Oid funcoid, int* outparam)
%token <keyword> K_REF
%token <keyword> K_RELATIVE
%token <keyword> K_RELEASE
%token <keyword> K_REPEAT
%token <keyword> K_REPLACE
%token <keyword> K_RESULT_OID
%token <keyword> K_RETURN
@ -543,6 +566,7 @@ static void processFunctionRecordOutParam(int varno, Oid funcoid, int* outparam)
%token <keyword> K_TO
%token <keyword> K_TYPE
%token <keyword> K_UNION
%token <keyword> K_UNTIL
%token <keyword> K_UPDATE
%token <keyword> K_USE_COLUMN
%token <keyword> K_USE_VARIABLE
@ -2764,6 +2788,14 @@ stmt_loop : opt_block_label K_LOOP loop_body
newp->body = $3.stmts;
newp->sqlString = plpgsql_get_curline_query();
if(strcmp(newp->label, "") == 0)
{
ereport(errstate,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("The label name is invalid"),
parser_errposition(@1)));
}
check_labels(u_sess->plsql_cxt.curr_compile_context->ns_top->name, $3.end_label, $3.end_label_location);
plpgsql_ns_pop();
@ -2774,15 +2806,25 @@ stmt_loop : opt_block_label K_LOOP loop_body
}
;
stmt_while : opt_block_label K_WHILE expr_until_loop loop_body
stmt_while : opt_block_label K_WHILE expr_until_while_loop loop_body
{
/*
* Check for correct syntax
*/
if(u_sess->attr.attr_sql.sql_compatibility == B_FORMAT)
{
if($3.endtoken != K_LOOP)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), errmsg("while-loop syntax is mixed with while-do syntax"), parser_errposition(@2)));
}
PLpgSQL_stmt_while *newp;
newp = (PLpgSQL_stmt_while *)palloc0(sizeof(PLpgSQL_stmt_while));
newp->cmd_type = PLPGSQL_STMT_WHILE;
newp->lineno = plpgsql_location_to_lineno(@2);
newp->label = $1;
newp->cond = $3;
newp->cond = $3.expr;
newp->body = $4.stmts;
newp->sqlString = plpgsql_get_curline_query();
@ -2794,6 +2836,197 @@ stmt_while : opt_block_label K_WHILE expr_until_loop loop_body
/* register the stmt if it is labeled */
record_stmt_label($1, (PLpgSQL_stmt *)newp);
}
| ':' K_WHILE expr_until_while_loop loop_body
{
/*
* When the database is in mysql compatible mode
* support "label: while-loop"
*/
if(u_sess->attr.attr_sql.sql_compatibility != B_FORMAT)
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("'label:' is only supported in database which dbcompatibility='B'.")));
/*
* Check for correct syntax
*/
if($3.endtoken != K_LOOP)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), errmsg("while-loop syntax is mixed with while-do syntax"), parser_errposition(@2)));
PLpgSQL_stmt_while *newp;
newp = (PLpgSQL_stmt_while *)palloc0(sizeof(PLpgSQL_stmt_while));
newp->cmd_type = PLPGSQL_STMT_WHILE;
newp->lineno = plpgsql_location_to_lineno(@2);
newp->label = u_sess->plsql_cxt.curr_compile_context->ns_top->name;
newp->cond = $3.expr;
newp->body = $4.stmts;
newp->sqlString = plpgsql_get_curline_query();
if(strcmp(newp->label, "") == 0)
{
ereport(errstate,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("The label name is invalid"),
parser_errposition(@1)));
}
check_labels(u_sess->plsql_cxt.curr_compile_context->ns_top->name, $4.end_label, $4.end_label_location);
plpgsql_ns_pop();
$$ = (PLpgSQL_stmt *)newp;
/* register the stmt if it is labeled */
record_stmt_label(u_sess->plsql_cxt.curr_compile_context->ns_top->name, (PLpgSQL_stmt *)newp);
}
| opt_block_label K_WHILE expr_until_while_loop while_body
{
/*
* When the database is in mysql compatible mode
* support "while-do"
*/
if(u_sess->attr.attr_sql.sql_compatibility != B_FORMAT)
{
ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("Incorrect use of syntax while-loop")));
}
else
{
/*
* Check for correct syntax
*/
if($3.endtoken != K_DO)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), errmsg("while-loop syntax is mixed with while-do syntax"), parser_errposition(@2)));
}
PLpgSQL_stmt_while *newp;
newp = (PLpgSQL_stmt_while *)palloc0(sizeof(PLpgSQL_stmt_while));
newp->cmd_type = PLPGSQL_STMT_WHILE;
newp->lineno = plpgsql_location_to_lineno(@2);
newp->label = $1;
newp->cond = $3.expr;
newp->body = $4.stmts;
newp->sqlString = plpgsql_get_curline_query();
check_labels($1, $4.end_label, $4.end_label_location);
plpgsql_ns_pop();
$$ = (PLpgSQL_stmt *)newp;
/* register the stmt if it is labeled */
record_stmt_label($1, (PLpgSQL_stmt *)newp);
}
| ':' K_WHILE expr_until_while_loop while_body
{
/*
* When the database is in mysql compatible mode
* support "label:"
*/
if(u_sess->attr.attr_sql.sql_compatibility != B_FORMAT)
{
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("'label:' is only supported in database which dbcompatibility='B'.")));
}
else
{
/*
* Check for correct syntax
*/
if($3.endtoken != K_DO)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), errmsg("while-loop syntax is mixed with while-do syntax"), parser_errposition(@2)));
}
PLpgSQL_stmt_while *newp;
newp = (PLpgSQL_stmt_while *)palloc0(sizeof(PLpgSQL_stmt_while));
newp->cmd_type = PLPGSQL_STMT_WHILE;
newp->lineno = plpgsql_location_to_lineno(@2);
newp->label = u_sess->plsql_cxt.curr_compile_context->ns_top->name;
newp->cond = $3.expr;
newp->body = $4.stmts;
newp->sqlString = plpgsql_get_curline_query();
if(strcmp(newp->label, "") == 0)
{
ereport(errstate,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("The label name is invalid"),
parser_errposition(@1)));
}
check_labels(u_sess->plsql_cxt.curr_compile_context->ns_top->name, $4.end_label, $4.end_label_location);
plpgsql_ns_pop();
$$ = (PLpgSQL_stmt *)newp;
/* register the stmt if it is labeled */
record_stmt_label(u_sess->plsql_cxt.curr_compile_context->ns_top->name, (PLpgSQL_stmt *)newp);
}
| opt_block_label K_REPEAT proc_sect K_UNTIL repeat_condition
{
/*
* When the database is in mysql compatible mode
* support "repeat"
*/
if(u_sess->attr.attr_sql.sql_compatibility != B_FORMAT)
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("'repeat' is only supported in database which dbcompatibility='B'.")));
PLpgSQL_stmt_while *newp;
newp = (PLpgSQL_stmt_while *)palloc0(sizeof(PLpgSQL_stmt_while));
newp->cmd_type = PLPGSQL_STMT_WHILE;
newp->lineno = plpgsql_location_to_lineno(@2);
newp->label = $1;
newp->cond = $5.expr;
newp->body = $3;
newp->sqlString = plpgsql_get_curline_query();
check_labels($1, $5.end_label, $5.end_label_location);
plpgsql_ns_pop();
$$ = (PLpgSQL_stmt *)newp;
/* register the stmt if it is labeled */
record_stmt_label($1, (PLpgSQL_stmt *)newp);
}
| ':' K_REPEAT proc_sect K_UNTIL repeat_condition
{
/*
* When the database is in mysql compatible mode
* support "repeat"
*/
if(u_sess->attr.attr_sql.sql_compatibility != B_FORMAT)
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("'label: repeat' is only supported in database which dbcompatibility='B'.")));
PLpgSQL_stmt_while *newp;
newp = (PLpgSQL_stmt_while *)palloc0(sizeof(PLpgSQL_stmt_while));
newp->cmd_type = PLPGSQL_STMT_WHILE;
newp->lineno = plpgsql_location_to_lineno(@2);
newp->label = u_sess->plsql_cxt.curr_compile_context->ns_top->name;
newp->cond = $5.expr;
newp->body = $3;
newp->sqlString = plpgsql_get_curline_query();
if(strcmp(newp->label, "") == 0)
{
ereport(errstate,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("The label name is invalid"),
parser_errposition(@1)));
}
check_labels(u_sess->plsql_cxt.curr_compile_context->ns_top->name, $5.end_label, $5.end_label_location);
plpgsql_ns_pop();
$$ = (PLpgSQL_stmt *)newp;
/* register the stmt if it is labeled */
record_stmt_label(u_sess->plsql_cxt.curr_compile_context->ns_top->name, (PLpgSQL_stmt *)newp);
}
;
stmt_for : opt_block_label K_FOR for_control loop_body
@ -3813,6 +4046,26 @@ loop_body : proc_sect K_END K_LOOP opt_label ';'
}
;
while_body : proc_sect K_END K_WHILE opt_label ';'
{
$$.stmts = $1;
$$.end_label = $4;
$$.end_label_location = @4;
}
;
repeat_condition : repeat_condition_expr K_REPEAT opt_label ';'
{
$$.expr = $1;
$$.end_label = $3;
$$.end_label_location = @3;
}
;
repeat_condition_expr :
{ $$ = read_sql_construct(K_END, 0, 0, "end", "SELECT NOT ", true, true, true, NULL, NULL); }
;
/*
* T_WORD+T_CWORD match any initial identifier that is not a known plpgsql
* variable. (The composite case is probably a syntax error, but we'll let
@ -5198,6 +5451,19 @@ expr_until_loop :
{ $$ = read_sql_expression(K_LOOP, "LOOP"); }
;
expr_until_while_loop:
{
int tok = -1;
$$.expr = read_sql_expression2(K_LOOP, K_DO, "LOOP or DO", &tok);
$$.endtoken = tok;
if(u_sess->attr.attr_sql.sql_compatibility != B_FORMAT && tok == K_DO)
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("'while-do' is only supported in database which dbcompatibility='B'.")));
}
;
opt_block_label :
{
plpgsql_ns_push(NULL);
@ -8317,7 +8583,7 @@ get_proc_str(int tok)
{
tok = yylex();
/* process end loop*/
if (tok == K_LOOP) {
if (tok == K_LOOP || tok == K_WHILE || tok == K_REPEAT) {
continue;
}
if (blocklevel == 1 && (pre_tok == ';' || pre_tok == K_BEGIN) && (tok == ';' || tok == 0))
@ -8683,7 +8949,7 @@ make_execsql_stmt(int firsttoken, int location)
int parenlevel = 0;
List *list_bracket = 0; /* stack structure bracket tracker */
List *list_bracket_loc = 0; /* location tracker */
bool label_loop = false;
bool label_begin = false;
initStringInfo(&ds);
/* special lookup mode for identifiers within the SQL text */
@ -8806,12 +9072,12 @@ make_execsql_stmt(int firsttoken, int location)
initStringInfo(&lb);
int lb_end = yylloc;
int tok1 = yylex();
if(tok1 == K_LOOP)
if(tok1 == K_LOOP || tok1 == K_WHILE || tok1 == K_REPEAT)
{
if(u_sess->attr.attr_sql.sql_compatibility == B_FORMAT)
{
int count = 0;
label_loop = true;
label_begin = true;
plpgsql_push_back_token(tok1);
plpgsql_push_back_token(tok);
plpgsql_append_source_text(&lb, location, lb_end);
@ -9131,7 +9397,7 @@ make_execsql_stmt(int firsttoken, int location)
}
}
}
} else if (label_loop)
} else if (label_begin)
{
appendStringInfoString(&ds, "\n");
} else {

View File

@ -131,6 +131,7 @@ static const ScanKeyword unreserved_keywords[] = {
PG_KEYWORD("debug", K_DEBUG, UNRESERVED_KEYWORD)
PG_KEYWORD("detail", K_DETAIL, UNRESERVED_KEYWORD)
PG_KEYWORD("distinct", K_DISTINCT, UNRESERVED_KEYWORD)
PG_KEYWORD("do", K_DO, UNRESERVED_KEYWORD)
PG_KEYWORD("dump", K_DUMP, UNRESERVED_KEYWORD)
PG_KEYWORD("errcode", K_ERRCODE, UNRESERVED_KEYWORD)
PG_KEYWORD("error", K_ERROR, UNRESERVED_KEYWORD)
@ -170,6 +171,7 @@ static const ScanKeyword unreserved_keywords[] = {
PG_KEYWORD("record", K_RECORD, UNRESERVED_KEYWORD)
PG_KEYWORD("relative", K_RELATIVE, UNRESERVED_KEYWORD)
PG_KEYWORD("release", K_RELEASE, UNRESERVED_KEYWORD)
PG_KEYWORD("repeat", K_REPEAT, UNRESERVED_KEYWORD)
PG_KEYWORD("replace", K_REPLACE, UNRESERVED_KEYWORD)
PG_KEYWORD("result_oid", K_RESULT_OID, UNRESERVED_KEYWORD)
PG_KEYWORD("returned_sqlstate", K_RETURNED_SQLSTATE, UNRESERVED_KEYWORD)
@ -187,6 +189,7 @@ static const ScanKeyword unreserved_keywords[] = {
PG_KEYWORD("table", K_TABLE, UNRESERVED_KEYWORD)
PG_KEYWORD("type", K_TYPE, UNRESERVED_KEYWORD)
PG_KEYWORD("union", K_UNION, UNRESERVED_KEYWORD)
PG_KEYWORD("until", K_UNTIL, UNRESERVED_KEYWORD)
PG_KEYWORD("use_column", K_USE_COLUMN, UNRESERVED_KEYWORD)
PG_KEYWORD("use_variable", K_USE_VARIABLE, UNRESERVED_KEYWORD)
PG_KEYWORD("variable_conflict", K_VARIABLE_CONFLICT, UNRESERVED_KEYWORD)

View File

@ -490,6 +490,7 @@ PG_KEYWORD("reloptions", RELOPTIONS, UNRESERVED_KEYWORD)
PG_KEYWORD("remote", REMOTE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("remove", REMOVE, UNRESERVED_KEYWORD)
PG_KEYWORD("rename", RENAME, UNRESERVED_KEYWORD)
PG_KEYWORD("repeat", REPEAT, UNRESERVED_KEYWORD)
PG_KEYWORD("repeatable", REPEATABLE, UNRESERVED_KEYWORD)
PG_KEYWORD("replace", REPLACE, UNRESERVED_KEYWORD)
PG_KEYWORD("replica", REPLICA, UNRESERVED_KEYWORD)
@ -650,6 +651,7 @@ PG_KEYWORD("wait", WAIT, UNRESERVED_KEYWORD)
PG_KEYWORD("weak", WEAK, UNRESERVED_KEYWORD)
PG_KEYWORD("when", WHEN, RESERVED_KEYWORD)
PG_KEYWORD("where", WHERE, RESERVED_KEYWORD)
PG_KEYWORD("while", WHILE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("whitespace", WHITESPACE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("window", WINDOW, RESERVED_KEYWORD)
PG_KEYWORD("with", WITH, RESERVED_KEYWORD)

View File

@ -1740,6 +1740,619 @@ DETAIL: drop cascades to function test.func1()
drop cascades to function test.debug(integer,integer)
drop cascades to function test.call(integer,integer)
\c regression
--error
create or replace function while_test1() returns void as $$
declare _i integer = 0; _r record;
begin
raise notice '---1---';
while _i < 10 do
_i := _i + 1;
raise notice '%', _i;
end while;
raise notice '---2---';
<<lbl>>
while _i > 0 do
_i := _i - 1;
loop
raise notice '%', _i;
continue lbl when _i > 0;
exit lbl;
end loop;
end while;
raise notice '---3---';
the_while:
while _i < 10 do
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while the_while;
raise notice '---3---';
_i := 1;
while _i <= 3 loop
raise notice '%', _i;
_i := _i + 1;
continue when _i = 3;
end loop;
end; $$ language plpgsql;
ERROR: 'while-do' is only supported in database which dbcompatibility='B'.
CONTEXT: compilation of PL/pgSQL function "while_test1" near line 4
--error
create or replace function while_test1() returns void as $$
declare _i integer = 0; _r record;
begin
while _i < 10 do
_i := _i + 1;
raise notice '%', _i;
end while the_while;
end; $$ language plpgsql;
ERROR: 'while-do' is only supported in database which dbcompatibility='B'.
CONTEXT: compilation of PL/pgSQL function "while_test1" near line 2
--error
create or replace function while_test1() returns void as $$
declare _i integer = 10; _r record;
begin
<<lbl>>
while _i > 0 do
_i := _i - 1;
loop
raise notice '%', _i;
continue lbl when _i > 0;
exit lbl;
end loop;
end while lbl;
end; $$ language plpgsql;
ERROR: 'while-do' is only supported in database which dbcompatibility='B'.
CONTEXT: compilation of PL/pgSQL function "while_test1" near line 2
--error
create or replace function while_test1() returns void as $$
declare _i integer = 0; _r record;
begin
the_while:
while _i < 10 do
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while the_while;
end; $$ language plpgsql;
ERROR: 'label:' is only supported in database which dbcompatibility='B'.
CONTEXT: compilation of PL/pgSQL function "while_test1" near line 2
--success
create or replace function while_test1() returns void as $$
declare _i integer = 10; _r record;
begin
<<lbl>>
while _i > 0 loop
_i := _i - 1;
loop
raise notice '%', _i;
continue lbl when _i > 0;
exit lbl;
end loop;
end loop lbl;
end; $$ language plpgsql;
select while_test1();
NOTICE: 9
CONTEXT: referenced column: while_test1
NOTICE: 8
CONTEXT: referenced column: while_test1
NOTICE: 7
CONTEXT: referenced column: while_test1
NOTICE: 6
CONTEXT: referenced column: while_test1
NOTICE: 5
CONTEXT: referenced column: while_test1
NOTICE: 4
CONTEXT: referenced column: while_test1
NOTICE: 3
CONTEXT: referenced column: while_test1
NOTICE: 2
CONTEXT: referenced column: while_test1
NOTICE: 1
CONTEXT: referenced column: while_test1
NOTICE: 0
CONTEXT: referenced column: while_test1
while_test1
-------------
(1 row)
drop function while_test1;
\c b
create or replace function while_test1() returns void as $$
declare _i integer = 0; _r record;
begin
raise notice '---1---';
while _i < 10 do
_i := _i + 1;
raise notice '%', _i;
end while;
raise notice '---2---';
<<lbl>>
while _i > 0 do
_i := _i - 1;
loop
raise notice '%', _i;
continue lbl when _i > 0;
exit lbl;
end loop;
end while;
raise notice '---3---';
the_while:
while _i < 10 do
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while the_while;
raise notice '---3---';
_i := 1;
while _i <= 3 loop
raise notice '%', _i;
_i := _i + 1;
continue when _i = 3;
end loop;
end; $$ language plpgsql;
select while_test1();
NOTICE: ---1---
CONTEXT: referenced column: while_test1
NOTICE: 1
CONTEXT: referenced column: while_test1
NOTICE: 2
CONTEXT: referenced column: while_test1
NOTICE: 3
CONTEXT: referenced column: while_test1
NOTICE: 4
CONTEXT: referenced column: while_test1
NOTICE: 5
CONTEXT: referenced column: while_test1
NOTICE: 6
CONTEXT: referenced column: while_test1
NOTICE: 7
CONTEXT: referenced column: while_test1
NOTICE: 8
CONTEXT: referenced column: while_test1
NOTICE: 9
CONTEXT: referenced column: while_test1
NOTICE: 10
CONTEXT: referenced column: while_test1
NOTICE: ---2---
CONTEXT: referenced column: while_test1
NOTICE: 9
CONTEXT: referenced column: while_test1
NOTICE: 8
CONTEXT: referenced column: while_test1
NOTICE: 7
CONTEXT: referenced column: while_test1
NOTICE: 6
CONTEXT: referenced column: while_test1
NOTICE: 5
CONTEXT: referenced column: while_test1
NOTICE: 4
CONTEXT: referenced column: while_test1
NOTICE: 3
CONTEXT: referenced column: while_test1
NOTICE: 2
CONTEXT: referenced column: while_test1
NOTICE: 1
CONTEXT: referenced column: while_test1
NOTICE: 0
CONTEXT: referenced column: while_test1
NOTICE: ---3---
CONTEXT: referenced column: while_test1
NOTICE: 1
CONTEXT: referenced column: while_test1
NOTICE: 3
CONTEXT: referenced column: while_test1
NOTICE: 5
CONTEXT: referenced column: while_test1
NOTICE: 7
CONTEXT: referenced column: while_test1
NOTICE: 9
CONTEXT: referenced column: while_test1
NOTICE: ---3---
CONTEXT: referenced column: while_test1
NOTICE: 1
CONTEXT: referenced column: while_test1
NOTICE: 2
CONTEXT: referenced column: while_test1
NOTICE: 3
CONTEXT: referenced column: while_test1
while_test1
-------------
(1 row)
--error
create or replace function while_test1() returns void as $$
declare _i integer = 0; _r record;
begin
while _i < 10 do
_i := _i + 1;
raise notice '%', _i;
end while the_while;
end; $$ language plpgsql;
ERROR: end label "the_while" specified for unlabelled block
LINE 7: end while the_while;
^
create or replace function while_test1() returns void as $$
declare _i integer = 10; _r record;
begin
<<lbl>>
while _i > 0 do
_i := _i - 1;
loop
raise notice '%', _i;
continue lbl when _i > 0;
exit lbl;
end loop;
end while lbl;
end; $$ language plpgsql;
select while_test1();
NOTICE: 9
CONTEXT: referenced column: while_test1
NOTICE: 8
CONTEXT: referenced column: while_test1
NOTICE: 7
CONTEXT: referenced column: while_test1
NOTICE: 6
CONTEXT: referenced column: while_test1
NOTICE: 5
CONTEXT: referenced column: while_test1
NOTICE: 4
CONTEXT: referenced column: while_test1
NOTICE: 3
CONTEXT: referenced column: while_test1
NOTICE: 2
CONTEXT: referenced column: while_test1
NOTICE: 1
CONTEXT: referenced column: while_test1
NOTICE: 0
CONTEXT: referenced column: while_test1
while_test1
-------------
(1 row)
create or replace function while_test1() returns void as $$
declare _i integer = 10; _r record;
begin
<<lbl>>
while _i > 0 loop
_i := _i - 1;
loop
raise notice '%', _i;
continue lbl when _i > 0;
exit lbl;
end loop;
end loop lbl;
end; $$ language plpgsql;
select while_test1();
NOTICE: 9
CONTEXT: referenced column: while_test1
NOTICE: 8
CONTEXT: referenced column: while_test1
NOTICE: 7
CONTEXT: referenced column: while_test1
NOTICE: 6
CONTEXT: referenced column: while_test1
NOTICE: 5
CONTEXT: referenced column: while_test1
NOTICE: 4
CONTEXT: referenced column: while_test1
NOTICE: 3
CONTEXT: referenced column: while_test1
NOTICE: 2
CONTEXT: referenced column: while_test1
NOTICE: 1
CONTEXT: referenced column: while_test1
NOTICE: 0
CONTEXT: referenced column: while_test1
while_test1
-------------
(1 row)
create or replace function while_test1() returns void as $$
declare _i integer = 0; _r record;
begin
the_while:
while _i < 10 do
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while the_while;
end; $$ language plpgsql;
select while_test1();
NOTICE: 1
CONTEXT: referenced column: while_test1
NOTICE: 3
CONTEXT: referenced column: while_test1
NOTICE: 5
CONTEXT: referenced column: while_test1
NOTICE: 7
CONTEXT: referenced column: while_test1
NOTICE: 9
CONTEXT: referenced column: while_test1
while_test1
-------------
(1 row)
--error
create or replace function while_test1() returns void as $$
declare _i integer = 0; _r record;
begin
the_while:
while _i < 10 loop
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while the_while;
end; $$ language plpgsql;
ERROR: while-loop syntax is mixed with while-do syntax
LINE 5: while _i < 10 loop
^
--error
create or replace function while_test1() returns void as $$
declare _i integer = 0; _r record;
begin
the_while:
while _i < 10 do
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end loop the_while;
end; $$ language plpgsql;
ERROR: while-loop syntax is mixed with while-do syntax
LINE 5: while _i < 10 do
^
create or replace procedure while_test2()
as
declare _i integer = 0;
BEGIN
the_while:
while _i < 10 do
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while the_while;
end;
/
select while_test2();
NOTICE: 1
CONTEXT: referenced column: while_test2
NOTICE: 3
CONTEXT: referenced column: while_test2
NOTICE: 5
CONTEXT: referenced column: while_test2
NOTICE: 7
CONTEXT: referenced column: while_test2
NOTICE: 9
CONTEXT: referenced column: while_test2
while_test2
-------------
(1 row)
--error
create or replace procedure while_test2()
as
declare _i integer = 0;
BEGIN
the_while:
while _i < 10 loop
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while the_while;
end;
/
ERROR: while-loop syntax is mixed with while-do syntax
LINE 5: while _i < 10 loop
^
QUERY:
declare _i integer = 0;
BEGIN
the_while:
while _i < 10 loop
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while the_while;
end
--error
create or replace procedure while_test2()
as
declare _i integer = 0;
BEGIN
while _i < 10 do
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end loop;
end;
/
ERROR: while-loop syntax is mixed with while-do syntax
LINE 4: while _i < 10 do
^
QUERY:
declare _i integer = 0;
BEGIN
while _i < 10 do
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end loop;
end
--error
create or replace procedure while_test2()
as
declare _i integer = 0;
BEGIN
while _i < 10 loop
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while;
end;
/
ERROR: while-loop syntax is mixed with while-do syntax
LINE 4: while _i < 10 loop
^
QUERY:
declare _i integer = 0;
BEGIN
while _i < 10 loop
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while;
end
drop function while_test1;
drop procedure while_test2;
\c regression
--error
CREATE or replace PROCEDURE dorepeat(p1 INT)
as
declare
i int =0;
BEGIN
repeat
i = i + 1;
until i >p1 end repeat;
raise notice '%',i;
end;
/
ERROR: 'repeat' is only supported in database which dbcompatibility='B'.
CONTEXT: compilation of PL/pgSQL function "dorepeat" near line 6
--error
CREATE or replace PROCEDURE dorepeat(p1 INT)
as
declare
i int =0;
BEGIN
<<label>>
repeat
i = i + 1;
until i >p1 end repeat label;
raise notice '%',i;
end;
/
ERROR: 'repeat' is only supported in database which dbcompatibility='B'.
CONTEXT: compilation of PL/pgSQL function "dorepeat" near line 7
--error
CREATE or replace PROCEDURE dorepeat(p1 INT)
as
declare
i int =0;
BEGIN
label:
repeat
i = i + 1;
until i >p1 end repeat label;
raise notice '%',i;
end;
/
ERROR: 'label:' is only supported in database which dbcompatibility='B'.
CONTEXT: compilation of PL/pgSQL function "dorepeat" near line 3
drop function if exists dorepeat;
NOTICE: function dorepeat() does not exist, skipping
\c b
--success
CREATE or replace PROCEDURE dorepeat(p1 INT)
as
declare
i int =0;
BEGIN
repeat
i = i + 1;
until i >p1 end repeat;
raise notice '%',i;
end;
/
select dorepeat(5);
NOTICE: 6
CONTEXT: referenced column: dorepeat
dorepeat
----------
(1 row)
--success
CREATE or replace PROCEDURE dorepeat(p1 INT)
as
declare
i int =0;
BEGIN
<<label>>
repeat
i = i + 1;
until i >p1 end repeat label;
raise notice '%',i;
end;
/
select dorepeat(5);
NOTICE: 6
CONTEXT: referenced column: dorepeat
dorepeat
----------
(1 row)
--success
CREATE or replace PROCEDURE dorepeat(p1 INT)
as
declare
i int =0;
BEGIN
label:
repeat
i = i + 1;
until i >p1 end repeat label;
raise notice '%',i;
end;
/
select dorepeat(5);
NOTICE: 6
CONTEXT: referenced column: dorepeat
dorepeat
----------
(1 row)
--error
CREATE or replace PROCEDURE dorepeat(p1 INT)
as
declare
i int =0;
BEGIN
repeat:
repeat
i = i + 1;
until i >p1 end repeat;
raise notice '%',i;
end;
/
ERROR: The label name is invalid
LINE 5: repeat:
^
QUERY:
declare
i int =0;
BEGIN
repeat:
repeat
i = i + 1;
until i >p1 end repeat;
raise notice '%',i;
end
drop function if exists dorepeat;
\c regression
drop database b;
DROP USER test_c;
DROP USER test_d;

View File

@ -1037,6 +1037,376 @@ drop schema test CASCADE;
\c regression
--error
create or replace function while_test1() returns void as $$
declare _i integer = 0; _r record;
begin
raise notice '---1---';
while _i < 10 do
_i := _i + 1;
raise notice '%', _i;
end while;
raise notice '---2---';
<<lbl>>
while _i > 0 do
_i := _i - 1;
loop
raise notice '%', _i;
continue lbl when _i > 0;
exit lbl;
end loop;
end while;
raise notice '---3---';
the_while:
while _i < 10 do
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while the_while;
raise notice '---3---';
_i := 1;
while _i <= 3 loop
raise notice '%', _i;
_i := _i + 1;
continue when _i = 3;
end loop;
end; $$ language plpgsql;
--error
create or replace function while_test1() returns void as $$
declare _i integer = 0; _r record;
begin
while _i < 10 do
_i := _i + 1;
raise notice '%', _i;
end while the_while;
end; $$ language plpgsql;
--error
create or replace function while_test1() returns void as $$
declare _i integer = 10; _r record;
begin
<<lbl>>
while _i > 0 do
_i := _i - 1;
loop
raise notice '%', _i;
continue lbl when _i > 0;
exit lbl;
end loop;
end while lbl;
end; $$ language plpgsql;
--error
create or replace function while_test1() returns void as $$
declare _i integer = 0; _r record;
begin
the_while:
while _i < 10 do
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while the_while;
end; $$ language plpgsql;
--success
create or replace function while_test1() returns void as $$
declare _i integer = 10; _r record;
begin
<<lbl>>
while _i > 0 loop
_i := _i - 1;
loop
raise notice '%', _i;
continue lbl when _i > 0;
exit lbl;
end loop;
end loop lbl;
end; $$ language plpgsql;
select while_test1();
drop function while_test1;
\c b
create or replace function while_test1() returns void as $$
declare _i integer = 0; _r record;
begin
raise notice '---1---';
while _i < 10 do
_i := _i + 1;
raise notice '%', _i;
end while;
raise notice '---2---';
<<lbl>>
while _i > 0 do
_i := _i - 1;
loop
raise notice '%', _i;
continue lbl when _i > 0;
exit lbl;
end loop;
end while;
raise notice '---3---';
the_while:
while _i < 10 do
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while the_while;
raise notice '---3---';
_i := 1;
while _i <= 3 loop
raise notice '%', _i;
_i := _i + 1;
continue when _i = 3;
end loop;
end; $$ language plpgsql;
select while_test1();
--error
create or replace function while_test1() returns void as $$
declare _i integer = 0; _r record;
begin
while _i < 10 do
_i := _i + 1;
raise notice '%', _i;
end while the_while;
end; $$ language plpgsql;
create or replace function while_test1() returns void as $$
declare _i integer = 10; _r record;
begin
<<lbl>>
while _i > 0 do
_i := _i - 1;
loop
raise notice '%', _i;
continue lbl when _i > 0;
exit lbl;
end loop;
end while lbl;
end; $$ language plpgsql;
select while_test1();
create or replace function while_test1() returns void as $$
declare _i integer = 10; _r record;
begin
<<lbl>>
while _i > 0 loop
_i := _i - 1;
loop
raise notice '%', _i;
continue lbl when _i > 0;
exit lbl;
end loop;
end loop lbl;
end; $$ language plpgsql;
select while_test1();
create or replace function while_test1() returns void as $$
declare _i integer = 0; _r record;
begin
the_while:
while _i < 10 do
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while the_while;
end; $$ language plpgsql;
select while_test1();
--error
create or replace function while_test1() returns void as $$
declare _i integer = 0; _r record;
begin
the_while:
while _i < 10 loop
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while the_while;
end; $$ language plpgsql;
--error
create or replace function while_test1() returns void as $$
declare _i integer = 0; _r record;
begin
the_while:
while _i < 10 do
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end loop the_while;
end; $$ language plpgsql;
create or replace procedure while_test2()
as
declare _i integer = 0;
BEGIN
the_while:
while _i < 10 do
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while the_while;
end;
/
select while_test2();
--error
create or replace procedure while_test2()
as
declare _i integer = 0;
BEGIN
the_while:
while _i < 10 loop
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while the_while;
end;
/
--error
create or replace procedure while_test2()
as
declare _i integer = 0;
BEGIN
while _i < 10 do
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end loop;
end;
/
--error
create or replace procedure while_test2()
as
declare _i integer = 0;
BEGIN
while _i < 10 loop
_i := _i + 1;
continue the_while when _i % 2 = 0;
raise notice '%', _i;
end while;
end;
/
drop function while_test1;
drop procedure while_test2;
\c regression
--error
CREATE or replace PROCEDURE dorepeat(p1 INT)
as
declare
i int =0;
BEGIN
repeat
i = i + 1;
until i >p1 end repeat;
raise notice '%',i;
end;
/
--error
CREATE or replace PROCEDURE dorepeat(p1 INT)
as
declare
i int =0;
BEGIN
<<label>>
repeat
i = i + 1;
until i >p1 end repeat label;
raise notice '%',i;
end;
/
--error
CREATE or replace PROCEDURE dorepeat(p1 INT)
as
declare
i int =0;
BEGIN
label:
repeat
i = i + 1;
until i >p1 end repeat label;
raise notice '%',i;
end;
/
drop function if exists dorepeat;
\c b
--success
CREATE or replace PROCEDURE dorepeat(p1 INT)
as
declare
i int =0;
BEGIN
repeat
i = i + 1;
until i >p1 end repeat;
raise notice '%',i;
end;
/
select dorepeat(5);
--success
CREATE or replace PROCEDURE dorepeat(p1 INT)
as
declare
i int =0;
BEGIN
<<label>>
repeat
i = i + 1;
until i >p1 end repeat label;
raise notice '%',i;
end;
/
select dorepeat(5);
--success
CREATE or replace PROCEDURE dorepeat(p1 INT)
as
declare
i int =0;
BEGIN
label:
repeat
i = i + 1;
until i >p1 end repeat label;
raise notice '%',i;
end;
/
select dorepeat(5);
--error
CREATE or replace PROCEDURE dorepeat(p1 INT)
as
declare
i int =0;
BEGIN
repeat:
repeat
i = i + 1;
until i >p1 end repeat;
raise notice '%',i;
end;
/
drop function if exists dorepeat;
\c regression
drop database b;
DROP USER test_c;
DROP USER test_d;