diff options
Diffstat (limited to '')
-rw-r--r-- | src/pl/plperl/GNUmakefile | 4 | ||||
-rw-r--r-- | src/pl/plperl/plperl.h | 195 | ||||
-rw-r--r-- | src/pl/plperl/plperl_system.h | 215 | ||||
-rw-r--r-- | src/pl/plpgsql/src/Makefile | 5 | ||||
-rw-r--r-- | src/pl/plpgsql/src/expected/plpgsql_misc.out | 31 | ||||
-rw-r--r-- | src/pl/plpgsql/src/pl_gram.c | 758 | ||||
-rw-r--r-- | src/pl/plpgsql/src/pl_gram.h | 2 | ||||
-rw-r--r-- | src/pl/plpgsql/src/pl_gram.y | 72 | ||||
-rw-r--r-- | src/pl/plpgsql/src/po/ru.po | 128 | ||||
-rw-r--r-- | src/pl/plpgsql/src/sql/plpgsql_misc.sql | 22 | ||||
-rw-r--r-- | src/pl/plpython/Makefile | 3 | ||||
-rw-r--r-- | src/pl/plpython/plpython.h | 73 | ||||
-rw-r--r-- | src/pl/plpython/plpython_system.h | 103 |
13 files changed, 920 insertions, 691 deletions
diff --git a/src/pl/plperl/GNUmakefile b/src/pl/plperl/GNUmakefile index a2e6410..3a6954c 100644 --- a/src/pl/plperl/GNUmakefile +++ b/src/pl/plperl/GNUmakefile @@ -103,11 +103,11 @@ uninstall: uninstall-lib uninstall-data install-data: installdirs $(INSTALL_DATA) $(addprefix $(srcdir)/, $(DATA)) '$(DESTDIR)$(datadir)/extension/' - $(INSTALL_DATA) $(srcdir)/plperl.h $(srcdir)/ppport.h $(srcdir)/plperl_helpers.h '$(DESTDIR)$(includedir_server)' + $(INSTALL_DATA) $(srcdir)/plperl.h $(srcdir)/plperl_system.h $(srcdir)/ppport.h $(srcdir)/plperl_helpers.h '$(DESTDIR)$(includedir_server)' uninstall-data: rm -f $(addprefix '$(DESTDIR)$(datadir)/extension'/, $(notdir $(DATA))) - rm -f $(addprefix '$(DESTDIR)$(includedir_server)'/, plperl.h ppport.h) + rm -f $(addprefix '$(DESTDIR)$(includedir_server)'/, plperl.h plperl_system.h ppport.h) .PHONY: install-data uninstall-data diff --git a/src/pl/plperl/plperl.h b/src/pl/plperl/plperl.h index ebca895..c0dd8cb 100644 --- a/src/pl/plperl/plperl.h +++ b/src/pl/plperl/plperl.h @@ -14,200 +14,11 @@ #ifndef PL_PERL_H #define PL_PERL_H -/* stop perl headers from hijacking stdio and other stuff on Windows */ -#ifdef WIN32 -#define WIN32IO_IS_STDIO -#endif /* WIN32 */ - -/* - * Supply a value of PERL_UNUSED_DECL that will satisfy gcc - the one - * perl itself supplies doesn't seem to. - */ -#define PERL_UNUSED_DECL pg_attribute_unused() - -/* - * Sometimes perl carefully scribbles on our *printf macros. - * So we undefine them here and redefine them after it's done its dirty deed. - */ -#undef vsnprintf -#undef snprintf -#undef vsprintf -#undef sprintf -#undef vfprintf -#undef fprintf -#undef vprintf -#undef printf - -/* - * Perl scribbles on the "_" macro too. - */ -#undef _ - -/* - * ActivePerl 5.18 and later are MinGW-built, and their headers use GCC's - * __inline__. Translate to something MSVC recognizes. Also, perl.h sometimes - * defines isnan, so undefine it here and put back the definition later if - * perl.h doesn't. - */ -#ifdef _MSC_VER -#define __inline__ inline -#ifdef isnan -#undef isnan -#endif -/* Work around for using MSVC and Strawberry Perl >= 5.30. */ -#define __builtin_expect(expr, val) (expr) -#endif - -/* - * Regarding bool, both PostgreSQL and Perl might use stdbool.h or not, - * depending on configuration. If both agree, things are relatively harmless. - * If not, things get tricky. If PostgreSQL does but Perl does not, define - * HAS_BOOL here so that Perl does not redefine bool; this avoids compiler - * warnings. If PostgreSQL does not but Perl does, we need to undefine bool - * after we include the Perl headers; see below. - */ -#ifdef PG_USE_STDBOOL -#define HAS_BOOL 1 -#endif - -/* - * Newer versions of the perl headers trigger a lot of warnings with our - * compiler flags (at least -Wdeclaration-after-statement, - * -Wshadow=compatible-local are known to be problematic). The system_header - * pragma hides warnings from within the rest of this file, if supported. - */ -#ifdef HAVE_PRAGMA_GCC_SYSTEM_HEADER -#pragma GCC system_header -#endif - /* - * Get the basic Perl API. We use PERL_NO_GET_CONTEXT mode so that our code - * can compile against MULTIPLICITY Perl builds without including XSUB.h. + * Pull in Perl headers via a wrapper header, to control the scope of + * the system_header pragma therein. */ -#define PERL_NO_GET_CONTEXT -#include "EXTERN.h" -#include "perl.h" - -/* - * We want to include XSUB.h only within .xs files, because on some platforms - * it undesirably redefines a lot of libc functions. But it must appear - * before ppport.h, so use a #define flag to control inclusion here. - */ -#ifdef PG_NEED_PERL_XSUB_H -/* - * On Windows, win32_port.h defines macros for a lot of these same functions. - * To avoid compiler warnings when XSUB.h redefines them, #undef our versions. - */ -#ifdef WIN32 -#undef accept -#undef bind -#undef connect -#undef fopen -#undef fstat -#undef kill -#undef listen -#undef lstat -#undef mkdir -#undef open -#undef putenv -#undef recv -#undef rename -#undef select -#undef send -#undef socket -#undef stat -#undef unlink -#endif - -#include "XSUB.h" -#endif - -/* put back our *printf macros ... this must match src/include/port.h */ -#ifdef vsnprintf -#undef vsnprintf -#endif -#ifdef snprintf -#undef snprintf -#endif -#ifdef vsprintf -#undef vsprintf -#endif -#ifdef sprintf -#undef sprintf -#endif -#ifdef vfprintf -#undef vfprintf -#endif -#ifdef fprintf -#undef fprintf -#endif -#ifdef vprintf -#undef vprintf -#endif -#ifdef printf -#undef printf -#endif - -#define vsnprintf pg_vsnprintf -#define snprintf pg_snprintf -#define vsprintf pg_vsprintf -#define sprintf pg_sprintf -#define vfprintf pg_vfprintf -#define fprintf pg_fprintf -#define vprintf pg_vprintf -#define printf(...) pg_printf(__VA_ARGS__) - -/* - * Put back "_" too; but rather than making it just gettext() as the core - * code does, make it dgettext() so that the right things will happen in - * loadable modules (if they've set up TEXTDOMAIN correctly). Note that - * we can't just set TEXTDOMAIN here, because this file is used by more - * extensions than just PL/Perl itself. - */ -#undef _ -#define _(x) dgettext(TEXTDOMAIN, x) - -/* put back the definition of isnan if needed */ -#ifdef _MSC_VER -#ifndef isnan -#define isnan(x) _isnan(x) -#endif -#endif - -/* perl version and platform portability */ -#include "ppport.h" - -/* - * perl might have included stdbool.h. If we also did that earlier (see c.h), - * then that's fine. If not, we probably rejected it for some reason. In - * that case, undef bool and proceed with our own bool. (Note that stdbool.h - * makes bool a macro, but our own replacement is a typedef, so the undef - * makes ours visible again). - */ -#ifndef PG_USE_STDBOOL -#ifdef bool -#undef bool -#endif -#endif - -/* supply HeUTF8 if it's missing - ppport.h doesn't supply it, unfortunately */ -#ifndef HeUTF8 -#define HeUTF8(he) ((HeKLEN(he) == HEf_SVKEY) ? \ - SvUTF8(HeKEY_sv(he)) : \ - (U32)HeKUTF8(he)) -#endif - -/* supply GvCV_set if it's missing - ppport.h doesn't supply it, unfortunately */ -#ifndef GvCV_set -#define GvCV_set(gv, cv) (GvCV(gv) = cv) -#endif - -/* Perl 5.19.4 changed array indices from I32 to SSize_t */ -#if PERL_BCDVERSION >= 0x5019004 -#define AV_SIZE_MAX SSize_t_MAX -#else -#define AV_SIZE_MAX I32_MAX -#endif +#include "plperl_system.h" /* declare routines from plperl.c for access by .xs files */ HV *plperl_spi_exec(char *, int); diff --git a/src/pl/plperl/plperl_system.h b/src/pl/plperl/plperl_system.h new file mode 100644 index 0000000..61550db --- /dev/null +++ b/src/pl/plperl/plperl_system.h @@ -0,0 +1,215 @@ +/*------------------------------------------------------------------------- + * + * plperl_system.h + * Pull in Perl's system header files. + * + * We break this out as a separate header file to precisely control + * the scope of the "system_header" pragma. No Postgres-specific + * declarations should be put here. However, we do include some stuff + * that is meant to prevent conflicts between our code and Perl. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1995, Regents of the University of California + * + * src/pl/plperl/plperl_system.h + */ + +#ifndef PL_PERL_SYSTEM_H +#define PL_PERL_SYSTEM_H + +/* + * Newer versions of the perl headers trigger a lot of warnings with our + * preferred compiler flags (at least -Wdeclaration-after-statement, + * -Wshadow=compatible-local are known to be problematic). The system_header + * pragma hides warnings from within the rest of this file, if supported. + */ +#ifdef HAVE_PRAGMA_GCC_SYSTEM_HEADER +#pragma GCC system_header +#endif + +/* stop perl headers from hijacking stdio and other stuff on Windows */ +#ifdef WIN32 +#define WIN32IO_IS_STDIO +#endif /* WIN32 */ + +/* + * Supply a value of PERL_UNUSED_DECL that will satisfy gcc - the one + * perl itself supplies doesn't seem to. + */ +#define PERL_UNUSED_DECL pg_attribute_unused() + +/* + * Sometimes perl carefully scribbles on our *printf macros. + * So we undefine them here and redefine them after it's done its dirty deed. + */ +#undef vsnprintf +#undef snprintf +#undef vsprintf +#undef sprintf +#undef vfprintf +#undef fprintf +#undef vprintf +#undef printf + +/* + * Perl scribbles on the "_" macro too. + */ +#undef _ + +/* + * ActivePerl 5.18 and later are MinGW-built, and their headers use GCC's + * __inline__. Translate to something MSVC recognizes. Also, perl.h sometimes + * defines isnan, so undefine it here and put back the definition later if + * perl.h doesn't. + */ +#ifdef _MSC_VER +#define __inline__ inline +#ifdef isnan +#undef isnan +#endif +/* Work around for using MSVC and Strawberry Perl >= 5.30. */ +#define __builtin_expect(expr, val) (expr) +#endif + +/* + * Regarding bool, both PostgreSQL and Perl might use stdbool.h or not, + * depending on configuration. If both agree, things are relatively harmless. + * If not, things get tricky. If PostgreSQL does but Perl does not, define + * HAS_BOOL here so that Perl does not redefine bool; this avoids compiler + * warnings. If PostgreSQL does not but Perl does, we need to undefine bool + * after we include the Perl headers; see below. + */ +#ifdef PG_USE_STDBOOL +#define HAS_BOOL 1 +#endif + +/* + * Get the basic Perl API. We use PERL_NO_GET_CONTEXT mode so that our code + * can compile against MULTIPLICITY Perl builds without including XSUB.h. + */ +#define PERL_NO_GET_CONTEXT +#include "EXTERN.h" +#include "perl.h" + +/* + * We want to include XSUB.h only within .xs files, because on some platforms + * it undesirably redefines a lot of libc functions. But it must appear + * before ppport.h, so use a #define flag to control inclusion here. + */ +#ifdef PG_NEED_PERL_XSUB_H +/* + * On Windows, win32_port.h defines macros for a lot of these same functions. + * To avoid compiler warnings when XSUB.h redefines them, #undef our versions. + */ +#ifdef WIN32 +#undef accept +#undef bind +#undef connect +#undef fopen +#undef fstat +#undef kill +#undef listen +#undef lstat +#undef mkdir +#undef open +#undef putenv +#undef recv +#undef rename +#undef select +#undef send +#undef socket +#undef stat +#undef unlink +#endif + +#include "XSUB.h" +#endif + +/* put back our *printf macros ... this must match src/include/port.h */ +#ifdef vsnprintf +#undef vsnprintf +#endif +#ifdef snprintf +#undef snprintf +#endif +#ifdef vsprintf +#undef vsprintf +#endif +#ifdef sprintf +#undef sprintf +#endif +#ifdef vfprintf +#undef vfprintf +#endif +#ifdef fprintf +#undef fprintf +#endif +#ifdef vprintf +#undef vprintf +#endif +#ifdef printf +#undef printf +#endif + +#define vsnprintf pg_vsnprintf +#define snprintf pg_snprintf +#define vsprintf pg_vsprintf +#define sprintf pg_sprintf +#define vfprintf pg_vfprintf +#define fprintf pg_fprintf +#define vprintf pg_vprintf +#define printf(...) pg_printf(__VA_ARGS__) + +/* + * Put back "_" too; but rather than making it just gettext() as the core + * code does, make it dgettext() so that the right things will happen in + * loadable modules (if they've set up TEXTDOMAIN correctly). Note that + * we can't just set TEXTDOMAIN here, because this file is used by more + * extensions than just PL/Perl itself. + */ +#undef _ +#define _(x) dgettext(TEXTDOMAIN, x) + +/* put back the definition of isnan if needed */ +#ifdef _MSC_VER +#ifndef isnan +#define isnan(x) _isnan(x) +#endif +#endif + +/* perl version and platform portability */ +#include "ppport.h" + +/* + * perl might have included stdbool.h. If we also did that earlier (see c.h), + * then that's fine. If not, we probably rejected it for some reason. In + * that case, undef bool and proceed with our own bool. (Note that stdbool.h + * makes bool a macro, but our own replacement is a typedef, so the undef + * makes ours visible again). + */ +#ifndef PG_USE_STDBOOL +#ifdef bool +#undef bool +#endif +#endif + +/* supply HeUTF8 if it's missing - ppport.h doesn't supply it, unfortunately */ +#ifndef HeUTF8 +#define HeUTF8(he) ((HeKLEN(he) == HEf_SVKEY) ? \ + SvUTF8(HeKEY_sv(he)) : \ + (U32)HeKUTF8(he)) +#endif + +/* supply GvCV_set if it's missing - ppport.h doesn't supply it, unfortunately */ +#ifndef GvCV_set +#define GvCV_set(gv, cv) (GvCV(gv) = cv) +#endif + +/* Perl 5.19.4 changed array indices from I32 to SSize_t */ +#if PERL_BCDVERSION >= 0x5019004 +#define AV_SIZE_MAX SSize_t_MAX +#else +#define AV_SIZE_MAX I32_MAX +#endif + +#endif /* PL_PERL_SYSTEM_H */ diff --git a/src/pl/plpgsql/src/Makefile b/src/pl/plpgsql/src/Makefile index f7eb42d..7cd8900 100644 --- a/src/pl/plpgsql/src/Makefile +++ b/src/pl/plpgsql/src/Makefile @@ -32,8 +32,9 @@ DATA = plpgsql.control plpgsql--1.0.sql REGRESS_OPTS = --dbname=$(PL_TESTDB) -REGRESS = plpgsql_array plpgsql_call plpgsql_control plpgsql_copy plpgsql_domain \ - plpgsql_record plpgsql_cache plpgsql_simple plpgsql_transaction \ +REGRESS = plpgsql_array plpgsql_cache plpgsql_call plpgsql_control \ + plpgsql_copy plpgsql_domain plpgsql_misc \ + plpgsql_record plpgsql_simple plpgsql_transaction \ plpgsql_trap plpgsql_trigger plpgsql_varprops # where to find gen_keywordlist.pl and subsidiary files diff --git a/src/pl/plpgsql/src/expected/plpgsql_misc.out b/src/pl/plpgsql/src/expected/plpgsql_misc.out new file mode 100644 index 0000000..faddba2 --- /dev/null +++ b/src/pl/plpgsql/src/expected/plpgsql_misc.out @@ -0,0 +1,31 @@ +-- +-- Miscellaneous topics +-- +-- Verify that we can parse new-style CREATE FUNCTION/PROCEDURE +do +$$ + declare procedure int; -- check we still recognize non-keywords as vars + begin + create function test1() returns int + begin atomic + select 2 + 2; + end; + create or replace procedure test2(x int) + begin atomic + select x + 2; + end; + end +$$; +\sf test1 +CREATE OR REPLACE FUNCTION public.test1() + RETURNS integer + LANGUAGE sql +BEGIN ATOMIC + SELECT (2 + 2); +END +\sf test2 +CREATE OR REPLACE PROCEDURE public.test2(IN x integer) + LANGUAGE sql +BEGIN ATOMIC + SELECT (x + 2); +END diff --git a/src/pl/plpgsql/src/pl_gram.c b/src/pl/plpgsql/src/pl_gram.c index 2d3e1c2..5d1cd56 100644 --- a/src/pl/plpgsql/src/pl_gram.c +++ b/src/pl/plpgsql/src/pl_gram.c @@ -157,7 +157,8 @@ static PLpgSQL_expr *read_sql_expression2(int until, int until2, int *endtoken); static PLpgSQL_expr *read_sql_stmt(void); static PLpgSQL_type *read_datatype(int tok); -static PLpgSQL_stmt *make_execsql_stmt(int firsttoken, int location); +static PLpgSQL_stmt *make_execsql_stmt(int firsttoken, int location, + PLword *word); static PLpgSQL_stmt_fetch *read_fetch_direction(void); static void complete_direction(PLpgSQL_stmt_fetch *fetch, bool *check_FROM); @@ -189,7 +190,7 @@ static List *read_raise_options(void); static void check_raise_parameters(PLpgSQL_stmt_raise *stmt); -#line 193 "pl_gram.c" +#line 194 "pl_gram.c" # ifndef YY_CAST # ifdef __cplusplus @@ -835,32 +836,32 @@ static const yytype_uint8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 361, 361, 367, 368, 371, 375, 384, 388, 392, - 398, 402, 407, 408, 411, 434, 442, 449, 458, 470, - 471, 474, 475, 479, 492, 530, 536, 535, 589, 592, - 596, 603, 609, 612, 643, 647, 653, 661, 662, 664, - 679, 694, 722, 750, 781, 782, 787, 798, 799, 804, - 809, 816, 817, 821, 823, 829, 830, 838, 839, 843, - 844, 854, 856, 858, 860, 862, 864, 866, 868, 870, - 872, 874, 876, 878, 880, 882, 884, 886, 888, 890, - 892, 894, 896, 898, 900, 904, 940, 958, 979, 1018, - 1081, 1084, 1088, 1094, 1098, 1104, 1117, 1161, 1179, 1184, - 1191, 1209, 1212, 1226, 1229, 1235, 1242, 1256, 1260, 1266, - 1278, 1281, 1296, 1314, 1333, 1367, 1626, 1652, 1666, 1673, - 1712, 1715, 1721, 1774, 1778, 1784, 1810, 1955, 1979, 1997, - 2001, 2005, 2009, 2020, 2033, 2097, 2175, 2205, 2218, 2223, - 2237, 2244, 2258, 2273, 2274, 2275, 2279, 2301, 2306, 2314, - 2316, 2315, 2357, 2361, 2367, 2380, 2389, 2395, 2432, 2436, - 2440, 2444, 2448, 2456, 2460, 2468, 2471, 2478, 2480, 2487, - 2491, 2495, 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, - 2562, 2563, 2564, 2565, 2566, 2567, 2568, 2569, 2570, 2571, - 2572, 2573, 2574, 2575, 2576, 2577, 2578, 2579, 2580, 2581, - 2582, 2583, 2584 + 0, 362, 362, 368, 369, 372, 376, 385, 389, 393, + 399, 403, 408, 409, 412, 435, 443, 450, 459, 471, + 472, 475, 476, 480, 493, 531, 537, 536, 590, 593, + 597, 604, 610, 613, 644, 648, 654, 662, 663, 665, + 680, 695, 723, 751, 782, 783, 788, 799, 800, 805, + 810, 817, 818, 822, 824, 830, 831, 839, 840, 844, + 845, 855, 857, 859, 861, 863, 865, 867, 869, 871, + 873, 875, 877, 879, 881, 883, 885, 887, 889, 891, + 893, 895, 897, 899, 901, 905, 941, 959, 980, 1019, + 1082, 1085, 1089, 1095, 1099, 1105, 1118, 1162, 1180, 1185, + 1192, 1210, 1213, 1227, 1230, 1236, 1243, 1257, 1261, 1267, + 1279, 1282, 1297, 1315, 1334, 1368, 1627, 1653, 1667, 1674, + 1713, 1716, 1722, 1775, 1779, 1785, 1811, 1956, 1980, 1998, + 2002, 2006, 2010, 2021, 2034, 2098, 2176, 2206, 2219, 2224, + 2238, 2245, 2259, 2274, 2275, 2276, 2280, 2302, 2307, 2315, + 2317, 2316, 2358, 2362, 2368, 2381, 2390, 2396, 2433, 2437, + 2441, 2445, 2449, 2457, 2461, 2469, 2472, 2479, 2481, 2488, + 2492, 2496, 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, 2562, + 2563, 2564, 2565, 2566, 2567, 2568, 2569, 2570, 2571, 2572, + 2573, 2574, 2575, 2576, 2577, 2578, 2579, 2580, 2581, 2582, + 2583, 2584, 2585 }; #endif @@ -2024,23 +2025,23 @@ yyreduce: switch (yyn) { case 2: /* pl_function: comp_options pl_block opt_semi */ -#line 362 "pl_gram.y" +#line 363 "pl_gram.y" { plpgsql_parse_result = (PLpgSQL_stmt_block *) (yyvsp[-1].stmt); } -#line 2032 "pl_gram.c" +#line 2033 "pl_gram.c" break; case 5: /* comp_option: '#' K_OPTION K_DUMP */ -#line 372 "pl_gram.y" +#line 373 "pl_gram.y" { plpgsql_DumpExecTree = true; } -#line 2040 "pl_gram.c" +#line 2041 "pl_gram.c" break; case 6: /* comp_option: '#' K_PRINT_STRICT_PARAMS option_value */ -#line 376 "pl_gram.y" +#line 377 "pl_gram.y" { if (strcmp((yyvsp[0].str), "on") == 0) plpgsql_curr_compile->print_strict_params = true; @@ -2049,51 +2050,51 @@ yyreduce: else elog(ERROR, "unrecognized print_strict_params option %s", (yyvsp[0].str)); } -#line 2053 "pl_gram.c" +#line 2054 "pl_gram.c" break; case 7: /* comp_option: '#' K_VARIABLE_CONFLICT K_ERROR */ -#line 385 "pl_gram.y" +#line 386 "pl_gram.y" { plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_ERROR; } -#line 2061 "pl_gram.c" +#line 2062 "pl_gram.c" break; case 8: /* comp_option: '#' K_VARIABLE_CONFLICT K_USE_VARIABLE */ -#line 389 "pl_gram.y" +#line 390 "pl_gram.y" { plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_VARIABLE; } -#line 2069 "pl_gram.c" +#line 2070 "pl_gram.c" break; case 9: /* comp_option: '#' K_VARIABLE_CONFLICT K_USE_COLUMN */ -#line 393 "pl_gram.y" +#line 394 "pl_gram.y" { plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_COLUMN; } -#line 2077 "pl_gram.c" +#line 2078 "pl_gram.c" break; case 10: /* option_value: T_WORD */ -#line 399 "pl_gram.y" +#line 400 "pl_gram.y" { (yyval.str) = (yyvsp[0].word).ident; } -#line 2085 "pl_gram.c" +#line 2086 "pl_gram.c" break; case 11: /* option_value: unreserved_keyword */ -#line 403 "pl_gram.y" +#line 404 "pl_gram.y" { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 2093 "pl_gram.c" +#line 2094 "pl_gram.c" break; case 14: /* pl_block: decl_sect K_BEGIN proc_sect exception_sect K_END opt_label */ -#line 412 "pl_gram.y" +#line 413 "pl_gram.y" { PLpgSQL_stmt_block *new; @@ -2113,11 +2114,11 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 2117 "pl_gram.c" +#line 2118 "pl_gram.c" break; case 15: /* decl_sect: opt_block_label */ -#line 435 "pl_gram.y" +#line 436 "pl_gram.y" { /* done with decls, so resume identifier lookup */ plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL; @@ -2125,33 +2126,33 @@ yyreduce: (yyval.declhdr).n_initvars = 0; (yyval.declhdr).initvarnos = NULL; } -#line 2129 "pl_gram.c" +#line 2130 "pl_gram.c" break; case 16: /* decl_sect: opt_block_label decl_start */ -#line 443 "pl_gram.y" +#line 444 "pl_gram.y" { plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL; (yyval.declhdr).label = (yyvsp[-1].str); (yyval.declhdr).n_initvars = 0; (yyval.declhdr).initvarnos = NULL; } -#line 2140 "pl_gram.c" +#line 2141 "pl_gram.c" break; case 17: /* decl_sect: opt_block_label decl_start decl_stmts */ -#line 450 "pl_gram.y" +#line 451 "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 2151 "pl_gram.c" +#line 2152 "pl_gram.c" break; case 18: /* decl_start: K_DECLARE */ -#line 459 "pl_gram.y" +#line 460 "pl_gram.y" { /* Forget any variables created before block */ plpgsql_add_initdatums(NULL); @@ -2161,19 +2162,19 @@ yyreduce: */ plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_DECLARE; } -#line 2165 "pl_gram.c" +#line 2166 "pl_gram.c" break; case 22: /* decl_stmt: K_DECLARE */ -#line 476 "pl_gram.y" +#line 477 "pl_gram.y" { /* We allow useless extra DECLAREs */ } -#line 2173 "pl_gram.c" +#line 2174 "pl_gram.c" break; case 23: /* decl_stmt: LESS_LESS any_identifier GREATER_GREATER */ -#line 480 "pl_gram.y" +#line 481 "pl_gram.y" { /* * Throw a helpful error if user tries to put block @@ -2184,11 +2185,11 @@ yyreduce: errmsg("block label must be placed before DECLARE, not after"), parser_errposition((yylsp[-2])))); } -#line 2188 "pl_gram.c" +#line 2189 "pl_gram.c" break; case 24: /* decl_statement: decl_varname decl_const decl_datatype decl_collate decl_notnull decl_defval */ -#line 493 "pl_gram.y" +#line 494 "pl_gram.y" { PLpgSQL_variable *var; @@ -2226,26 +2227,26 @@ yyreduce: var->refname), parser_errposition((yylsp[-1])))); } -#line 2230 "pl_gram.c" +#line 2231 "pl_gram.c" break; case 25: /* decl_statement: decl_varname K_ALIAS K_FOR decl_aliasitem ';' */ -#line 531 "pl_gram.y" +#line 532 "pl_gram.y" { plpgsql_ns_additem((yyvsp[-1].nsitem)->itemtype, (yyvsp[-1].nsitem)->itemno, (yyvsp[-4].varname).name); } -#line 2239 "pl_gram.c" +#line 2240 "pl_gram.c" break; case 26: /* $@1: %empty */ -#line 536 "pl_gram.y" +#line 537 "pl_gram.y" { plpgsql_ns_push((yyvsp[-2].varname).name, PLPGSQL_LABEL_OTHER); } -#line 2245 "pl_gram.c" +#line 2246 "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 538 "pl_gram.y" +#line 539 "pl_gram.y" { PLpgSQL_var *new; PLpgSQL_expr *curname_def; @@ -2294,51 +2295,51 @@ yyreduce: new->cursor_explicit_argrow = (yyvsp[-2].datum)->dno; new->cursor_options = CURSOR_OPT_FAST_PLAN | (yyvsp[-5].ival); } -#line 2298 "pl_gram.c" +#line 2299 "pl_gram.c" break; case 28: /* opt_scrollable: %empty */ -#line 589 "pl_gram.y" +#line 590 "pl_gram.y" { (yyval.ival) = 0; } -#line 2306 "pl_gram.c" +#line 2307 "pl_gram.c" break; case 29: /* opt_scrollable: K_NO K_SCROLL */ -#line 593 "pl_gram.y" +#line 594 "pl_gram.y" { (yyval.ival) = CURSOR_OPT_NO_SCROLL; } -#line 2314 "pl_gram.c" +#line 2315 "pl_gram.c" break; case 30: /* opt_scrollable: K_SCROLL */ -#line 597 "pl_gram.y" +#line 598 "pl_gram.y" { (yyval.ival) = CURSOR_OPT_SCROLL; } -#line 2322 "pl_gram.c" +#line 2323 "pl_gram.c" break; case 31: /* decl_cursor_query: %empty */ -#line 603 "pl_gram.y" +#line 604 "pl_gram.y" { (yyval.expr) = read_sql_stmt(); } -#line 2330 "pl_gram.c" +#line 2331 "pl_gram.c" break; case 32: /* decl_cursor_args: %empty */ -#line 609 "pl_gram.y" +#line 610 "pl_gram.y" { (yyval.datum) = NULL; } -#line 2338 "pl_gram.c" +#line 2339 "pl_gram.c" break; case 33: /* decl_cursor_args: '(' decl_cursor_arglist ')' */ -#line 613 "pl_gram.y" +#line 614 "pl_gram.y" { PLpgSQL_row *new; int i; @@ -2367,37 +2368,37 @@ yyreduce: plpgsql_adddatum((PLpgSQL_datum *) new); (yyval.datum) = (PLpgSQL_datum *) new; } -#line 2371 "pl_gram.c" +#line 2372 "pl_gram.c" break; case 34: /* decl_cursor_arglist: decl_cursor_arg */ -#line 644 "pl_gram.y" +#line 645 "pl_gram.y" { (yyval.list) = list_make1((yyvsp[0].datum)); } -#line 2379 "pl_gram.c" +#line 2380 "pl_gram.c" break; case 35: /* decl_cursor_arglist: decl_cursor_arglist ',' decl_cursor_arg */ -#line 648 "pl_gram.y" +#line 649 "pl_gram.y" { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].datum)); } -#line 2387 "pl_gram.c" +#line 2388 "pl_gram.c" break; case 36: /* decl_cursor_arg: decl_varname decl_datatype */ -#line 654 "pl_gram.y" +#line 655 "pl_gram.y" { (yyval.datum) = (PLpgSQL_datum *) plpgsql_build_variable((yyvsp[-1].varname).name, (yyvsp[-1].varname).lineno, (yyvsp[0].dtype), true); } -#line 2397 "pl_gram.c" +#line 2398 "pl_gram.c" break; case 39: /* decl_aliasitem: T_WORD */ -#line 665 "pl_gram.y" +#line 666 "pl_gram.y" { PLpgSQL_nsitem *nsi; @@ -2412,11 +2413,11 @@ yyreduce: parser_errposition((yylsp[0])))); (yyval.nsitem) = nsi; } -#line 2416 "pl_gram.c" +#line 2417 "pl_gram.c" break; case 40: /* decl_aliasitem: unreserved_keyword */ -#line 680 "pl_gram.y" +#line 681 "pl_gram.y" { PLpgSQL_nsitem *nsi; @@ -2431,11 +2432,11 @@ yyreduce: parser_errposition((yylsp[0])))); (yyval.nsitem) = nsi; } -#line 2435 "pl_gram.c" +#line 2436 "pl_gram.c" break; case 41: /* decl_aliasitem: T_CWORD */ -#line 695 "pl_gram.y" +#line 696 "pl_gram.y" { PLpgSQL_nsitem *nsi; @@ -2461,11 +2462,11 @@ yyreduce: parser_errposition((yylsp[0])))); (yyval.nsitem) = nsi; } -#line 2465 "pl_gram.c" +#line 2466 "pl_gram.c" break; case 42: /* decl_varname: T_WORD */ -#line 723 "pl_gram.y" +#line 724 "pl_gram.y" { (yyval.varname).name = (yyvsp[0].word).ident; (yyval.varname).lineno = plpgsql_location_to_lineno((yylsp[0])); @@ -2493,11 +2494,11 @@ yyreduce: } } -#line 2497 "pl_gram.c" +#line 2498 "pl_gram.c" break; case 43: /* decl_varname: unreserved_keyword */ -#line 751 "pl_gram.y" +#line 752 "pl_gram.y" { (yyval.varname).name = pstrdup((yyvsp[0].keyword)); (yyval.varname).lineno = plpgsql_location_to_lineno((yylsp[0])); @@ -2525,23 +2526,23 @@ yyreduce: } } -#line 2529 "pl_gram.c" +#line 2530 "pl_gram.c" break; case 44: /* decl_const: %empty */ -#line 781 "pl_gram.y" +#line 782 "pl_gram.y" { (yyval.boolean) = false; } -#line 2535 "pl_gram.c" +#line 2536 "pl_gram.c" break; case 45: /* decl_const: K_CONSTANT */ -#line 783 "pl_gram.y" +#line 784 "pl_gram.y" { (yyval.boolean) = true; } -#line 2541 "pl_gram.c" +#line 2542 "pl_gram.c" break; case 46: /* decl_datatype: %empty */ -#line 787 "pl_gram.y" +#line 788 "pl_gram.y" { /* * If there's a lookahead token, read_datatype @@ -2550,75 +2551,75 @@ yyreduce: (yyval.dtype) = read_datatype(yychar); yyclearin; } -#line 2554 "pl_gram.c" +#line 2555 "pl_gram.c" break; case 47: /* decl_collate: %empty */ -#line 798 "pl_gram.y" +#line 799 "pl_gram.y" { (yyval.oid) = InvalidOid; } -#line 2560 "pl_gram.c" +#line 2561 "pl_gram.c" break; case 48: /* decl_collate: K_COLLATE T_WORD */ -#line 800 "pl_gram.y" +#line 801 "pl_gram.y" { (yyval.oid) = get_collation_oid(list_make1(makeString((yyvsp[0].word).ident)), false); } -#line 2569 "pl_gram.c" +#line 2570 "pl_gram.c" break; case 49: /* decl_collate: K_COLLATE unreserved_keyword */ -#line 805 "pl_gram.y" +#line 806 "pl_gram.y" { (yyval.oid) = get_collation_oid(list_make1(makeString(pstrdup((yyvsp[0].keyword)))), false); } -#line 2578 "pl_gram.c" +#line 2579 "pl_gram.c" break; case 50: /* decl_collate: K_COLLATE T_CWORD */ -#line 810 "pl_gram.y" +#line 811 "pl_gram.y" { (yyval.oid) = get_collation_oid((yyvsp[0].cword).idents, false); } -#line 2586 "pl_gram.c" +#line 2587 "pl_gram.c" break; case 51: /* decl_notnull: %empty */ -#line 816 "pl_gram.y" +#line 817 "pl_gram.y" { (yyval.boolean) = false; } -#line 2592 "pl_gram.c" +#line 2593 "pl_gram.c" break; case 52: /* decl_notnull: K_NOT K_NULL */ -#line 818 "pl_gram.y" +#line 819 "pl_gram.y" { (yyval.boolean) = true; } -#line 2598 "pl_gram.c" +#line 2599 "pl_gram.c" break; case 53: /* decl_defval: ';' */ -#line 822 "pl_gram.y" +#line 823 "pl_gram.y" { (yyval.expr) = NULL; } -#line 2604 "pl_gram.c" +#line 2605 "pl_gram.c" break; case 54: /* decl_defval: decl_defkey */ -#line 824 "pl_gram.y" +#line 825 "pl_gram.y" { (yyval.expr) = read_sql_expression(';', ";"); } -#line 2612 "pl_gram.c" +#line 2613 "pl_gram.c" break; case 59: /* proc_sect: %empty */ -#line 843 "pl_gram.y" +#line 844 "pl_gram.y" { (yyval.list) = NIL; } -#line 2618 "pl_gram.c" +#line 2619 "pl_gram.c" break; case 60: /* proc_sect: proc_sect proc_stmt */ -#line 845 "pl_gram.y" +#line 846 "pl_gram.y" { /* don't bother linking null statements into list */ if ((yyvsp[0].stmt) == NULL) @@ -2626,155 +2627,155 @@ yyreduce: else (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].stmt)); } -#line 2630 "pl_gram.c" +#line 2631 "pl_gram.c" break; case 61: /* proc_stmt: pl_block ';' */ -#line 855 "pl_gram.y" +#line 856 "pl_gram.y" { (yyval.stmt) = (yyvsp[-1].stmt); } -#line 2636 "pl_gram.c" +#line 2637 "pl_gram.c" break; case 62: /* proc_stmt: stmt_assign */ -#line 857 "pl_gram.y" +#line 858 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2642 "pl_gram.c" +#line 2643 "pl_gram.c" break; case 63: /* proc_stmt: stmt_if */ -#line 859 "pl_gram.y" +#line 860 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2648 "pl_gram.c" +#line 2649 "pl_gram.c" break; case 64: /* proc_stmt: stmt_case */ -#line 861 "pl_gram.y" +#line 862 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2654 "pl_gram.c" +#line 2655 "pl_gram.c" break; case 65: /* proc_stmt: stmt_loop */ -#line 863 "pl_gram.y" +#line 864 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2660 "pl_gram.c" +#line 2661 "pl_gram.c" break; case 66: /* proc_stmt: stmt_while */ -#line 865 "pl_gram.y" +#line 866 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2666 "pl_gram.c" +#line 2667 "pl_gram.c" break; case 67: /* proc_stmt: stmt_for */ -#line 867 "pl_gram.y" +#line 868 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2672 "pl_gram.c" +#line 2673 "pl_gram.c" break; case 68: /* proc_stmt: stmt_foreach_a */ -#line 869 "pl_gram.y" +#line 870 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2678 "pl_gram.c" +#line 2679 "pl_gram.c" break; case 69: /* proc_stmt: stmt_exit */ -#line 871 "pl_gram.y" +#line 872 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2684 "pl_gram.c" +#line 2685 "pl_gram.c" break; case 70: /* proc_stmt: stmt_return */ -#line 873 "pl_gram.y" +#line 874 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2690 "pl_gram.c" +#line 2691 "pl_gram.c" break; case 71: /* proc_stmt: stmt_raise */ -#line 875 "pl_gram.y" +#line 876 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2696 "pl_gram.c" +#line 2697 "pl_gram.c" break; case 72: /* proc_stmt: stmt_assert */ -#line 877 "pl_gram.y" +#line 878 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2702 "pl_gram.c" +#line 2703 "pl_gram.c" break; case 73: /* proc_stmt: stmt_execsql */ -#line 879 "pl_gram.y" +#line 880 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2708 "pl_gram.c" +#line 2709 "pl_gram.c" break; case 74: /* proc_stmt: stmt_dynexecute */ -#line 881 "pl_gram.y" +#line 882 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2714 "pl_gram.c" +#line 2715 "pl_gram.c" break; case 75: /* proc_stmt: stmt_perform */ -#line 883 "pl_gram.y" +#line 884 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2720 "pl_gram.c" +#line 2721 "pl_gram.c" break; case 76: /* proc_stmt: stmt_call */ -#line 885 "pl_gram.y" +#line 886 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2726 "pl_gram.c" +#line 2727 "pl_gram.c" break; case 77: /* proc_stmt: stmt_getdiag */ -#line 887 "pl_gram.y" +#line 888 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2732 "pl_gram.c" +#line 2733 "pl_gram.c" break; case 78: /* proc_stmt: stmt_open */ -#line 889 "pl_gram.y" +#line 890 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2738 "pl_gram.c" +#line 2739 "pl_gram.c" break; case 79: /* proc_stmt: stmt_fetch */ -#line 891 "pl_gram.y" +#line 892 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2744 "pl_gram.c" +#line 2745 "pl_gram.c" break; case 80: /* proc_stmt: stmt_move */ -#line 893 "pl_gram.y" +#line 894 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2750 "pl_gram.c" +#line 2751 "pl_gram.c" break; case 81: /* proc_stmt: stmt_close */ -#line 895 "pl_gram.y" +#line 896 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2756 "pl_gram.c" +#line 2757 "pl_gram.c" break; case 82: /* proc_stmt: stmt_null */ -#line 897 "pl_gram.y" +#line 898 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2762 "pl_gram.c" +#line 2763 "pl_gram.c" break; case 83: /* proc_stmt: stmt_commit */ -#line 899 "pl_gram.y" +#line 900 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2768 "pl_gram.c" +#line 2769 "pl_gram.c" break; case 84: /* proc_stmt: stmt_rollback */ -#line 901 "pl_gram.y" +#line 902 "pl_gram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2774 "pl_gram.c" +#line 2775 "pl_gram.c" break; case 85: /* stmt_perform: K_PERFORM */ -#line 905 "pl_gram.y" +#line 906 "pl_gram.y" { PLpgSQL_stmt_perform *new; int startloc; @@ -2808,11 +2809,11 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 2812 "pl_gram.c" +#line 2813 "pl_gram.c" break; case 86: /* stmt_call: K_CALL */ -#line 941 "pl_gram.y" +#line 942 "pl_gram.y" { PLpgSQL_stmt_call *new; @@ -2830,11 +2831,11 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 2834 "pl_gram.c" +#line 2835 "pl_gram.c" break; case 87: /* stmt_call: K_DO */ -#line 959 "pl_gram.y" +#line 960 "pl_gram.y" { /* use the same structures as for CALL, for simplicity */ PLpgSQL_stmt_call *new; @@ -2853,11 +2854,11 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 2857 "pl_gram.c" +#line 2858 "pl_gram.c" break; case 88: /* stmt_assign: T_DATUM */ -#line 980 "pl_gram.y" +#line 981 "pl_gram.y" { PLpgSQL_stmt_assign *new; RawParseMode pmode; @@ -2894,11 +2895,11 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 2898 "pl_gram.c" +#line 2899 "pl_gram.c" break; case 89: /* stmt_getdiag: K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';' */ -#line 1019 "pl_gram.y" +#line 1020 "pl_gram.y" { PLpgSQL_stmt_getdiag *new; ListCell *lc; @@ -2958,51 +2959,51 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 2962 "pl_gram.c" +#line 2963 "pl_gram.c" break; case 90: /* getdiag_area_opt: %empty */ -#line 1081 "pl_gram.y" +#line 1082 "pl_gram.y" { (yyval.boolean) = false; } -#line 2970 "pl_gram.c" +#line 2971 "pl_gram.c" break; case 91: /* getdiag_area_opt: K_CURRENT */ -#line 1085 "pl_gram.y" +#line 1086 "pl_gram.y" { (yyval.boolean) = false; } -#line 2978 "pl_gram.c" +#line 2979 "pl_gram.c" break; case 92: /* getdiag_area_opt: K_STACKED */ -#line 1089 "pl_gram.y" +#line 1090 "pl_gram.y" { (yyval.boolean) = true; } -#line 2986 "pl_gram.c" +#line 2987 "pl_gram.c" break; case 93: /* getdiag_list: getdiag_list ',' getdiag_list_item */ -#line 1095 "pl_gram.y" +#line 1096 "pl_gram.y" { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].diagitem)); } -#line 2994 "pl_gram.c" +#line 2995 "pl_gram.c" break; case 94: /* getdiag_list: getdiag_list_item */ -#line 1099 "pl_gram.y" +#line 1100 "pl_gram.y" { (yyval.list) = list_make1((yyvsp[0].diagitem)); } -#line 3002 "pl_gram.c" +#line 3003 "pl_gram.c" break; case 95: /* getdiag_list_item: getdiag_target assign_operator getdiag_item */ -#line 1105 "pl_gram.y" +#line 1106 "pl_gram.y" { PLpgSQL_diag_item *new; @@ -3012,11 +3013,11 @@ yyreduce: (yyval.diagitem) = new; } -#line 3016 "pl_gram.c" +#line 3017 "pl_gram.c" break; case 96: /* getdiag_item: %empty */ -#line 1117 "pl_gram.y" +#line 1118 "pl_gram.y" { int tok = yylex(); @@ -3059,11 +3060,11 @@ yyreduce: else yyerror("unrecognized GET DIAGNOSTICS item"); } -#line 3063 "pl_gram.c" +#line 3064 "pl_gram.c" break; case 97: /* getdiag_target: T_DATUM */ -#line 1162 "pl_gram.y" +#line 1163 "pl_gram.y" { /* * In principle we should support a getdiag_target @@ -3081,29 +3082,29 @@ yyreduce: check_assignable((yyvsp[0].wdatum).datum, (yylsp[0])); (yyval.datum) = (yyvsp[0].wdatum).datum; } -#line 3085 "pl_gram.c" +#line 3086 "pl_gram.c" break; case 98: /* getdiag_target: T_WORD */ -#line 1180 "pl_gram.y" +#line 1181 "pl_gram.y" { /* just to give a better message than "syntax error" */ word_is_not_variable(&((yyvsp[0].word)), (yylsp[0])); } -#line 3094 "pl_gram.c" +#line 3095 "pl_gram.c" break; case 99: /* getdiag_target: T_CWORD */ -#line 1185 "pl_gram.y" +#line 1186 "pl_gram.y" { /* just to give a better message than "syntax error" */ cword_is_not_variable(&((yyvsp[0].cword)), (yylsp[0])); } -#line 3103 "pl_gram.c" +#line 3104 "pl_gram.c" break; case 100: /* stmt_if: K_IF expr_until_then proc_sect stmt_elsifs stmt_else K_END K_IF ';' */ -#line 1192 "pl_gram.y" +#line 1193 "pl_gram.y" { PLpgSQL_stmt_if *new; @@ -3118,19 +3119,19 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 3122 "pl_gram.c" +#line 3123 "pl_gram.c" break; case 101: /* stmt_elsifs: %empty */ -#line 1209 "pl_gram.y" +#line 1210 "pl_gram.y" { (yyval.list) = NIL; } -#line 3130 "pl_gram.c" +#line 3131 "pl_gram.c" break; case 102: /* stmt_elsifs: stmt_elsifs K_ELSIF expr_until_then proc_sect */ -#line 1213 "pl_gram.y" +#line 1214 "pl_gram.y" { PLpgSQL_if_elsif *new; @@ -3141,35 +3142,35 @@ yyreduce: (yyval.list) = lappend((yyvsp[-3].list), new); } -#line 3145 "pl_gram.c" +#line 3146 "pl_gram.c" break; case 103: /* stmt_else: %empty */ -#line 1226 "pl_gram.y" +#line 1227 "pl_gram.y" { (yyval.list) = NIL; } -#line 3153 "pl_gram.c" +#line 3154 "pl_gram.c" break; case 104: /* stmt_else: K_ELSE proc_sect */ -#line 1230 "pl_gram.y" +#line 1231 "pl_gram.y" { (yyval.list) = (yyvsp[0].list); } -#line 3161 "pl_gram.c" +#line 3162 "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 1236 "pl_gram.y" +#line 1237 "pl_gram.y" { (yyval.stmt) = make_case((yylsp[-6]), (yyvsp[-5].expr), (yyvsp[-4].list), (yyvsp[-3].list)); } -#line 3169 "pl_gram.c" +#line 3170 "pl_gram.c" break; case 106: /* opt_expr_until_when: %empty */ -#line 1242 "pl_gram.y" +#line 1243 "pl_gram.y" { PLpgSQL_expr *expr = NULL; int tok = yylex(); @@ -3182,27 +3183,27 @@ yyreduce: plpgsql_push_back_token(K_WHEN); (yyval.expr) = expr; } -#line 3186 "pl_gram.c" +#line 3187 "pl_gram.c" break; case 107: /* case_when_list: case_when_list case_when */ -#line 1257 "pl_gram.y" +#line 1258 "pl_gram.y" { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].casewhen)); } -#line 3194 "pl_gram.c" +#line 3195 "pl_gram.c" break; case 108: /* case_when_list: case_when */ -#line 1261 "pl_gram.y" +#line 1262 "pl_gram.y" { (yyval.list) = list_make1((yyvsp[0].casewhen)); } -#line 3202 "pl_gram.c" +#line 3203 "pl_gram.c" break; case 109: /* case_when: K_WHEN expr_until_then proc_sect */ -#line 1267 "pl_gram.y" +#line 1268 "pl_gram.y" { PLpgSQL_case_when *new = palloc(sizeof(PLpgSQL_case_when)); @@ -3211,19 +3212,19 @@ yyreduce: new->stmts = (yyvsp[0].list); (yyval.casewhen) = new; } -#line 3215 "pl_gram.c" +#line 3216 "pl_gram.c" break; case 110: /* opt_case_else: %empty */ -#line 1278 "pl_gram.y" +#line 1279 "pl_gram.y" { (yyval.list) = NIL; } -#line 3223 "pl_gram.c" +#line 3224 "pl_gram.c" break; case 111: /* opt_case_else: K_ELSE proc_sect */ -#line 1282 "pl_gram.y" +#line 1283 "pl_gram.y" { /* * proc_sect could return an empty list, but we @@ -3236,11 +3237,11 @@ yyreduce: else (yyval.list) = list_make1(NULL); } -#line 3240 "pl_gram.c" +#line 3241 "pl_gram.c" break; case 112: /* stmt_loop: opt_loop_label K_LOOP loop_body */ -#line 1297 "pl_gram.y" +#line 1298 "pl_gram.y" { PLpgSQL_stmt_loop *new; @@ -3256,11 +3257,11 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 3260 "pl_gram.c" +#line 3261 "pl_gram.c" break; case 113: /* stmt_while: opt_loop_label K_WHILE expr_until_loop loop_body */ -#line 1315 "pl_gram.y" +#line 1316 "pl_gram.y" { PLpgSQL_stmt_while *new; @@ -3277,11 +3278,11 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 3281 "pl_gram.c" +#line 3282 "pl_gram.c" break; case 114: /* stmt_for: opt_loop_label K_FOR for_control loop_body */ -#line 1334 "pl_gram.y" +#line 1335 "pl_gram.y" { /* This runs after we've scanned the loop body */ if ((yyvsp[-1].stmt)->cmd_type == PLPGSQL_STMT_FORI) @@ -3313,11 +3314,11 @@ yyreduce: /* close namespace started in opt_loop_label */ plpgsql_ns_pop(); } -#line 3317 "pl_gram.c" +#line 3318 "pl_gram.c" break; case 115: /* for_control: for_variable K_IN */ -#line 1368 "pl_gram.y" +#line 1369 "pl_gram.y" { int tok = yylex(); int tokloc = yylloc; @@ -3556,11 +3557,11 @@ yyreduce: } } } -#line 3560 "pl_gram.c" +#line 3561 "pl_gram.c" break; case 116: /* for_variable: T_DATUM */ -#line 1627 "pl_gram.y" +#line 1628 "pl_gram.y" { (yyval.forvariable).name = NameOfDatum(&((yyvsp[0].wdatum))); (yyval.forvariable).lineno = plpgsql_location_to_lineno((yylsp[0])); @@ -3586,11 +3587,11 @@ yyreduce: (yylsp[0])); } } -#line 3590 "pl_gram.c" +#line 3591 "pl_gram.c" break; case 117: /* for_variable: T_WORD */ -#line 1653 "pl_gram.y" +#line 1654 "pl_gram.y" { int tok; @@ -3604,20 +3605,20 @@ yyreduce: if (tok == ',') word_is_not_variable(&((yyvsp[0].word)), (yylsp[0])); } -#line 3608 "pl_gram.c" +#line 3609 "pl_gram.c" break; case 118: /* for_variable: T_CWORD */ -#line 1667 "pl_gram.y" +#line 1668 "pl_gram.y" { /* just to give a better message than "syntax error" */ cword_is_not_variable(&((yyvsp[0].cword)), (yylsp[0])); } -#line 3617 "pl_gram.c" +#line 3618 "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 1674 "pl_gram.y" +#line 1675 "pl_gram.y" { PLpgSQL_stmt_foreach_a *new; @@ -3653,27 +3654,27 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 3657 "pl_gram.c" +#line 3658 "pl_gram.c" break; case 120: /* foreach_slice: %empty */ -#line 1712 "pl_gram.y" +#line 1713 "pl_gram.y" { (yyval.ival) = 0; } -#line 3665 "pl_gram.c" +#line 3666 "pl_gram.c" break; case 121: /* foreach_slice: K_SLICE ICONST */ -#line 1716 "pl_gram.y" +#line 1717 "pl_gram.y" { (yyval.ival) = (yyvsp[0].ival); } -#line 3673 "pl_gram.c" +#line 3674 "pl_gram.c" break; case 122: /* stmt_exit: exit_type opt_label opt_exitcond */ -#line 1722 "pl_gram.y" +#line 1723 "pl_gram.y" { PLpgSQL_stmt_exit *new; @@ -3724,27 +3725,27 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 3728 "pl_gram.c" +#line 3729 "pl_gram.c" break; case 123: /* exit_type: K_EXIT */ -#line 1775 "pl_gram.y" +#line 1776 "pl_gram.y" { (yyval.boolean) = true; } -#line 3736 "pl_gram.c" +#line 3737 "pl_gram.c" break; case 124: /* exit_type: K_CONTINUE */ -#line 1779 "pl_gram.y" +#line 1780 "pl_gram.y" { (yyval.boolean) = false; } -#line 3744 "pl_gram.c" +#line 3745 "pl_gram.c" break; case 125: /* stmt_return: K_RETURN */ -#line 1785 "pl_gram.y" +#line 1786 "pl_gram.y" { int tok; @@ -3768,11 +3769,11 @@ yyreduce: (yyval.stmt) = make_return_stmt((yylsp[0])); } } -#line 3772 "pl_gram.c" +#line 3773 "pl_gram.c" break; case 126: /* stmt_raise: K_RAISE */ -#line 1811 "pl_gram.y" +#line 1812 "pl_gram.y" { PLpgSQL_stmt_raise *new; int tok; @@ -3915,11 +3916,11 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 3919 "pl_gram.c" +#line 3920 "pl_gram.c" break; case 127: /* stmt_assert: K_ASSERT */ -#line 1956 "pl_gram.y" +#line 1957 "pl_gram.y" { PLpgSQL_stmt_assert *new; int tok; @@ -3941,45 +3942,45 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 3945 "pl_gram.c" +#line 3946 "pl_gram.c" break; case 128: /* loop_body: proc_sect K_END K_LOOP opt_label ';' */ -#line 1980 "pl_gram.y" +#line 1981 "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 3955 "pl_gram.c" +#line 3956 "pl_gram.c" break; case 129: /* stmt_execsql: K_IMPORT */ -#line 1998 "pl_gram.y" +#line 1999 "pl_gram.y" { - (yyval.stmt) = make_execsql_stmt(K_IMPORT, (yylsp[0])); + (yyval.stmt) = make_execsql_stmt(K_IMPORT, (yylsp[0]), NULL); } -#line 3963 "pl_gram.c" +#line 3964 "pl_gram.c" break; case 130: /* stmt_execsql: K_INSERT */ -#line 2002 "pl_gram.y" +#line 2003 "pl_gram.y" { - (yyval.stmt) = make_execsql_stmt(K_INSERT, (yylsp[0])); + (yyval.stmt) = make_execsql_stmt(K_INSERT, (yylsp[0]), NULL); } -#line 3971 "pl_gram.c" +#line 3972 "pl_gram.c" break; case 131: /* stmt_execsql: K_MERGE */ -#line 2006 "pl_gram.y" +#line 2007 "pl_gram.y" { - (yyval.stmt) = make_execsql_stmt(K_MERGE, (yylsp[0])); + (yyval.stmt) = make_execsql_stmt(K_MERGE, (yylsp[0]), NULL); } -#line 3979 "pl_gram.c" +#line 3980 "pl_gram.c" break; case 132: /* stmt_execsql: T_WORD */ -#line 2010 "pl_gram.y" +#line 2011 "pl_gram.y" { int tok; @@ -3988,13 +3989,13 @@ yyreduce: if (tok == '=' || tok == COLON_EQUALS || tok == '[' || tok == '.') word_is_not_variable(&((yyvsp[0].word)), (yylsp[0])); - (yyval.stmt) = make_execsql_stmt(T_WORD, (yylsp[0])); + (yyval.stmt) = make_execsql_stmt(T_WORD, (yylsp[0]), &((yyvsp[0].word))); } -#line 3994 "pl_gram.c" +#line 3995 "pl_gram.c" break; case 133: /* stmt_execsql: T_CWORD */ -#line 2021 "pl_gram.y" +#line 2022 "pl_gram.y" { int tok; @@ -4003,13 +4004,13 @@ yyreduce: if (tok == '=' || tok == COLON_EQUALS || tok == '[' || tok == '.') cword_is_not_variable(&((yyvsp[0].cword)), (yylsp[0])); - (yyval.stmt) = make_execsql_stmt(T_CWORD, (yylsp[0])); + (yyval.stmt) = make_execsql_stmt(T_CWORD, (yylsp[0]), NULL); } -#line 4009 "pl_gram.c" +#line 4010 "pl_gram.c" break; case 134: /* stmt_dynexecute: K_EXECUTE */ -#line 2034 "pl_gram.y" +#line 2035 "pl_gram.y" { PLpgSQL_stmt_dynexecute *new; PLpgSQL_expr *expr; @@ -4070,11 +4071,11 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 4074 "pl_gram.c" +#line 4075 "pl_gram.c" break; case 135: /* stmt_open: K_OPEN cursor_variable */ -#line 2098 "pl_gram.y" +#line 2099 "pl_gram.y" { PLpgSQL_stmt_open *new; int tok; @@ -4150,11 +4151,11 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 4154 "pl_gram.c" +#line 4155 "pl_gram.c" break; case 136: /* stmt_fetch: K_FETCH opt_fetch_direction cursor_variable K_INTO */ -#line 2176 "pl_gram.y" +#line 2177 "pl_gram.y" { PLpgSQL_stmt_fetch *fetch = (yyvsp[-2].fetch); PLpgSQL_variable *target; @@ -4182,11 +4183,11 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) fetch; } -#line 4186 "pl_gram.c" +#line 4187 "pl_gram.c" break; case 137: /* stmt_move: K_MOVE opt_fetch_direction cursor_variable ';' */ -#line 2206 "pl_gram.y" +#line 2207 "pl_gram.y" { PLpgSQL_stmt_fetch *fetch = (yyvsp[-2].fetch); @@ -4196,19 +4197,19 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) fetch; } -#line 4200 "pl_gram.c" +#line 4201 "pl_gram.c" break; case 138: /* opt_fetch_direction: %empty */ -#line 2218 "pl_gram.y" +#line 2219 "pl_gram.y" { (yyval.fetch) = read_fetch_direction(); } -#line 4208 "pl_gram.c" +#line 4209 "pl_gram.c" break; case 139: /* stmt_close: K_CLOSE cursor_variable ';' */ -#line 2224 "pl_gram.y" +#line 2225 "pl_gram.y" { PLpgSQL_stmt_close *new; @@ -4220,20 +4221,20 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 4224 "pl_gram.c" +#line 4225 "pl_gram.c" break; case 140: /* stmt_null: K_NULL ';' */ -#line 2238 "pl_gram.y" +#line 2239 "pl_gram.y" { /* We do not bother building a node for NULL */ (yyval.stmt) = NULL; } -#line 4233 "pl_gram.c" +#line 4234 "pl_gram.c" break; case 141: /* stmt_commit: K_COMMIT opt_transaction_chain ';' */ -#line 2245 "pl_gram.y" +#line 2246 "pl_gram.y" { PLpgSQL_stmt_commit *new; @@ -4245,11 +4246,11 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 4249 "pl_gram.c" +#line 4250 "pl_gram.c" break; case 142: /* stmt_rollback: K_ROLLBACK opt_transaction_chain ';' */ -#line 2259 "pl_gram.y" +#line 2260 "pl_gram.y" { PLpgSQL_stmt_rollback *new; @@ -4261,29 +4262,29 @@ yyreduce: (yyval.stmt) = (PLpgSQL_stmt *) new; } -#line 4265 "pl_gram.c" +#line 4266 "pl_gram.c" break; case 143: /* opt_transaction_chain: K_AND K_CHAIN */ -#line 2273 "pl_gram.y" +#line 2274 "pl_gram.y" { (yyval.ival) = true; } -#line 4271 "pl_gram.c" +#line 4272 "pl_gram.c" break; case 144: /* opt_transaction_chain: K_AND K_NO K_CHAIN */ -#line 2274 "pl_gram.y" +#line 2275 "pl_gram.y" { (yyval.ival) = false; } -#line 4277 "pl_gram.c" +#line 4278 "pl_gram.c" break; case 145: /* opt_transaction_chain: %empty */ -#line 2275 "pl_gram.y" +#line 2276 "pl_gram.y" { (yyval.ival) = false; } -#line 4283 "pl_gram.c" +#line 4284 "pl_gram.c" break; case 146: /* cursor_variable: T_DATUM */ -#line 2280 "pl_gram.y" +#line 2281 "pl_gram.y" { /* * In principle we should support a cursor_variable @@ -4305,35 +4306,35 @@ yyreduce: parser_errposition((yylsp[0])))); (yyval.var) = (PLpgSQL_var *) (yyvsp[0].wdatum).datum; } -#line 4309 "pl_gram.c" +#line 4310 "pl_gram.c" break; case 147: /* cursor_variable: T_WORD */ -#line 2302 "pl_gram.y" +#line 2303 "pl_gram.y" { /* just to give a better message than "syntax error" */ word_is_not_variable(&((yyvsp[0].word)), (yylsp[0])); } -#line 4318 "pl_gram.c" +#line 4319 "pl_gram.c" break; case 148: /* cursor_variable: T_CWORD */ -#line 2307 "pl_gram.y" +#line 2308 "pl_gram.y" { /* just to give a better message than "syntax error" */ cword_is_not_variable(&((yyvsp[0].cword)), (yylsp[0])); } -#line 4327 "pl_gram.c" +#line 4328 "pl_gram.c" break; case 149: /* exception_sect: %empty */ -#line 2314 "pl_gram.y" +#line 2315 "pl_gram.y" { (yyval.exception_block) = NULL; } -#line 4333 "pl_gram.c" +#line 4334 "pl_gram.c" break; case 150: /* @2: %empty */ -#line 2316 "pl_gram.y" +#line 2317 "pl_gram.y" { /* * We use a mid-rule action to add these @@ -4366,38 +4367,38 @@ yyreduce: (yyval.exception_block) = new; } -#line 4370 "pl_gram.c" +#line 4371 "pl_gram.c" break; case 151: /* exception_sect: K_EXCEPTION @2 proc_exceptions */ -#line 2349 "pl_gram.y" +#line 2350 "pl_gram.y" { PLpgSQL_exception_block *new = (yyvsp[-1].exception_block); new->exc_list = (yyvsp[0].list); (yyval.exception_block) = new; } -#line 4381 "pl_gram.c" +#line 4382 "pl_gram.c" break; case 152: /* proc_exceptions: proc_exceptions proc_exception */ -#line 2358 "pl_gram.y" +#line 2359 "pl_gram.y" { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].exception)); } -#line 4389 "pl_gram.c" +#line 4390 "pl_gram.c" break; case 153: /* proc_exceptions: proc_exception */ -#line 2362 "pl_gram.y" +#line 2363 "pl_gram.y" { (yyval.list) = list_make1((yyvsp[0].exception)); } -#line 4397 "pl_gram.c" +#line 4398 "pl_gram.c" break; case 154: /* proc_exception: K_WHEN proc_conditions K_THEN proc_sect */ -#line 2368 "pl_gram.y" +#line 2369 "pl_gram.y" { PLpgSQL_exception *new; @@ -4408,11 +4409,11 @@ yyreduce: (yyval.exception) = new; } -#line 4412 "pl_gram.c" +#line 4413 "pl_gram.c" break; case 155: /* proc_conditions: proc_conditions K_OR proc_condition */ -#line 2381 "pl_gram.y" +#line 2382 "pl_gram.y" { PLpgSQL_condition *old; @@ -4421,19 +4422,19 @@ yyreduce: old->next = (yyvsp[0].condition); (yyval.condition) = (yyvsp[-2].condition); } -#line 4425 "pl_gram.c" +#line 4426 "pl_gram.c" break; case 156: /* proc_conditions: proc_condition */ -#line 2390 "pl_gram.y" +#line 2391 "pl_gram.y" { (yyval.condition) = (yyvsp[0].condition); } -#line 4433 "pl_gram.c" +#line 4434 "pl_gram.c" break; case 157: /* proc_condition: any_identifier */ -#line 2396 "pl_gram.y" +#line 2397 "pl_gram.y" { if (strcmp((yyvsp[0].str), "sqlstate") != 0) { @@ -4467,120 +4468,120 @@ yyreduce: (yyval.condition) = new; } } -#line 4471 "pl_gram.c" +#line 4472 "pl_gram.c" break; case 158: /* expr_until_semi: %empty */ -#line 2432 "pl_gram.y" +#line 2433 "pl_gram.y" { (yyval.expr) = read_sql_expression(';', ";"); } -#line 4477 "pl_gram.c" +#line 4478 "pl_gram.c" break; case 159: /* expr_until_then: %empty */ -#line 2436 "pl_gram.y" +#line 2437 "pl_gram.y" { (yyval.expr) = read_sql_expression(K_THEN, "THEN"); } -#line 4483 "pl_gram.c" +#line 4484 "pl_gram.c" break; case 160: /* expr_until_loop: %empty */ -#line 2440 "pl_gram.y" +#line 2441 "pl_gram.y" { (yyval.expr) = read_sql_expression(K_LOOP, "LOOP"); } -#line 4489 "pl_gram.c" +#line 4490 "pl_gram.c" break; case 161: /* opt_block_label: %empty */ -#line 2444 "pl_gram.y" +#line 2445 "pl_gram.y" { plpgsql_ns_push(NULL, PLPGSQL_LABEL_BLOCK); (yyval.str) = NULL; } -#line 4498 "pl_gram.c" +#line 4499 "pl_gram.c" break; case 162: /* opt_block_label: LESS_LESS any_identifier GREATER_GREATER */ -#line 2449 "pl_gram.y" +#line 2450 "pl_gram.y" { plpgsql_ns_push((yyvsp[-1].str), PLPGSQL_LABEL_BLOCK); (yyval.str) = (yyvsp[-1].str); } -#line 4507 "pl_gram.c" +#line 4508 "pl_gram.c" break; case 163: /* opt_loop_label: %empty */ -#line 2456 "pl_gram.y" +#line 2457 "pl_gram.y" { plpgsql_ns_push(NULL, PLPGSQL_LABEL_LOOP); (yyval.str) = NULL; } -#line 4516 "pl_gram.c" +#line 4517 "pl_gram.c" break; case 164: /* opt_loop_label: LESS_LESS any_identifier GREATER_GREATER */ -#line 2461 "pl_gram.y" +#line 2462 "pl_gram.y" { plpgsql_ns_push((yyvsp[-1].str), PLPGSQL_LABEL_LOOP); (yyval.str) = (yyvsp[-1].str); } -#line 4525 "pl_gram.c" +#line 4526 "pl_gram.c" break; case 165: /* opt_label: %empty */ -#line 2468 "pl_gram.y" +#line 2469 "pl_gram.y" { (yyval.str) = NULL; } -#line 4533 "pl_gram.c" +#line 4534 "pl_gram.c" break; case 166: /* opt_label: any_identifier */ -#line 2472 "pl_gram.y" +#line 2473 "pl_gram.y" { /* label validity will be checked by outer production */ (yyval.str) = (yyvsp[0].str); } -#line 4542 "pl_gram.c" +#line 4543 "pl_gram.c" break; case 167: /* opt_exitcond: ';' */ -#line 2479 "pl_gram.y" +#line 2480 "pl_gram.y" { (yyval.expr) = NULL; } -#line 4548 "pl_gram.c" +#line 4549 "pl_gram.c" break; case 168: /* opt_exitcond: K_WHEN expr_until_semi */ -#line 2481 "pl_gram.y" +#line 2482 "pl_gram.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 4554 "pl_gram.c" +#line 4555 "pl_gram.c" break; case 169: /* any_identifier: T_WORD */ -#line 2488 "pl_gram.y" +#line 2489 "pl_gram.y" { (yyval.str) = (yyvsp[0].word).ident; } -#line 4562 "pl_gram.c" +#line 4563 "pl_gram.c" break; case 170: /* any_identifier: unreserved_keyword */ -#line 2492 "pl_gram.y" +#line 2493 "pl_gram.y" { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 4570 "pl_gram.c" +#line 4571 "pl_gram.c" break; case 171: /* any_identifier: T_DATUM */ -#line 2496 "pl_gram.y" +#line 2497 "pl_gram.y" { if ((yyvsp[0].wdatum).ident == NULL) /* composite name not OK */ yyerror("syntax error"); (yyval.str) = (yyvsp[0].wdatum).ident; } -#line 4580 "pl_gram.c" +#line 4581 "pl_gram.c" break; -#line 4584 "pl_gram.c" +#line 4585 "pl_gram.c" default: break; } @@ -4779,7 +4780,7 @@ yyreturn: return yyresult; } -#line 2587 "pl_gram.y" +#line 2588 "pl_gram.y" /* @@ -5139,8 +5140,13 @@ read_datatype(int tok) return result; } +/* + * Read a generic SQL statement. We have already read its first token; + * firsttoken is that token's code and location its starting location. + * If firsttoken == T_WORD, pass its yylval value as "word", else pass NULL. + */ static PLpgSQL_stmt * -make_execsql_stmt(int firsttoken, int location) +make_execsql_stmt(int firsttoken, int location, PLword *word) { StringInfoData ds; IdentifierLookup save_IdentifierLookup; @@ -5153,9 +5159,16 @@ make_execsql_stmt(int firsttoken, int location) bool have_strict = false; int into_start_loc = -1; int into_end_loc = -1; + int paren_depth = 0; + int begin_depth = 0; + bool in_routine_definition = false; + int token_count = 0; + char tokens[4]; /* records the first few tokens */ initStringInfo(&ds); + memset(tokens, 0, sizeof(tokens)); + /* special lookup mode for identifiers within the SQL text */ save_IdentifierLookup = plpgsql_IdentifierLookup; plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR; @@ -5164,6 +5177,12 @@ make_execsql_stmt(int firsttoken, int location) * Scan to the end of the SQL command. Identify any INTO-variables * clause lurking within it, and parse that via read_into_target(). * + * The end of the statement is defined by a semicolon ... except that + * semicolons within parentheses or BEGIN/END blocks don't terminate a + * statement. We follow psql's lead in not recognizing BEGIN/END except + * after CREATE [OR REPLACE] {FUNCTION|PROCEDURE}. END can also appear + * within a CASE construct, so we treat CASE/END like BEGIN/END. + * * Because INTO is sometimes used in the main SQL grammar, we have to be * careful not to take any such usage of INTO as a PL/pgSQL INTO clause. * There are currently three such cases: @@ -5189,13 +5208,50 @@ make_execsql_stmt(int firsttoken, int location) * break this logic again ... beware! */ tok = firsttoken; + if (tok == T_WORD && strcmp(word->ident, "create") == 0) + tokens[token_count] = 'c'; + token_count++; + for (;;) { prev_tok = tok; tok = yylex(); if (have_into && into_end_loc < 0) into_end_loc = yylloc; /* token after the INTO part */ - if (tok == ';') + /* Detect CREATE [OR REPLACE] {FUNCTION|PROCEDURE} */ + if (tokens[0] == 'c' && token_count < sizeof(tokens)) + { + if (tok == K_OR) + tokens[token_count] = 'o'; + else if (tok == T_WORD && + strcmp(yylval.word.ident, "replace") == 0) + tokens[token_count] = 'r'; + else if (tok == T_WORD && + strcmp(yylval.word.ident, "function") == 0) + tokens[token_count] = 'f'; + else if (tok == T_WORD && + strcmp(yylval.word.ident, "procedure") == 0) + tokens[token_count] = 'f'; /* treat same as "function" */ + if (tokens[1] == 'f' || + (tokens[1] == 'o' && tokens[2] == 'r' && tokens[3] == 'f')) + in_routine_definition = true; + token_count++; + } + /* Track paren nesting (needed for CREATE RULE syntax) */ + if (tok == '(') + paren_depth++; + else if (tok == ')' && paren_depth > 0) + paren_depth--; + /* We need track BEGIN/END nesting only in a routine definition */ + if (in_routine_definition && paren_depth == 0) + { + if (tok == K_BEGIN || tok == K_CASE) + begin_depth++; + else if (tok == K_END && begin_depth > 0) + begin_depth--; + } + /* Command-ending semicolon? */ + if (tok == ';' && paren_depth == 0 && begin_depth == 0) break; if (tok == 0) yyerror("unexpected end of function definition"); diff --git a/src/pl/plpgsql/src/pl_gram.h b/src/pl/plpgsql/src/pl_gram.h index 9fd14bd..e22b1c0 100644 --- a/src/pl/plpgsql/src/pl_gram.h +++ b/src/pl/plpgsql/src/pl_gram.h @@ -189,7 +189,7 @@ extern int plpgsql_yydebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 120 "pl_gram.y" +#line 121 "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 0b8aea9..debbafe 100644 --- a/src/pl/plpgsql/src/pl_gram.y +++ b/src/pl/plpgsql/src/pl_gram.y @@ -79,7 +79,8 @@ static PLpgSQL_expr *read_sql_expression2(int until, int until2, int *endtoken); static PLpgSQL_expr *read_sql_stmt(void); static PLpgSQL_type *read_datatype(int tok); -static PLpgSQL_stmt *make_execsql_stmt(int firsttoken, int location); +static PLpgSQL_stmt *make_execsql_stmt(int firsttoken, int location, + PLword *word); static PLpgSQL_stmt_fetch *read_fetch_direction(void); static void complete_direction(PLpgSQL_stmt_fetch *fetch, bool *check_FROM); @@ -1996,15 +1997,15 @@ loop_body : proc_sect K_END K_LOOP opt_label ';' */ stmt_execsql : K_IMPORT { - $$ = make_execsql_stmt(K_IMPORT, @1); + $$ = make_execsql_stmt(K_IMPORT, @1, NULL); } | K_INSERT { - $$ = make_execsql_stmt(K_INSERT, @1); + $$ = make_execsql_stmt(K_INSERT, @1, NULL); } | K_MERGE { - $$ = make_execsql_stmt(K_MERGE, @1); + $$ = make_execsql_stmt(K_MERGE, @1, NULL); } | T_WORD { @@ -2015,7 +2016,7 @@ stmt_execsql : K_IMPORT if (tok == '=' || tok == COLON_EQUALS || tok == '[' || tok == '.') word_is_not_variable(&($1), @1); - $$ = make_execsql_stmt(T_WORD, @1); + $$ = make_execsql_stmt(T_WORD, @1, &($1)); } | T_CWORD { @@ -2026,7 +2027,7 @@ stmt_execsql : K_IMPORT if (tok == '=' || tok == COLON_EQUALS || tok == '[' || tok == '.') cword_is_not_variable(&($1), @1); - $$ = make_execsql_stmt(T_CWORD, @1); + $$ = make_execsql_stmt(T_CWORD, @1, NULL); } ; @@ -2943,8 +2944,13 @@ read_datatype(int tok) return result; } +/* + * Read a generic SQL statement. We have already read its first token; + * firsttoken is that token's code and location its starting location. + * If firsttoken == T_WORD, pass its yylval value as "word", else pass NULL. + */ static PLpgSQL_stmt * -make_execsql_stmt(int firsttoken, int location) +make_execsql_stmt(int firsttoken, int location, PLword *word) { StringInfoData ds; IdentifierLookup save_IdentifierLookup; @@ -2957,9 +2963,16 @@ make_execsql_stmt(int firsttoken, int location) bool have_strict = false; int into_start_loc = -1; int into_end_loc = -1; + int paren_depth = 0; + int begin_depth = 0; + bool in_routine_definition = false; + int token_count = 0; + char tokens[4]; /* records the first few tokens */ initStringInfo(&ds); + memset(tokens, 0, sizeof(tokens)); + /* special lookup mode for identifiers within the SQL text */ save_IdentifierLookup = plpgsql_IdentifierLookup; plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR; @@ -2968,6 +2981,12 @@ make_execsql_stmt(int firsttoken, int location) * Scan to the end of the SQL command. Identify any INTO-variables * clause lurking within it, and parse that via read_into_target(). * + * The end of the statement is defined by a semicolon ... except that + * semicolons within parentheses or BEGIN/END blocks don't terminate a + * statement. We follow psql's lead in not recognizing BEGIN/END except + * after CREATE [OR REPLACE] {FUNCTION|PROCEDURE}. END can also appear + * within a CASE construct, so we treat CASE/END like BEGIN/END. + * * Because INTO is sometimes used in the main SQL grammar, we have to be * careful not to take any such usage of INTO as a PL/pgSQL INTO clause. * There are currently three such cases: @@ -2993,13 +3012,50 @@ make_execsql_stmt(int firsttoken, int location) * break this logic again ... beware! */ tok = firsttoken; + if (tok == T_WORD && strcmp(word->ident, "create") == 0) + tokens[token_count] = 'c'; + token_count++; + for (;;) { prev_tok = tok; tok = yylex(); if (have_into && into_end_loc < 0) into_end_loc = yylloc; /* token after the INTO part */ - if (tok == ';') + /* Detect CREATE [OR REPLACE] {FUNCTION|PROCEDURE} */ + if (tokens[0] == 'c' && token_count < sizeof(tokens)) + { + if (tok == K_OR) + tokens[token_count] = 'o'; + else if (tok == T_WORD && + strcmp(yylval.word.ident, "replace") == 0) + tokens[token_count] = 'r'; + else if (tok == T_WORD && + strcmp(yylval.word.ident, "function") == 0) + tokens[token_count] = 'f'; + else if (tok == T_WORD && + strcmp(yylval.word.ident, "procedure") == 0) + tokens[token_count] = 'f'; /* treat same as "function" */ + if (tokens[1] == 'f' || + (tokens[1] == 'o' && tokens[2] == 'r' && tokens[3] == 'f')) + in_routine_definition = true; + token_count++; + } + /* Track paren nesting (needed for CREATE RULE syntax) */ + if (tok == '(') + paren_depth++; + else if (tok == ')' && paren_depth > 0) + paren_depth--; + /* We need track BEGIN/END nesting only in a routine definition */ + if (in_routine_definition && paren_depth == 0) + { + if (tok == K_BEGIN || tok == K_CASE) + begin_depth++; + else if (tok == K_END && begin_depth > 0) + begin_depth--; + } + /* Command-ending semicolon? */ + if (tok == ';' && paren_depth == 0 && begin_depth == 0) break; if (tok == 0) yyerror("unexpected end of function definition"); diff --git a/src/pl/plpgsql/src/po/ru.po b/src/pl/plpgsql/src/po/ru.po index 5c93496..a1a17a0 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: 2023-05-03 05:56+0300\n" +"POT-Creation-Date: 2024-02-02 18:11+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:3331 pl_gram.y:3319 +#: pl_exec.c:3331 pl_gram.y:3375 #, 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:3551 pl_gram.y:3383 +#: pl_exec.c:3551 pl_gram.y:3439 #, 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:8319 pl_gram.y:3442 +#: pl_exec.c:8319 pl_gram.y:3498 #, 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:487 +#: pl_gram.y:488 #, c-format msgid "block label must be placed before DECLARE, not after" msgstr "метка блока должна помещаться до DECLARE, а не после" -#: pl_gram.y:507 +#: pl_gram.y:508 #, c-format msgid "collations are not supported by type %s" msgstr "тип %s не поддерживает сортировку (COLLATION)" -#: pl_gram.y:526 +#: pl_gram.y:527 #, c-format msgid "variable \"%s\" must have a default value, since it's declared NOT NULL" msgstr "" "у переменной \"%s\" должно быть значение по умолчанию, так как она объявлена " "как NOT NULL" -#: pl_gram.y:674 pl_gram.y:689 pl_gram.y:715 +#: pl_gram.y:675 pl_gram.y:690 pl_gram.y:716 #, c-format msgid "variable \"%s\" does not exist" msgstr "переменная \"%s\" не существует" -#: pl_gram.y:733 pl_gram.y:761 +#: pl_gram.y:734 pl_gram.y:762 msgid "duplicate declaration" msgstr "повторяющееся объявление" -#: pl_gram.y:744 pl_gram.y:772 +#: pl_gram.y:745 pl_gram.y:773 #, c-format msgid "variable \"%s\" shadows a previously defined variable" msgstr "переменная \"%s\" скрывает ранее определённую переменную" -#: pl_gram.y:1044 +#: pl_gram.y:1045 #, c-format msgid "diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS" msgstr "команда GET STACKED DIAGNOSTICS не принимает элемент %s" -#: pl_gram.y:1062 +#: pl_gram.y:1063 #, c-format msgid "diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS" msgstr "команда GET CURRENT DIAGNOSTICS не принимает элемент %s" -#: pl_gram.y:1157 +#: pl_gram.y:1158 msgid "unrecognized GET DIAGNOSTICS item" msgstr "нераспознанный элемент GET DIAGNOSTICS" -#: pl_gram.y:1173 pl_gram.y:3558 +#: pl_gram.y:1174 pl_gram.y:3614 #, c-format msgid "\"%s\" is not a scalar variable" msgstr "\"%s\" - не скалярная переменная" -#: pl_gram.y:1403 pl_gram.y:1597 +#: pl_gram.y:1404 pl_gram.y:1598 #, 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:1438 +#: pl_gram.y:1439 #, c-format msgid "cursor FOR loop must have only one target variable" msgstr "в цикле FOR с курсором должна быть только одна переменная" -#: pl_gram.y:1445 +#: pl_gram.y:1446 #, c-format msgid "cursor FOR loop must use a bound cursor variable" msgstr "" "в цикле FOR с курсором должен использоваться курсор, привязанный к запросу" -#: pl_gram.y:1536 +#: pl_gram.y:1537 #, c-format msgid "integer FOR loop must have only one target variable" msgstr "в целочисленном цикле FOR должна быть только одна переменная" -#: pl_gram.y:1570 +#: pl_gram.y:1571 #, c-format msgid "cannot specify REVERSE in query FOR loop" msgstr "в цикле FOR с запросом нельзя указать REVERSE" -#: pl_gram.y:1700 +#: pl_gram.y:1701 #, c-format msgid "loop variable of FOREACH must be a known variable or list of variables" msgstr "" "переменной цикла FOREACH должна быть известная переменная или список " "переменных" -#: pl_gram.y:1742 +#: pl_gram.y:1743 #, c-format msgid "" "there is no label \"%s\" attached to any block or loop enclosing this " "statement" msgstr "в блоке или цикле, окружающем этот оператор, нет метки \"%s\"" -#: pl_gram.y:1750 +#: pl_gram.y:1751 #, c-format msgid "block label \"%s\" cannot be used in CONTINUE" msgstr "метку блока \"%s\" нельзя использовать в CONTINUE" -#: pl_gram.y:1765 +#: pl_gram.y:1766 #, c-format msgid "EXIT cannot be used outside a loop, unless it has a label" msgstr "EXIT можно использовать вне цикла только с указанием метки" -#: pl_gram.y:1766 +#: pl_gram.y:1767 #, c-format msgid "CONTINUE cannot be used outside a loop" msgstr "CONTINUE нельзя использовать вне цикла" -#: pl_gram.y:1790 pl_gram.y:1828 pl_gram.y:1876 pl_gram.y:3005 pl_gram.y:3093 -#: pl_gram.y:3204 pl_gram.y:3957 +#: pl_gram.y:1791 pl_gram.y:1829 pl_gram.y:1877 pl_gram.y:3061 pl_gram.y:3149 +#: pl_gram.y:3260 pl_gram.y:4013 msgid "unexpected end of function definition" msgstr "неожиданный конец определения функции" -#: pl_gram.y:1896 pl_gram.y:1920 pl_gram.y:1936 pl_gram.y:1942 pl_gram.y:2067 -#: pl_gram.y:2075 pl_gram.y:2089 pl_gram.y:2184 pl_gram.y:2408 pl_gram.y:2498 -#: pl_gram.y:2656 pl_gram.y:3800 pl_gram.y:3861 pl_gram.y:3938 +#: pl_gram.y:1897 pl_gram.y:1921 pl_gram.y:1937 pl_gram.y:1943 pl_gram.y:2068 +#: pl_gram.y:2076 pl_gram.y:2090 pl_gram.y:2185 pl_gram.y:2409 pl_gram.y:2499 +#: pl_gram.y:2657 pl_gram.y:3856 pl_gram.y:3917 pl_gram.y:3994 msgid "syntax error" msgstr "ошибка синтаксиса" -#: pl_gram.y:1924 pl_gram.y:1926 pl_gram.y:2412 pl_gram.y:2414 +#: pl_gram.y:1925 pl_gram.y:1927 pl_gram.y:2413 pl_gram.y:2415 msgid "invalid SQLSTATE code" msgstr "неверный код SQLSTATE" -#: pl_gram.y:2132 +#: pl_gram.y:2133 msgid "syntax error, expected \"FOR\"" msgstr "ошибка синтаксиса, ожидался \"FOR\"" -#: pl_gram.y:2193 +#: pl_gram.y:2194 #, c-format msgid "FETCH statement cannot return multiple rows" msgstr "оператор FETCH не может вернуть несколько строк" -#: pl_gram.y:2290 +#: pl_gram.y:2291 #, c-format msgid "cursor variable must be a simple variable" msgstr "переменная-курсор должна быть простой переменной" -#: pl_gram.y:2296 +#: pl_gram.y:2297 #, c-format msgid "variable \"%s\" must be of type cursor or refcursor" msgstr "переменная \"%s\" должна быть типа cursor или refcursor" -#: pl_gram.y:2627 pl_gram.y:2638 +#: pl_gram.y:2628 pl_gram.y:2639 #, c-format msgid "\"%s\" is not a known variable" msgstr "\"%s\" - не известная переменная" -#: pl_gram.y:2744 pl_gram.y:2754 pl_gram.y:2910 +#: pl_gram.y:2745 pl_gram.y:2755 pl_gram.y:2911 msgid "mismatched parentheses" msgstr "непарные скобки" -#: pl_gram.y:2758 +#: pl_gram.y:2759 #, c-format msgid "missing \"%s\" at end of SQL expression" msgstr "отсутствует \"%s\" в конце выражения SQL" -#: pl_gram.y:2764 +#: pl_gram.y:2765 #, c-format msgid "missing \"%s\" at end of SQL statement" msgstr "отсутствует \"%s\" в конце оператора SQL" -#: pl_gram.y:2781 +#: pl_gram.y:2782 msgid "missing expression" msgstr "отсутствует выражение" -#: pl_gram.y:2783 +#: pl_gram.y:2784 msgid "missing SQL statement" msgstr "отсутствует оператор SQL" -#: pl_gram.y:2912 +#: pl_gram.y:2913 msgid "incomplete data type declaration" msgstr "неполное определение типа данных" -#: pl_gram.y:2935 +#: pl_gram.y:2936 msgid "missing data type declaration" msgstr "отсутствует определение типа данных" -#: pl_gram.y:3015 +#: pl_gram.y:3071 msgid "INTO specified more than once" msgstr "INTO указано неоднократно" -#: pl_gram.y:3185 +#: pl_gram.y:3241 msgid "expected FROM or IN" msgstr "ожидалось FROM или IN" -#: pl_gram.y:3246 +#: pl_gram.y:3302 #, c-format msgid "RETURN cannot have a parameter in function returning set" msgstr "в функции, возвращающей множество, RETURN должен быть без параметров" -#: pl_gram.y:3247 +#: pl_gram.y:3303 #, c-format msgid "Use RETURN NEXT or RETURN QUERY." msgstr "Используйте RETURN NEXT или RETURN QUERY." -#: pl_gram.y:3257 +#: pl_gram.y:3313 #, c-format msgid "RETURN cannot have a parameter in a procedure" msgstr "в процедуре RETURN должен быть без параметров" -#: pl_gram.y:3262 +#: pl_gram.y:3318 #, c-format msgid "RETURN cannot have a parameter in function returning void" msgstr "в функции, не возвращающей ничего, RETURN не должен иметь параметров" -#: pl_gram.y:3271 +#: pl_gram.y:3327 #, c-format msgid "RETURN cannot have a parameter in function with OUT parameters" msgstr "RETURN должен быть без параметров в функции с параметрами OUT" -#: pl_gram.y:3334 +#: pl_gram.y:3390 #, c-format msgid "RETURN NEXT cannot have a parameter in function with OUT parameters" msgstr "RETURN NEXT должен быть без параметров в функции с параметрами OUT" -#: pl_gram.y:3500 +#: pl_gram.y:3556 #, c-format msgid "record variable cannot be part of multiple-item INTO list" msgstr "" "переменная типа запись не может быть частью списка INTO с несколькими " "элементами" -#: pl_gram.y:3546 +#: pl_gram.y:3602 #, c-format msgid "too many INTO variables specified" msgstr "указано слишком много переменных INTO" -#: pl_gram.y:3754 +#: pl_gram.y:3810 #, c-format msgid "end label \"%s\" specified for unlabeled block" msgstr "конечная метка \"%s\" указана для непомеченного блока" -#: pl_gram.y:3761 +#: pl_gram.y:3817 #, c-format msgid "end label \"%s\" differs from block's label \"%s\"" msgstr "конечная метка \"%s\" отличается от метки блока \"%s\"" -#: pl_gram.y:3795 +#: pl_gram.y:3851 #, c-format msgid "cursor \"%s\" has no arguments" msgstr "курсор \"%s\" не имеет аргументов" -#: pl_gram.y:3809 +#: pl_gram.y:3865 #, c-format msgid "cursor \"%s\" has arguments" msgstr "курсор \"%s\" имеет аргументы" -#: pl_gram.y:3851 +#: pl_gram.y:3907 #, c-format msgid "cursor \"%s\" has no argument named \"%s\"" msgstr "курсор \"%s\" не имеет аргумента \"%s\"" -#: pl_gram.y:3871 +#: pl_gram.y:3927 #, c-format msgid "value for parameter \"%s\" of cursor \"%s\" specified more than once" msgstr "значение параметра \"%s\" курсора \"%s\" указано неоднократно" -#: pl_gram.y:3896 +#: pl_gram.y:3952 #, c-format msgid "not enough arguments for cursor \"%s\"" msgstr "недостаточно аргументов для курсора \"%s\"" -#: pl_gram.y:3903 +#: pl_gram.y:3959 #, c-format msgid "too many arguments for cursor \"%s\"" msgstr "слишком много аргументов для курсора \"%s\"" -#: pl_gram.y:3989 +#: pl_gram.y:4045 msgid "unrecognized RAISE statement option" msgstr "нераспознанный параметр оператора RAISE" -#: pl_gram.y:3993 +#: pl_gram.y:4049 msgid "syntax error, expected \"=\"" msgstr "ошибка синтаксиса, ожидалось \"=\"" -#: pl_gram.y:4034 +#: pl_gram.y:4090 #, c-format msgid "too many parameters specified for RAISE" msgstr "слишком много параметров для RAISE" -#: pl_gram.y:4038 +#: pl_gram.y:4094 #, c-format msgid "too few parameters specified for RAISE" msgstr "недостаточно параметров для RAISE" diff --git a/src/pl/plpgsql/src/sql/plpgsql_misc.sql b/src/pl/plpgsql/src/sql/plpgsql_misc.sql new file mode 100644 index 0000000..71a8fc2 --- /dev/null +++ b/src/pl/plpgsql/src/sql/plpgsql_misc.sql @@ -0,0 +1,22 @@ +-- +-- Miscellaneous topics +-- + +-- Verify that we can parse new-style CREATE FUNCTION/PROCEDURE +do +$$ + declare procedure int; -- check we still recognize non-keywords as vars + begin + create function test1() returns int + begin atomic + select 2 + 2; + end; + create or replace procedure test2(x int) + begin atomic + select x + 2; + end; + end +$$; + +\sf test1 +\sf test2 diff --git a/src/pl/plpython/Makefile b/src/pl/plpython/Makefile index 6b1865c..bb26426 100644 --- a/src/pl/plpython/Makefile +++ b/src/pl/plpython/Makefile @@ -39,6 +39,7 @@ DATA = $(NAME)u.control $(NAME)u--1.0.sql # header files to install - it's not clear which of these might be needed # so install them all. INCS = plpython.h \ + plpython_system.h \ plpy_cursorobject.h \ plpy_elog.h \ plpy_exec.h \ @@ -120,7 +121,7 @@ install-data: installdirs uninstall-data: rm -f $(addprefix '$(DESTDIR)$(datadir)/extension'/, $(notdir $(DATA))) - rm -f $(addprefix '$(DESTDIR)$(includedir_server)'/, plpython.h plpy_util.h) + rm -f $(addprefix '$(DESTDIR)$(includedir_server)'/, $(INCS)) .PHONY: install-data uninstall-data diff --git a/src/pl/plpython/plpython.h b/src/pl/plpython/plpython.h index 2a0c9bf..c8f12c0 100644 --- a/src/pl/plpython/plpython.h +++ b/src/pl/plpython/plpython.h @@ -22,82 +22,15 @@ #endif /* - * Undefine some things that get (re)defined in the Python headers. They aren't - * used by the PL/Python code, and all PostgreSQL headers should be included - * earlier, so this should be pretty safe. + * Pull in Python headers via a wrapper header, to control the scope of + * the system_header pragma therein. */ -#undef _POSIX_C_SOURCE -#undef _XOPEN_SOURCE - -/* - * Sometimes python carefully scribbles on our *printf macros. - * So we undefine them here and redefine them after it's done its dirty deed. - */ -#undef vsnprintf -#undef snprintf -#undef vsprintf -#undef sprintf -#undef vfprintf -#undef fprintf -#undef vprintf -#undef printf - -#if defined(_MSC_VER) && defined(_DEBUG) -/* Python uses #pragma to bring in a non-default libpython on VC++ if - * _DEBUG is defined */ -#undef _DEBUG -/* Also hide away errcode, since we load Python.h before postgres.h */ -#define errcode __msvc_errcode -#include <Python.h> -#undef errcode -#define _DEBUG -#elif defined (_MSC_VER) -#define errcode __msvc_errcode -#include <Python.h> -#undef errcode -#else -#include <Python.h> -#endif +#include "plpython_system.h" /* define our text domain for translations */ #undef TEXTDOMAIN #define TEXTDOMAIN PG_TEXTDOMAIN("plpython") -/* put back our *printf macros ... this must match src/include/port.h */ -#ifdef vsnprintf -#undef vsnprintf -#endif -#ifdef snprintf -#undef snprintf -#endif -#ifdef vsprintf -#undef vsprintf -#endif -#ifdef sprintf -#undef sprintf -#endif -#ifdef vfprintf -#undef vfprintf -#endif -#ifdef fprintf -#undef fprintf -#endif -#ifdef vprintf -#undef vprintf -#endif -#ifdef printf -#undef printf -#endif - -#define vsnprintf pg_vsnprintf -#define snprintf pg_snprintf -#define vsprintf pg_vsprintf -#define sprintf pg_sprintf -#define vfprintf pg_vfprintf -#define fprintf pg_fprintf -#define vprintf pg_vprintf -#define printf(...) pg_printf(__VA_ARGS__) - /* * Used throughout, so it's easier to just include it everywhere. */ diff --git a/src/pl/plpython/plpython_system.h b/src/pl/plpython/plpython_system.h new file mode 100644 index 0000000..e93583f --- /dev/null +++ b/src/pl/plpython/plpython_system.h @@ -0,0 +1,103 @@ +/*------------------------------------------------------------------------- + * + * plpython_system.h - pull in Python's system header files + * + * We break this out as a separate header file to precisely control + * the scope of the "system_header" pragma. No Postgres-specific + * declarations should be put here. However, we do include some stuff + * that is meant to prevent conflicts between our code and Python. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/pl/plpython/plpython_system.h + * + *------------------------------------------------------------------------- + */ +#ifndef PLPYTHON_SYSTEM_H +#define PLPYTHON_SYSTEM_H + +/* + * Newer versions of the Python headers trigger a lot of warnings with our + * preferred compiler flags (at least -Wdeclaration-after-statement is known + * to be problematic). The system_header pragma hides warnings from within + * the rest of this file, if supported. + */ +#ifdef HAVE_PRAGMA_GCC_SYSTEM_HEADER +#pragma GCC system_header +#endif + +/* + * Undefine some things that get (re)defined in the Python headers. They aren't + * used by the PL/Python code, and all PostgreSQL headers should be included + * earlier, so this should be pretty safe. + */ +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +/* + * Sometimes python carefully scribbles on our *printf macros. + * So we undefine them here and redefine them after it's done its dirty deed. + */ +#undef vsnprintf +#undef snprintf +#undef vsprintf +#undef sprintf +#undef vfprintf +#undef fprintf +#undef vprintf +#undef printf + +#if defined(_MSC_VER) && defined(_DEBUG) +/* Python uses #pragma to bring in a non-default libpython on VC++ if + * _DEBUG is defined */ +#undef _DEBUG +/* Also hide away errcode, since we load Python.h before postgres.h */ +#define errcode __msvc_errcode +#include <Python.h> +#undef errcode +#define _DEBUG +#elif defined (_MSC_VER) +#define errcode __msvc_errcode +#include <Python.h> +#undef errcode +#else +#include <Python.h> +#endif + +/* put back our *printf macros ... this must match src/include/port.h */ +#ifdef vsnprintf +#undef vsnprintf +#endif +#ifdef snprintf +#undef snprintf +#endif +#ifdef vsprintf +#undef vsprintf +#endif +#ifdef sprintf +#undef sprintf +#endif +#ifdef vfprintf +#undef vfprintf +#endif +#ifdef fprintf +#undef fprintf +#endif +#ifdef vprintf +#undef vprintf +#endif +#ifdef printf +#undef printf +#endif + +#define vsnprintf pg_vsnprintf +#define snprintf pg_snprintf +#define vsprintf pg_vsprintf +#define sprintf pg_sprintf +#define vfprintf pg_vfprintf +#define fprintf pg_fprintf +#define vprintf pg_vprintf +#define printf(...) pg_printf(__VA_ARGS__) + +#endif /* PLPYTHON_SYSTEM_H */ |