summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2019-02-24 12:51:51 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2019-02-24 12:51:51 -0500
commit53c2bb78db9f9bb47de14d61fc8b2a71cf1052ca (patch)
tree5c04cb654ef7d9dadc65b3cc36df54d4a220d4c5
parentede6b19624d1836635d8bd2c8cdc6a694d8ff678 (diff)
Fix ecpg bugs caused by missing semicolons in the backend grammar.
The Bison documentation clearly states that a semicolon is required after every grammar rule, and our scripts that generate ecpg's grammar from the backend's implicitly assumed this is true. But it turns out that only ancient versions of Bison actually enforce that. There have been a couple of rules without trailing semicolons in gram.y for some time, and as a consequence, ecpg's grammar was faulty and produced wrong output for the affected statements. To fix, add the missing semis, and add some cross-checks to ecpg's scripts so that they'll bleat if we mess this up again. The cases that were broken were: * "SET variable = DEFAULT" (but not "SET variable TO DEFAULT"), as well as allied syntaxes such as ALTER SYSTEM SET ... DEFAULT. These produced syntactically invalid output that the server would reject. * Multiple type names in DROP TYPE/DOMAIN commands. Only the first type name would be listed in the emitted command. Per report from Daisuke Higuchi. Back-patch to all supported versions. Discussion: https://postgr.es/m/1803D792815FC24D871C00D17AE95905DB51CE@g01jpexmbkw24
-rw-r--r--src/backend/parser/gram.y1
-rw-r--r--src/interfaces/ecpg/preproc/check_rules.pl12
-rw-r--r--src/interfaces/ecpg/preproc/parse.pl8
3 files changed, 19 insertions, 2 deletions
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 030285c1fda..b1846e31e37 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -1377,6 +1377,7 @@ generic_set:
n->name = $1;
$$ = n;
}
+ ;
set_rest_more: /* Generic SET syntaxes: */
generic_set {$$ = $1;}
diff --git a/src/interfaces/ecpg/preproc/check_rules.pl b/src/interfaces/ecpg/preproc/check_rules.pl
index e34d7a18607..9fc8d8a4e41 100644
--- a/src/interfaces/ecpg/preproc/check_rules.pl
+++ b/src/interfaces/ecpg/preproc/check_rules.pl
@@ -1,7 +1,7 @@
#!/usr/bin/perl
# src/interfaces/ecpg/preproc/check_rules.pl
-# test parser generater for ecpg
-# call with backend parser as stdin
+# test parser generator for ecpg
+# call with backend grammar as stdin
#
# Copyright (c) 2009-2014, PostgreSQL Global Development Group
#
@@ -47,6 +47,7 @@ my %replace_line = (
my $block = '';
my $yaccmode = 0;
+my $in_rule = 0;
my $brace_indent = 0;
my (@arr, %found);
my $comment = 0;
@@ -131,10 +132,14 @@ while (<GRAM>)
$found{$block} = 1;
$cc++;
$block = '';
+ $in_rule = 0 if $arr[$fieldIndexer] eq ';';
}
elsif (($arr[$fieldIndexer] =~ '[A-Za-z0-9]+:')
|| $arr[ $fieldIndexer + 1 ] eq ':')
{
+ die "unterminated rule at grammar line $.\n"
+ if $in_rule;
+ $in_rule = 1;
$non_term_id = $arr[$fieldIndexer];
$non_term_id =~ tr/://d;
}
@@ -145,6 +150,9 @@ while (<GRAM>)
}
}
+die "unterminated rule at end of grammar\n"
+ if $in_rule;
+
close GRAM;
if ($verbose)
{
diff --git a/src/interfaces/ecpg/preproc/parse.pl b/src/interfaces/ecpg/preproc/parse.pl
index d33ab180d63..d892abeb865 100644
--- a/src/interfaces/ecpg/preproc/parse.pl
+++ b/src/interfaces/ecpg/preproc/parse.pl
@@ -22,6 +22,7 @@ $path = "." unless $path;
my $copymode = 0;
my $brace_indent = 0;
my $yaccmode = 0;
+my $in_rule = 0;
my $header_included = 0;
my $feature_not_supported = 0;
my $tokenmode = 0;
@@ -285,6 +286,7 @@ sub main
@fields = ();
$infield = 0;
$line = '';
+ $in_rule = 0;
next;
}
@@ -362,6 +364,9 @@ sub main
$line = '';
@fields = ();
$infield = 1;
+ die "unterminated rule at grammar line $.\n"
+ if $in_rule;
+ $in_rule = 1;
next;
}
elsif ($copymode)
@@ -412,6 +417,9 @@ sub main
}
}
}
+ die "unterminated rule at end of grammar\n"
+ if $in_rule;
+ return;
}