Inadequate infrastructure for NextValueExpr

Started by Tom Laneover 8 years ago7 messages
#1Tom Lane
tgl@sss.pgh.pa.us

Somebody decided they could add a new primnode type without bothering to
build out very much infrastructure for it. Thus:

regression=# create table foo (f1 int, f2 int generated always as identity);
CREATE TABLE
regression=# insert into foo values(1);
INSERT 0 1
regression=# explain verbose insert into foo values(1);
ERROR: unrecognized node type: 146

because ruleutils.c has never heard of NextValueExpr. The lack of
outfuncs/readfuncs support for it is rather distressing as well.
That doesn't break parallel queries today, because (I think)
you can't get one of these nodes in a parallelizable query, but it
is going to cause problems for debugging. It will also break
(more or less) pg_stat_statements. I also wonder whether costsize.c
oughtn't be charging some estimated execution cost for it.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#2Thomas Munro
thomas.munro@enterprisedb.com
In reply to: Tom Lane (#1)
2 attachment(s)
Re: Inadequate infrastructure for NextValueExpr

On Fri, Jul 14, 2017 at 9:34 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Somebody decided they could add a new primnode type without bothering to
build out very much infrastructure for it. Thus:

regression=# create table foo (f1 int, f2 int generated always as identity);
CREATE TABLE
regression=# insert into foo values(1);
INSERT 0 1
regression=# explain verbose insert into foo values(1);
ERROR: unrecognized node type: 146

because ruleutils.c has never heard of NextValueExpr. The lack of
outfuncs/readfuncs support for it is rather distressing as well.
That doesn't break parallel queries today, because (I think)
you can't get one of these nodes in a parallelizable query, but it
is going to cause problems for debugging. It will also break
(more or less) pg_stat_statements. I also wonder whether costsize.c
oughtn't be charging some estimated execution cost for it.

I wrote a script to cross-check various node handling functions and it told me:

T_NextValueExpr not handled in outfuncs.c
T_ObjectWithArgs not handled in outfuncs.c
T_AccessPriv not handled in outfuncs.c
T_CreateOpClassItem not handled in outfuncs.c
T_FunctionParameter not handled in outfuncs.c
T_InferClause not handled in outfuncs.c
T_OnConflictClause not handled in outfuncs.c
T_RoleSpec not handled in outfuncs.c
T_PartitionCmd not handled in outfuncs.c
T_NamedTuplestoreScan can be produced by outfuncs.c with tagname
NAMEDTUPLESTORESCAN but that tagname is not recognized by readfuncs.c
T_Alias not handled in ruleutils.c
T_RangeVar not handled in ruleutils.c
T_Expr not handled in ruleutils.c
T_CaseWhen not handled in ruleutils.c
T_TargetEntry not handled in ruleutils.c
T_RangeTblRef not handled in ruleutils.c
T_JoinExpr not handled in ruleutils.c
T_FromExpr not handled in ruleutils.c
T_OnConflictExpr not handled in ruleutils.c
T_IntoClause not handled in ruleutils.c
T_NextValueExpr not handled in ruleutils.c

It classifies all node types into categories PLAN NODES, PRIMITIVE
NODES, ... using the per-group comments in nodes.h, and then checks
some rules that I inferred (obviously incorrectly) about which of
those categories should be handled by copy, out, equal, read and
get_rule_expr functions and also checks that readfuncs.c and
outfuncs.c agree on the name string. It needs some work though:
anyone got any ideas on how to improve the categories and rules to
make it right? To use this approach, it would need to be the case
that each checked function exhaustively handles a subset of node tags
that can be described by listing those categories.

That revealed a defect in commit
18ce3a4ab22d2984f8540ab480979c851dae5338 which I think should be
corrected with something like the attached, though I'm not sure if
it's possible to reach it. It would be nice to do something more
mechanised for this type of code...

--
Thomas Munro
http://www.enterprisedb.com

Attachments:

read-namedtuplestorescan.patchapplication/octet-stream; name=read-namedtuplestorescan.patchDownload
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 1380703cbc6..73c82826ed3 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -1876,6 +1876,21 @@ _readCteScan(void)
 }
 
 /*
+ * _readNamedtuplestoreScan
+ */
+static NamedTuplestoreScan *
+_readNamedTuplestoreScan(void)
+{
+	READ_LOCALS(NamedTuplestoreScan);
+
+	ReadCommonScan(&local_node->scan);
+
+	READ_STRING_FIELD(enrname);
+
+	READ_DONE();
+}
+
+/*
  * _readWorkTableScan
  */
 static WorkTableScan *
@@ -2587,6 +2602,8 @@ parseNodeString(void)
 		return_value = _readTableFuncScan();
 	else if (MATCH("CTESCAN", 7))
 		return_value = _readCteScan();
+	else if (MATCH("NAMEDTUPLESTORESCAN", 19))
+		return_value = _readNamedTuplestoreScan();
 	else if (MATCH("WORKTABLESCAN", 13))
 		return_value = _readWorkTableScan();
 	else if (MATCH("FOREIGNSCAN", 11))
check_node_infrastructure.pytext/x-python-script; charset=US-ASCII; name=check_node_infrastructure.pyDownload
#3Robert Haas
robertmhaas@gmail.com
In reply to: Thomas Munro (#2)
Re: Inadequate infrastructure for NextValueExpr

On Thu, Jul 13, 2017 at 9:46 PM, Thomas Munro
<thomas.munro@enterprisedb.com> wrote:

I wrote a script to cross-check various node handling functions and it told me:

T_NextValueExpr not handled in outfuncs.c
T_ObjectWithArgs not handled in outfuncs.c
T_AccessPriv not handled in outfuncs.c
T_CreateOpClassItem not handled in outfuncs.c
T_FunctionParameter not handled in outfuncs.c
T_InferClause not handled in outfuncs.c
T_OnConflictClause not handled in outfuncs.c
T_RoleSpec not handled in outfuncs.c
T_PartitionCmd not handled in outfuncs.c
T_NamedTuplestoreScan can be produced by outfuncs.c with tagname
NAMEDTUPLESTORESCAN but that tagname is not recognized by readfuncs.c
T_Alias not handled in ruleutils.c
T_RangeVar not handled in ruleutils.c
T_Expr not handled in ruleutils.c
T_CaseWhen not handled in ruleutils.c
T_TargetEntry not handled in ruleutils.c
T_RangeTblRef not handled in ruleutils.c
T_JoinExpr not handled in ruleutils.c
T_FromExpr not handled in ruleutils.c
T_OnConflictExpr not handled in ruleutils.c
T_IntoClause not handled in ruleutils.c
T_NextValueExpr not handled in ruleutils.c

That's pretty cool. Per long-standing precedent, anything we use in a
build needs to be in Perl, not Python, but I think it would be great
to fix all of these (or the script) and then add this to our standard
build process. It would be *great* to stop making mistakes like this.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#4Thomas Munro
thomas.munro@enterprisedb.com
In reply to: Robert Haas (#3)
1 attachment(s)
Re: Inadequate infrastructure for NextValueExpr

On Wed, Jul 26, 2017 at 6:35 AM, Robert Haas <robertmhaas@gmail.com> wrote:

That's pretty cool. Per long-standing precedent, anything we use in a
build needs to be in Perl, not Python, but I think it would be great
to fix all of these (or the script) and then add this to our standard
build process. It would be *great* to stop making mistakes like this.

Ok, here is a Perl version. It is literally my first Perl program so
I probably got all those squiggles wrong. Ouput as of today:

$ ./src/tools/check_node_support_code.pl
T_ObjectWithArgs (category PARSE TREE NODES) not handled in outfuncs.c
T_AccessPriv (category PARSE TREE NODES) not handled in outfuncs.c
T_CreateOpClassItem (category PARSE TREE NODES) not handled in outfuncs.c
T_FunctionParameter (category PARSE TREE NODES) not handled in outfuncs.c
T_InferClause (category PARSE TREE NODES) not handled in outfuncs.c
T_OnConflictClause (category PARSE TREE NODES) not handled in outfuncs.c
T_RoleSpec (category PARSE TREE NODES) not handled in outfuncs.c
T_PartitionCmd (category PARSE TREE NODES) not handled in outfuncs.c
T_NamedTuplestoreScan is written by outfuncs.c as NAMEDTUPLESTORESCAN
but that name is not recognized by readfuncs.c
T_Alias (category PRIMITIVE NODES) not handled in equalfuncs.c
T_RangeVar (category PRIMITIVE NODES) not handled in equalfuncs.c
T_Expr (category PRIMITIVE NODES) not handled in equalfuncs.c
T_CaseWhen (category PRIMITIVE NODES) not handled in equalfuncs.c
T_TargetEntry (category PRIMITIVE NODES) not handled in equalfuncs.c
T_RangeTblRef (category PRIMITIVE NODES) not handled in equalfuncs.c
T_JoinExpr (category PRIMITIVE NODES) not handled in equalfuncs.c
T_FromExpr (category PRIMITIVE NODES) not handled in equalfuncs.c
T_OnConflictExpr (category PRIMITIVE NODES) not handled in equalfuncs.c
T_IntoClause (category PRIMITIVE NODES) not handled in equalfuncs.c

--
Thomas Munro
http://www.enterprisedb.com

Attachments:

check-node-support-code-v1.patchapplication/octet-stream; name=check-node-support-code-v1.patchDownload
diff --git a/src/tools/check_node_support_code.pl b/src/tools/check_node_support_code.pl
new file mode 100755
index 00000000000..0b15ad9b042
--- /dev/null
+++ b/src/tools/check_node_support_code.pl
@@ -0,0 +1,182 @@
+#!/usr/bin/env perl
+
+#################################################################
+#
+# Perform some simple checks on on the handling of node types.
+#
+# Execute with the top of the PostgreSQL source tree as current
+# directory.
+#
+# Copyright (c) 2017, PostgreSQL Global Development Group
+#
+#################################################################
+
+use strict;
+use warnings;
+
+sub scan_node_categories {
+  my $path = "src/include/nodes/nodes.h";
+  my $category = "INVALID";
+  my %results = ();
+  open my $file, $path or die "Could not open $path: $!";
+  while (my $line = <$file>) {
+    if ($line =~ /TAGS FOR ([A-Z].*(NODES|STUFF))/) {
+      $category = $1;
+      $results{ $category } = [];
+    } elsif ($line =~ /\W(T_[a-zA-Z0-9_]+)/) {
+      push @{ $results{ $category } }, $1;
+    }
+  }
+  return %results;
+}
+
+sub scan_switch {
+  my ($path, $function) = @_;
+  my @results = [];
+  my $in_function = 0;
+  open my $file, $path or die "Could not open $path: $!";
+  while (my $line = <$file>) {
+    if ($line =~ /^$function\(/) {
+      $in_function = 1;
+    } elsif ($line =~ /^}/) {
+      $in_function = 0;
+    } elsif ($in_function && $line =~ /case (T_.+):/) {
+      push @results, $1;
+    }
+  }
+  return @results;
+}
+
+sub scan_read_tagnames {
+  my $path = "src/backend/nodes/readfuncs.c";
+  my @results = [];
+  open my $file, $path or die "Could not open $path: $!";
+  while (my $line = <$file>) {
+    if ($line =~ /MATCH\(\"([A-Z]+)\", ([0-9]+)/) {
+      push @results, $1;
+      if (length($1) != $2) {
+        print "Unexpected length in readfuncs.c: $line";
+      }
+    }
+  }
+  return @results;
+}
+
+sub scan_out_tagnames {
+  my $path = "src/backend/nodes/outfuncs.c";
+  my %results = ();
+  my $current_tag = "";
+  open my $file, $path or die "Could not open $path: $!";
+  while (my $line = <$file>) {
+    if ($line =~ /_out.*, const ([^ ]+) \*/) {
+      # see makeNode macro definition: typedef Foo must have enum T_Foo
+      $current_tag = "T_" . $1;
+    } elsif ($line =~ /^}/) {
+      $current_tag = "";
+    } elsif ($current_tag ne "" &&
+      $line =~ /WRITE_NODE_TYPE\(\"([A-Z]+)\"\)/) {
+      $results{$current_tag} = $1;
+    }
+  }
+  return %results;
+}
+
+# how are you supposed to write the equivalent of python x is in <list>?
+sub is_in {
+  my ($needle, @haystack) = @_;
+  foreach my $value (@haystack) {
+    if ($needle eq $value) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+my %node_categories = scan_node_categories();
+
+#################################################################
+#
+# Check node categories that must be supported by copy, out.  We'll
+# exclude some special cases that don't fit the usual pattern, trusting
+# that they just work.
+#
+#################################################################
+
+my @copyfuncs = scan_switch("src/backend/nodes/copyfuncs.c", "copyObjectImpl");
+my @outfuncs = scan_switch("src/backend/nodes/outfuncs.c", "outNode");
+my @special_cases = ( "T_List", "T_IntList", "T_OidList", "T_Integer",
+                      "T_Float", "T_String", "T_BitString", "T_Expr",
+                      "T_Null", "T_Value" );
+
+foreach my $category ("PLAN NODES", "PRIMITIVE NODES", "VALUE NODES", "LIST NODES", "PARSE TREE NODES") {
+  foreach my $node (@{ $node_categories{ $category} }) {
+    if (!is_in($node, @special_cases)) {
+      if (!is_in($node, @copyfuncs)) {
+        print "$node (category $category) not handled in copyfuncs.c\n";
+      }
+      if (!is_in($node, @outfuncs)) {
+        print "$node (category $category) not handled in outfuncs.c\n";
+      }
+    }
+  }
+}
+
+#################################################################
+#
+# Check node categories that must be supported by equals.
+#
+#################################################################
+
+my @equalfuncs = scan_switch("src/backend/nodes/equalfuncs.c", "equal");
+
+foreach my $category ("PRIMITIVE NODES", "VALUE NODES", "LIST NODES", "PARSE TREE NODES") {
+  foreach my $node (@{ $node_categories{ $category} }) {
+    if (!is_in($node, @special_cases)) {
+      if (!is_in($node, @equalfuncs)) {
+        print "$node (category $category) not handled in equalfuncs.c\n";
+      }
+    }
+  }
+}
+
+#################################################################
+#
+# Check node categories that must be supported by parseNodeString
+# using the tagname that is output by outfuncs.c
+#
+#################################################################
+
+my @readfuncs_tagnames = scan_read_tagnames();
+my %outfuncs_tagnames = scan_out_tagnames();
+
+foreach my $category ("PLAN NODES", "PRIMITIVE NODES") {
+  foreach my $node (@{ $node_categories{ $category} }) {
+    if (exists($outfuncs_tagnames{ $node }) &&
+        !is_in($outfuncs_tagnames{ $node }, @readfuncs_tagnames)) {
+      print "$node is written by outfuncs.c as $outfuncs_tagnames{ $node } but that name is not recognized by readfuncs.c\n";
+    }
+  }
+}
+
+#################################################################
+#
+# Check node categories that must be supported by ruleutils.c.
+#
+#################################################################
+
+my @get_rule_expr = scan_switch("src/backend/utils/adt/ruleutils.c", "get_rule_expr");
+
+foreach my $category ("PRIMITIVE NODES") {
+  foreach my $node (@{ $node_categories{ $category} }) {
+    if(!is_in($node, @get_rule_expr)) {
+      print "$node (category $category) not handled in equalfuncs.c\n";
+    }
+  }
+}
+
+# TODO: Figure out what checks to run on these switch statements (and more...)
+
+my @exprSetCollation = scan_switch("src/backend/nodes/nodeFuncs.c", "exprSetCollation");
+my @expression_tree_walker = scan_switch("src/backend/nodes/nodeFuncs.c", "expression_tree_walker");
+my @expression_tree_mutator = scan_switch("src/backend/nodes/nodeFuncs.c", "expression_tree_mutator");
+my @raw_expression_tree_walker = scan_switch("src/backend/nodes/nodeFuncs.c", "expression_tree_mutator");
#5Thomas Munro
thomas.munro@enterprisedb.com
In reply to: Thomas Munro (#4)
1 attachment(s)
Re: Inadequate infrastructure for NextValueExpr

On Wed, Jul 26, 2017 at 4:04 PM, Thomas Munro
<thomas.munro@enterprisedb.com> wrote:

On Wed, Jul 26, 2017 at 6:35 AM, Robert Haas <robertmhaas@gmail.com> wrote:

That's pretty cool. Per long-standing precedent, anything we use in a
build needs to be in Perl, not Python, but I think it would be great
to fix all of these (or the script) and then add this to our standard
build process. It would be *great* to stop making mistakes like this.

Ok, here is a Perl version. It is literally my first Perl program so
I probably got all those squiggles wrong. Ouput as of today:

Argh, let me try that again with a copy-and-paste error corrected:

$ ./src/tools/check_node_support_code.pl
T_ObjectWithArgs (category PARSE TREE NODES) not handled in outfuncs.c
T_AccessPriv (category PARSE TREE NODES) not handled in outfuncs.c
T_CreateOpClassItem (category PARSE TREE NODES) not handled in outfuncs.c
T_FunctionParameter (category PARSE TREE NODES) not handled in outfuncs.c
T_InferClause (category PARSE TREE NODES) not handled in outfuncs.c
T_OnConflictClause (category PARSE TREE NODES) not handled in outfuncs.c
T_RoleSpec (category PARSE TREE NODES) not handled in outfuncs.c
T_PartitionCmd (category PARSE TREE NODES) not handled in outfuncs.c
T_NamedTuplestoreScan is written by outfuncs.c as NAMEDTUPLESTORESCAN
but that name is not recognized by readfuncs.c
T_Alias (category PRIMITIVE NODES) not handled in ruleutils.c:get_rule_expr
T_RangeVar (category PRIMITIVE NODES) not handled in ruleutils.c:get_rule_expr
T_Expr (category PRIMITIVE NODES) not handled in ruleutils.c:get_rule_expr
T_CaseWhen (category PRIMITIVE NODES) not handled in ruleutils.c:get_rule_expr
T_TargetEntry (category PRIMITIVE NODES) not handled in
ruleutils.c:get_rule_expr
T_RangeTblRef (category PRIMITIVE NODES) not handled in
ruleutils.c:get_rule_expr
T_JoinExpr (category PRIMITIVE NODES) not handled in ruleutils.c:get_rule_expr
T_FromExpr (category PRIMITIVE NODES) not handled in ruleutils.c:get_rule_expr
T_OnConflictExpr (category PRIMITIVE NODES) not handled in
ruleutils.c:get_rule_expr
T_IntoClause (category PRIMITIVE NODES) not handled in ruleutils.c:get_rule_expr

--
Thomas Munro
http://www.enterprisedb.com

Attachments:

check-node-support-code-v2.patchapplication/octet-stream; name=check-node-support-code-v2.patchDownload
diff --git a/src/tools/check_node_support_code.pl b/src/tools/check_node_support_code.pl
new file mode 100755
index 00000000000..61193154c74
--- /dev/null
+++ b/src/tools/check_node_support_code.pl
@@ -0,0 +1,182 @@
+#!/usr/bin/env perl
+
+#################################################################
+#
+# Perform some simple checks on on the handling of node types.
+#
+# Execute with the top of the PostgreSQL source tree as current
+# directory.
+#
+# Copyright (c) 2017, PostgreSQL Global Development Group
+#
+#################################################################
+
+use strict;
+use warnings;
+
+sub scan_node_categories {
+  my $path = "src/include/nodes/nodes.h";
+  my $category = "INVALID";
+  my %results = ();
+  open my $file, $path or die "Could not open $path: $!";
+  while (my $line = <$file>) {
+    if ($line =~ /TAGS FOR ([A-Z].*(NODES|STUFF))/) {
+      $category = $1;
+      $results{ $category } = [];
+    } elsif ($line =~ /\W(T_[a-zA-Z0-9_]+)/) {
+      push @{ $results{ $category } }, $1;
+    }
+  }
+  return %results;
+}
+
+sub scan_switch {
+  my ($path, $function) = @_;
+  my @results = [];
+  my $in_function = 0;
+  open my $file, $path or die "Could not open $path: $!";
+  while (my $line = <$file>) {
+    if ($line =~ /^$function\(/) {
+      $in_function = 1;
+    } elsif ($line =~ /^}/) {
+      $in_function = 0;
+    } elsif ($in_function && $line =~ /case (T_.+):/) {
+      push @results, $1;
+    }
+  }
+  return @results;
+}
+
+sub scan_read_tagnames {
+  my $path = "src/backend/nodes/readfuncs.c";
+  my @results = [];
+  open my $file, $path or die "Could not open $path: $!";
+  while (my $line = <$file>) {
+    if ($line =~ /MATCH\(\"([A-Z]+)\", ([0-9]+)/) {
+      push @results, $1;
+      if (length($1) != $2) {
+        print "Unexpected length in readfuncs.c: $line";
+      }
+    }
+  }
+  return @results;
+}
+
+sub scan_out_tagnames {
+  my $path = "src/backend/nodes/outfuncs.c";
+  my %results = ();
+  my $current_tag = "";
+  open my $file, $path or die "Could not open $path: $!";
+  while (my $line = <$file>) {
+    if ($line =~ /_out.*, const ([^ ]+) \*/) {
+      # see makeNode macro definition: typedef Foo must have enum T_Foo
+      $current_tag = "T_" . $1;
+    } elsif ($line =~ /^}/) {
+      $current_tag = "";
+    } elsif ($current_tag ne "" &&
+      $line =~ /WRITE_NODE_TYPE\(\"([A-Z]+)\"\)/) {
+      $results{$current_tag} = $1;
+    }
+  }
+  return %results;
+}
+
+# how are you supposed to write the equivalent of python x is in <list>?
+sub is_in {
+  my ($needle, @haystack) = @_;
+  foreach my $value (@haystack) {
+    if ($needle eq $value) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+my %node_categories = scan_node_categories();
+
+#################################################################
+#
+# Check node categories that must be supported by copy, out.  We'll
+# exclude some special cases that don't fit the usual pattern, trusting
+# that they just work.
+#
+#################################################################
+
+my @copyfuncs = scan_switch("src/backend/nodes/copyfuncs.c", "copyObjectImpl");
+my @outfuncs = scan_switch("src/backend/nodes/outfuncs.c", "outNode");
+my @special_cases = ( "T_List", "T_IntList", "T_OidList", "T_Integer",
+                      "T_Float", "T_String", "T_BitString", "T_Expr",
+                      "T_Null", "T_Value" );
+
+foreach my $category ("PLAN NODES", "PRIMITIVE NODES", "VALUE NODES", "LIST NODES", "PARSE TREE NODES") {
+  foreach my $node (@{ $node_categories{ $category} }) {
+    if (!is_in($node, @special_cases)) {
+      if (!is_in($node, @copyfuncs)) {
+        print "$node (category $category) not handled in copyfuncs.c\n";
+      }
+      if (!is_in($node, @outfuncs)) {
+        print "$node (category $category) not handled in outfuncs.c\n";
+      }
+    }
+  }
+}
+
+#################################################################
+#
+# Check node categories that must be supported by equals.
+#
+#################################################################
+
+my @equalfuncs = scan_switch("src/backend/nodes/equalfuncs.c", "equal");
+
+foreach my $category ("PRIMITIVE NODES", "VALUE NODES", "LIST NODES", "PARSE TREE NODES") {
+  foreach my $node (@{ $node_categories{ $category} }) {
+    if (!is_in($node, @special_cases)) {
+      if (!is_in($node, @equalfuncs)) {
+        print "$node (category $category) not handled in equalfuncs.c\n";
+      }
+    }
+  }
+}
+
+#################################################################
+#
+# Check node categories that must be supported by parseNodeString
+# using the tagname that is output by outfuncs.c
+#
+#################################################################
+
+my @readfuncs_tagnames = scan_read_tagnames();
+my %outfuncs_tagnames = scan_out_tagnames();
+
+foreach my $category ("PLAN NODES", "PRIMITIVE NODES") {
+  foreach my $node (@{ $node_categories{ $category} }) {
+    if (exists($outfuncs_tagnames{ $node }) &&
+        !is_in($outfuncs_tagnames{ $node }, @readfuncs_tagnames)) {
+      print "$node is written by outfuncs.c as $outfuncs_tagnames{ $node } but that name is not recognized by readfuncs.c\n";
+    }
+  }
+}
+
+#################################################################
+#
+# Check node categories that must be supported by ruleutils.c.
+#
+#################################################################
+
+my @get_rule_expr = scan_switch("src/backend/utils/adt/ruleutils.c", "get_rule_expr");
+
+foreach my $category ("PRIMITIVE NODES") {
+  foreach my $node (@{ $node_categories{ $category} }) {
+    if(!is_in($node, @get_rule_expr)) {
+      print "$node (category $category) not handled in ruleutils.c:get_rule_expr\n";
+    }
+  }
+}
+
+# TODO: Figure out what checks to run on these switch statements (and more...)
+
+my @exprSetCollation = scan_switch("src/backend/nodes/nodeFuncs.c", "exprSetCollation");
+my @expression_tree_walker = scan_switch("src/backend/nodes/nodeFuncs.c", "expression_tree_walker");
+my @expression_tree_mutator = scan_switch("src/backend/nodes/nodeFuncs.c", "expression_tree_mutator");
+my @raw_expression_tree_walker = scan_switch("src/backend/nodes/nodeFuncs.c", "expression_tree_mutator");
#6Thomas Munro
thomas.munro@enterprisedb.com
In reply to: Thomas Munro (#2)
Re: Inadequate infrastructure for NextValueExpr

On Fri, Jul 14, 2017 at 1:46 PM, Thomas Munro
<thomas.munro@enterprisedb.com> wrote:

[...]
T_NamedTuplestoreScan can be produced by outfuncs.c with tagname
NAMEDTUPLESTORESCAN but that tagname is not recognized by readfuncs.c
[...]

That revealed a defect in commit
18ce3a4ab22d2984f8540ab480979c851dae5338 which I think should be
corrected with something like the attached, though I'm not sure if
it's possible to reach it.

Adding Kevin and Andrew G. Thoughts on whether this is a defect that
should be corrected with something like
read-namedtuplestorescan.patch?

--
Thomas Munro
http://www.enterprisedb.com

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#7Andrew Gierth
andrew@tao11.riddles.org.uk
In reply to: Thomas Munro (#6)
Re: Inadequate infrastructure for NextValueExpr

"Thomas" == Thomas Munro <thomas.munro@enterprisedb.com> writes:

[...]
T_NamedTuplestoreScan can be produced by outfuncs.c with tagname
NAMEDTUPLESTORESCAN but that tagname is not recognized by readfuncs.c
[...]

That revealed a defect in commit
18ce3a4ab22d2984f8540ab480979c851dae5338 which I think should be
corrected with something like the attached, though I'm not sure if
it's possible to reach it.

Thomas> Adding Kevin and Andrew G. Thoughts on whether this is a
Thomas> defect that should be corrected with something like
Thomas> read-namedtuplestorescan.patch?

It's a defect that should probably be corrected for consistency, though
at present it looks like it's not actually possible to reach the code.
The patch looks good to me though I've not tested it.

Kevin, you want to take it? Or shall I deal with it?

--
Andrew (irc:RhodiumToad)

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers