diff --git a/src/backend/nodes/.gitignore b/src/backend/nodes/.gitignore index 0c14b5697b..91cbd2cf24 100644 --- a/src/backend/nodes/.gitignore +++ b/src/backend/nodes/.gitignore @@ -1,4 +1,5 @@ /node-support-stamp +/nodesizes.h /nodetags.h /*funcs.funcs.c /*funcs.switch.c diff --git a/src/backend/nodes/Makefile b/src/backend/nodes/Makefile index 0a95e683d0..46ce62f828 100644 --- a/src/backend/nodes/Makefile +++ b/src/backend/nodes/Makefile @@ -99,4 +99,4 @@ queryjumblefuncs.o: queryjumblefuncs.c queryjumblefuncs.funcs.c queryjumblefuncs readfuncs.o: readfuncs.c readfuncs.funcs.c readfuncs.switch.c | node-support-stamp maintainer-clean: clean - rm -f node-support-stamp $(addsuffix funcs.funcs.c,copy equal out queryjumble read) $(addsuffix funcs.switch.c,copy equal out queryjumble read) nodetags.h + rm -f node-support-stamp $(addsuffix funcs.funcs.c,copy equal out queryjumble read) $(addsuffix funcs.switch.c,copy equal out queryjumble read) nodesizes.h nodetags.h diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index f2568ff5e6..ccd4cbfa01 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,9 +15,54 @@ #include "postgres.h" +#include "access/amapi.h" +#include "access/tableam.h" +#include "access/tsmapi.h" +#include "commands/event_trigger.h" +#include "commands/trigger.h" +#include "foreign/fdwapi.h" #include "miscadmin.h" +#include "nodes/execnodes.h" +#include "nodes/extensible.h" +#include "nodes/miscnodes.h" +#include "nodes/parsenodes.h" +#include "nodes/pathnodes.h" +#include "nodes/plannodes.h" +#include "nodes/replnodes.h" +#include "nodes/supportnodes.h" +#include "nodes/tidbitmap.h" #include "utils/datum.h" +static const Size flat_node_sizes[] = { + 0, /* T_Invalid */ +#include "nodes/nodesizes.h" +}; + +/* + * copyObjectFlat + * Allocate a new copy of the Node type denoted by 'from' and flat copy the + * contents of it into the newly allocated node and return it. + */ +void * +copyObjectFlat(const void *from) +{ + Size size; + void *retval; + NodeTag tag = nodeTag(from); + + if ((unsigned int) tag >= lengthof(flat_node_sizes)) + { + elog(ERROR, "unrecognized node type: %d", (int) tag); + return NULL; + } + + /* XXX how to handle ExtensibleNodes? Can we just deep copy? */ + size = flat_node_sizes[tag]; + retval = palloc(size); + memcpy(retval, from, size); + + return retval; +} /* * Macros to simplify copying of different kinds of fields. Use these diff --git a/src/backend/nodes/gen_node_support.pl b/src/backend/nodes/gen_node_support.pl index 72c7963578..e9a759c5a0 100644 --- a/src/backend/nodes/gen_node_support.pl +++ b/src/backend/nodes/gen_node_support.pl @@ -2,6 +2,7 @@ #---------------------------------------------------------------------- # # Generate node support files: +# - nodesizes.h # - nodetags.h # - copyfuncs # - equalfuncs @@ -599,6 +600,28 @@ my $header_comment = */ '; +# nodesizes.h + +push @output_files, 'nodesizes.h'; +open my $ns, '>', "$output_path/nodesizes.h$tmpext" + or die "$output_path/nodesizes.h$tmpext: $!"; + +printf $ns $header_comment, 'nodesizes.h'; + +foreach my $n (@node_types) +{ + next if elem $n, @abstract_types; + if (defined $manual_nodetag_number{$n}) + { + print $ns "\tsizeof(T_${n}),\n"; + } + else + { + print $ns "\tsizeof(${n}),\n"; + } +} + +close $ns; # nodetags.h diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 44efb1f4eb..2bfcddbce2 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -5143,7 +5143,15 @@ create_ordered_paths(PlannerInfo *root, input_path->pathkeys, &presorted_keys); if (is_sorted) - sorted_path = input_path; + { + /* + * Perform a flat copy of the already-sorted node so as not to reference an + * existing Path from another RelOptInfo. The add_path() call below may + * pfree this path, which would be problematic when it's still referenced + * by input_rel. + */ + sorted_path = copyObjectFlat(input_path); + } else { /* diff --git a/src/include/Makefile b/src/include/Makefile index 5d213187e2..283ae311b3 100644 --- a/src/include/Makefile +++ b/src/include/Makefile @@ -44,6 +44,7 @@ install: all installdirs $(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir_server)' $(INSTALL_DATA) pg_config_ext.h '$(DESTDIR)$(includedir_server)' $(INSTALL_DATA) pg_config_os.h '$(DESTDIR)$(includedir_server)' + $(INSTALL_DATA) nodes/nodesizes.h '$(DESTDIR)$(includedir_server)/nodes' $(INSTALL_DATA) nodes/nodetags.h '$(DESTDIR)$(includedir_server)/nodes' $(INSTALL_DATA) utils/errcodes.h '$(DESTDIR)$(includedir_server)/utils' $(INSTALL_DATA) utils/fmgroids.h '$(DESTDIR)$(includedir_server)/utils' @@ -75,7 +76,7 @@ clean: rm -f storage/lwlocknames.h utils/probes.h utils/wait_event_types.h rm -f catalog/schemapg.h catalog/system_fk_info.h rm -f catalog/pg_*_d.h catalog/header-stamp - rm -f nodes/nodetags.h nodes/header-stamp + rm -f nodes/nodesizes.h nodes/nodetags.h nodes/header-stamp distclean maintainer-clean: clean rm -f pg_config.h pg_config_ext.h pg_config_os.h stamp-h stamp-ext-h diff --git a/src/include/nodes/meson.build b/src/include/nodes/meson.build index 626dc696d5..cc25d99701 100644 --- a/src/include/nodes/meson.build +++ b/src/include/nodes/meson.build @@ -31,7 +31,7 @@ foreach i : node_support_input_i endforeach node_support_output = [ - 'nodetags.h', + 'nodesizes.h', 'nodetags.h', 'outfuncs.funcs.c', 'outfuncs.switch.c', 'readfuncs.funcs.c', 'readfuncs.switch.c', 'copyfuncs.funcs.c', 'copyfuncs.switch.c', @@ -39,6 +39,7 @@ node_support_output = [ 'queryjumblefuncs.funcs.c', 'queryjumblefuncs.switch.c', ] node_support_install = [ + dir_include_server / 'nodes', dir_include_server / 'nodes', false, false, false, false, diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index f8e8fe699a..a325e15dcd 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -235,6 +235,7 @@ extern int16 *readAttrNumberCols(int numCols); /* * nodes/copyfuncs.c */ +extern void *copyObjectFlat(const void *from); extern void *copyObjectImpl(const void *from); /* cast result back to argument type, if supported by compiler */ diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 1cbc857e35..52b71e5f84 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -847,6 +847,14 @@ EOF close($f); } + if (IsNewer( + 'src/include/nodes/nodesizes.h', + 'src/backend/nodes/nodesizes.h')) + { + copyFile('src/backend/nodes/nodesizes.h', + 'src/include/nodes/nodesizes.h'); + } + if (IsNewer( 'src/include/nodes/nodetags.h', 'src/backend/nodes/nodetags.h')) diff --git a/src/tools/msvc/clean.bat b/src/tools/msvc/clean.bat index 7cb23ea894..f38e0f8dd2 100755 --- a/src/tools/msvc/clean.bat +++ b/src/tools/msvc/clean.bat @@ -41,6 +41,7 @@ REM Delete files created with GenerateFiles() in Solution.pm if exist src\include\pg_config.h del /q src\include\pg_config.h if exist src\include\pg_config_ext.h del /q src\include\pg_config_ext.h if exist src\include\pg_config_os.h del /q src\include\pg_config_os.h +if exist src\include\nodes\nodesizes.h del /q src\include\nodes\nodesizes.h if exist src\include\nodes\nodetags.h del /q src\include\nodes\nodetags.h if exist src\include\utils\errcodes.h del /q src\include\utils\errcodes.h if exist src\include\utils\fmgroids.h del /q src\include\utils\fmgroids.h diff --git a/src/tools/pginclude/cpluspluscheck b/src/tools/pginclude/cpluspluscheck index 4e09c4686b..a5f999c5da 100755 --- a/src/tools/pginclude/cpluspluscheck +++ b/src/tools/pginclude/cpluspluscheck @@ -97,6 +97,10 @@ do # sepgsql.h depends on headers that aren't there on most platforms. test "$f" = contrib/sepgsql/sepgsql.h && continue + # nodesizes.h cannot be included standalone: it's just a code fragment. + test "$f" = src/include/nodes/nodesizes.h && continue + test "$f" = src/backend/nodes/nodesizes.h && continue + # nodetags.h cannot be included standalone: it's just a code fragment. test "$f" = src/include/nodes/nodetags.h && continue test "$f" = src/backend/nodes/nodetags.h && continue diff --git a/src/tools/pginclude/headerscheck b/src/tools/pginclude/headerscheck index 8dee1b5670..18cb54dbb1 100755 --- a/src/tools/pginclude/headerscheck +++ b/src/tools/pginclude/headerscheck @@ -92,6 +92,10 @@ do # sepgsql.h depends on headers that aren't there on most platforms. test "$f" = contrib/sepgsql/sepgsql.h && continue + # nodesizes.h cannot be included standalone: it's just a code fragment. + test "$f" = src/include/nodes/nodesizes.h && continue + test "$f" = src/backend/nodes/nodesizes.h && continue + # nodetags.h cannot be included standalone: it's just a code fragment. test "$f" = src/include/nodes/nodetags.h && continue test "$f" = src/backend/nodes/nodetags.h && continue