summaryrefslogtreecommitdiffstats
path: root/src/pl
diff options
context:
space:
mode:
Diffstat (limited to 'src/pl')
-rw-r--r--src/pl/plpgsql/src/expected/plpgsql_control.out17
-rw-r--r--src/pl/plpgsql/src/pl_gram.c733
-rw-r--r--src/pl/plpgsql/src/pl_gram.h2
-rw-r--r--src/pl/plpgsql/src/pl_gram.y47
-rw-r--r--src/pl/plpgsql/src/pl_scanner.c17
-rw-r--r--src/pl/plpgsql/src/plpgsql.h1
-rw-r--r--src/pl/plpgsql/src/po/ru.po132
-rw-r--r--src/pl/plpgsql/src/sql/plpgsql_control.sql14
-rw-r--r--src/pl/plpython/plpy_exec.c12
-rw-r--r--src/pl/plpython/po/ru.po18
10 files changed, 518 insertions, 475 deletions
diff --git a/src/pl/plpgsql/src/expected/plpgsql_control.out b/src/pl/plpgsql/src/expected/plpgsql_control.out
index 328bd48..ccd4f54 100644
--- a/src/pl/plpgsql/src/expected/plpgsql_control.out
+++ b/src/pl/plpgsql/src/expected/plpgsql_control.out
@@ -681,3 +681,20 @@ select case_test(13);
other
(1 row)
+-- test line comment between WHEN and THEN
+create or replace function case_comment(int) returns text as $$
+begin
+ case $1
+ when 1 -- comment before THEN
+ then return 'one';
+ else
+ return 'other';
+ end case;
+end;
+$$ language plpgsql immutable;
+select case_comment(1);
+ case_comment
+--------------
+ one
+(1 row)
+
diff --git a/src/pl/plpgsql/src/pl_gram.c b/src/pl/plpgsql/src/pl_gram.c
index 1f098b3..6e06dac 100644
--- a/src/pl/plpgsql/src/pl_gram.c
+++ b/src/pl/plpgsql/src/pl_gram.c
@@ -144,7 +144,6 @@ static PLpgSQL_expr *read_sql_construct(int until,
RawParseMode parsemode,
bool isexpression,
bool valid_sql,
- bool trim,
int *startloc,
int *endtoken);
static PLpgSQL_expr *read_sql_expression(int until,
@@ -187,7 +186,7 @@ static List *read_raise_options(void);
static void check_raise_parameters(PLpgSQL_stmt_raise *stmt);
-#line 191 "pl_gram.c"
+#line 190 "pl_gram.c"
# ifndef YY_CAST
# ifdef __cplusplus
@@ -834,32 +833,32 @@ static const yytype_uint8 yytranslate[] =
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_int16 yyrline[] =
{
- 0, 360, 360, 366, 367, 370, 374, 383, 387, 391,
- 397, 401, 406, 407, 410, 433, 441, 448, 457, 469,
- 470, 473, 474, 478, 491, 529, 535, 534, 561, 564,
- 568, 575, 581, 584, 615, 619, 625, 633, 634, 636,
- 651, 666, 694, 722, 753, 754, 759, 770, 771, 776,
- 781, 788, 789, 793, 795, 801, 802, 810, 811, 815,
- 816, 826, 828, 830, 832, 834, 836, 838, 840, 842,
- 844, 846, 848, 850, 852, 854, 856, 858, 860, 862,
- 864, 866, 868, 870, 872, 876, 912, 930, 951, 990,
- 1054, 1057, 1061, 1067, 1071, 1077, 1090, 1137, 1155, 1160,
- 1167, 1185, 1188, 1202, 1205, 1211, 1218, 1232, 1236, 1242,
- 1254, 1257, 1272, 1290, 1309, 1343, 1602, 1628, 1642, 1649,
- 1688, 1691, 1697, 1750, 1754, 1760, 1786, 1931, 1955, 1973,
- 1977, 1981, 1985, 1996, 2009, 2073, 2151, 2181, 2194, 2199,
- 2213, 2220, 2234, 2249, 2250, 2251, 2255, 2277, 2282, 2290,
- 2292, 2291, 2333, 2337, 2343, 2356, 2365, 2371, 2408, 2412,
- 2416, 2420, 2424, 2432, 2436, 2444, 2447, 2454, 2456, 2463,
- 2467, 2471, 2480, 2481, 2482, 2483, 2484, 2485, 2486, 2487,
- 2488, 2489, 2490, 2491, 2492, 2493, 2494, 2495, 2496, 2497,
- 2498, 2499, 2500, 2501, 2502, 2503, 2504, 2505, 2506, 2507,
- 2508, 2509, 2510, 2511, 2512, 2513, 2514, 2515, 2516, 2517,
- 2518, 2519, 2520, 2521, 2522, 2523, 2524, 2525, 2526, 2527,
- 2528, 2529, 2530, 2531, 2532, 2533, 2534, 2535, 2536, 2537,
- 2538, 2539, 2540, 2541, 2542, 2543, 2544, 2545, 2546, 2547,
- 2548, 2549, 2550, 2551, 2552, 2553, 2554, 2555, 2556, 2557,
- 2558, 2559, 2560, 2561
+ 0, 359, 359, 365, 366, 369, 373, 382, 386, 390,
+ 396, 400, 405, 406, 409, 432, 440, 447, 456, 468,
+ 469, 472, 473, 477, 490, 528, 534, 533, 560, 563,
+ 567, 574, 580, 583, 614, 618, 624, 632, 633, 635,
+ 650, 665, 693, 721, 752, 753, 758, 769, 770, 775,
+ 780, 787, 788, 792, 794, 800, 801, 809, 810, 814,
+ 815, 825, 827, 829, 831, 833, 835, 837, 839, 841,
+ 843, 845, 847, 849, 851, 853, 855, 857, 859, 861,
+ 863, 865, 867, 869, 871, 875, 911, 929, 950, 989,
+ 1053, 1056, 1060, 1066, 1070, 1076, 1089, 1136, 1154, 1159,
+ 1166, 1184, 1187, 1201, 1204, 1210, 1217, 1231, 1235, 1241,
+ 1253, 1256, 1271, 1289, 1308, 1342, 1600, 1626, 1640, 1647,
+ 1686, 1689, 1695, 1748, 1752, 1758, 1784, 1929, 1953, 1971,
+ 1975, 1979, 1983, 1994, 2007, 2071, 2149, 2179, 2192, 2197,
+ 2211, 2218, 2232, 2247, 2248, 2249, 2253, 2275, 2280, 2288,
+ 2290, 2289, 2331, 2335, 2341, 2354, 2363, 2369, 2406, 2410,
+ 2414, 2418, 2422, 2430, 2434, 2442, 2445, 2452, 2454, 2461,
+ 2465, 2469, 2478, 2479, 2480, 2481, 2482, 2483, 2484, 2485,
+ 2486, 2487, 2488, 2489, 2490, 2491, 2492, 2493, 2494, 2495,
+ 2496, 2497, 2498, 2499, 2500, 2501, 2502, 2503, 2504, 2505,
+ 2506, 2507, 2508, 2509, 2510, 2511, 2512, 2513, 2514, 2515,
+ 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523, 2524, 2525,
+ 2526, 2527, 2528, 2529, 2530, 2531, 2532, 2533, 2534, 2535,
+ 2536, 2537, 2538, 2539, 2540, 2541, 2542, 2543, 2544, 2545,
+ 2546, 2547, 2548, 2549, 2550, 2551, 2552, 2553, 2554, 2555,
+ 2556, 2557, 2558, 2559
};
#endif
@@ -2005,23 +2004,23 @@ yyreduce:
switch (yyn)
{
case 2: /* pl_function: comp_options pl_block opt_semi */
-#line 361 "pl_gram.y"
+#line 360 "pl_gram.y"
{
plpgsql_parse_result = (PLpgSQL_stmt_block *) (yyvsp[-1].stmt);
}
-#line 2013 "pl_gram.c"
+#line 2012 "pl_gram.c"
break;
case 5: /* comp_option: '#' K_OPTION K_DUMP */
-#line 371 "pl_gram.y"
+#line 370 "pl_gram.y"
{
plpgsql_DumpExecTree = true;
}
-#line 2021 "pl_gram.c"
+#line 2020 "pl_gram.c"
break;
case 6: /* comp_option: '#' K_PRINT_STRICT_PARAMS option_value */
-#line 375 "pl_gram.y"
+#line 374 "pl_gram.y"
{
if (strcmp((yyvsp[0].str), "on") == 0)
plpgsql_curr_compile->print_strict_params = true;
@@ -2030,51 +2029,51 @@ yyreduce:
else
elog(ERROR, "unrecognized print_strict_params option %s", (yyvsp[0].str));
}
-#line 2034 "pl_gram.c"
+#line 2033 "pl_gram.c"
break;
case 7: /* comp_option: '#' K_VARIABLE_CONFLICT K_ERROR */
-#line 384 "pl_gram.y"
+#line 383 "pl_gram.y"
{
plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_ERROR;
}
-#line 2042 "pl_gram.c"
+#line 2041 "pl_gram.c"
break;
case 8: /* comp_option: '#' K_VARIABLE_CONFLICT K_USE_VARIABLE */
-#line 388 "pl_gram.y"
+#line 387 "pl_gram.y"
{
plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_VARIABLE;
}
-#line 2050 "pl_gram.c"
+#line 2049 "pl_gram.c"
break;
case 9: /* comp_option: '#' K_VARIABLE_CONFLICT K_USE_COLUMN */
-#line 392 "pl_gram.y"
+#line 391 "pl_gram.y"
{
plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_COLUMN;
}
-#line 2058 "pl_gram.c"
+#line 2057 "pl_gram.c"
break;
case 10: /* option_value: T_WORD */
-#line 398 "pl_gram.y"
+#line 397 "pl_gram.y"
{
(yyval.str) = (yyvsp[0].word).ident;
}
-#line 2066 "pl_gram.c"
+#line 2065 "pl_gram.c"
break;
case 11: /* option_value: unreserved_keyword */
-#line 402 "pl_gram.y"
+#line 401 "pl_gram.y"
{
(yyval.str) = pstrdup((yyvsp[0].keyword));
}
-#line 2074 "pl_gram.c"
+#line 2073 "pl_gram.c"
break;
case 14: /* pl_block: decl_sect K_BEGIN proc_sect exception_sect K_END opt_label */
-#line 411 "pl_gram.y"
+#line 410 "pl_gram.y"
{
PLpgSQL_stmt_block *new;
@@ -2094,11 +2093,11 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 2098 "pl_gram.c"
+#line 2097 "pl_gram.c"
break;
case 15: /* decl_sect: opt_block_label */
-#line 434 "pl_gram.y"
+#line 433 "pl_gram.y"
{
/* done with decls, so resume identifier lookup */
plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
@@ -2106,33 +2105,33 @@ yyreduce:
(yyval.declhdr).n_initvars = 0;
(yyval.declhdr).initvarnos = NULL;
}
-#line 2110 "pl_gram.c"
+#line 2109 "pl_gram.c"
break;
case 16: /* decl_sect: opt_block_label decl_start */
-#line 442 "pl_gram.y"
+#line 441 "pl_gram.y"
{
plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
(yyval.declhdr).label = (yyvsp[-1].str);
(yyval.declhdr).n_initvars = 0;
(yyval.declhdr).initvarnos = NULL;
}
-#line 2121 "pl_gram.c"
+#line 2120 "pl_gram.c"
break;
case 17: /* decl_sect: opt_block_label decl_start decl_stmts */
-#line 449 "pl_gram.y"
+#line 448 "pl_gram.y"
{
plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
(yyval.declhdr).label = (yyvsp[-2].str);
/* Remember variables declared in decl_stmts */
(yyval.declhdr).n_initvars = plpgsql_add_initdatums(&((yyval.declhdr).initvarnos));
}
-#line 2132 "pl_gram.c"
+#line 2131 "pl_gram.c"
break;
case 18: /* decl_start: K_DECLARE */
-#line 458 "pl_gram.y"
+#line 457 "pl_gram.y"
{
/* Forget any variables created before block */
plpgsql_add_initdatums(NULL);
@@ -2142,19 +2141,19 @@ yyreduce:
*/
plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_DECLARE;
}
-#line 2146 "pl_gram.c"
+#line 2145 "pl_gram.c"
break;
case 22: /* decl_stmt: K_DECLARE */
-#line 475 "pl_gram.y"
+#line 474 "pl_gram.y"
{
/* We allow useless extra DECLAREs */
}
-#line 2154 "pl_gram.c"
+#line 2153 "pl_gram.c"
break;
case 23: /* decl_stmt: LESS_LESS any_identifier GREATER_GREATER */
-#line 479 "pl_gram.y"
+#line 478 "pl_gram.y"
{
/*
* Throw a helpful error if user tries to put block
@@ -2165,11 +2164,11 @@ yyreduce:
errmsg("block label must be placed before DECLARE, not after"),
parser_errposition((yylsp[-2]))));
}
-#line 2169 "pl_gram.c"
+#line 2168 "pl_gram.c"
break;
case 24: /* decl_statement: decl_varname decl_const decl_datatype decl_collate decl_notnull decl_defval */
-#line 492 "pl_gram.y"
+#line 491 "pl_gram.y"
{
PLpgSQL_variable *var;
@@ -2207,26 +2206,26 @@ yyreduce:
var->refname),
parser_errposition((yylsp[-1]))));
}
-#line 2211 "pl_gram.c"
+#line 2210 "pl_gram.c"
break;
case 25: /* decl_statement: decl_varname K_ALIAS K_FOR decl_aliasitem ';' */
-#line 530 "pl_gram.y"
+#line 529 "pl_gram.y"
{
plpgsql_ns_additem((yyvsp[-1].nsitem)->itemtype,
(yyvsp[-1].nsitem)->itemno, (yyvsp[-4].varname).name);
}
-#line 2220 "pl_gram.c"
+#line 2219 "pl_gram.c"
break;
case 26: /* $@1: %empty */
-#line 535 "pl_gram.y"
+#line 534 "pl_gram.y"
{ plpgsql_ns_push((yyvsp[-2].varname).name, PLPGSQL_LABEL_OTHER); }
-#line 2226 "pl_gram.c"
+#line 2225 "pl_gram.c"
break;
case 27: /* decl_statement: decl_varname opt_scrollable K_CURSOR $@1 decl_cursor_args decl_is_for decl_cursor_query */
-#line 537 "pl_gram.y"
+#line 536 "pl_gram.y"
{
PLpgSQL_var *new;
@@ -2248,51 +2247,51 @@ yyreduce:
new->cursor_explicit_argrow = (yyvsp[-2].datum)->dno;
new->cursor_options = CURSOR_OPT_FAST_PLAN | (yyvsp[-5].ival);
}
-#line 2252 "pl_gram.c"
+#line 2251 "pl_gram.c"
break;
case 28: /* opt_scrollable: %empty */
-#line 561 "pl_gram.y"
+#line 560 "pl_gram.y"
{
(yyval.ival) = 0;
}
-#line 2260 "pl_gram.c"
+#line 2259 "pl_gram.c"
break;
case 29: /* opt_scrollable: K_NO K_SCROLL */
-#line 565 "pl_gram.y"
+#line 564 "pl_gram.y"
{
(yyval.ival) = CURSOR_OPT_NO_SCROLL;
}
-#line 2268 "pl_gram.c"
+#line 2267 "pl_gram.c"
break;
case 30: /* opt_scrollable: K_SCROLL */
-#line 569 "pl_gram.y"
+#line 568 "pl_gram.y"
{
(yyval.ival) = CURSOR_OPT_SCROLL;
}
-#line 2276 "pl_gram.c"
+#line 2275 "pl_gram.c"
break;
case 31: /* decl_cursor_query: %empty */
-#line 575 "pl_gram.y"
+#line 574 "pl_gram.y"
{
(yyval.expr) = read_sql_stmt();
}
-#line 2284 "pl_gram.c"
+#line 2283 "pl_gram.c"
break;
case 32: /* decl_cursor_args: %empty */
-#line 581 "pl_gram.y"
+#line 580 "pl_gram.y"
{
(yyval.datum) = NULL;
}
-#line 2292 "pl_gram.c"
+#line 2291 "pl_gram.c"
break;
case 33: /* decl_cursor_args: '(' decl_cursor_arglist ')' */
-#line 585 "pl_gram.y"
+#line 584 "pl_gram.y"
{
PLpgSQL_row *new;
int i;
@@ -2321,37 +2320,37 @@ yyreduce:
plpgsql_adddatum((PLpgSQL_datum *) new);
(yyval.datum) = (PLpgSQL_datum *) new;
}
-#line 2325 "pl_gram.c"
+#line 2324 "pl_gram.c"
break;
case 34: /* decl_cursor_arglist: decl_cursor_arg */
-#line 616 "pl_gram.y"
+#line 615 "pl_gram.y"
{
(yyval.list) = list_make1((yyvsp[0].datum));
}
-#line 2333 "pl_gram.c"
+#line 2332 "pl_gram.c"
break;
case 35: /* decl_cursor_arglist: decl_cursor_arglist ',' decl_cursor_arg */
-#line 620 "pl_gram.y"
+#line 619 "pl_gram.y"
{
(yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].datum));
}
-#line 2341 "pl_gram.c"
+#line 2340 "pl_gram.c"
break;
case 36: /* decl_cursor_arg: decl_varname decl_datatype */
-#line 626 "pl_gram.y"
+#line 625 "pl_gram.y"
{
(yyval.datum) = (PLpgSQL_datum *)
plpgsql_build_variable((yyvsp[-1].varname).name, (yyvsp[-1].varname).lineno,
(yyvsp[0].dtype), true);
}
-#line 2351 "pl_gram.c"
+#line 2350 "pl_gram.c"
break;
case 39: /* decl_aliasitem: T_WORD */
-#line 637 "pl_gram.y"
+#line 636 "pl_gram.y"
{
PLpgSQL_nsitem *nsi;
@@ -2366,11 +2365,11 @@ yyreduce:
parser_errposition((yylsp[0]))));
(yyval.nsitem) = nsi;
}
-#line 2370 "pl_gram.c"
+#line 2369 "pl_gram.c"
break;
case 40: /* decl_aliasitem: unreserved_keyword */
-#line 652 "pl_gram.y"
+#line 651 "pl_gram.y"
{
PLpgSQL_nsitem *nsi;
@@ -2385,11 +2384,11 @@ yyreduce:
parser_errposition((yylsp[0]))));
(yyval.nsitem) = nsi;
}
-#line 2389 "pl_gram.c"
+#line 2388 "pl_gram.c"
break;
case 41: /* decl_aliasitem: T_CWORD */
-#line 667 "pl_gram.y"
+#line 666 "pl_gram.y"
{
PLpgSQL_nsitem *nsi;
@@ -2415,11 +2414,11 @@ yyreduce:
parser_errposition((yylsp[0]))));
(yyval.nsitem) = nsi;
}
-#line 2419 "pl_gram.c"
+#line 2418 "pl_gram.c"
break;
case 42: /* decl_varname: T_WORD */
-#line 695 "pl_gram.y"
+#line 694 "pl_gram.y"
{
(yyval.varname).name = (yyvsp[0].word).ident;
(yyval.varname).lineno = plpgsql_location_to_lineno((yylsp[0]));
@@ -2447,11 +2446,11 @@ yyreduce:
}
}
-#line 2451 "pl_gram.c"
+#line 2450 "pl_gram.c"
break;
case 43: /* decl_varname: unreserved_keyword */
-#line 723 "pl_gram.y"
+#line 722 "pl_gram.y"
{
(yyval.varname).name = pstrdup((yyvsp[0].keyword));
(yyval.varname).lineno = plpgsql_location_to_lineno((yylsp[0]));
@@ -2479,23 +2478,23 @@ yyreduce:
}
}
-#line 2483 "pl_gram.c"
+#line 2482 "pl_gram.c"
break;
case 44: /* decl_const: %empty */
-#line 753 "pl_gram.y"
+#line 752 "pl_gram.y"
{ (yyval.boolean) = false; }
-#line 2489 "pl_gram.c"
+#line 2488 "pl_gram.c"
break;
case 45: /* decl_const: K_CONSTANT */
-#line 755 "pl_gram.y"
+#line 754 "pl_gram.y"
{ (yyval.boolean) = true; }
-#line 2495 "pl_gram.c"
+#line 2494 "pl_gram.c"
break;
case 46: /* decl_datatype: %empty */
-#line 759 "pl_gram.y"
+#line 758 "pl_gram.y"
{
/*
* If there's a lookahead token, read_datatype
@@ -2504,75 +2503,75 @@ yyreduce:
(yyval.dtype) = read_datatype(yychar);
yyclearin;
}
-#line 2508 "pl_gram.c"
+#line 2507 "pl_gram.c"
break;
case 47: /* decl_collate: %empty */
-#line 770 "pl_gram.y"
+#line 769 "pl_gram.y"
{ (yyval.oid) = InvalidOid; }
-#line 2514 "pl_gram.c"
+#line 2513 "pl_gram.c"
break;
case 48: /* decl_collate: K_COLLATE T_WORD */
-#line 772 "pl_gram.y"
+#line 771 "pl_gram.y"
{
(yyval.oid) = get_collation_oid(list_make1(makeString((yyvsp[0].word).ident)),
false);
}
-#line 2523 "pl_gram.c"
+#line 2522 "pl_gram.c"
break;
case 49: /* decl_collate: K_COLLATE unreserved_keyword */
-#line 777 "pl_gram.y"
+#line 776 "pl_gram.y"
{
(yyval.oid) = get_collation_oid(list_make1(makeString(pstrdup((yyvsp[0].keyword)))),
false);
}
-#line 2532 "pl_gram.c"
+#line 2531 "pl_gram.c"
break;
case 50: /* decl_collate: K_COLLATE T_CWORD */
-#line 782 "pl_gram.y"
+#line 781 "pl_gram.y"
{
(yyval.oid) = get_collation_oid((yyvsp[0].cword).idents, false);
}
-#line 2540 "pl_gram.c"
+#line 2539 "pl_gram.c"
break;
case 51: /* decl_notnull: %empty */
-#line 788 "pl_gram.y"
+#line 787 "pl_gram.y"
{ (yyval.boolean) = false; }
-#line 2546 "pl_gram.c"
+#line 2545 "pl_gram.c"
break;
case 52: /* decl_notnull: K_NOT K_NULL */
-#line 790 "pl_gram.y"
+#line 789 "pl_gram.y"
{ (yyval.boolean) = true; }
-#line 2552 "pl_gram.c"
+#line 2551 "pl_gram.c"
break;
case 53: /* decl_defval: ';' */
-#line 794 "pl_gram.y"
+#line 793 "pl_gram.y"
{ (yyval.expr) = NULL; }
-#line 2558 "pl_gram.c"
+#line 2557 "pl_gram.c"
break;
case 54: /* decl_defval: decl_defkey */
-#line 796 "pl_gram.y"
+#line 795 "pl_gram.y"
{
(yyval.expr) = read_sql_expression(';', ";");
}
-#line 2566 "pl_gram.c"
+#line 2565 "pl_gram.c"
break;
case 59: /* proc_sect: %empty */
-#line 815 "pl_gram.y"
+#line 814 "pl_gram.y"
{ (yyval.list) = NIL; }
-#line 2572 "pl_gram.c"
+#line 2571 "pl_gram.c"
break;
case 60: /* proc_sect: proc_sect proc_stmt */
-#line 817 "pl_gram.y"
+#line 816 "pl_gram.y"
{
/* don't bother linking null statements into list */
if ((yyvsp[0].stmt) == NULL)
@@ -2580,155 +2579,155 @@ yyreduce:
else
(yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].stmt));
}
-#line 2584 "pl_gram.c"
+#line 2583 "pl_gram.c"
break;
case 61: /* proc_stmt: pl_block ';' */
-#line 827 "pl_gram.y"
+#line 826 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[-1].stmt); }
-#line 2590 "pl_gram.c"
+#line 2589 "pl_gram.c"
break;
case 62: /* proc_stmt: stmt_assign */
-#line 829 "pl_gram.y"
+#line 828 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2596 "pl_gram.c"
+#line 2595 "pl_gram.c"
break;
case 63: /* proc_stmt: stmt_if */
-#line 831 "pl_gram.y"
+#line 830 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2602 "pl_gram.c"
+#line 2601 "pl_gram.c"
break;
case 64: /* proc_stmt: stmt_case */
-#line 833 "pl_gram.y"
+#line 832 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2608 "pl_gram.c"
+#line 2607 "pl_gram.c"
break;
case 65: /* proc_stmt: stmt_loop */
-#line 835 "pl_gram.y"
+#line 834 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2614 "pl_gram.c"
+#line 2613 "pl_gram.c"
break;
case 66: /* proc_stmt: stmt_while */
-#line 837 "pl_gram.y"
+#line 836 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2620 "pl_gram.c"
+#line 2619 "pl_gram.c"
break;
case 67: /* proc_stmt: stmt_for */
-#line 839 "pl_gram.y"
+#line 838 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2626 "pl_gram.c"
+#line 2625 "pl_gram.c"
break;
case 68: /* proc_stmt: stmt_foreach_a */
-#line 841 "pl_gram.y"
+#line 840 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2632 "pl_gram.c"
+#line 2631 "pl_gram.c"
break;
case 69: /* proc_stmt: stmt_exit */
-#line 843 "pl_gram.y"
+#line 842 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2638 "pl_gram.c"
+#line 2637 "pl_gram.c"
break;
case 70: /* proc_stmt: stmt_return */
-#line 845 "pl_gram.y"
+#line 844 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2644 "pl_gram.c"
+#line 2643 "pl_gram.c"
break;
case 71: /* proc_stmt: stmt_raise */
-#line 847 "pl_gram.y"
+#line 846 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2650 "pl_gram.c"
+#line 2649 "pl_gram.c"
break;
case 72: /* proc_stmt: stmt_assert */
-#line 849 "pl_gram.y"
+#line 848 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2656 "pl_gram.c"
+#line 2655 "pl_gram.c"
break;
case 73: /* proc_stmt: stmt_execsql */
-#line 851 "pl_gram.y"
+#line 850 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2662 "pl_gram.c"
+#line 2661 "pl_gram.c"
break;
case 74: /* proc_stmt: stmt_dynexecute */
-#line 853 "pl_gram.y"
+#line 852 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2668 "pl_gram.c"
+#line 2667 "pl_gram.c"
break;
case 75: /* proc_stmt: stmt_perform */
-#line 855 "pl_gram.y"
+#line 854 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2674 "pl_gram.c"
+#line 2673 "pl_gram.c"
break;
case 76: /* proc_stmt: stmt_call */
-#line 857 "pl_gram.y"
+#line 856 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2680 "pl_gram.c"
+#line 2679 "pl_gram.c"
break;
case 77: /* proc_stmt: stmt_getdiag */
-#line 859 "pl_gram.y"
+#line 858 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2686 "pl_gram.c"
+#line 2685 "pl_gram.c"
break;
case 78: /* proc_stmt: stmt_open */
-#line 861 "pl_gram.y"
+#line 860 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2692 "pl_gram.c"
+#line 2691 "pl_gram.c"
break;
case 79: /* proc_stmt: stmt_fetch */
-#line 863 "pl_gram.y"
+#line 862 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2698 "pl_gram.c"
+#line 2697 "pl_gram.c"
break;
case 80: /* proc_stmt: stmt_move */
-#line 865 "pl_gram.y"
+#line 864 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2704 "pl_gram.c"
+#line 2703 "pl_gram.c"
break;
case 81: /* proc_stmt: stmt_close */
-#line 867 "pl_gram.y"
+#line 866 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2710 "pl_gram.c"
+#line 2709 "pl_gram.c"
break;
case 82: /* proc_stmt: stmt_null */
-#line 869 "pl_gram.y"
+#line 868 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2716 "pl_gram.c"
+#line 2715 "pl_gram.c"
break;
case 83: /* proc_stmt: stmt_commit */
-#line 871 "pl_gram.y"
+#line 870 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2722 "pl_gram.c"
+#line 2721 "pl_gram.c"
break;
case 84: /* proc_stmt: stmt_rollback */
-#line 873 "pl_gram.y"
+#line 872 "pl_gram.y"
{ (yyval.stmt) = (yyvsp[0].stmt); }
-#line 2728 "pl_gram.c"
+#line 2727 "pl_gram.c"
break;
case 85: /* stmt_perform: K_PERFORM */
-#line 877 "pl_gram.y"
+#line 876 "pl_gram.y"
{
PLpgSQL_stmt_perform *new;
int startloc;
@@ -2749,7 +2748,7 @@ yyreduce:
*/
new->expr = read_sql_construct(';', 0, 0, ";",
RAW_PARSE_DEFAULT,
- false, false, true,
+ false, false,
&startloc, NULL);
/* overwrite "perform" ... */
memcpy(new->expr->query, " SELECT", 7);
@@ -2762,11 +2761,11 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 2766 "pl_gram.c"
+#line 2765 "pl_gram.c"
break;
case 86: /* stmt_call: K_CALL */
-#line 913 "pl_gram.y"
+#line 912 "pl_gram.y"
{
PLpgSQL_stmt_call *new;
@@ -2784,11 +2783,11 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 2788 "pl_gram.c"
+#line 2787 "pl_gram.c"
break;
case 87: /* stmt_call: K_DO */
-#line 931 "pl_gram.y"
+#line 930 "pl_gram.y"
{
/* use the same structures as for CALL, for simplicity */
PLpgSQL_stmt_call *new;
@@ -2807,11 +2806,11 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 2811 "pl_gram.c"
+#line 2810 "pl_gram.c"
break;
case 88: /* stmt_assign: T_DATUM */
-#line 952 "pl_gram.y"
+#line 951 "pl_gram.y"
{
PLpgSQL_stmt_assign *new;
RawParseMode pmode;
@@ -2843,16 +2842,16 @@ yyreduce:
plpgsql_push_back_token(T_DATUM);
new->expr = read_sql_construct(';', 0, 0, ";",
pmode,
- false, true, true,
+ false, true,
NULL, NULL);
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 2852 "pl_gram.c"
+#line 2851 "pl_gram.c"
break;
case 89: /* stmt_getdiag: K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';' */
-#line 991 "pl_gram.y"
+#line 990 "pl_gram.y"
{
PLpgSQL_stmt_getdiag *new;
ListCell *lc;
@@ -2913,51 +2912,51 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 2917 "pl_gram.c"
+#line 2916 "pl_gram.c"
break;
case 90: /* getdiag_area_opt: %empty */
-#line 1054 "pl_gram.y"
+#line 1053 "pl_gram.y"
{
(yyval.boolean) = false;
}
-#line 2925 "pl_gram.c"
+#line 2924 "pl_gram.c"
break;
case 91: /* getdiag_area_opt: K_CURRENT */
-#line 1058 "pl_gram.y"
+#line 1057 "pl_gram.y"
{
(yyval.boolean) = false;
}
-#line 2933 "pl_gram.c"
+#line 2932 "pl_gram.c"
break;
case 92: /* getdiag_area_opt: K_STACKED */
-#line 1062 "pl_gram.y"
+#line 1061 "pl_gram.y"
{
(yyval.boolean) = true;
}
-#line 2941 "pl_gram.c"
+#line 2940 "pl_gram.c"
break;
case 93: /* getdiag_list: getdiag_list ',' getdiag_list_item */
-#line 1068 "pl_gram.y"
+#line 1067 "pl_gram.y"
{
(yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].diagitem));
}
-#line 2949 "pl_gram.c"
+#line 2948 "pl_gram.c"
break;
case 94: /* getdiag_list: getdiag_list_item */
-#line 1072 "pl_gram.y"
+#line 1071 "pl_gram.y"
{
(yyval.list) = list_make1((yyvsp[0].diagitem));
}
-#line 2957 "pl_gram.c"
+#line 2956 "pl_gram.c"
break;
case 95: /* getdiag_list_item: getdiag_target assign_operator getdiag_item */
-#line 1078 "pl_gram.y"
+#line 1077 "pl_gram.y"
{
PLpgSQL_diag_item *new;
@@ -2967,11 +2966,11 @@ yyreduce:
(yyval.diagitem) = new;
}
-#line 2971 "pl_gram.c"
+#line 2970 "pl_gram.c"
break;
case 96: /* getdiag_item: %empty */
-#line 1090 "pl_gram.y"
+#line 1089 "pl_gram.y"
{
int tok = yylex();
@@ -3017,11 +3016,11 @@ yyreduce:
else
yyerror("unrecognized GET DIAGNOSTICS item");
}
-#line 3021 "pl_gram.c"
+#line 3020 "pl_gram.c"
break;
case 97: /* getdiag_target: T_DATUM */
-#line 1138 "pl_gram.y"
+#line 1137 "pl_gram.y"
{
/*
* In principle we should support a getdiag_target
@@ -3039,29 +3038,29 @@ yyreduce:
check_assignable((yyvsp[0].wdatum).datum, (yylsp[0]));
(yyval.datum) = (yyvsp[0].wdatum).datum;
}
-#line 3043 "pl_gram.c"
+#line 3042 "pl_gram.c"
break;
case 98: /* getdiag_target: T_WORD */
-#line 1156 "pl_gram.y"
+#line 1155 "pl_gram.y"
{
/* just to give a better message than "syntax error" */
word_is_not_variable(&((yyvsp[0].word)), (yylsp[0]));
}
-#line 3052 "pl_gram.c"
+#line 3051 "pl_gram.c"
break;
case 99: /* getdiag_target: T_CWORD */
-#line 1161 "pl_gram.y"
+#line 1160 "pl_gram.y"
{
/* just to give a better message than "syntax error" */
cword_is_not_variable(&((yyvsp[0].cword)), (yylsp[0]));
}
-#line 3061 "pl_gram.c"
+#line 3060 "pl_gram.c"
break;
case 100: /* stmt_if: K_IF expr_until_then proc_sect stmt_elsifs stmt_else K_END K_IF ';' */
-#line 1168 "pl_gram.y"
+#line 1167 "pl_gram.y"
{
PLpgSQL_stmt_if *new;
@@ -3076,19 +3075,19 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 3080 "pl_gram.c"
+#line 3079 "pl_gram.c"
break;
case 101: /* stmt_elsifs: %empty */
-#line 1185 "pl_gram.y"
+#line 1184 "pl_gram.y"
{
(yyval.list) = NIL;
}
-#line 3088 "pl_gram.c"
+#line 3087 "pl_gram.c"
break;
case 102: /* stmt_elsifs: stmt_elsifs K_ELSIF expr_until_then proc_sect */
-#line 1189 "pl_gram.y"
+#line 1188 "pl_gram.y"
{
PLpgSQL_if_elsif *new;
@@ -3099,35 +3098,35 @@ yyreduce:
(yyval.list) = lappend((yyvsp[-3].list), new);
}
-#line 3103 "pl_gram.c"
+#line 3102 "pl_gram.c"
break;
case 103: /* stmt_else: %empty */
-#line 1202 "pl_gram.y"
+#line 1201 "pl_gram.y"
{
(yyval.list) = NIL;
}
-#line 3111 "pl_gram.c"
+#line 3110 "pl_gram.c"
break;
case 104: /* stmt_else: K_ELSE proc_sect */
-#line 1206 "pl_gram.y"
+#line 1205 "pl_gram.y"
{
(yyval.list) = (yyvsp[0].list);
}
-#line 3119 "pl_gram.c"
+#line 3118 "pl_gram.c"
break;
case 105: /* stmt_case: K_CASE opt_expr_until_when case_when_list opt_case_else K_END K_CASE ';' */
-#line 1212 "pl_gram.y"
+#line 1211 "pl_gram.y"
{
(yyval.stmt) = make_case((yylsp[-6]), (yyvsp[-5].expr), (yyvsp[-4].list), (yyvsp[-3].list));
}
-#line 3127 "pl_gram.c"
+#line 3126 "pl_gram.c"
break;
case 106: /* opt_expr_until_when: %empty */
-#line 1218 "pl_gram.y"
+#line 1217 "pl_gram.y"
{
PLpgSQL_expr *expr = NULL;
int tok = yylex();
@@ -3140,27 +3139,27 @@ yyreduce:
plpgsql_push_back_token(K_WHEN);
(yyval.expr) = expr;
}
-#line 3144 "pl_gram.c"
+#line 3143 "pl_gram.c"
break;
case 107: /* case_when_list: case_when_list case_when */
-#line 1233 "pl_gram.y"
+#line 1232 "pl_gram.y"
{
(yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].casewhen));
}
-#line 3152 "pl_gram.c"
+#line 3151 "pl_gram.c"
break;
case 108: /* case_when_list: case_when */
-#line 1237 "pl_gram.y"
+#line 1236 "pl_gram.y"
{
(yyval.list) = list_make1((yyvsp[0].casewhen));
}
-#line 3160 "pl_gram.c"
+#line 3159 "pl_gram.c"
break;
case 109: /* case_when: K_WHEN expr_until_then proc_sect */
-#line 1243 "pl_gram.y"
+#line 1242 "pl_gram.y"
{
PLpgSQL_case_when *new = palloc(sizeof(PLpgSQL_case_when));
@@ -3169,19 +3168,19 @@ yyreduce:
new->stmts = (yyvsp[0].list);
(yyval.casewhen) = new;
}
-#line 3173 "pl_gram.c"
+#line 3172 "pl_gram.c"
break;
case 110: /* opt_case_else: %empty */
-#line 1254 "pl_gram.y"
+#line 1253 "pl_gram.y"
{
(yyval.list) = NIL;
}
-#line 3181 "pl_gram.c"
+#line 3180 "pl_gram.c"
break;
case 111: /* opt_case_else: K_ELSE proc_sect */
-#line 1258 "pl_gram.y"
+#line 1257 "pl_gram.y"
{
/*
* proc_sect could return an empty list, but we
@@ -3194,11 +3193,11 @@ yyreduce:
else
(yyval.list) = list_make1(NULL);
}
-#line 3198 "pl_gram.c"
+#line 3197 "pl_gram.c"
break;
case 112: /* stmt_loop: opt_loop_label K_LOOP loop_body */
-#line 1273 "pl_gram.y"
+#line 1272 "pl_gram.y"
{
PLpgSQL_stmt_loop *new;
@@ -3214,11 +3213,11 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 3218 "pl_gram.c"
+#line 3217 "pl_gram.c"
break;
case 113: /* stmt_while: opt_loop_label K_WHILE expr_until_loop loop_body */
-#line 1291 "pl_gram.y"
+#line 1290 "pl_gram.y"
{
PLpgSQL_stmt_while *new;
@@ -3235,11 +3234,11 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 3239 "pl_gram.c"
+#line 3238 "pl_gram.c"
break;
case 114: /* stmt_for: opt_loop_label K_FOR for_control loop_body */
-#line 1310 "pl_gram.y"
+#line 1309 "pl_gram.y"
{
/* This runs after we've scanned the loop body */
if ((yyvsp[-1].stmt)->cmd_type == PLPGSQL_STMT_FORI)
@@ -3271,11 +3270,11 @@ yyreduce:
/* close namespace started in opt_loop_label */
plpgsql_ns_pop();
}
-#line 3275 "pl_gram.c"
+#line 3274 "pl_gram.c"
break;
case 115: /* for_control: for_variable K_IN */
-#line 1344 "pl_gram.y"
+#line 1343 "pl_gram.y"
{
int tok = yylex();
int tokloc = yylloc;
@@ -3408,7 +3407,6 @@ yyreduce:
RAW_PARSE_DEFAULT,
true,
false,
- true,
&expr1loc,
&tok);
@@ -3514,11 +3512,11 @@ yyreduce:
}
}
}
-#line 3518 "pl_gram.c"
+#line 3516 "pl_gram.c"
break;
case 116: /* for_variable: T_DATUM */
-#line 1603 "pl_gram.y"
+#line 1601 "pl_gram.y"
{
(yyval.forvariable).name = NameOfDatum(&((yyvsp[0].wdatum)));
(yyval.forvariable).lineno = plpgsql_location_to_lineno((yylsp[0]));
@@ -3544,11 +3542,11 @@ yyreduce:
(yylsp[0]));
}
}
-#line 3548 "pl_gram.c"
+#line 3546 "pl_gram.c"
break;
case 117: /* for_variable: T_WORD */
-#line 1629 "pl_gram.y"
+#line 1627 "pl_gram.y"
{
int tok;
@@ -3562,20 +3560,20 @@ yyreduce:
if (tok == ',')
word_is_not_variable(&((yyvsp[0].word)), (yylsp[0]));
}
-#line 3566 "pl_gram.c"
+#line 3564 "pl_gram.c"
break;
case 118: /* for_variable: T_CWORD */
-#line 1643 "pl_gram.y"
+#line 1641 "pl_gram.y"
{
/* just to give a better message than "syntax error" */
cword_is_not_variable(&((yyvsp[0].cword)), (yylsp[0]));
}
-#line 3575 "pl_gram.c"
+#line 3573 "pl_gram.c"
break;
case 119: /* stmt_foreach_a: opt_loop_label K_FOREACH for_variable foreach_slice K_IN K_ARRAY expr_until_loop loop_body */
-#line 1650 "pl_gram.y"
+#line 1648 "pl_gram.y"
{
PLpgSQL_stmt_foreach_a *new;
@@ -3611,27 +3609,27 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 3615 "pl_gram.c"
+#line 3613 "pl_gram.c"
break;
case 120: /* foreach_slice: %empty */
-#line 1688 "pl_gram.y"
+#line 1686 "pl_gram.y"
{
(yyval.ival) = 0;
}
-#line 3623 "pl_gram.c"
+#line 3621 "pl_gram.c"
break;
case 121: /* foreach_slice: K_SLICE ICONST */
-#line 1692 "pl_gram.y"
+#line 1690 "pl_gram.y"
{
(yyval.ival) = (yyvsp[0].ival);
}
-#line 3631 "pl_gram.c"
+#line 3629 "pl_gram.c"
break;
case 122: /* stmt_exit: exit_type opt_label opt_exitcond */
-#line 1698 "pl_gram.y"
+#line 1696 "pl_gram.y"
{
PLpgSQL_stmt_exit *new;
@@ -3682,27 +3680,27 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 3686 "pl_gram.c"
+#line 3684 "pl_gram.c"
break;
case 123: /* exit_type: K_EXIT */
-#line 1751 "pl_gram.y"
+#line 1749 "pl_gram.y"
{
(yyval.boolean) = true;
}
-#line 3694 "pl_gram.c"
+#line 3692 "pl_gram.c"
break;
case 124: /* exit_type: K_CONTINUE */
-#line 1755 "pl_gram.y"
+#line 1753 "pl_gram.y"
{
(yyval.boolean) = false;
}
-#line 3702 "pl_gram.c"
+#line 3700 "pl_gram.c"
break;
case 125: /* stmt_return: K_RETURN */
-#line 1761 "pl_gram.y"
+#line 1759 "pl_gram.y"
{
int tok;
@@ -3726,11 +3724,11 @@ yyreduce:
(yyval.stmt) = make_return_stmt((yylsp[0]));
}
}
-#line 3730 "pl_gram.c"
+#line 3728 "pl_gram.c"
break;
case 126: /* stmt_raise: K_RAISE */
-#line 1787 "pl_gram.y"
+#line 1785 "pl_gram.y"
{
PLpgSQL_stmt_raise *new;
int tok;
@@ -3825,7 +3823,7 @@ yyreduce:
expr = read_sql_construct(',', ';', K_USING,
", or ; or USING",
RAW_PARSE_PLPGSQL_EXPR,
- true, true, true,
+ true, true,
NULL, &tok);
new->params = lappend(new->params, expr);
}
@@ -3873,11 +3871,11 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 3877 "pl_gram.c"
+#line 3875 "pl_gram.c"
break;
case 127: /* stmt_assert: K_ASSERT */
-#line 1932 "pl_gram.y"
+#line 1930 "pl_gram.y"
{
PLpgSQL_stmt_assert *new;
int tok;
@@ -3899,45 +3897,45 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 3903 "pl_gram.c"
+#line 3901 "pl_gram.c"
break;
case 128: /* loop_body: proc_sect K_END K_LOOP opt_label ';' */
-#line 1956 "pl_gram.y"
+#line 1954 "pl_gram.y"
{
(yyval.loop_body).stmts = (yyvsp[-4].list);
(yyval.loop_body).end_label = (yyvsp[-1].str);
(yyval.loop_body).end_label_location = (yylsp[-1]);
}
-#line 3913 "pl_gram.c"
+#line 3911 "pl_gram.c"
break;
case 129: /* stmt_execsql: K_IMPORT */
-#line 1974 "pl_gram.y"
+#line 1972 "pl_gram.y"
{
(yyval.stmt) = make_execsql_stmt(K_IMPORT, (yylsp[0]), NULL);
}
-#line 3921 "pl_gram.c"
+#line 3919 "pl_gram.c"
break;
case 130: /* stmt_execsql: K_INSERT */
-#line 1978 "pl_gram.y"
+#line 1976 "pl_gram.y"
{
(yyval.stmt) = make_execsql_stmt(K_INSERT, (yylsp[0]), NULL);
}
-#line 3929 "pl_gram.c"
+#line 3927 "pl_gram.c"
break;
case 131: /* stmt_execsql: K_MERGE */
-#line 1982 "pl_gram.y"
+#line 1980 "pl_gram.y"
{
(yyval.stmt) = make_execsql_stmt(K_MERGE, (yylsp[0]), NULL);
}
-#line 3937 "pl_gram.c"
+#line 3935 "pl_gram.c"
break;
case 132: /* stmt_execsql: T_WORD */
-#line 1986 "pl_gram.y"
+#line 1984 "pl_gram.y"
{
int tok;
@@ -3948,11 +3946,11 @@ yyreduce:
word_is_not_variable(&((yyvsp[0].word)), (yylsp[0]));
(yyval.stmt) = make_execsql_stmt(T_WORD, (yylsp[0]), &((yyvsp[0].word)));
}
-#line 3952 "pl_gram.c"
+#line 3950 "pl_gram.c"
break;
case 133: /* stmt_execsql: T_CWORD */
-#line 1997 "pl_gram.y"
+#line 1995 "pl_gram.y"
{
int tok;
@@ -3963,11 +3961,11 @@ yyreduce:
cword_is_not_variable(&((yyvsp[0].cword)), (yylsp[0]));
(yyval.stmt) = make_execsql_stmt(T_CWORD, (yylsp[0]), NULL);
}
-#line 3967 "pl_gram.c"
+#line 3965 "pl_gram.c"
break;
case 134: /* stmt_dynexecute: K_EXECUTE */
-#line 2010 "pl_gram.y"
+#line 2008 "pl_gram.y"
{
PLpgSQL_stmt_dynexecute *new;
PLpgSQL_expr *expr;
@@ -3976,7 +3974,7 @@ yyreduce:
expr = read_sql_construct(K_INTO, K_USING, ';',
"INTO or USING or ;",
RAW_PARSE_PLPGSQL_EXPR,
- true, true, true,
+ true, true,
NULL, &endtoken);
new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
@@ -4015,7 +4013,7 @@ yyreduce:
expr = read_sql_construct(',', ';', K_INTO,
", or ; or INTO",
RAW_PARSE_PLPGSQL_EXPR,
- true, true, true,
+ true, true,
NULL, &endtoken);
new->params = lappend(new->params, expr);
} while (endtoken == ',');
@@ -4028,11 +4026,11 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 4032 "pl_gram.c"
+#line 4030 "pl_gram.c"
break;
case 135: /* stmt_open: K_OPEN cursor_variable */
-#line 2074 "pl_gram.y"
+#line 2072 "pl_gram.y"
{
PLpgSQL_stmt_open *new;
int tok;
@@ -4108,11 +4106,11 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 4112 "pl_gram.c"
+#line 4110 "pl_gram.c"
break;
case 136: /* stmt_fetch: K_FETCH opt_fetch_direction cursor_variable K_INTO */
-#line 2152 "pl_gram.y"
+#line 2150 "pl_gram.y"
{
PLpgSQL_stmt_fetch *fetch = (yyvsp[-2].fetch);
PLpgSQL_variable *target;
@@ -4140,11 +4138,11 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) fetch;
}
-#line 4144 "pl_gram.c"
+#line 4142 "pl_gram.c"
break;
case 137: /* stmt_move: K_MOVE opt_fetch_direction cursor_variable ';' */
-#line 2182 "pl_gram.y"
+#line 2180 "pl_gram.y"
{
PLpgSQL_stmt_fetch *fetch = (yyvsp[-2].fetch);
@@ -4154,19 +4152,19 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) fetch;
}
-#line 4158 "pl_gram.c"
+#line 4156 "pl_gram.c"
break;
case 138: /* opt_fetch_direction: %empty */
-#line 2194 "pl_gram.y"
+#line 2192 "pl_gram.y"
{
(yyval.fetch) = read_fetch_direction();
}
-#line 4166 "pl_gram.c"
+#line 4164 "pl_gram.c"
break;
case 139: /* stmt_close: K_CLOSE cursor_variable ';' */
-#line 2200 "pl_gram.y"
+#line 2198 "pl_gram.y"
{
PLpgSQL_stmt_close *new;
@@ -4178,20 +4176,20 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 4182 "pl_gram.c"
+#line 4180 "pl_gram.c"
break;
case 140: /* stmt_null: K_NULL ';' */
-#line 2214 "pl_gram.y"
+#line 2212 "pl_gram.y"
{
/* We do not bother building a node for NULL */
(yyval.stmt) = NULL;
}
-#line 4191 "pl_gram.c"
+#line 4189 "pl_gram.c"
break;
case 141: /* stmt_commit: K_COMMIT opt_transaction_chain ';' */
-#line 2221 "pl_gram.y"
+#line 2219 "pl_gram.y"
{
PLpgSQL_stmt_commit *new;
@@ -4203,11 +4201,11 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 4207 "pl_gram.c"
+#line 4205 "pl_gram.c"
break;
case 142: /* stmt_rollback: K_ROLLBACK opt_transaction_chain ';' */
-#line 2235 "pl_gram.y"
+#line 2233 "pl_gram.y"
{
PLpgSQL_stmt_rollback *new;
@@ -4219,29 +4217,29 @@ yyreduce:
(yyval.stmt) = (PLpgSQL_stmt *) new;
}
-#line 4223 "pl_gram.c"
+#line 4221 "pl_gram.c"
break;
case 143: /* opt_transaction_chain: K_AND K_CHAIN */
-#line 2249 "pl_gram.y"
+#line 2247 "pl_gram.y"
{ (yyval.ival) = true; }
-#line 4229 "pl_gram.c"
+#line 4227 "pl_gram.c"
break;
case 144: /* opt_transaction_chain: K_AND K_NO K_CHAIN */
-#line 2250 "pl_gram.y"
+#line 2248 "pl_gram.y"
{ (yyval.ival) = false; }
-#line 4235 "pl_gram.c"
+#line 4233 "pl_gram.c"
break;
case 145: /* opt_transaction_chain: %empty */
-#line 2251 "pl_gram.y"
+#line 2249 "pl_gram.y"
{ (yyval.ival) = false; }
-#line 4241 "pl_gram.c"
+#line 4239 "pl_gram.c"
break;
case 146: /* cursor_variable: T_DATUM */
-#line 2256 "pl_gram.y"
+#line 2254 "pl_gram.y"
{
/*
* In principle we should support a cursor_variable
@@ -4263,35 +4261,35 @@ yyreduce:
parser_errposition((yylsp[0]))));
(yyval.var) = (PLpgSQL_var *) (yyvsp[0].wdatum).datum;
}
-#line 4267 "pl_gram.c"
+#line 4265 "pl_gram.c"
break;
case 147: /* cursor_variable: T_WORD */
-#line 2278 "pl_gram.y"
+#line 2276 "pl_gram.y"
{
/* just to give a better message than "syntax error" */
word_is_not_variable(&((yyvsp[0].word)), (yylsp[0]));
}
-#line 4276 "pl_gram.c"
+#line 4274 "pl_gram.c"
break;
case 148: /* cursor_variable: T_CWORD */
-#line 2283 "pl_gram.y"
+#line 2281 "pl_gram.y"
{
/* just to give a better message than "syntax error" */
cword_is_not_variable(&((yyvsp[0].cword)), (yylsp[0]));
}
-#line 4285 "pl_gram.c"
+#line 4283 "pl_gram.c"
break;
case 149: /* exception_sect: %empty */
-#line 2290 "pl_gram.y"
+#line 2288 "pl_gram.y"
{ (yyval.exception_block) = NULL; }
-#line 4291 "pl_gram.c"
+#line 4289 "pl_gram.c"
break;
case 150: /* @2: %empty */
-#line 2292 "pl_gram.y"
+#line 2290 "pl_gram.y"
{
/*
* We use a mid-rule action to add these
@@ -4324,38 +4322,38 @@ yyreduce:
(yyval.exception_block) = new;
}
-#line 4328 "pl_gram.c"
+#line 4326 "pl_gram.c"
break;
case 151: /* exception_sect: K_EXCEPTION @2 proc_exceptions */
-#line 2325 "pl_gram.y"
+#line 2323 "pl_gram.y"
{
PLpgSQL_exception_block *new = (yyvsp[-1].exception_block);
new->exc_list = (yyvsp[0].list);
(yyval.exception_block) = new;
}
-#line 4339 "pl_gram.c"
+#line 4337 "pl_gram.c"
break;
case 152: /* proc_exceptions: proc_exceptions proc_exception */
-#line 2334 "pl_gram.y"
+#line 2332 "pl_gram.y"
{
(yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].exception));
}
-#line 4347 "pl_gram.c"
+#line 4345 "pl_gram.c"
break;
case 153: /* proc_exceptions: proc_exception */
-#line 2338 "pl_gram.y"
+#line 2336 "pl_gram.y"
{
(yyval.list) = list_make1((yyvsp[0].exception));
}
-#line 4355 "pl_gram.c"
+#line 4353 "pl_gram.c"
break;
case 154: /* proc_exception: K_WHEN proc_conditions K_THEN proc_sect */
-#line 2344 "pl_gram.y"
+#line 2342 "pl_gram.y"
{
PLpgSQL_exception *new;
@@ -4366,11 +4364,11 @@ yyreduce:
(yyval.exception) = new;
}
-#line 4370 "pl_gram.c"
+#line 4368 "pl_gram.c"
break;
case 155: /* proc_conditions: proc_conditions K_OR proc_condition */
-#line 2357 "pl_gram.y"
+#line 2355 "pl_gram.y"
{
PLpgSQL_condition *old;
@@ -4379,19 +4377,19 @@ yyreduce:
old->next = (yyvsp[0].condition);
(yyval.condition) = (yyvsp[-2].condition);
}
-#line 4383 "pl_gram.c"
+#line 4381 "pl_gram.c"
break;
case 156: /* proc_conditions: proc_condition */
-#line 2366 "pl_gram.y"
+#line 2364 "pl_gram.y"
{
(yyval.condition) = (yyvsp[0].condition);
}
-#line 4391 "pl_gram.c"
+#line 4389 "pl_gram.c"
break;
case 157: /* proc_condition: any_identifier */
-#line 2372 "pl_gram.y"
+#line 2370 "pl_gram.y"
{
if (strcmp((yyvsp[0].str), "sqlstate") != 0)
{
@@ -4425,120 +4423,120 @@ yyreduce:
(yyval.condition) = new;
}
}
-#line 4429 "pl_gram.c"
+#line 4427 "pl_gram.c"
break;
case 158: /* expr_until_semi: %empty */
-#line 2408 "pl_gram.y"
+#line 2406 "pl_gram.y"
{ (yyval.expr) = read_sql_expression(';', ";"); }
-#line 4435 "pl_gram.c"
+#line 4433 "pl_gram.c"
break;
case 159: /* expr_until_then: %empty */
-#line 2412 "pl_gram.y"
+#line 2410 "pl_gram.y"
{ (yyval.expr) = read_sql_expression(K_THEN, "THEN"); }
-#line 4441 "pl_gram.c"
+#line 4439 "pl_gram.c"
break;
case 160: /* expr_until_loop: %empty */
-#line 2416 "pl_gram.y"
+#line 2414 "pl_gram.y"
{ (yyval.expr) = read_sql_expression(K_LOOP, "LOOP"); }
-#line 4447 "pl_gram.c"
+#line 4445 "pl_gram.c"
break;
case 161: /* opt_block_label: %empty */
-#line 2420 "pl_gram.y"
+#line 2418 "pl_gram.y"
{
plpgsql_ns_push(NULL, PLPGSQL_LABEL_BLOCK);
(yyval.str) = NULL;
}
-#line 4456 "pl_gram.c"
+#line 4454 "pl_gram.c"
break;
case 162: /* opt_block_label: LESS_LESS any_identifier GREATER_GREATER */
-#line 2425 "pl_gram.y"
+#line 2423 "pl_gram.y"
{
plpgsql_ns_push((yyvsp[-1].str), PLPGSQL_LABEL_BLOCK);
(yyval.str) = (yyvsp[-1].str);
}
-#line 4465 "pl_gram.c"
+#line 4463 "pl_gram.c"
break;
case 163: /* opt_loop_label: %empty */
-#line 2432 "pl_gram.y"
+#line 2430 "pl_gram.y"
{
plpgsql_ns_push(NULL, PLPGSQL_LABEL_LOOP);
(yyval.str) = NULL;
}
-#line 4474 "pl_gram.c"
+#line 4472 "pl_gram.c"
break;
case 164: /* opt_loop_label: LESS_LESS any_identifier GREATER_GREATER */
-#line 2437 "pl_gram.y"
+#line 2435 "pl_gram.y"
{
plpgsql_ns_push((yyvsp[-1].str), PLPGSQL_LABEL_LOOP);
(yyval.str) = (yyvsp[-1].str);
}
-#line 4483 "pl_gram.c"
+#line 4481 "pl_gram.c"
break;
case 165: /* opt_label: %empty */
-#line 2444 "pl_gram.y"
+#line 2442 "pl_gram.y"
{
(yyval.str) = NULL;
}
-#line 4491 "pl_gram.c"
+#line 4489 "pl_gram.c"
break;
case 166: /* opt_label: any_identifier */
-#line 2448 "pl_gram.y"
+#line 2446 "pl_gram.y"
{
/* label validity will be checked by outer production */
(yyval.str) = (yyvsp[0].str);
}
-#line 4500 "pl_gram.c"
+#line 4498 "pl_gram.c"
break;
case 167: /* opt_exitcond: ';' */
-#line 2455 "pl_gram.y"
+#line 2453 "pl_gram.y"
{ (yyval.expr) = NULL; }
-#line 4506 "pl_gram.c"
+#line 4504 "pl_gram.c"
break;
case 168: /* opt_exitcond: K_WHEN expr_until_semi */
-#line 2457 "pl_gram.y"
+#line 2455 "pl_gram.y"
{ (yyval.expr) = (yyvsp[0].expr); }
-#line 4512 "pl_gram.c"
+#line 4510 "pl_gram.c"
break;
case 169: /* any_identifier: T_WORD */
-#line 2464 "pl_gram.y"
+#line 2462 "pl_gram.y"
{
(yyval.str) = (yyvsp[0].word).ident;
}
-#line 4520 "pl_gram.c"
+#line 4518 "pl_gram.c"
break;
case 170: /* any_identifier: unreserved_keyword */
-#line 2468 "pl_gram.y"
+#line 2466 "pl_gram.y"
{
(yyval.str) = pstrdup((yyvsp[0].keyword));
}
-#line 4528 "pl_gram.c"
+#line 4526 "pl_gram.c"
break;
case 171: /* any_identifier: T_DATUM */
-#line 2472 "pl_gram.y"
+#line 2470 "pl_gram.y"
{
if ((yyvsp[0].wdatum).ident == NULL) /* composite name not OK */
yyerror("syntax error");
(yyval.str) = (yyvsp[0].wdatum).ident;
}
-#line 4538 "pl_gram.c"
+#line 4536 "pl_gram.c"
break;
-#line 4542 "pl_gram.c"
+#line 4540 "pl_gram.c"
default: break;
}
@@ -4737,7 +4735,7 @@ yyreturn:
return yyresult;
}
-#line 2564 "pl_gram.y"
+#line 2562 "pl_gram.y"
/*
@@ -4816,7 +4814,7 @@ read_sql_expression(int until, const char *expected)
{
return read_sql_construct(until, 0, 0, expected,
RAW_PARSE_PLPGSQL_EXPR,
- true, true, true, NULL, NULL);
+ true, true, NULL, NULL);
}
/* Convenience routine to read an expression with two possible terminators */
@@ -4826,7 +4824,7 @@ read_sql_expression2(int until, int until2, const char *expected,
{
return read_sql_construct(until, until2, 0, expected,
RAW_PARSE_PLPGSQL_EXPR,
- true, true, true, NULL, endtoken);
+ true, true, NULL, endtoken);
}
/* Convenience routine to read a SQL statement that must end with ';' */
@@ -4835,7 +4833,7 @@ read_sql_stmt(void)
{
return read_sql_construct(';', 0, 0, ";",
RAW_PARSE_DEFAULT,
- false, true, true, NULL, NULL);
+ false, true, NULL, NULL);
}
/*
@@ -4848,7 +4846,6 @@ read_sql_stmt(void)
* parsemode: raw_parser() mode to use
* isexpression: whether to say we're reading an "expression" or a "statement"
* valid_sql: whether to check the syntax of the expr
- * trim: trim trailing whitespace
* startloc: if not NULL, location of first token is stored at *startloc
* endtoken: if not NULL, ending token is stored at *endtoken
* (this is only interesting if until2 or until3 isn't zero)
@@ -4861,7 +4858,6 @@ read_sql_construct(int until,
RawParseMode parsemode,
bool isexpression,
bool valid_sql,
- bool trim,
int *startloc,
int *endtoken)
{
@@ -4869,6 +4865,7 @@ read_sql_construct(int until,
StringInfoData ds;
IdentifierLookup save_IdentifierLookup;
int startlocation = -1;
+ int endlocation = -1;
int parenlevel = 0;
PLpgSQL_expr *expr;
@@ -4919,6 +4916,8 @@ read_sql_construct(int until,
expected),
parser_errposition(yylloc)));
}
+ /* Remember end+1 location of last accepted token */
+ endlocation = yylloc + plpgsql_token_length();
}
plpgsql_IdentifierLookup = save_IdentifierLookup;
@@ -4929,7 +4928,7 @@ read_sql_construct(int until,
*endtoken = tok;
/* give helpful complaint about empty input */
- if (startlocation >= yylloc)
+ if (startlocation >= endlocation)
{
if (isexpression)
yyerror("missing expression");
@@ -4937,14 +4936,14 @@ read_sql_construct(int until,
yyerror("missing SQL statement");
}
- plpgsql_append_source_text(&ds, startlocation, yylloc);
-
- /* trim any trailing whitespace, for neatness */
- if (trim)
- {
- while (ds.len > 0 && scanner_isspace(ds.data[ds.len - 1]))
- ds.data[--ds.len] = '\0';
- }
+ /*
+ * We save only the text from startlocation to endlocation-1. This
+ * suppresses the "until" token as well as any whitespace or comments
+ * following the last accepted token. (We used to strip such trailing
+ * whitespace by hand, but that causes problems if there's a "-- comment"
+ * in front of said whitespace.)
+ */
+ plpgsql_append_source_text(&ds, startlocation, endlocation);
expr = palloc0(sizeof(PLpgSQL_expr));
expr->query = pstrdup(ds.data);
@@ -6085,16 +6084,12 @@ read_cursor_args(PLpgSQL_var *cursor, int until)
* Read the value expression. To provide the user with meaningful
* parse error positions, we check the syntax immediately, instead of
* checking the final expression that may have the arguments
- * reordered. Trailing whitespace must not be trimmed, because
- * otherwise input of the form (param -- comment\n, param) would be
- * translated into a form where the second parameter is commented
- * out.
+ * reordered.
*/
item = read_sql_construct(',', ')', 0,
",\" or \")",
RAW_PARSE_PLPGSQL_EXPR,
true, true,
- false, /* do not trim */
NULL, &endtoken);
argv[argpos] = item->query;
diff --git a/src/pl/plpgsql/src/pl_gram.h b/src/pl/plpgsql/src/pl_gram.h
index b6cf68d..d02a130 100644
--- a/src/pl/plpgsql/src/pl_gram.h
+++ b/src/pl/plpgsql/src/pl_gram.h
@@ -190,7 +190,7 @@ extern int plpgsql_yydebug;
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE
{
-#line 118 "pl_gram.y"
+#line 117 "pl_gram.y"
core_YYSTYPE core_yystype;
/* these fields must match core_YYSTYPE: */
diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y
index 1d9182f..20c52e7 100644
--- a/src/pl/plpgsql/src/pl_gram.y
+++ b/src/pl/plpgsql/src/pl_gram.y
@@ -66,7 +66,6 @@ static PLpgSQL_expr *read_sql_construct(int until,
RawParseMode parsemode,
bool isexpression,
bool valid_sql,
- bool trim,
int *startloc,
int *endtoken);
static PLpgSQL_expr *read_sql_expression(int until,
@@ -894,7 +893,7 @@ stmt_perform : K_PERFORM
*/
new->expr = read_sql_construct(';', 0, 0, ";",
RAW_PARSE_DEFAULT,
- false, false, true,
+ false, false,
&startloc, NULL);
/* overwrite "perform" ... */
memcpy(new->expr->query, " SELECT", 7);
@@ -980,7 +979,7 @@ stmt_assign : T_DATUM
plpgsql_push_back_token(T_DATUM);
new->expr = read_sql_construct(';', 0, 0, ";",
pmode,
- false, true, true,
+ false, true,
NULL, NULL);
$$ = (PLpgSQL_stmt *) new;
@@ -1473,7 +1472,6 @@ for_control : for_variable K_IN
RAW_PARSE_DEFAULT,
true,
false,
- true,
&expr1loc,
&tok);
@@ -1878,7 +1876,7 @@ stmt_raise : K_RAISE
expr = read_sql_construct(',', ';', K_USING,
", or ; or USING",
RAW_PARSE_PLPGSQL_EXPR,
- true, true, true,
+ true, true,
NULL, &tok);
new->params = lappend(new->params, expr);
}
@@ -2015,7 +2013,7 @@ stmt_dynexecute : K_EXECUTE
expr = read_sql_construct(K_INTO, K_USING, ';',
"INTO or USING or ;",
RAW_PARSE_PLPGSQL_EXPR,
- true, true, true,
+ true, true,
NULL, &endtoken);
new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
@@ -2054,7 +2052,7 @@ stmt_dynexecute : K_EXECUTE
expr = read_sql_construct(',', ';', K_INTO,
", or ; or INTO",
RAW_PARSE_PLPGSQL_EXPR,
- true, true, true,
+ true, true,
NULL, &endtoken);
new->params = lappend(new->params, expr);
} while (endtoken == ',');
@@ -2639,7 +2637,7 @@ read_sql_expression(int until, const char *expected)
{
return read_sql_construct(until, 0, 0, expected,
RAW_PARSE_PLPGSQL_EXPR,
- true, true, true, NULL, NULL);
+ true, true, NULL, NULL);
}
/* Convenience routine to read an expression with two possible terminators */
@@ -2649,7 +2647,7 @@ read_sql_expression2(int until, int until2, const char *expected,
{
return read_sql_construct(until, until2, 0, expected,
RAW_PARSE_PLPGSQL_EXPR,
- true, true, true, NULL, endtoken);
+ true, true, NULL, endtoken);
}
/* Convenience routine to read a SQL statement that must end with ';' */
@@ -2658,7 +2656,7 @@ read_sql_stmt(void)
{
return read_sql_construct(';', 0, 0, ";",
RAW_PARSE_DEFAULT,
- false, true, true, NULL, NULL);
+ false, true, NULL, NULL);
}
/*
@@ -2671,7 +2669,6 @@ read_sql_stmt(void)
* parsemode: raw_parser() mode to use
* isexpression: whether to say we're reading an "expression" or a "statement"
* valid_sql: whether to check the syntax of the expr
- * trim: trim trailing whitespace
* startloc: if not NULL, location of first token is stored at *startloc
* endtoken: if not NULL, ending token is stored at *endtoken
* (this is only interesting if until2 or until3 isn't zero)
@@ -2684,7 +2681,6 @@ read_sql_construct(int until,
RawParseMode parsemode,
bool isexpression,
bool valid_sql,
- bool trim,
int *startloc,
int *endtoken)
{
@@ -2692,6 +2688,7 @@ read_sql_construct(int until,
StringInfoData ds;
IdentifierLookup save_IdentifierLookup;
int startlocation = -1;
+ int endlocation = -1;
int parenlevel = 0;
PLpgSQL_expr *expr;
@@ -2742,6 +2739,8 @@ read_sql_construct(int until,
expected),
parser_errposition(yylloc)));
}
+ /* Remember end+1 location of last accepted token */
+ endlocation = yylloc + plpgsql_token_length();
}
plpgsql_IdentifierLookup = save_IdentifierLookup;
@@ -2752,7 +2751,7 @@ read_sql_construct(int until,
*endtoken = tok;
/* give helpful complaint about empty input */
- if (startlocation >= yylloc)
+ if (startlocation >= endlocation)
{
if (isexpression)
yyerror("missing expression");
@@ -2760,14 +2759,14 @@ read_sql_construct(int until,
yyerror("missing SQL statement");
}
- plpgsql_append_source_text(&ds, startlocation, yylloc);
-
- /* trim any trailing whitespace, for neatness */
- if (trim)
- {
- while (ds.len > 0 && scanner_isspace(ds.data[ds.len - 1]))
- ds.data[--ds.len] = '\0';
- }
+ /*
+ * We save only the text from startlocation to endlocation-1. This
+ * suppresses the "until" token as well as any whitespace or comments
+ * following the last accepted token. (We used to strip such trailing
+ * whitespace by hand, but that causes problems if there's a "-- comment"
+ * in front of said whitespace.)
+ */
+ plpgsql_append_source_text(&ds, startlocation, endlocation);
expr = palloc0(sizeof(PLpgSQL_expr));
expr->query = pstrdup(ds.data);
@@ -3908,16 +3907,12 @@ read_cursor_args(PLpgSQL_var *cursor, int until)
* Read the value expression. To provide the user with meaningful
* parse error positions, we check the syntax immediately, instead of
* checking the final expression that may have the arguments
- * reordered. Trailing whitespace must not be trimmed, because
- * otherwise input of the form (param -- comment\n, param) would be
- * translated into a form where the second parameter is commented
- * out.
+ * reordered.
*/
item = read_sql_construct(',', ')', 0,
",\" or \")",
RAW_PARSE_PLPGSQL_EXPR,
true, true,
- false, /* do not trim */
NULL, &endtoken);
argv[argpos] = item->query;
diff --git a/src/pl/plpgsql/src/pl_scanner.c b/src/pl/plpgsql/src/pl_scanner.c
index 4e98af2..4d56f15 100644
--- a/src/pl/plpgsql/src/pl_scanner.c
+++ b/src/pl/plpgsql/src/pl_scanner.c
@@ -184,6 +184,8 @@ plpgsql_yylex(void)
tok1 = T_DATUM;
else
tok1 = T_CWORD;
+ /* Adjust token length to include A.B.C */
+ aux1.leng = aux5.lloc - aux1.lloc + aux5.leng;
}
else
{
@@ -197,6 +199,8 @@ plpgsql_yylex(void)
tok1 = T_DATUM;
else
tok1 = T_CWORD;
+ /* Adjust token length to include A.B */
+ aux1.leng = aux3.lloc - aux1.lloc + aux3.leng;
}
}
else
@@ -210,6 +214,8 @@ plpgsql_yylex(void)
tok1 = T_DATUM;
else
tok1 = T_CWORD;
+ /* Adjust token length to include A.B */
+ aux1.leng = aux3.lloc - aux1.lloc + aux3.leng;
}
}
else
@@ -299,6 +305,17 @@ plpgsql_yylex(void)
}
/*
+ * Return the length of the token last returned by plpgsql_yylex().
+ *
+ * In the case of compound tokens, the length includes all the parts.
+ */
+int
+plpgsql_token_length(void)
+{
+ return plpgsql_yyleng;
+}
+
+/*
* Internal yylex function. This wraps the core lexer and adds one feature:
* a token pushback stack. We also make a couple of trivial single-token
* translations from what the core lexer does to what we want, in particular
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index 2b4bcd1..cead9eb 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -1316,6 +1316,7 @@ extern void plpgsql_dumptree(PLpgSQL_function *func);
*/
extern int plpgsql_base_yylex(void);
extern int plpgsql_yylex(void);
+extern int plpgsql_token_length(void);
extern void plpgsql_push_back_token(int token);
extern bool plpgsql_token_is_unreserved_keyword(int token);
extern void plpgsql_append_source_text(StringInfo buf,
diff --git a/src/pl/plpgsql/src/po/ru.po b/src/pl/plpgsql/src/po/ru.po
index c327e3c..6f29a9c 100644
--- a/src/pl/plpgsql/src/po/ru.po
+++ b/src/pl/plpgsql/src/po/ru.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: plpgsql (PostgreSQL current)\n"
"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
-"POT-Creation-Date: 2024-02-02 18:10+0300\n"
+"POT-Creation-Date: 2024-05-04 16:29+0300\n"
"PO-Revision-Date: 2022-09-05 13:38+0300\n"
"Last-Translator: Alexander Lakhin <exclusion@gmail.com>\n"
"Language-Team: Russian <pgsql-ru-general@postgresql.org>\n"
@@ -323,7 +323,7 @@ msgid ""
msgstr ""
"функция, возвращающая составной тип, не может вернуть несоставное значение"
-#: pl_exec.c:3337 pl_gram.y:3351
+#: pl_exec.c:3337 pl_gram.y:3350
#, c-format
msgid "cannot use RETURN NEXT in a non-SETOF function"
msgstr ""
@@ -344,7 +344,7 @@ msgstr "в RETURN NEXT передан неправильный тип запис
msgid "RETURN NEXT must have a parameter"
msgstr "у оператора RETURN NEXT должен быть параметр"
-#: pl_exec.c:3557 pl_gram.y:3415
+#: pl_exec.c:3557 pl_gram.y:3414
#, c-format
msgid "cannot use RETURN QUERY in a non-SETOF function"
msgstr ""
@@ -545,7 +545,7 @@ msgid "The tuple structure of a not-yet-assigned record is indeterminate."
msgstr ""
"Для записи, которой не присвоено значение, структура кортежа не определена."
-#: pl_exec.c:8322 pl_gram.y:3474
+#: pl_exec.c:8322 pl_gram.y:3473
#, c-format
msgid "variable \"%s\" is declared CONSTANT"
msgstr "переменная \"%s\" объявлена как CONSTANT"
@@ -582,57 +582,57 @@ msgstr "SQL-оператор"
msgid "FOR over EXECUTE statement"
msgstr "FOR по результатам EXECUTE"
-#: pl_gram.y:486
+#: pl_gram.y:485
#, c-format
msgid "block label must be placed before DECLARE, not after"
msgstr "метка блока должна помещаться до DECLARE, а не после"
-#: pl_gram.y:506
+#: pl_gram.y:505
#, c-format
msgid "collations are not supported by type %s"
msgstr "тип %s не поддерживает сортировку (COLLATION)"
-#: pl_gram.y:525
+#: pl_gram.y:524
#, c-format
msgid "variable \"%s\" must have a default value, since it's declared NOT NULL"
msgstr ""
"у переменной \"%s\" должно быть значение по умолчанию, так как она объявлена "
"как NOT NULL"
-#: pl_gram.y:646 pl_gram.y:661 pl_gram.y:687
+#: pl_gram.y:645 pl_gram.y:660 pl_gram.y:686
#, c-format
msgid "variable \"%s\" does not exist"
msgstr "переменная \"%s\" не существует"
-#: pl_gram.y:705 pl_gram.y:733
+#: pl_gram.y:704 pl_gram.y:732
msgid "duplicate declaration"
msgstr "повторяющееся объявление"
-#: pl_gram.y:716 pl_gram.y:744
+#: pl_gram.y:715 pl_gram.y:743
#, c-format
msgid "variable \"%s\" shadows a previously defined variable"
msgstr "переменная \"%s\" скрывает ранее определённую переменную"
-#: pl_gram.y:1017
+#: pl_gram.y:1016
#, c-format
msgid "diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS"
msgstr "команда GET STACKED DIAGNOSTICS не принимает элемент %s"
-#: pl_gram.y:1035
+#: pl_gram.y:1034
#, c-format
msgid "diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS"
msgstr "команда GET CURRENT DIAGNOSTICS не принимает элемент %s"
-#: pl_gram.y:1133
+#: pl_gram.y:1132
msgid "unrecognized GET DIAGNOSTICS item"
msgstr "нераспознанный элемент GET DIAGNOSTICS"
-#: pl_gram.y:1149 pl_gram.y:3590
+#: pl_gram.y:1148 pl_gram.y:3589
#, c-format
msgid "\"%s\" is not a scalar variable"
msgstr "\"%s\" - не скалярная переменная"
-#: pl_gram.y:1379 pl_gram.y:1573
+#: pl_gram.y:1378 pl_gram.y:1571
#, c-format
msgid ""
"loop variable of loop over rows must be a record variable or list of scalar "
@@ -641,229 +641,229 @@ msgstr ""
"переменная цикла по кортежам должна быть переменной типа запись или списком "
"скалярных переменных"
-#: pl_gram.y:1414
+#: pl_gram.y:1413
#, c-format
msgid "cursor FOR loop must have only one target variable"
msgstr "в цикле FOR с курсором должна быть только одна переменная"
-#: pl_gram.y:1421
+#: pl_gram.y:1420
#, c-format
msgid "cursor FOR loop must use a bound cursor variable"
msgstr ""
"в цикле FOR с курсором должен использоваться курсор, привязанный к запросу"
-#: pl_gram.y:1512
+#: pl_gram.y:1510
#, c-format
msgid "integer FOR loop must have only one target variable"
msgstr "в целочисленном цикле FOR должна быть только одна переменная"
-#: pl_gram.y:1546
+#: pl_gram.y:1544
#, c-format
msgid "cannot specify REVERSE in query FOR loop"
msgstr "в цикле FOR с запросом нельзя указать REVERSE"
-#: pl_gram.y:1676
+#: pl_gram.y:1674
#, c-format
msgid "loop variable of FOREACH must be a known variable or list of variables"
msgstr ""
"переменной цикла FOREACH должна быть известная переменная или список "
"переменных"
-#: pl_gram.y:1718
+#: pl_gram.y:1716
#, c-format
msgid ""
"there is no label \"%s\" attached to any block or loop enclosing this "
"statement"
msgstr "в блоке или цикле, окружающем этот оператор, нет метки \"%s\""
-#: pl_gram.y:1726
+#: pl_gram.y:1724
#, c-format
msgid "block label \"%s\" cannot be used in CONTINUE"
msgstr "метку блока \"%s\" нельзя использовать в CONTINUE"
-#: pl_gram.y:1741
+#: pl_gram.y:1739
#, c-format
msgid "EXIT cannot be used outside a loop, unless it has a label"
msgstr "EXIT можно использовать вне цикла только с указанием метки"
-#: pl_gram.y:1742
+#: pl_gram.y:1740
#, c-format
msgid "CONTINUE cannot be used outside a loop"
msgstr "CONTINUE нельзя использовать вне цикла"
-#: pl_gram.y:1766 pl_gram.y:1804 pl_gram.y:1852 pl_gram.y:3037 pl_gram.y:3125
-#: pl_gram.y:3236 pl_gram.y:3989
+#: pl_gram.y:1764 pl_gram.y:1802 pl_gram.y:1850 pl_gram.y:3036 pl_gram.y:3124
+#: pl_gram.y:3235 pl_gram.y:3984
msgid "unexpected end of function definition"
msgstr "неожиданный конец определения функции"
-#: pl_gram.y:1872 pl_gram.y:1896 pl_gram.y:1912 pl_gram.y:1918 pl_gram.y:2043
-#: pl_gram.y:2051 pl_gram.y:2065 pl_gram.y:2160 pl_gram.y:2384 pl_gram.y:2474
-#: pl_gram.y:2633 pl_gram.y:3832 pl_gram.y:3893 pl_gram.y:3970
+#: pl_gram.y:1870 pl_gram.y:1894 pl_gram.y:1910 pl_gram.y:1916 pl_gram.y:2041
+#: pl_gram.y:2049 pl_gram.y:2063 pl_gram.y:2158 pl_gram.y:2382 pl_gram.y:2472
+#: pl_gram.y:2631 pl_gram.y:3831 pl_gram.y:3892 pl_gram.y:3965
msgid "syntax error"
msgstr "ошибка синтаксиса"
-#: pl_gram.y:1900 pl_gram.y:1902 pl_gram.y:2388 pl_gram.y:2390
+#: pl_gram.y:1898 pl_gram.y:1900 pl_gram.y:2386 pl_gram.y:2388
msgid "invalid SQLSTATE code"
msgstr "неверный код SQLSTATE"
-#: pl_gram.y:2108
+#: pl_gram.y:2106
msgid "syntax error, expected \"FOR\""
msgstr "ошибка синтаксиса, ожидался \"FOR\""
-#: pl_gram.y:2169
+#: pl_gram.y:2167
#, c-format
msgid "FETCH statement cannot return multiple rows"
msgstr "оператор FETCH не может вернуть несколько строк"
-#: pl_gram.y:2266
+#: pl_gram.y:2264
#, c-format
msgid "cursor variable must be a simple variable"
msgstr "переменная-курсор должна быть простой переменной"
-#: pl_gram.y:2272
+#: pl_gram.y:2270
#, c-format
msgid "variable \"%s\" must be of type cursor or refcursor"
msgstr "переменная \"%s\" должна быть типа cursor или refcursor"
-#: pl_gram.y:2604 pl_gram.y:2615
+#: pl_gram.y:2602 pl_gram.y:2613
#, c-format
msgid "\"%s\" is not a known variable"
msgstr "\"%s\" - не известная переменная"
-#: pl_gram.y:2721 pl_gram.y:2731 pl_gram.y:2887
+#: pl_gram.y:2718 pl_gram.y:2728 pl_gram.y:2886
msgid "mismatched parentheses"
msgstr "непарные скобки"
-#: pl_gram.y:2735
+#: pl_gram.y:2732
#, c-format
msgid "missing \"%s\" at end of SQL expression"
msgstr "отсутствует \"%s\" в конце выражения SQL"
-#: pl_gram.y:2741
+#: pl_gram.y:2738
#, c-format
msgid "missing \"%s\" at end of SQL statement"
msgstr "отсутствует \"%s\" в конце оператора SQL"
-#: pl_gram.y:2758
+#: pl_gram.y:2757
msgid "missing expression"
msgstr "отсутствует выражение"
-#: pl_gram.y:2760
+#: pl_gram.y:2759
msgid "missing SQL statement"
msgstr "отсутствует оператор SQL"
-#: pl_gram.y:2889
+#: pl_gram.y:2888
msgid "incomplete data type declaration"
msgstr "неполное определение типа данных"
-#: pl_gram.y:2912
+#: pl_gram.y:2911
msgid "missing data type declaration"
msgstr "отсутствует определение типа данных"
-#: pl_gram.y:3047
+#: pl_gram.y:3046
msgid "INTO specified more than once"
msgstr "INTO указано неоднократно"
-#: pl_gram.y:3217
+#: pl_gram.y:3216
msgid "expected FROM or IN"
msgstr "ожидалось FROM или IN"
-#: pl_gram.y:3278
+#: pl_gram.y:3277
#, c-format
msgid "RETURN cannot have a parameter in function returning set"
msgstr "в функции, возвращающей множество, RETURN должен быть без параметров"
-#: pl_gram.y:3279
+#: pl_gram.y:3278
#, c-format
msgid "Use RETURN NEXT or RETURN QUERY."
msgstr "Используйте RETURN NEXT или RETURN QUERY."
-#: pl_gram.y:3289
+#: pl_gram.y:3288
#, c-format
msgid "RETURN cannot have a parameter in a procedure"
msgstr "в процедуре RETURN должен быть без параметров"
-#: pl_gram.y:3294
+#: pl_gram.y:3293
#, c-format
msgid "RETURN cannot have a parameter in function returning void"
msgstr "в функции, не возвращающей ничего, RETURN не должен иметь параметров"
-#: pl_gram.y:3303
+#: pl_gram.y:3302
#, c-format
msgid "RETURN cannot have a parameter in function with OUT parameters"
msgstr "RETURN должен быть без параметров в функции с параметрами OUT"
-#: pl_gram.y:3366
+#: pl_gram.y:3365
#, c-format
msgid "RETURN NEXT cannot have a parameter in function with OUT parameters"
msgstr "RETURN NEXT должен быть без параметров в функции с параметрами OUT"
-#: pl_gram.y:3532
+#: pl_gram.y:3531
#, c-format
msgid "record variable cannot be part of multiple-item INTO list"
msgstr ""
"переменная типа запись не может быть частью списка INTO с несколькими "
"элементами"
-#: pl_gram.y:3578
+#: pl_gram.y:3577
#, c-format
msgid "too many INTO variables specified"
msgstr "указано слишком много переменных INTO"
-#: pl_gram.y:3786
+#: pl_gram.y:3785
#, c-format
msgid "end label \"%s\" specified for unlabeled block"
msgstr "конечная метка \"%s\" указана для непомеченного блока"
-#: pl_gram.y:3793
+#: pl_gram.y:3792
#, c-format
msgid "end label \"%s\" differs from block's label \"%s\""
msgstr "конечная метка \"%s\" отличается от метки блока \"%s\""
-#: pl_gram.y:3827
+#: pl_gram.y:3826
#, c-format
msgid "cursor \"%s\" has no arguments"
msgstr "курсор \"%s\" не имеет аргументов"
-#: pl_gram.y:3841
+#: pl_gram.y:3840
#, c-format
msgid "cursor \"%s\" has arguments"
msgstr "курсор \"%s\" имеет аргументы"
-#: pl_gram.y:3883
+#: pl_gram.y:3882
#, c-format
msgid "cursor \"%s\" has no argument named \"%s\""
msgstr "курсор \"%s\" не имеет аргумента \"%s\""
-#: pl_gram.y:3903
+#: pl_gram.y:3902
#, c-format
msgid "value for parameter \"%s\" of cursor \"%s\" specified more than once"
msgstr "значение параметра \"%s\" курсора \"%s\" указано неоднократно"
-#: pl_gram.y:3928
+#: pl_gram.y:3923
#, c-format
msgid "not enough arguments for cursor \"%s\""
msgstr "недостаточно аргументов для курсора \"%s\""
-#: pl_gram.y:3935
+#: pl_gram.y:3930
#, c-format
msgid "too many arguments for cursor \"%s\""
msgstr "слишком много аргументов для курсора \"%s\""
-#: pl_gram.y:4021
+#: pl_gram.y:4016
msgid "unrecognized RAISE statement option"
msgstr "нераспознанный параметр оператора RAISE"
-#: pl_gram.y:4025
+#: pl_gram.y:4020
msgid "syntax error, expected \"=\""
msgstr "ошибка синтаксиса, ожидалось \"=\""
-#: pl_gram.y:4066
+#: pl_gram.y:4061
#, c-format
msgid "too many parameters specified for RAISE"
msgstr "слишком много параметров для RAISE"
-#: pl_gram.y:4070
+#: pl_gram.y:4065
#, c-format
msgid "too few parameters specified for RAISE"
msgstr "недостаточно параметров для RAISE"
@@ -898,13 +898,13 @@ msgid "List of programming constructs that should produce an error."
msgstr "Список программных конструкций, которые должны выдавать ошибку."
#. translator: %s is typically the translation of "syntax error"
-#: pl_scanner.c:508
+#: pl_scanner.c:525
#, c-format
msgid "%s at end of input"
msgstr "%s в конце"
#. translator: first %s is typically the translation of "syntax error"
-#: pl_scanner.c:524
+#: pl_scanner.c:541
#, c-format
msgid "%s at or near \"%s\""
msgstr "%s (примерное положение: \"%s\")"
diff --git a/src/pl/plpgsql/src/sql/plpgsql_control.sql b/src/pl/plpgsql/src/sql/plpgsql_control.sql
index ed72311..8e007c5 100644
--- a/src/pl/plpgsql/src/sql/plpgsql_control.sql
+++ b/src/pl/plpgsql/src/sql/plpgsql_control.sql
@@ -486,3 +486,17 @@ select case_test(1);
select case_test(2);
select case_test(12);
select case_test(13);
+
+-- test line comment between WHEN and THEN
+create or replace function case_comment(int) returns text as $$
+begin
+ case $1
+ when 1 -- comment before THEN
+ then return 'one';
+ else
+ return 'other';
+ end case;
+end;
+$$ language plpgsql immutable;
+
+select case_comment(1);
diff --git a/src/pl/plpython/plpy_exec.c b/src/pl/plpython/plpy_exec.c
index e06fde1..3145c69 100644
--- a/src/pl/plpython/plpy_exec.c
+++ b/src/pl/plpython/plpy_exec.c
@@ -689,7 +689,7 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r
*pltrelid,
*plttablename,
*plttableschema,
- *pltargs = NULL,
+ *pltargs,
*pytnew,
*pytold,
*pltdata;
@@ -713,6 +713,11 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r
return NULL;
}
}
+ else
+ {
+ Py_INCREF(Py_None);
+ pltargs = Py_None;
+ }
PG_TRY();
{
@@ -856,7 +861,7 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r
PyObject *pltarg;
/* pltargs should have been allocated before the PG_TRY block. */
- Assert(pltargs);
+ Assert(pltargs && pltargs != Py_None);
for (i = 0; i < tdata->tg_trigger->tgnargs; i++)
{
@@ -870,8 +875,7 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r
}
else
{
- Py_INCREF(Py_None);
- pltargs = Py_None;
+ Assert(pltargs == Py_None);
}
PyDict_SetItemString(pltdata, "args", pltargs);
Py_DECREF(pltargs);
diff --git a/src/pl/plpython/po/ru.po b/src/pl/plpython/po/ru.po
index b3a6d40..9f7a3ac 100644
--- a/src/pl/plpython/po/ru.po
+++ b/src/pl/plpython/po/ru.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: plpython (PostgreSQL current)\n"
"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
-"POT-Creation-Date: 2023-11-03 09:08+0300\n"
+"POT-Creation-Date: 2024-05-04 16:29+0300\n"
"PO-Revision-Date: 2019-08-29 15:42+0300\n"
"Last-Translator: Alexander Lakhin <exclusion@gmail.com>\n"
"Language-Team: Russian <pgsql-ru-general@postgresql.org>\n"
@@ -156,22 +156,22 @@ msgstr ""
msgid "while creating return value"
msgstr "при создании возвращаемого значения"
-#: plpy_exec.c:924
+#: plpy_exec.c:928
#, c-format
msgid "TD[\"new\"] deleted, cannot modify row"
msgstr "элемент TD[\"new\"] удалён -- изменить строку нельзя"
-#: plpy_exec.c:929
+#: plpy_exec.c:933
#, c-format
msgid "TD[\"new\"] is not a dictionary"
msgstr "TD[\"new\"] - не словарь"
-#: plpy_exec.c:954
+#: plpy_exec.c:958
#, c-format
msgid "TD[\"new\"] dictionary key at ordinal position %d is not a string"
msgstr "ключ словаря TD[\"new\"] с порядковым номером %d не является строкой"
-#: plpy_exec.c:961
+#: plpy_exec.c:965
#, c-format
msgid ""
"key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering "
@@ -180,22 +180,22 @@ msgstr ""
"ключу \"%s\", найденному в TD[\"new\"], не соответствует столбец в строке, "
"обрабатываемой триггером"
-#: plpy_exec.c:966
+#: plpy_exec.c:970
#, c-format
msgid "cannot set system attribute \"%s\""
msgstr "присвоить значение системному атрибуту \"%s\" нельзя"
-#: plpy_exec.c:971
+#: plpy_exec.c:975
#, c-format
msgid "cannot set generated column \"%s\""
msgstr "присвоить значение генерируемому столбцу \"%s\" нельзя"
-#: plpy_exec.c:1029
+#: plpy_exec.c:1033
#, c-format
msgid "while modifying trigger row"
msgstr "при изменении строки в триггере"
-#: plpy_exec.c:1087
+#: plpy_exec.c:1091
#, c-format
msgid "forcibly aborting a subtransaction that has not been exited"
msgstr "принудительное прерывание незавершённой подтранзакции"