[pgpool-hackers: 429] WIP patch for exception and memory manager integration

Muhammad Usama m.usama at gmail.com
Wed Dec 11 03:20:16 JST 2013


Hi

I have been working on adoption of memory and exception managers in pgpool
code and keeping
the track of my work in development branch named EXCEPTION_MGR, And this
patch is basically
the diff of dev branch with current master.

Here is a little background on this front.
==============================
Although some of the below is already shared on pgpool hackers but to give
a little refresher the
plan is to use the PostgreSQL exception manager API (elog and friends) and
integrate it into pgpool.
Since the PG's exception manager uses the long jump to handle exceptions,
so importing that API
in pgpool will effect all existing pgpool code flows especially in case of
an error. and lot of care
will be required for this integration, and secondly the elog API along with
its friends will touch almost
all parts of pgpool source code which will add up to a very huge patch, So
I am keeping the work
in the development repository EXCEPTION_MGR.

Current state of things.
=================

-- Code for both Exception Manager borrowed from PG is added to pgpool, The
API consists
of elog.c and elog.h files. Since this API is very extensive and is
designed for PostgreSQL so
to fit it properly into pgpool I have modified it a little bit, and most of
the modifications are
related to removal of code which is not required for pgpool.

-- Added on_proc_exit callback mechanism of Postgres. To facilitate the
cleanup at exit time.

-- Added PostgreSQL's memory manager (palloc API). This includes the client
side palloc
functions placed in 'src/tools' directory (fe_memutils)

-- Removed the existing memory manager which was very minimalistic and was
not
integrated in all parts of the code.

-- I have also refectored some portions of code to make the code more
readable at first glance.
This includes
*- Splitting of main.c file*: The main.c file is divided into two files
main.c and pgpool_main.c,
Now the main.c file only contains the code related to early initialisations
of pgpool and parsing
the command line options and related code. The actual logic of the pgpool
main process is
moved to new pgpool_main.c file.
*- Splitting of some larger functions*:
*- Rewriting of the pgpool main loop logic:*


What is left on this front.
==================

-- There are still some portions of code that have not yet got these
managers hooked in. and most
of that code belongs to the query parsing functionality.

-- elog.c and elog.h files needs some cleanups and changes ( to remove
unwanted functions and
data members of ErrorData structure) but this will be done at the end when
we will have 100%
surety if something in there is required or not.

Patch summary for review
======================
Attached is the diff of dev repository with the current master, since the
patch is very large mainly
because of new files added from PostgreSQL's code and replacing of
pool_error(), pool_debug() and pool_log()
function calls to ereport(ERROR,..) ereport(DEBUG,..) and ereport(LOG,..),
So it would be little time consuming to review the patch. Although all the
above also needs the thorough
review, as replacing pool_error() with ereport(ERROR) or ereport(FATAL) is
just not a cosmetic
but changes the flow of code, but there are few things, that requires the
more attention, comments, and suggestions.

Process Loops and Memory Contexts
===========================
On same footings as of PostgreSQL, the patch creates TOP MEMORY CONTEXT for
pgpool process,
which remains untouched till the life time of the process. and a per loop
memory context for each process
which gets resets on every loop iteration. Along with these coded also
creates the ERROR CONTEXT
which is used by elog api same as in PostgreSQL.

pgpool parent process loop
====================
pgpool_main.c PgpoolMain()

The patch changes the flow of how health check failures are processed,
health_check() function which
previously used to return health check failing node number or success is
changed to do_health_check(),
which reports an error through ereport in case of failed health check on
backend node and than the failure is
processed by "process_backend_health_check_failure()" function.
This portion of the code requires the most review and suggestions, Since
there are many different
ways to implement this health checking.

Another way could be to use PG_TRY and PG_CATCH inside health_check
function and if
"make_persistent_db_connection()" throws an error, the PG_CATCH block
catches the error
and return the failing node number

something like

health_check()
{
....
for(i =0; i< MAX_BACKEND; i++)
PG_TRY()
{
    make_persistent_db_connection();
...
}
PG_CATCH();
{
....
 return i;
}
PG_END_TRY();
return 0;
}


And than the main loop process the failure, the similar way it it
processing it now (with out the patch).
But the current approach followed by the patch seems to come more natural
with the exception manager
and yet on the negative side the current approach requires to add a state
machine to the main loop.
So suggestions and comments on this portion of code and implementation
approach would be very helpful.

pgpool child process loop
==================
src/protocol/child.c  do_child()

do_child() function is the work horse of pg_pool child process, and
basically contains two loops those
spans the life cycle of child process. First step is to wait for the client
connection, and once this part
is successful, the child is connected with the front end, the process goes
into the query process mode.
So I have used two memory contexts instead of one per loop memory context
for this process.
QueryProcessMemoryContext and ChildLoopMemoryContext, where later is used
for the pahse
where child is waiting for the front end connections and the former is for
the query process phase.

Secondly for the query processing function all my current code browsing
leads me to the believe that
although "pool_process_query()" caller has handled five possible return
values from the function
i.e POOL_END, POOL_ERROR, POOL_FATAL, POOL_IDLE and POOL_CONTINUE.
But in actual the function returns only POOL_END, POOL_ERROR and the
success which is
POOL_CONTINUE. and to squeeze in the managers in query processing function
I have moved forward
with the above mentioned assumptions. Also my current code understanding on
child process flow is when
ever some error occurs in query process phase of child process that error
actually terminates that particular client
So I have added the below code in elog.c file to treat the ERROR in child
process as FATAL in case the
front end clint is connected with the child process.

if(elevel  == ERROR)
{
   if(processType == PT_CHILD)
   {
     /*
      * If the frontend connection exists, treat this error as FATAL
      */
     if(is_session_connected())
        elevel = FATAL;
    }
}

Reviews comments and suggestions are most welcome

Thanks

Muhammad Usama
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.sraoss.jp/pipermail/pgpool-hackers/attachments/20131210/d4af6c5d/attachment-0001.html>
-------------- next part --------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 82e2993..fa32ce6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -5,6 +5,7 @@ bin_PROGRAMS = pgpool
 
 pgpool_SOURCES = main/main.c \
 	main/pool_globals.c \
+	main/pgpool_main.c \
 	config/pool_config.l \
 	pcp_con/pcp_child.c \
 	pcp_con/recovery.c \
@@ -41,7 +42,10 @@ pgpool_SOURCES = main/main.c \
 	utils/pool_process_reporting.c \
 	utils/pool_ssl.c \
 	utils/pool_stream.c \
-	utils/getopt_long.c
+	utils/getopt_long.c \
+	utils/mmgr/mcxt.c \
+	utils/mmgr/aset.c \
+	utils/error/elog.c
 
 DEFS = @DEFS@ \
 	-DDEFAULT_CONFIGDIR=\"$(sysconfdir)\"
diff --git a/src/Makefile.in b/src/Makefile.in
index b8f7fa9..82daea1 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -58,11 +58,12 @@ am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgdatadir)" \
 PROGRAMS = $(bin_PROGRAMS)
 am__dirstamp = $(am__leading_dot)dirstamp
 am_pgpool_OBJECTS = main/main.$(OBJEXT) main/pool_globals.$(OBJEXT) \
-	config/pool_config.$(OBJEXT) pcp_con/pcp_child.$(OBJEXT) \
-	pcp_con/recovery.$(OBJEXT) auth/md5.$(OBJEXT) \
-	auth/pool_auth.$(OBJEXT) auth/pool_passwd.$(OBJEXT) \
-	auth/pool_hba.$(OBJEXT) protocol/pool_proto2.$(OBJEXT) \
-	protocol/child.$(OBJEXT) protocol/pool_process_query.$(OBJEXT) \
+	main/pgpool_main.$(OBJEXT) config/pool_config.$(OBJEXT) \
+	pcp_con/pcp_child.$(OBJEXT) pcp_con/recovery.$(OBJEXT) \
+	auth/md5.$(OBJEXT) auth/pool_auth.$(OBJEXT) \
+	auth/pool_passwd.$(OBJEXT) auth/pool_hba.$(OBJEXT) \
+	protocol/pool_proto2.$(OBJEXT) protocol/child.$(OBJEXT) \
+	protocol/pool_process_query.$(OBJEXT) \
 	protocol/pool_connection_pool.$(OBJEXT) \
 	protocol/pool_proto_modules.$(OBJEXT) \
 	query_cache/pool_memqcache.$(OBJEXT) \
@@ -82,7 +83,8 @@ am_pgpool_OBJECTS = main/main.$(OBJEXT) main/pool_globals.$(OBJEXT) \
 	utils/pool_relcache.$(OBJEXT) \
 	utils/pool_process_reporting.$(OBJEXT) \
 	utils/pool_ssl.$(OBJEXT) utils/pool_stream.$(OBJEXT) \
-	utils/getopt_long.$(OBJEXT)
+	utils/getopt_long.$(OBJEXT) utils/mmgr/mcxt.$(OBJEXT) \
+	utils/mmgr/aset.$(OBJEXT) utils/error/elog.$(OBJEXT)
 pgpool_OBJECTS = $(am_pgpool_OBJECTS)
 pgpool_DEPENDENCIES = parser/libsql-parser.a $(libs_dir)/pcp/libpcp.la \
 	parser/nodes.o watchdog/lib-watchdog.a
@@ -102,9 +104,9 @@ CCLD = $(CC)
 LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
 	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
 	$(LDFLAGS) -o $@
-LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS)
+LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS)
 LTLEXCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-	--mode=compile $(LEX) $(LFLAGS) $(AM_LFLAGS)
+	--mode=compile $(LEX) $(AM_LFLAGS) $(LFLAGS)
 YLWRAP = $(top_srcdir)/ylwrap
 SOURCES = $(pgpool_SOURCES)
 DIST_SOURCES = $(pgpool_SOURCES)
@@ -136,6 +138,12 @@ am__nobase_list = $(am__nobase_strip_setup); \
 am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
 DATA = $(pkgdata_DATA) $(sysconf_DATA)
 RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
   distclean-recursive maintainer-clean-recursive
@@ -303,6 +311,7 @@ libs_dir = $(top_srcdir)/src/libs
 AM_CPPFLAGS = -D_GNU_SOURCE -I @PGSQL_INCLUDE_DIR@
 pgpool_SOURCES = main/main.c \
 	main/pool_globals.c \
+	main/pgpool_main.c \
 	config/pool_config.l \
 	pcp_con/pcp_child.c \
 	pcp_con/recovery.c \
@@ -339,7 +348,10 @@ pgpool_SOURCES = main/main.c \
 	utils/pool_process_reporting.c \
 	utils/pool_ssl.c \
 	utils/pool_stream.c \
-	utils/getopt_long.c
+	utils/getopt_long.c \
+	utils/mmgr/mcxt.c \
+	utils/mmgr/aset.c \
+	utils/error/elog.c
 
 sysconf_DATA = sample/pgpool.conf.sample \
 			   sample/pcp.conf.sample \
@@ -517,6 +529,8 @@ main/main.$(OBJEXT): main/$(am__dirstamp) \
 	main/$(DEPDIR)/$(am__dirstamp)
 main/pool_globals.$(OBJEXT): main/$(am__dirstamp) \
 	main/$(DEPDIR)/$(am__dirstamp)
+main/pgpool_main.$(OBJEXT): main/$(am__dirstamp) \
+	main/$(DEPDIR)/$(am__dirstamp)
 config/$(am__dirstamp):
 	@$(MKDIR_P) config
 	@: > config/$(am__dirstamp)
@@ -660,7 +674,25 @@ utils/pool_stream.$(OBJEXT): utils/$(am__dirstamp) \
 	utils/$(DEPDIR)/$(am__dirstamp)
 utils/getopt_long.$(OBJEXT): utils/$(am__dirstamp) \
 	utils/$(DEPDIR)/$(am__dirstamp)
-pgpool$(EXEEXT): $(pgpool_OBJECTS) $(pgpool_DEPENDENCIES) 
+utils/mmgr/$(am__dirstamp):
+	@$(MKDIR_P) utils/mmgr
+	@: > utils/mmgr/$(am__dirstamp)
+utils/mmgr/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) utils/mmgr/$(DEPDIR)
+	@: > utils/mmgr/$(DEPDIR)/$(am__dirstamp)
+utils/mmgr/mcxt.$(OBJEXT): utils/mmgr/$(am__dirstamp) \
+	utils/mmgr/$(DEPDIR)/$(am__dirstamp)
+utils/mmgr/aset.$(OBJEXT): utils/mmgr/$(am__dirstamp) \
+	utils/mmgr/$(DEPDIR)/$(am__dirstamp)
+utils/error/$(am__dirstamp):
+	@$(MKDIR_P) utils/error
+	@: > utils/error/$(am__dirstamp)
+utils/error/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) utils/error/$(DEPDIR)
+	@: > utils/error/$(DEPDIR)/$(am__dirstamp)
+utils/error/elog.$(OBJEXT): utils/error/$(am__dirstamp) \
+	utils/error/$(DEPDIR)/$(am__dirstamp)
+pgpool$(EXEEXT): $(pgpool_OBJECTS) $(pgpool_DEPENDENCIES) $(EXTRA_pgpool_DEPENDENCIES) 
 	@rm -f pgpool$(EXEEXT)
 	$(pgpool_LINK) $(pgpool_OBJECTS) $(pgpool_LDADD) $(LIBS)
 
@@ -675,6 +707,7 @@ mostlyclean-compile:
 	-rm -f context/pool_query_context.$(OBJEXT)
 	-rm -f context/pool_session_context.$(OBJEXT)
 	-rm -f main/main.$(OBJEXT)
+	-rm -f main/pgpool_main.$(OBJEXT)
 	-rm -f main/pool_globals.$(OBJEXT)
 	-rm -f parallel_query/pool_rewrite_outfuncs.$(OBJEXT)
 	-rm -f parallel_query/pool_rewrite_query.$(OBJEXT)
@@ -690,7 +723,10 @@ mostlyclean-compile:
 	-rm -f rewrite/pool_timestamp.$(OBJEXT)
 	-rm -f streaming_replication/pool_worker_child.$(OBJEXT)
 	-rm -f system_db/pool_system.$(OBJEXT)
+	-rm -f utils/error/elog.$(OBJEXT)
 	-rm -f utils/getopt_long.$(OBJEXT)
+	-rm -f utils/mmgr/aset.$(OBJEXT)
+	-rm -f utils/mmgr/mcxt.$(OBJEXT)
 	-rm -f utils/pool_error.$(OBJEXT)
 	-rm -f utils/pool_ip.$(OBJEXT)
 	-rm -f utils/pool_params.$(OBJEXT)
@@ -718,6 +754,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at context/$(DEPDIR)/pool_query_context.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at context/$(DEPDIR)/pool_session_context.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at main/$(DEPDIR)/main.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at main/$(DEPDIR)/pgpool_main.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at main/$(DEPDIR)/pool_globals.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at parallel_query/$(DEPDIR)/pool_rewrite_outfuncs.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at parallel_query/$(DEPDIR)/pool_rewrite_query.Po at am__quote@
@@ -748,6 +785,9 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at utils/$(DEPDIR)/pool_stream.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at utils/$(DEPDIR)/ps_status.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at utils/$(DEPDIR)/strlcpy.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at utils/error/$(DEPDIR)/elog.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at utils/mmgr/$(DEPDIR)/aset.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at utils/mmgr/$(DEPDIR)/mcxt.Po at am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -798,9 +838,7 @@ uninstall-pkgdataDATA:
 	@$(NORMAL_UNINSTALL)
 	@list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(pkgdatadir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(pkgdatadir)" && rm -f $$files
+	dir='$(DESTDIR)$(pkgdatadir)'; $(am__uninstall_files_from_dir)
 install-sysconfDATA: $(sysconf_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(sysconfdir)" || $(MKDIR_P) "$(DESTDIR)$(sysconfdir)"
@@ -818,9 +856,7 @@ uninstall-sysconfDATA:
 	@$(NORMAL_UNINSTALL)
 	@list='$(sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(sysconfdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(sysconfdir)" && rm -f $$files
+	dir='$(DESTDIR)$(sysconfdir)'; $(am__uninstall_files_from_dir)
 
 # This directory's subdirectories are mostly independent; you can cd
 # into them and run `make' without going through this Makefile.
@@ -1033,10 +1069,15 @@ install-am: all-am
 
 installcheck: installcheck-recursive
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
@@ -1068,6 +1109,10 @@ distclean-generic:
 	-rm -f system_db/$(am__dirstamp)
 	-rm -f utils/$(DEPDIR)/$(am__dirstamp)
 	-rm -f utils/$(am__dirstamp)
+	-rm -f utils/error/$(DEPDIR)/$(am__dirstamp)
+	-rm -f utils/error/$(am__dirstamp)
+	-rm -f utils/mmgr/$(DEPDIR)/$(am__dirstamp)
+	-rm -f utils/mmgr/$(am__dirstamp)
 
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
@@ -1078,7 +1123,7 @@ clean: clean-recursive
 clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-recursive
-	-rm -rf auth/$(DEPDIR) config/$(DEPDIR) context/$(DEPDIR) main/$(DEPDIR) parallel_query/$(DEPDIR) pcp_con/$(DEPDIR) protocol/$(DEPDIR) query_cache/$(DEPDIR) rewrite/$(DEPDIR) streaming_replication/$(DEPDIR) system_db/$(DEPDIR) utils/$(DEPDIR)
+	-rm -rf auth/$(DEPDIR) config/$(DEPDIR) context/$(DEPDIR) main/$(DEPDIR) parallel_query/$(DEPDIR) pcp_con/$(DEPDIR) protocol/$(DEPDIR) query_cache/$(DEPDIR) rewrite/$(DEPDIR) streaming_replication/$(DEPDIR) system_db/$(DEPDIR) utils/$(DEPDIR) utils/error/$(DEPDIR) utils/mmgr/$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-tags
@@ -1124,7 +1169,7 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-recursive
-	-rm -rf auth/$(DEPDIR) config/$(DEPDIR) context/$(DEPDIR) main/$(DEPDIR) parallel_query/$(DEPDIR) pcp_con/$(DEPDIR) protocol/$(DEPDIR) query_cache/$(DEPDIR) rewrite/$(DEPDIR) streaming_replication/$(DEPDIR) system_db/$(DEPDIR) utils/$(DEPDIR)
+	-rm -rf auth/$(DEPDIR) config/$(DEPDIR) context/$(DEPDIR) main/$(DEPDIR) parallel_query/$(DEPDIR) pcp_con/$(DEPDIR) protocol/$(DEPDIR) query_cache/$(DEPDIR) rewrite/$(DEPDIR) streaming_replication/$(DEPDIR) system_db/$(DEPDIR) utils/$(DEPDIR) utils/error/$(DEPDIR) utils/mmgr/$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
diff --git a/src/auth/pool_auth.c b/src/auth/pool_auth.c
index 22e9cbb..9bd9b77 100644
--- a/src/auth/pool_auth.c
+++ b/src/auth/pool_auth.c
@@ -26,7 +26,7 @@
 #include "utils/pool_stream.h"
 #include "pool_config.h"
 #include "auth/pool_passwd.h"
-
+#include "utils/elog.h"
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
@@ -67,14 +67,15 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp)
 	int authkind;
 	int i;
 	StartupPacket *sp;
+	
 
 	protoMajor = MAJOR(cp);
 
 	kind = pool_read_kind(cp);
 	if (kind < 0)
-	{
-		return -1;
-	}
+		ereport(ERROR,
+			(errmsg("invalid authentication packet from backend"),
+				errdetail("failed to get response kind")));
 
 	/* error response? */
 	if (kind == 'E')
@@ -84,27 +85,30 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp)
 		 * a V2 protocol error response in the hope that v3 frontend
 		 * will negotiate again using v2 protocol.
 		 */
-		pool_log("pool_do_auth: maybe protocol version mismatch (current version %d)", protoMajor);
+
 		ErrorResponse(frontend, cp);
-		return -1;
+
+		ereport(ERROR,
+			(errmsg("backend authentication failed"),
+				errdetail("backend response with kind \'E\' when expecting \'R\'"),
+					errhint("This issue can be caused by version mismatch (current version %d)", protoMajor)));
 	}
 	else if (kind != 'R')
-	{
-		pool_error("pool_do_auth: expect \"R\" got %c", kind);
-		return -1;
-	}
+		ereport(ERROR,
+			(errmsg("backend authentication failed"),
+				errdetail("backend response with kind \'%c\' when expecting \'R\'",kind)));
 
 	/*
 	 * message length (v3 only)
 	 */
 	if (protoMajor == PROTO_MAJOR_V3 && pool_read_message_length(cp) < 0)
-	{
-		pool_error("Failed to read the authentication packet length. \
-This is likely caused by the inconsistency of auth method among DB nodes. \
-In this case you can check the previous error messages (hint: length field) \
-from pool_read_message_length and recheck the pg_hba.conf settings.");
-		return -1;
-	}
+		ereport(ERROR,
+			(errmsg("invalid authentication packet from backend"),
+				errdetail("failed to get the authentication packet length"),
+					errhint("This is likely caused by the inconsistency of auth method among DB nodes. \
+							Please check the previous error messages (hint: length field) \
+							from pool_read_message_length and recheck the pg_hba.conf settings.")));
+
 
 	/*
 	 * read authentication request kind.
@@ -124,10 +128,9 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
 
 	authkind = pool_read_int(cp);
 	if (authkind < 0)
-	{
-		pool_error("pool_do_auth: read auth kind failed");
-		return -1;
-	}
+		ereport(ERROR,
+			(errmsg("invalid authentication packet from backend"),
+				errdetail("failed to get auth kind")));
 
 	authkind = ntohl(authkind);
 
@@ -149,7 +152,10 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
 		msglen = htonl(0);
 		if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0)
 		{
-			return -1;
+			ereport(ERROR,
+				(errmsg("failed to authenticate with backend"),
+					errdetail("unable to write to frontend")));
+
 		}
 		MASTER(cp)->auth_kind = 0;
 	}
@@ -170,7 +176,9 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
 			{
 				pool_debug("do_clear_text_password failed in slot %d", i);
 				pool_send_auth_fail(frontend, cp);
-				return -1;
+				ereport(ERROR,
+					(errmsg("failed to authenticate with backend"),
+						errdetail("do_clear_text_password failed in slot %d", i)));
 			}
 		}
 	}
@@ -189,9 +197,10 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
 
 			if (authkind < 0)
 			{
-				pool_debug("do_crypt_text_password failed in slot %d", i);
 				pool_send_auth_fail(frontend, cp);
-				return -1;
+				ereport(ERROR,
+					(errmsg("failed to authenticate with backend"),
+						errdetail("do_crypt_text_password failed in slot %d", i)));
 			}
 		}
 	}
@@ -209,7 +218,10 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
 									"",
 									"check pg_hba.conf",
 									__FILE__, __LINE__);
-			return -1;
+			ereport(ERROR,
+				(errmsg("failed to authenticate with backend"),
+					errdetail("MD5 authentication is not supported in replication, master-slave and parallel modes."),
+						errhint("check pg_hba.conf settings on backend node")));
 		}
 
 		for (i=0;i<NUM_BACKENDS;i++)
@@ -223,24 +235,25 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
 
 			if (authkind < 0)
 			{
-				pool_debug("do_md5failed in slot %d", i);
 				pool_send_auth_fail(frontend, cp);
-				return -1;
+				ereport(ERROR,
+					(errmsg("failed to authenticate with backend"),
+						errdetail("MD5 authentication failed in slot [%d].",i)));
 			}
 		}
 	}
 
 	else
 	{
-		pool_error("pool_do_auth: unsupported auth kind received: %d", authkind);
-		return -1;
+		ereport(ERROR,
+			(errmsg("failed to authenticate with backend"),
+				errdetail("unsupported auth kind received from backend: authkind:%d", authkind)));
 	}
 
 	if (authkind != 0)
-	{
-		pool_error("pool_do_auth: unknown authentication response from backend %d", authkind);
-		return -1;
-	}
+		ereport(ERROR,
+			(errmsg("failed to authenticate with backend"),
+				errdetail("invalid auth kind received from backend: authkind:%d", authkind)));
 
 	/*
 	 * authentication ok. now read pid and secret key from the
@@ -248,13 +261,14 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
 	 */
 	for (;;)
 	{
-		char *message;
-
+		char *message = NULL;
 		kind = pool_read_kind(cp);
+
 		if (kind < 0)
 		{
-			pool_error("pool_do_auth: failed to read kind before BackendKeyData");
-			return -1;
+			ereport(ERROR,
+				(errmsg("authentication failed from backend"),
+					errdetail("failed to read kind before BackendKeyData")));
 		}
 		else if (kind == 'K')
 			break;
@@ -271,31 +285,42 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
 					break;
 
 				case 'N':
-					if (pool_extract_error_message(true, MASTER(cp), protoMajor, true, &message) == 1)
+					if (pool_extract_error_message(false, MASTER(cp), protoMajor, true, &message) == 1)
 					{
-						pool_log("pool_do_auth: notice message from backend:%s", message);
+						ereport(NOTICE,
+							(errmsg("notice from backend"),
+								errdetail("BACKEND NOTICE: \"%s\"",message)));
 					}
 					/* process notice message */
 					if (SimpleForwardToFrontend(kind, frontend, cp))
-						return -1;
+						ereport(ERROR,
+							(errmsg("authentication failed"),
+								errdetail("failed to forward message to frontend")));
 					pool_flush(frontend);
 					break;
 
 					/* process error message */
 				case 'E':
-					if (pool_extract_error_message(true, MASTER(cp), protoMajor, true, &message) == 1)
+
+					if (pool_extract_error_message(false, MASTER(cp), protoMajor, true, &message) == 1)
 					{
 						pool_log("pool_do_auth: error message from backend:%s", message);
 					}
+
 					SimpleForwardToFrontend(kind, frontend, cp);
+
 					pool_flush(frontend);
-					return -1;
+
+					ereport(ERROR,
+						(errmsg("authentication failed, backend node replied with an error"),
+							errdetail("SERVER ERROR:\"%s\"",message?message:"could not extract backend message")));
+
 					break;
 
 				default:
-					pool_error("pool_do_auth: unknown response \"%c\" before processing BackendKeyData",
-							   kind);
-					return -1;
+					ereport(ERROR,
+						(errmsg("authentication failed"),
+							errdetail("unknown response \"%c\" before processing BackendKeyData",kind)));
 					break;
 			}
 		}
@@ -307,19 +332,19 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
 				case 'N':
 					/* process notice message */
 					if (NoticeResponse(frontend, cp) != POOL_CONTINUE)
-						return -1;
+						ereport(ERROR,
+							(errmsg("authentication failed"),
+								errdetail("unable to send Notice response to backend")));
 					break;
 
 					/* process error message */
 				case 'E':
 					ErrorResponse(frontend, cp);
-					return -1;
-					break;
-
+					/* fallthrough*/
 				default:
-					pool_error("pool_do_auth: unknown response \"%c\" before processing V2 BackendKeyData",
-							   kind);
-					return -1;
+					ereport(ERROR,
+						(errmsg("authentication failed"),
+							errdetail("invalid response \"%c\" before processing BackendKeyData",kind)));
 					break;
 			}
 		}
@@ -331,15 +356,15 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
 	if (protoMajor == PROTO_MAJOR_V3)
 	{
 		if (kind != 'K')
-		{
-			pool_error("pool_do_auth: expect \"K\" got %c", kind);
-			return -1;
-		}
+			ereport(ERROR,
+				(errmsg("authentication failed"),
+					errdetail("invalid find \"%c\" when expecting \"K\"",kind)));
 
 		if ((length = pool_read_message_length(cp)) != 12)
 		{
-			pool_error("pool_do_auth: invalid messages length(%d) for BackendKeyData", length);
-			return -1;
+			ereport(ERROR,
+				(errmsg("authentication failed"),
+					errdetail("invalid messages length(%d) for BackendKeyData", length)));
 		}
 	}
 
@@ -356,8 +381,9 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
 			/* read pid */
 			if (pool_read(CONNECTION(cp, i), &pid, sizeof(pid)) < 0)
 			{
-				pool_error("pool_do_auth: failed to read pid in slot %d", i);
-				return -1;
+				ereport(ERROR,
+					(errmsg("authentication failed"),
+						errdetail("failed to read pid in slot %d", i)));
 			}
 
 			pool_debug("pool_do_auth: cp->info[i]:%p pid:%u", &cp->info[i], ntohl(pid));
@@ -367,8 +393,9 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
 			/* read key */
 			if (pool_read(CONNECTION(cp, i), &key, sizeof(key)) < 0)
 			{
-				pool_error("pool_do_auth: failed to read key in slot %d", i);
-				return -1;
+				ereport(ERROR,
+					(errmsg("authentication failed"),
+						errdetail("failed to read key in slot %d", i)));
 			}
 			CONNECTION_SLOT(cp, i)->key = cp->info[i].key = key;
 
@@ -382,11 +409,15 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
 
 	if (pid == -1)
 	{
-		pool_error("pool_do_auth: all backends are down");
-		return -1;
+		ereport(ERROR,
+                (errmsg("authentication failed"),
+                 errdetail("pool_do_auth: all backends are down")));
 	}
-
-	return pool_send_backend_key_data(frontend, pid, key, protoMajor);
+	if(pool_send_backend_key_data(frontend, pid, key, protoMajor))
+		ereport(ERROR,
+			(errmsg("authentication failed"),
+				errdetail("failed to send backend data to frontend")));
+	return 0;
 }
 
 /*
diff --git a/src/auth/pool_hba.c b/src/auth/pool_hba.c
index 6e43d65..dee7254 100644
--- a/src/auth/pool_hba.c
+++ b/src/auth/pool_hba.c
@@ -35,7 +35,8 @@
 #include "utils/pool_ip.h"
 #include "utils/pool_stream.h"
 #include "pool_config.h"
-#include "parser/pool_memory.h"
+#include "pool_type.h"
+#include "utils/palloc.h"
 #include "parser/pg_list.h"
 #include "auth/pool_passwd.h"
 
@@ -46,7 +47,7 @@ static List *hba_lines = NIL;
 static List *hba_line_nums = NIL;
 static char *hbaFileName;
 
-static POOL_MEMORY_POOL *hba_memory_context = NULL;
+//static MemoryContext hba_memory_context;
 
 static void sendAuthRequest(POOL_CONNECTION *frontend, AuthRequest areq);
 static void auth_failed(POOL_CONNECTION *frontend);
@@ -103,18 +104,18 @@ int load_hba(char *hbapath)
 {
 	FILE *file;
 
-	POOL_MEMORY_POOL *old_context;
-	if (hba_memory_context == NULL)
-	{
-		hba_memory_context = pool_memory_create(PARSER_BLOCK_SIZE);
-		if (hba_memory_context == NULL)
-		{
-			pool_error("load_hba: pool_memory_create() failed");
-			return -1;
-		}
-	}
+//	POOL_MEMORY_POOL *old_context;
+//	if (hba_memory_context == NULL)
+//	{
+//		hba_memory_context = pool_memory_create(PARSER_BLOCK_SIZE);
+//		if (hba_memory_context == NULL)
+//		{
+//			pool_error("load_hba: pool_memory_create() failed");
+//			return -1;
+//		}
+//	}
 	/* switch memory context */
-	old_context = pool_memory_context_switch_to(hba_memory_context);
+//	old_context = pool_memory_context_switch_to(hba_memory_context);
 
 	if (hba_lines || hba_line_nums)
 		free_lines(&hba_lines, &hba_line_nums);
@@ -124,14 +125,14 @@ int load_hba(char *hbapath)
 	{
 		pool_error("could not open \"%s\". reason: %s",
 				   hbapath, strerror(errno));
-		pool_memory_delete(hba_memory_context, 0);
-
-		/* switch to old memory context */
-		pool_memory_context_switch_to(old_context);
+//		pool_memory_delete(hba_memory_context, 0);
+//
+//		/* switch to old memory context */
+//		pool_memory_context_switch_to(old_context);
 
 		return -1;
 	}
-
+	
 	pool_debug("loading \"%s\" for client authentication configuration file",
 			   hbapath);
 
@@ -141,7 +142,7 @@ int load_hba(char *hbapath)
 	hbaFileName = pstrdup(hbapath);
 
 	/* switch to old memory context */
-	pool_memory_context_switch_to(old_context);
+//	pool_memory_context_switch_to(old_context);
 
 	return 0;
 }
diff --git a/src/config/pool_config.c b/src/config/pool_config.c
index 0ed97ae..f265ab1 100644
--- a/src/config/pool_config.c
+++ b/src/config/pool_config.c
@@ -46,6 +46,7 @@ typedef int16_t flex_int16_t;
 typedef uint16_t flex_uint16_t;
 typedef int32_t flex_int32_t;
 typedef uint32_t flex_uint32_t;
+typedef uint64_t flex_uint64_t;
 #else
 typedef signed char flex_int8_t;
 typedef short int flex_int16_t;
@@ -152,7 +153,12 @@ typedef unsigned int flex_uint32_t;
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
 #endif
 
-extern int yyleng;
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern yy_size_t yyleng;
 
 extern FILE *yyin, *yyout;
 
@@ -178,11 +184,6 @@ extern FILE *yyin, *yyout;
 
 #define unput(c) yyunput( c, (yytext_ptr)  )
 
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
@@ -200,7 +201,7 @@ struct yy_buffer_state
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 */
-	int yy_n_chars;
+	yy_size_t yy_n_chars;
 
 	/* Whether we "own" the buffer - i.e., we know we created it,
 	 * and can realloc() it to grow it, and should free() it to
@@ -270,8 +271,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
 
 /* yy_hold_char holds the character lost when yytext is formed. */
 static char yy_hold_char;
-static int yy_n_chars;		/* number of characters read into yy_ch_buf */
-int yyleng;
+static yy_size_t yy_n_chars;		/* number of characters read into yy_ch_buf */
+yy_size_t yyleng;
 
 /* Points to current character in buffer. */
 static char *yy_c_buf_p = (char *) 0;
@@ -299,7 +300,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
 
 YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
 YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len  );
 
 void *yyalloc (yy_size_t  );
 void *yyrealloc (void *,yy_size_t  );
@@ -357,7 +358,7 @@ static void yy_fatal_error (yyconst char msg[]  );
  */
 #define YY_DO_BEFORE_ACTION \
 	(yytext_ptr) = yy_bp; \
-	yyleng = (size_t) (yy_cp - yy_bp); \
+	yyleng = (yy_size_t) (yy_cp - yy_bp); \
 	(yy_hold_char) = *yy_cp; \
 	*yy_cp = '\0'; \
 	(yy_c_buf_p) = yy_cp;
@@ -507,9 +508,13 @@ char *yytext;
  *
  */
 #line 27 "pool_config.l"
-
 #include "pool.h"
 #include "pool_config.h"
+#ifndef POOL_PRIVATE
+#include "utils/elog.h"
+#else
+#include "utils/fe_ports.h"
+#endif
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -517,6 +522,15 @@ char *yytext;
 
 #define CHECK_CONTEXT(mask, context) ((mask) & (context))
 
+#ifdef POOL_PRIVATE
+
+/* we do not have elog api for pg_md5 utility*/
+/* include/utils/elog.h */
+#define ereport(elevel, rest) printf("pool_config: error at %s:%d\n", __FILE__, __LINE__)
+#define ereport(elevel, rest) printf("pool_config: error at %s:%d\n", __FILE__, __LINE__)
+
+#endif
+
 /* to shut off compiler warnings */
 int yylex(void);
 
@@ -541,7 +555,7 @@ static char *extract_string(char *value, POOL_TOKEN token);
 static char **extract_string_tokens(char *str, char *delim, int *n);
 static void clear_host_entry(int slot);
 
-#line 545 "config/pool_config.c"
+#line 559 "config/pool_config.c"
 
 #define INITIAL 0
 
@@ -580,7 +594,7 @@ FILE *yyget_out (void );
 
 void yyset_out  (FILE * out_str  );
 
-int yyget_leng (void );
+yy_size_t yyget_leng (void );
 
 char *yyget_text (void );
 
@@ -628,7 +642,7 @@ static int input (void );
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -639,7 +653,7 @@ static int input (void );
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
 		{ \
 		int c = '*'; \
-		unsigned n; \
+		yy_size_t n; \
 		for ( n = 0; n < max_size && \
 			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
 			buf[n] = (char) c; \
@@ -721,10 +735,10 @@ YY_DECL
 	register char *yy_cp, *yy_bp;
 	register int yy_act;
     
-#line 85 "pool_config.l"
+#line 98 "pool_config.l"
 
 
-#line 728 "config/pool_config.c"
+#line 742 "config/pool_config.c"
 
 	if ( !(yy_init) )
 		{
@@ -806,12 +820,12 @@ do_action:	/* This label is used only to access EOF actions. */
 case 1:
 /* rule 1 can match eol */
 YY_RULE_SETUP
-#line 87 "pool_config.l"
+#line 100 "pool_config.l"
 Lineno++; return POOL_EOL;
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 88 "pool_config.l"
+#line 101 "pool_config.l"
 /* eat whitespace */
 	YY_BREAK
 case 3:
@@ -819,50 +833,50 @@ case 3:
 (yy_c_buf_p) = yy_cp -= 1;
 YY_DO_BEFORE_ACTION; /* set up yytext again */
 YY_RULE_SETUP
-#line 89 "pool_config.l"
+#line 102 "pool_config.l"
 /* eat comment */
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 91 "pool_config.l"
+#line 104 "pool_config.l"
 return POOL_KEY;
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 92 "pool_config.l"
+#line 105 "pool_config.l"
 return POOL_STRING;
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 93 "pool_config.l"
+#line 106 "pool_config.l"
 return POOL_UNQUOTED_STRING;
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 94 "pool_config.l"
+#line 107 "pool_config.l"
 return POOL_INTEGER;
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 95 "pool_config.l"
+#line 108 "pool_config.l"
 return POOL_REAL;
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 96 "pool_config.l"
+#line 109 "pool_config.l"
 return POOL_EQUALS;
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 98 "pool_config.l"
+#line 111 "pool_config.l"
 return POOL_PARSE_ERROR;
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 100 "pool_config.l"
+#line 113 "pool_config.l"
 ECHO;
 	YY_BREAK
-#line 866 "config/pool_config.c"
+#line 880 "config/pool_config.c"
 case YY_STATE_EOF(INITIAL):
 	yyterminate();
 
@@ -1049,7 +1063,7 @@ static int yy_get_next_buffer (void)
 
 	else
 		{
-			int num_to_read =
+			yy_size_t num_to_read =
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 
 		while ( num_to_read <= 0 )
@@ -1063,7 +1077,7 @@ static int yy_get_next_buffer (void)
 
 			if ( b->yy_is_our_buffer )
 				{
-				int new_size = b->yy_buf_size * 2;
+				yy_size_t new_size = b->yy_buf_size * 2;
 
 				if ( new_size <= 0 )
 					b->yy_buf_size += b->yy_buf_size / 8;
@@ -1094,7 +1108,7 @@ static int yy_get_next_buffer (void)
 
 		/* Read in more data. */
 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			(yy_n_chars), (size_t) num_to_read );
+			(yy_n_chars), num_to_read );
 
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
 		}
@@ -1216,7 +1230,7 @@ static int yy_get_next_buffer (void)
 
 		else
 			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
+			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
 			++(yy_c_buf_p);
 
 			switch ( yy_get_next_buffer(  ) )
@@ -1240,7 +1254,7 @@ static int yy_get_next_buffer (void)
 				case EOB_ACT_END_OF_FILE:
 					{
 					if ( yywrap( ) )
-						return EOF;
+						return 0;
 
 					if ( ! (yy_did_buffer_switch_on_eof) )
 						YY_NEW_FILE;
@@ -1488,7 +1502,7 @@ void yypop_buffer_state (void)
  */
 static void yyensure_buffer_stack (void)
 {
-	int num_to_alloc;
+	yy_size_t num_to_alloc;
     
 	if (!(yy_buffer_stack)) {
 
@@ -1585,12 +1599,11 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
  * 
  * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len )
 {
 	YY_BUFFER_STATE b;
 	char *buf;
-	yy_size_t n;
-	int i;
+	yy_size_t n, i;
     
 	/* Get memory for full buffer, including space for trailing EOB's. */
 	n = _yybytes_len + 2;
@@ -1672,7 +1685,7 @@ FILE *yyget_out  (void)
 /** Get the length of the current token.
  * 
  */
-int yyget_leng  (void)
+yy_size_t yyget_leng  (void)
 {
         return yyleng;
 }
@@ -1820,7 +1833,7 @@ void yyfree (void * ptr )
 
 #define YYTABLES_NAME "yytables"
 
-#line 100 "pool_config.l"
+#line 113 "pool_config.l"
 
 
 
@@ -2159,15 +2172,30 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context)
 	bool use_memcached = false;
 #endif
 
-#define PARSE_ERROR()		pool_error("pool_config: parse error at line %d '%s'", Lineno, yytext)
+#ifndef POOL_PRIVATE
+#define PARSE_ERROR()		ereport(FATAL, \
+								(errmsg("syntex error in configuration file \"%s\"",POOL_CONF_FILE_NAME), \
+									errdetail("parse error at line %d '%s'", Lineno, yytext)))
+#else
+#define PARSE_ERROR()		fprintf(stderr,"ERROR: syntex error in configuration file \"%s\"",POOL_CONF_FILE_NAME); \
+							fprintf(stderr,"DETAILS: parse error at line %d '%s'", Lineno, yytext)
+#endif
 
 	/* open config file */
 	fd = fopen(confpath, "r");
 	if (!fd)
 	{
-		fprintf(stderr, "pool_config: could not open configuration file (%s)\n",
+#ifndef POOL_PRIVATE
+		ereport(WARNING,
+			(errmsg("could not open configuration file \"%s\"\n",
+				POOL_CONF_FILE_NAME)));
+		ereport(NOTICE,
+			(errmsg("using default configuration parameter values")));
+#else
+		fprintf(stderr,"WARNING: could not open configuration file \"%s\"\n",
 				POOL_CONF_FILE_NAME);
-		fprintf(stderr, "pool_config: using default values...\n");
+		fprintf(stderr,"NOTICE: using default configuration parameter values");
+#endif
 		return 0;
 	}
 
@@ -2199,15 +2227,19 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context)
 
 		strlcpy(key, yytext, sizeof(key));
 
-		pool_debug("key: %s", key);
-
+#ifndef POOL_PRIVATE
+		ereport(DEBUG5,
+			(errmsg("key: %s", key)));
+#endif
 		token = yylex();
 
 		if (token == POOL_EQUALS)
 			token = yylex();
 
-		pool_debug("value: %s kind: %d", yytext, token);
-
+#ifndef POOL_PRIVATE
+		ereport(DEBUG5,
+			(errmsg("value: %s kind: %d", yytext, token)));
+#endif
 		if (!strcmp(key, "allow_inet_domain_socket") && CHECK_CONTEXT(INIT_CONFIG, context))
 		{
 			/* for backward compatibility */
diff --git a/src/config/pool_config.l b/src/config/pool_config.l
index 82a33a7..2458b24 100644
--- a/src/config/pool_config.l
+++ b/src/config/pool_config.l
@@ -24,9 +24,13 @@
  */
 
 %{
-
 #include "pool.h"
 #include "pool_config.h"
+#ifndef POOL_PRIVATE
+#include "utils/elog.h"
+#else
+#include "utils/fe_ports.h"
+#endif
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -34,6 +38,15 @@
 
 #define CHECK_CONTEXT(mask, context) ((mask) & (context))
 
+#ifdef POOL_PRIVATE
+
+/* we do not have elog api for pg_md5 utility*/
+/* include/utils/elog.h */
+#define ereport(elevel, rest) printf("pool_config: error at %s:%d\n", __FILE__, __LINE__)
+#define ereport(elevel, rest) printf("pool_config: error at %s:%d\n", __FILE__, __LINE__)
+
+#endif
+
 /* to shut off compiler warnings */
 int yylex(void);
 
@@ -434,15 +447,30 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context)
 	bool use_memcached = false;
 #endif
 
-#define PARSE_ERROR()		pool_error("pool_config: parse error at line %d '%s'", Lineno, yytext)
+#ifndef POOL_PRIVATE
+#define PARSE_ERROR()		ereport(FATAL, \
+								(errmsg("syntex error in configuration file \"%s\"",POOL_CONF_FILE_NAME), \
+									errdetail("parse error at line %d '%s'", Lineno, yytext)))
+#else
+#define PARSE_ERROR()		fprintf(stderr,"ERROR: syntex error in configuration file \"%s\"",POOL_CONF_FILE_NAME); \
+							fprintf(stderr,"DETAILS: parse error at line %d '%s'", Lineno, yytext)
+#endif
 
 	/* open config file */
 	fd = fopen(confpath, "r");
 	if (!fd)
 	{
-		fprintf(stderr, "pool_config: could not open configuration file (%s)\n",
+#ifndef POOL_PRIVATE
+		ereport(WARNING,
+			(errmsg("could not open configuration file \"%s\"\n",
+				POOL_CONF_FILE_NAME)));
+		ereport(NOTICE,
+			(errmsg("using default configuration parameter values")));
+#else
+		fprintf(stderr,"WARNING: could not open configuration file \"%s\"\n",
 				POOL_CONF_FILE_NAME);
-		fprintf(stderr, "pool_config: using default values...\n");
+		fprintf(stderr,"NOTICE: using default configuration parameter values");
+#endif
 		return 0;
 	}
 
@@ -474,15 +502,19 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context)
 
 		strlcpy(key, yytext, sizeof(key));
 
-		pool_debug("key: %s", key);
-
+#ifndef POOL_PRIVATE
+		ereport(DEBUG5,
+			(errmsg("key: %s", key)));
+#endif
 		token = yylex();
 
 		if (token == POOL_EQUALS)
 			token = yylex();
 
-		pool_debug("value: %s kind: %d", yytext, token);
-
+#ifndef POOL_PRIVATE
+		ereport(DEBUG5,
+			(errmsg("value: %s kind: %d", yytext, token)));
+#endif
 		if (!strcmp(key, "allow_inet_domain_socket") && CHECK_CONTEXT(INIT_CONFIG, context))
 		{
 			/* for backward compatibility */
diff --git a/src/config/pool_config_md5.c b/src/config/pool_config_md5.c
index 6c7a8b2..574320a 100644
--- a/src/config/pool_config_md5.c
+++ b/src/config/pool_config_md5.c
@@ -26,4 +26,6 @@
  */
 
 #define POOL_PRIVATE
+
+#include "../tools/fe_memutils.c"
 #include "pool_config.c"
diff --git a/src/context/pool_query_context.c b/src/context/pool_query_context.c
index 91737fb..c47b684 100644
--- a/src/context/pool_query_context.c
+++ b/src/context/pool_query_context.c
@@ -23,6 +23,8 @@
 #include "pool.h"
 #include "pool_config.h"
 #include "protocol/pool_proto_modules.h"
+#include "utils/palloc.h"
+#include "utils/memutils.h"
 #include "utils/pool_select_walker.h"
 #include "context/pool_session_context.h"
 #include "context/pool_query_context.h"
@@ -61,7 +63,11 @@ POOL_QUERY_CONTEXT *pool_init_query_context(void)
 	}
 
 	/* Create memory context */
-	qc->memory_context = pool_memory_create(PARSER_BLOCK_SIZE);
+	qc->memory_context = AllocSetContextCreate(CurrentMemoryContext,
+									 "QueryContext",
+									 ALLOCSET_DEFAULT_MINSIZE,
+									 ALLOCSET_DEFAULT_INITSIZE,
+									 ALLOCSET_DEFAULT_MAXSIZE);
 
 	return qc;
 }
@@ -78,7 +84,8 @@ void pool_query_context_destroy(POOL_QUERY_CONTEXT *query_context)
 		session_context = pool_get_session_context();
 		pool_unset_query_in_progress();
 		session_context->query_context = NULL;
-		pool_memory_delete(query_context->memory_context, 0);
+		MemoryContextDelete(query_context->memory_context);
+
 		free(query_context);
 	}
 }
@@ -361,11 +368,11 @@ void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *no
 	else if (MASTER_SLAVE)
 	{
 		POOL_DEST dest;
-		POOL_MEMORY_POOL *old_context;
+		MemoryContext old_context;
 
-		old_context = pool_memory_context_switch_to(query_context->memory_context);
+		old_context = MemoryContextSwitchTo(query_context->memory_context);
 		dest = send_to_where(node, query);
-		pool_memory_context_switch_to(old_context);
+		MemoryContextSwitchTo(old_context);
 
 		pool_debug("send_to_where: %d query: %s", dest, query);
 
@@ -936,6 +943,7 @@ POOL_STATUS pool_extended_send_and_wait(POOL_QUERY_CONTEXT *query_context,
  * primary, the standby or either or both in master/slave+HR/SR mode.
  */
 static POOL_DEST send_to_where(Node *node, char *query)
+
 {
 /* From storage/lock.h */
 #define NoLock					0
diff --git a/src/context/pool_session_context.c b/src/context/pool_session_context.c
index 21551ca..f1b8f0a 100644
--- a/src/context/pool_session_context.c
+++ b/src/context/pool_session_context.c
@@ -25,6 +25,8 @@
 #include <string.h>
 
 #include "pool.h"
+#include "utils/palloc.h"
+#include "utils/memutils.h"
 #include "pool_config.h"
 #include "context/pool_session_context.h"
 
@@ -62,8 +64,13 @@ void pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *
 	init_sent_message_list();
 
 	/* Create memory context */
-	session_context->memory_context = pool_memory_create(PREPARE_BLOCK_SIZE);
-
+	/* TODO re-think about the parent for this context ??*/
+	session_context->memory_context = AllocSetContextCreate(TopMemoryContext,
+									 "SessionContext",
+									 ALLOCSET_SMALL_MINSIZE,
+									 ALLOCSET_SMALL_INITSIZE,
+									 ALLOCSET_SMALL_MAXSIZE);
+									 
 	/* Choose load balancing node if necessary */
 	if (pool_config->load_balance_mode)
 	{
@@ -128,7 +135,7 @@ void pool_session_context_destroy(void)
 	{
 		pool_clear_sent_message_list();
 		free(session_context->message_list.sent_messages);
-		pool_memory_delete(session_context->memory_context, 0);
+		MemoryContextDelete(session_context->memory_context);
 		if (pool_config->memory_cache_enabled)
 		{
 			pool_discard_query_cache_array(session_context->query_cache_array);
@@ -440,10 +447,10 @@ void pool_sent_message_destroy(POOL_SENT_MESSAGE *message)
 	if (message)
 	{
 		if (message->contents)
-			pool_memory_free(session_context->memory_context, message->contents);
+			pfree(message->contents);
 		
 		if (message->name)
-			pool_memory_free(session_context->memory_context, message->name);
+			pfree(message->name);
 
 		if (message->query_context)
 		{
@@ -469,7 +476,7 @@ void pool_sent_message_destroy(POOL_SENT_MESSAGE *message)
 		}
 
 		if (session_context->memory_context)
-			pool_memory_free(session_context->memory_context, message);
+			pfree(message);
 	}
 }
 
@@ -513,16 +520,16 @@ POOL_SENT_MESSAGE *pool_create_sent_message(char kind, int len, char *contents,
 		pool_error("pool_create_sent_message: session context is not initialized");
 		return NULL;
 	}
-
-	msg = pool_memory_alloc(session_context->memory_context,
-							sizeof(POOL_SENT_MESSAGE));
+	MemoryContext old_context = MemoryContextSwitchTo(session_context->memory_context);
+	msg = palloc(sizeof(POOL_SENT_MESSAGE));
 	msg->kind = kind;
 	msg->len = len;
-	msg->contents = pool_memory_alloc(session_context->memory_context, len);
+	msg->contents = palloc(len);
 	memcpy(msg->contents, contents, len);
 	msg->num_tsparams = num_tsparams;
-	msg->name = pool_memory_strdup(session_context->memory_context, name);
+	msg->name = pstrdup(name);
 	msg->query_context = query_context;
+	MemoryContextSwitchTo(old_context);
 
 	return msg;
 }
diff --git a/src/include/Makefile.in b/src/include/Makefile.in
index 09b7d2c..7c63707 100644
--- a/src/include/Makefile.in
+++ b/src/include/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -223,10 +223,8 @@ $(ACLOCAL_M4):  $(am__aclocal_m4_deps)
 $(am__aclocal_m4_deps):
 
 config.h: stamp-h1
-	@if test ! -f $@; then \
-	  rm -f stamp-h1; \
-	  $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
-	else :; fi
+	@if test ! -f $@; then rm -f stamp-h1; else :; fi
+	@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
 
 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
 	@rm -f stamp-h1
@@ -295,10 +293,15 @@ install-am: all-am
 
 installcheck: installcheck-am
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
diff --git a/src/include/context/pool_query_context.h b/src/include/context/pool_query_context.h
index 918b25e..8eb4307 100644
--- a/src/include/context/pool_query_context.h
+++ b/src/include/context/pool_query_context.h
@@ -30,7 +30,7 @@
 #include "pool_process_context.h"
 #include "parser/nodes.h"
 #include "parser/parsenodes.h"
-#include "parser/pool_memory.h"
+#include "utils/palloc.h"
 #include "query_cache/pool_memqcache.h"
 
 /*
@@ -58,7 +58,7 @@ typedef struct {
 	Node *rewritten_parse_tree;	/* rewritten raw parser output if any */
 	bool where_to_send[MAX_NUM_BACKENDS];	/* DB node map to send query */
 	int  virtual_master_node_id;	   		/* the 1st DB node to send query */
-	POOL_MEMORY_POOL *memory_context;		/* memory context for query */
+	MemoryContext memory_context;		/* memory context for query */
 	POOL_QUERY_STATE query_state[MAX_NUM_BACKENDS];	/* for extended query protocol */
 	bool is_cache_safe;	/* true if SELECT is safe to cache */
 	POOL_TEMP_QUERY_CACHE *temp_cache;	/* temporary cache */
diff --git a/src/include/context/pool_session_context.h b/src/include/context/pool_session_context.h
index 29f407d..9a0324d 100644
--- a/src/include/context/pool_session_context.h
+++ b/src/include/context/pool_session_context.h
@@ -31,7 +31,6 @@
 #include "pool_process_context.h"
 #include "pool_session_context.h"
 #include "pool_query_context.h"
-#include "parser/pool_memory.h"
 #include "query_cache/pool_memqcache.h"
 
 /*
@@ -121,7 +120,7 @@ typedef struct {
 	/* where to send map for PREPARE/EXECUTE/DEALLOCATE */
 	POOL_PREPARED_SEND_MAP prep_where;
 #endif /* NOT_USED */
-	POOL_MEMORY_POOL *memory_context;	/* memory context for session */
+	MemoryContext memory_context;	/* memory context for session */
 
 	/* message which doesn't receive complete message */
 	POOL_SENT_MESSAGE *uncompleted_message;
diff --git a/src/include/parallel_query/pool_rewrite_query.h b/src/include/parallel_query/pool_rewrite_query.h
index 557551c..8f64974 100644
--- a/src/include/parallel_query/pool_rewrite_query.h
+++ b/src/include/parallel_query/pool_rewrite_query.h
@@ -29,7 +29,6 @@
 #include "parser/parser.h"
 #include "parser/pg_list.h"
 #include "parser/parsenodes.h"
-#include "parser/pool_memory.h"
 #include "parser/pool_string.h"
 
 /* return code set */
diff --git a/src/include/parser/memnodes.h b/src/include/parser/memnodes.h
deleted file mode 100644
index f63fc6f..0000000
--- a/src/include/parser/memnodes.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * memnodes.h
- *	  POSTGRES memory context node definitions.
- *
- *
- * Portions Copyright (c) 2003-2013, PgPool Global Development Group
- * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * src/include/nodes/memnodes.h
- *
- *-------------------------------------------------------------------------
- */
-#ifndef MEMNODES_H
-#define MEMNODES_H
-
-#include "nodes.h"
-
-/*
- * MemoryContext
- *		A logical context in which memory allocations occur.
- *
- * MemoryContext itself is an abstract type that can have multiple
- * implementations, though for now we have only AllocSetContext.
- * The function pointers in MemoryContextMethods define one specific
- * implementation of MemoryContext --- they are a virtual function table
- * in C++ terms.
- *
- * Node types that are actual implementations of memory contexts must
- * begin with the same fields as MemoryContext.
- *
- * Note: for largely historical reasons, typedef MemoryContext is a pointer
- * to the context struct rather than the struct type itself.
- */
-
-typedef struct MemoryContextMethods
-{
-	void	   *(*alloc) (MemoryContext context, Size size);
-	/* call this free_p in case someone #define's free() */
-	void		(*free_p) (MemoryContext context, void *pointer);
-	void	   *(*realloc) (MemoryContext context, void *pointer, Size size);
-	void		(*init) (MemoryContext context);
-	void		(*reset) (MemoryContext context);
-	void		(*delete) (MemoryContext context);
-	Size		(*get_chunk_space) (MemoryContext context, void *pointer);
-	bool		(*is_empty) (MemoryContext context);
-	void		(*stats) (MemoryContext context);
-#ifdef MEMORY_CONTEXT_CHECKING
-	void		(*check) (MemoryContext context);
-#endif
-} MemoryContextMethods;
-
-
-typedef struct MemoryContextData
-{
-	NodeTag		type;			/* identifies exact kind of context */
-	MemoryContextMethods *methods;		/* virtual function table */
-	MemoryContext parent;		/* NULL if no parent (toplevel context) */
-	MemoryContext firstchild;	/* head of linked list of children */
-	MemoryContext nextchild;	/* next child of same parent */
-	char	   *name;			/* context name (just for debugging) */
-	bool		isReset;		/* T = no space alloced since last reset */
-} MemoryContextData;
-
-/* utils/palloc.h contains typedef struct MemoryContextData *MemoryContext */
-
-
-/*
- * MemoryContextIsValid
- *		True iff memory context is valid.
- *
- * Add new context types to the set accepted by this macro.
- */
-#define MemoryContextIsValid(context) \
-	((context) != NULL && \
-	 (IsA((context), AllocSetContext)))
-
-#endif   /* MEMNODES_H */
diff --git a/src/include/parser/pool_memory.h b/src/include/parser/pool_memory.h
deleted file mode 100644
index 134166a..0000000
--- a/src/include/parser/pool_memory.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*-pgsql-c-*- */
-/*
- * $Header$
- *
- * pgpool: a language independent connection pool server for PostgreSQL 
- * written by Tatsuo Ishii
- *
- * Copyright (c) 2003-2013	PgPool Global Development Group
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of the
- * author not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. The author makes no representations about the
- * suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * pool_memory.h: Memory pooling module for SQL parser.
- *
- */
-
-#ifndef POOL_MEMORY_H
-#define POOL_MEMORY_H
-
-#define SLOT_NUM 11
-
-#define PARSER_BLOCK_SIZE 8192
-#define PREPARE_BLOCK_SIZE 1024
-
-typedef struct POOL_BLOCK {
-	int size;
-	int allocsize;
-	void *block;
-	void *freepoint;
-	struct POOL_BLOCK *next;
-} POOL_BLOCK;
-
-typedef union {
-	unsigned int size;
-	struct POOL_CHUNK *next;
-} POOL_CHUNK_HEADER;
-
-typedef struct POOL_CHUNK {
-	POOL_CHUNK_HEADER header;
-	char data[1];
-} POOL_CHUNK;
-
-typedef struct {
-	int size;
-	int blocksize;
-	POOL_BLOCK *blocks;
-	POOL_BLOCK *largeblocks;
-	POOL_CHUNK *freelist[SLOT_NUM];
-} POOL_MEMORY_POOL;
-
-extern POOL_MEMORY_POOL *pool_memory;
-
-extern void *pool_memory_alloc(POOL_MEMORY_POOL *pool, unsigned int size);
-extern void pool_memory_free(POOL_MEMORY_POOL *pool, void *ptr);
-extern void *pool_memory_realloc(POOL_MEMORY_POOL *pool, void *ptr, unsigned int size);
-extern POOL_MEMORY_POOL *pool_memory_create(int blocksize);
-extern void pool_memory_delete(POOL_MEMORY_POOL *pool_memory, int reuse);
-extern char *pool_memory_strdup(POOL_MEMORY_POOL *pool_memory, const char *string);
-extern void *pool_memory_alloc_zero(POOL_MEMORY_POOL *pool_memory, unsigned int size);
-extern POOL_MEMORY_POOL *pool_memory_context_switch_to(POOL_MEMORY_POOL *pm);
-
-#define palloc(s) pool_memory_alloc(pool_memory, (s))
-#define pfree(p)  pool_memory_free(pool_memory, (p))
-#define repalloc(p, s)  pool_memory_realloc(pool_memory, (p), (s))
-#define pstrdup(s)  pool_memory_strdup(pool_memory, (s))
-#define palloc0(s) pool_memory_alloc_zero(pool_memory, (s))
-#define palloc0fast(s) pool_memory_alloc_zero(pool_memory, (s))	/* Added in 8.4 */
-
-#endif /* POOL_MEMORY_H */
diff --git a/src/include/parser/pool_parser.h b/src/include/parser/pool_parser.h
index 1c7ff53..e2fe2d7 100644
--- a/src/include/parser/pool_parser.h
+++ b/src/include/parser/pool_parser.h
@@ -25,8 +25,6 @@
 extern jmp_buf jmpbuffer;
 extern int	server_version_num;
 
-#define AssertMacro
-#define Assert(expr)	((void) 0)
 
 /* include/c.h */
 /* integer */
@@ -42,19 +40,9 @@ extern int	server_version_num;
  * bitsN
  *		Unit of bitwise operation, AT LEAST N BITS IN SIZE.
  */
-typedef uint8 bits8;			/* >= 8 bits */
-typedef uint16 bits16;			/* >= 16 bits */
-typedef uint32 bits32;			/* >= 32 bits */
-typedef unsigned long long int uint64;
-
-
-typedef size_t Size;
-typedef unsigned int PoolOid;
 typedef unsigned int Index;
 typedef short AttrNumber;
-typedef unsigned long Datum;	/* XXX sizeof(long) >= sizeof(void *) */
 
-#define Oid PoolOid
 #define InvalidOid		((Oid) 0)
 
 /*
@@ -85,7 +73,6 @@ typedef unsigned long Datum;	/* XXX sizeof(long) >= sizeof(void *) */
 #define HIGHBIT					(0x80)
 #define IS_HIGHBIT_SET(ch)		((unsigned char)(ch) & HIGHBIT)
 
-#define PGDLLIMPORT
 
 
 /* include/utils/datetime.h */
@@ -205,7 +192,7 @@ typedef unsigned long Datum;	/* XXX sizeof(long) >= sizeof(void *) */
 #endif
 
 
-/* include/utils/elog.h */
+/* include/utils/elog.h 
 #define NOTICE 18
 #define WARNING 19
 #define ERROR 20
@@ -217,6 +204,6 @@ extern void pool_parser_error(int level, const char *file, int line);
 #ifndef elog
 #define elog(elevel, fmt, ...) pool_parser_error(elevel, __FILE__, __LINE__)
 #endif
-
+*/
 
 #endif /* POOL_PARSER_H */
diff --git a/src/include/parser/pool_string.h b/src/include/parser/pool_string.h
index 0389eeb..f5fc9aa 100644
--- a/src/include/parser/pool_string.h
+++ b/src/include/parser/pool_string.h
@@ -18,7 +18,7 @@
 
 #ifndef POOL_STRING_H
 #define POOL_STRING_H
-
+#include "pg_list.h"
 #define STRING_SIZE 128
 
 typedef struct
@@ -28,6 +28,7 @@ typedef struct
 	char *data;
 } String;
 
+extern String *NameListToString(List *names);
 extern String *init_string(char *str);
 extern void string_append_string(String *string, String *append_data);
 extern void string_append_char(String *string, char *append_data);
diff --git a/src/include/parser/stringinfo.h b/src/include/parser/stringinfo.h
index c147035..2baa975 100644
--- a/src/include/parser/stringinfo.h
+++ b/src/include/parser/stringinfo.h
@@ -18,6 +18,7 @@
 #ifndef STRINGINFO_H
 #define STRINGINFO_H
 
+#include <stdio.h>
 #include "pg_config_manual.h"
 
 /* port.h */
@@ -28,11 +29,14 @@ extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
  *  above from being replaced, and this is required because gcc doesn't
  *  know anything about pg_printf.
  */
+#ifndef vsnprintf
+
 #ifdef __GNUC__
 #define vsnprintf(...)  pg_vsnprintf(__VA_ARGS__)
 #else
 #define vsnprintf       pg_vsnprintf
 #endif
+#endif
 
 /* utils.memutils.h */
 
diff --git a/src/include/pool.h b/src/include/pool.h
index 8a808e4..b478290 100644
--- a/src/include/pool.h
+++ b/src/include/pool.h
@@ -31,7 +31,6 @@
 #include "utils/pool_signal.h"
 #include "parser/nodes.h"
 
-#include "libpq-fe.h"
 #include <stdio.h>
 #include <time.h>
 #include <sys/time.h>
@@ -75,6 +74,12 @@
 /* default string used to identify pgpool on syslog output */
 #define DEFAULT_SYSLOG_IDENT "pgpool"
 
+/* function return codes */
+#define GENERAL_ERROR		(-1)
+#define RETRY				(-2)
+#define OPERATION_TIMEOUT	(-3)
+
+
 typedef enum {
 	POOL_CONTINUE = 0,
 	POOL_IDLE,
@@ -415,6 +420,29 @@ typedef enum {
 extern pid_t mypid; /* parent pid */
 extern bool run_as_pcp_child;
 
+typedef enum
+{
+	PT_MAIN,
+	PT_CHILD,
+	PT_WORKER,
+	PT_PCP
+} ProcessType;
+
+extern ProcessType processType;
+
+typedef enum
+{
+	INITIALIZING,
+	PERFORMING_HEALTH_CHECK,
+	PERFORMING_SYSDB_CHECK,
+	SLEEPING,
+	WAITIG_FOR_CONNECTION,
+	BACKEND_CONNECTING,
+	PROCESSING
+} ProcessState;
+
+extern ProcessState processState;
+
 extern POOL_CONNECTION_POOL *pool_connection_pool;	/* connection pool */
 extern volatile sig_atomic_t backend_timer_expired; /* flag for connection closed timer is expired */
 extern volatile sig_atomic_t health_check_timer_expired;		/* non 0 if health check timer expired */
@@ -534,6 +562,7 @@ extern void pool_free_startup_packet(StartupPacket *sp);
 extern void child_exit(int code);
 
 extern void init_prepared_list(void);
+extern void proc_exit(int);
 
 extern void *pool_shared_memory_create(size_t size);
 extern void pool_shmem_exit(int code);
@@ -546,7 +575,6 @@ extern BackendInfo *pool_get_node_info(int node_number);
 extern int pool_get_node_count(void);
 extern int *pool_get_process_list(int *array_size);
 extern ProcessInfo *pool_get_process_info(pid_t pid);
-extern SystemDBInfo *pool_get_system_db_info(void);
 extern POOL_STATUS OneNode_do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, char *query, char *database);
 
 /* child.c */
@@ -562,6 +590,9 @@ extern int pool_get_id (DistDefInfo *info, const char * value);
 extern int system_db_connect (void);
 extern int pool_memset_system_db_info (SystemDBInfo *info);
 extern void pool_close_libpq_connection(void);
+extern int system_db_health_check(void);
+extern SystemDBInfo *pool_get_system_db_info(void);
+
 
 /* pool_hba.c */
 extern int load_hba(char *hbapath);
@@ -571,7 +602,7 @@ extern void ClientAuthentication(POOL_CONNECTION *frontend);
 extern void pool_getnameinfo_all(SockAddr *saddr, char *remote_host, char *remote_port);
 
 /* strlcpy.c */
-extern size_t strlcpy(char *dst, const char *src, size_t siz);
+//extern size_t strlcpy(char *dst, const char *src, size_t siz);
 
 /* ps_status.c */
 extern bool update_process_title;
@@ -591,6 +622,7 @@ extern int wait_connection_closed(void);
 extern void cancel_request(CancelPacket *sp);
 extern void check_stop_request(void);
 extern void pool_initialize_private_backend_status(void);
+extern bool is_session_connected(void);
 
 /* pool_process_query.c */
 extern void reset_variables(void);
@@ -633,4 +665,5 @@ extern int connect_inet_domain_socket_by_port(char *host, int port, bool retry);
 extern int connect_unix_domain_socket_by_port(int port, char *socket_dir, bool retry);
 extern int pool_pool_index(void);
 
+extern int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps);
 #endif /* POOL_H */
diff --git a/src/include/pool_type.h b/src/include/pool_type.h
index 63bbc17..4a2fedd 100644
--- a/src/include/pool_type.h
+++ b/src/include/pool_type.h
@@ -30,7 +30,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include "pcp/libpcp_ext.h"
-
+#include "libpq-fe.h"
 /* Define common boolean type. C++ and BEOS already has it so exclude them. */
 #ifdef c_plusplus
 #ifndef __cplusplus
@@ -86,6 +86,18 @@ typedef struct {
 	BACKEND_STATUS status[MAX_NUM_BACKENDS];
 } BackendStatusRecord;
 
+
+#define MAXIMUM_ALIGNOF 8
+
+#define TYPEALIGN(ALIGNVAL,LEN)  \
+	(((intptr_t) (LEN) + ((ALIGNVAL) - 1)) & ~((intptr_t) ((ALIGNVAL) - 1)))
+
+#define SHORTALIGN(LEN)			TYPEALIGN(ALIGNOF_SHORT, (LEN))
+#define INTALIGN(LEN)			TYPEALIGN(ALIGNOF_INT, (LEN))
+#define LONGALIGN(LEN)			TYPEALIGN(ALIGNOF_LONG, (LEN))
+#define DOUBLEALIGN(LEN)		TYPEALIGN(ALIGNOF_DOUBLE, (LEN))
+#define MAXALIGN(LEN)			TYPEALIGN(MAXIMUM_ALIGNOF, (LEN))
+
 /*
  *  It seems that sockaddr_storage is now commonly used in place of sockaddr.
  *  So, define it if it is not define yet, and create new SockAddr structure
@@ -165,5 +177,279 @@ UserAuth;
 
 typedef unsigned int AuthRequest;
 
+/* no special DLL markers on most ports */
+#ifndef PGDLLIMPORT
+#define PGDLLIMPORT
+#endif
+#ifndef PGDLLEXPORT
+#define PGDLLEXPORT
+#endif
+#define STATIC_IF_INLINE
+
+typedef uint8 bits8;			/* >= 8 bits */
+typedef uint16 bits16;			/* >= 16 bits */
+typedef uint32 bits32;			/* >= 32 bits */
+typedef unsigned long long int uint64;
+
+
+typedef size_t Size;
+typedef unsigned long Datum;	/* XXX sizeof(long) >= sizeof(void *) */
+
+typedef void (*pg_on_exit_callback) (int code, Datum arg);
+/*
+ * NULL
+  *		Null pointer.
+   */
+#ifndef NULL
+#define NULL	((void *) 0)
+#endif
+
+/* ----------------------------------------------------------------
+ *				Section 6:	assertions
+ * ----------------------------------------------------------------
+ */
+
+/*
+ * USE_ASSERT_CHECKING, if defined, turns on all the assertions.
+ * - plai  9/5/90
+ *
+ * It should _NOT_ be defined in releases or in benchmark copies
+ */
+
+/*
+ * Assert() can be used in both frontend and backend code. In frontend code it
+ * just calls the standard assert, if it's available. If use of assertions is
+ * not configured, it does nothing.
+ */
+#ifndef USE_ASSERT_CHECKING
+
+#define Assert(condition)
+#define AssertMacro(condition)	((void)true)
+#define AssertArg(condition)
+#define AssertState(condition)
+#define Trap(condition, errorType)
+#define TrapMacro(condition, errorType)	(true)
+
+#elif defined(FRONTEND)
+
+#include <assert.h>
+#define Assert(p) assert(p)
+#define AssertMacro(p)	((void) assert(p))
+#define AssertArg(condition) assert(condition)
+#define AssertState(condition) assert(condition)
+#else							/* USE_ASSERT_CHECKING && !FRONTEND */
+
+/*
+ * Trap
+ *		Generates an exception if the given condition is true.
+ */
+#define Trap(condition, errorType) \
+	do { \
+		if ((assert_enabled) && (condition)) \
+		ExceptionalCondition(CppAsString(condition), (errorType), \
+				__FILE__, __LINE__); \
+	} while (0)
+
+/*
+ *	TrapMacro is the same as Trap but it's intended for use in macros:
+ *
+ *		#define foo(x) (AssertMacro(x != 0), bar(x))
+ *
+ *	Isn't CPP fun?
+ */
+#define TrapMacro(condition, errorType) \
+	((bool) ((! assert_enabled) || ! (condition) || \
+		(ExceptionalCondition(CppAsString(condition), (errorType), \
+							  __FILE__, __LINE__), 0)))
+
+#define Assert(condition) \
+	Trap(!(condition), "FailedAssertion")
+
+#define AssertMacro(condition) \
+	((void) TrapMacro(!(condition), "FailedAssertion"))
+
+#define AssertArg(condition) \
+	Trap(!(condition), "BadArgument")
+
+#define AssertState(condition) \
+	Trap(!(condition), "BadState")
+#endif   /* USE_ASSERT_CHECKING && !FRONTEND */
+
+
+/*
+ * Macros to support compile-time assertion checks.
+ *
+ * If the "condition" (a compile-time-constant expression) evaluates to false,
+ * throw a compile error using the "errmessage" (a string literal).
+ *
+ * gcc 4.6 and up supports _Static_assert(), but there are bizarre syntactic
+ * placement restrictions.	These macros make it safe to use as a statement
+ * or in an expression, respectively.
+ *
+ * Otherwise we fall back on a kluge that assumes the compiler will complain
+ * about a negative width for a struct bit-field.  This will not include a
+ * helpful error message, but it beats not getting an error at all.
+ */
+#ifdef HAVE__STATIC_ASSERT
+#define StaticAssertStmt(condition, errmessage) \
+	do { _Static_assert(condition, errmessage); } while(0)
+#define StaticAssertExpr(condition, errmessage) \
+	({ StaticAssertStmt(condition, errmessage); true; })
+#else							/* !HAVE__STATIC_ASSERT */
+#define StaticAssertStmt(condition, errmessage) \
+	((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; }))
+#define StaticAssertExpr(condition, errmessage) \
+	StaticAssertStmt(condition, errmessage)
+#endif   /* HAVE__STATIC_ASSERT */
+
+
+/*
+ * Compile-time checks that a variable (or expression) has the specified type.
+ *
+ * AssertVariableIsOfType() can be used as a statement.
+ * AssertVariableIsOfTypeMacro() is intended for use in macros, eg
+ *		#define foo(x) (AssertVariableIsOfTypeMacro(x, int), bar(x))
+ *
+ * If we don't have __builtin_types_compatible_p, we can still assert that
+ * the types have the same size.  This is far from ideal (especially on 32-bit
+ * platforms) but it provides at least some coverage.
+ */
+#ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P
+#define AssertVariableIsOfType(varname, typename) \
+	StaticAssertStmt(__builtin_types_compatible_p(__typeof__(varname), typename), \
+			CppAsString(varname) " does not have type " CppAsString(typename))
+#define AssertVariableIsOfTypeMacro(varname, typename) \
+	((void) StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
+		CppAsString(varname) " does not have type " CppAsString(typename)))
+#else							/* !HAVE__BUILTIN_TYPES_COMPATIBLE_P */
+#define AssertVariableIsOfType(varname, typename) \
+	StaticAssertStmt(sizeof(varname) == sizeof(typename), \
+			CppAsString(varname) " does not have type " CppAsString(typename))
+#define AssertVariableIsOfTypeMacro(varname, typename) \
+																((void) StaticAssertExpr(sizeof(varname) == sizeof(typename),		\
+																	 CppAsString(varname) " does not have type " CppAsString(typename)))
+#endif   /* HAVE__BUILTIN_TYPES_COMPATIBLE_P */
+/*
+ * StrNCpy
+ *	Like standard library function strncpy(), except that result string
+ *	is guaranteed to be null-terminated --- that is, at most N-1 bytes
+ *	of the source string will be kept.
+ *	Also, the macro returns no result (too hard to do that without
+ *	evaluating the arguments multiple times, which seems worse).
+ *
+ *	BTW: when you need to copy a non-null-terminated string (like a text
+ *	datum) and add a null, do not do it with StrNCpy(..., len+1).  That
+ *	might seem to work, but it fetches one byte more than there is in the
+ *	text object.  One fine day you'll have a SIGSEGV because there isn't
+ *	another byte before the end of memory.	Don't laugh, we've had real
+ *	live bug reports from real live users over exactly this mistake.
+ *	Do it honestly with "memcpy(dst,src,len); dst[len] = '\0';", instead.
+ */
+#define StrNCpy(dst,src,len) \
+	do \
+	{ \
+		char * _dst = (dst); \
+		Size _len = (len); \
+\
+		if (_len > 0) \
+		{ \
+			strncpy(_dst, (src), _len); \
+			_dst[_len-1] = '\0'; \
+		} \
+	} while (0)
+
+
+/* Get a bit mask of the bits set in non-long aligned addresses */
+#define LONG_ALIGN_MASK (sizeof(long) - 1)
+#define MEMSET_LOOP_LIMIT 1024
+
+/*
+ * MemSet
+ *	Exactly the same as standard library function memset(), but considerably
+ *	faster for zeroing small word-aligned structures (such as parsetree nodes).
+ *	This has to be a macro because the main point is to avoid function-call
+ *	overhead.	However, we have also found that the loop is faster than
+ *	native libc memset() on some platforms, even those with assembler
+ *	memset() functions.  More research needs to be done, perhaps with
+ *	MEMSET_LOOP_LIMIT tests in configure.
+ */
+#define MemSet(start, val, len) \
+	do \
+	{ \
+		/* must be void* because we don't know if it is integer aligned yet */ \
+		void   *_vstart = (void *) (start); \
+		int		_val = (val); \
+		Size	_len = (len); \
+\
+		if ((((intptr_t) _vstart) & LONG_ALIGN_MASK) == 0 && \
+			(_len & LONG_ALIGN_MASK) == 0 && \
+			_val == 0 && \
+			_len <= MEMSET_LOOP_LIMIT && \
+			/* \
+			 *	If MEMSET_LOOP_LIMIT == 0, optimizer should find \
+			 *	the whole "if" false at compile time. \
+			 */ \
+			MEMSET_LOOP_LIMIT != 0) \
+		{ \
+			long *_start = (long *) _vstart; \
+			long *_stop = (long *) ((char *) _start + _len); \
+			while (_start < _stop) \
+				*_start++ = 0; \
+		} \
+		else \
+			memset(_vstart, _val, _len); \
+	} while (0)
+
+/*
+ * MemSetAligned is the same as MemSet except it omits the test to see if
+ * "start" is word-aligned.  This is okay to use if the caller knows a-priori
+ * that the pointer is suitably aligned (typically, because he just got it
+ * from palloc(), which always delivers a max-aligned pointer).
+ */
+#define MemSetAligned(start, val, len) \
+	do \
+	{ \
+		long   *_start = (long *) (start); \
+		int		_val = (val); \
+		Size	_len = (len); \
+\
+		if ((_len & LONG_ALIGN_MASK) == 0 && \
+			_val == 0 && \
+			_len <= MEMSET_LOOP_LIMIT && \
+			MEMSET_LOOP_LIMIT != 0) \
+		{ \
+			long *_stop = (long *) ((char *) _start + _len); \
+			while (_start < _stop) \
+				*_start++ = 0; \
+		} \
+		else \
+			memset(_start, _val, _len); \
+	} while (0)
+
+
+/*
+ * MemSetTest/MemSetLoop are a variant version that allow all the tests in
+ * MemSet to be done at compile time in cases where "val" and "len" are
+ * constants *and* we know the "start" pointer must be word-aligned.
+ * If MemSetTest succeeds, then it is okay to use MemSetLoop, otherwise use
+ * MemSetAligned.  Beware of multiple evaluations of the arguments when using
+ * this approach.
+ */
+#define MemSetTest(val, len) \
+	( ((len) & LONG_ALIGN_MASK) == 0 && \
+	(len) <= MEMSET_LOOP_LIMIT && \
+	MEMSET_LOOP_LIMIT != 0 && \
+	(val) == 0 )
+
+#define MemSetLoop(start, val, len) \
+	do \
+	{ \
+		long * _start = (long *) (start); \
+		long * _stop = (long *) ((char *) _start + (Size) (len)); \
+	\
+		while (_start < _stop) \
+			*_start++ = 0; \
+	} while (0)
+
 
 #endif /* POOL_TYPE_H */
diff --git a/src/include/protocol/pool_proto_modules.h b/src/include/protocol/pool_proto_modules.h
index 7390bf6..0bd863f 100644
--- a/src/include/protocol/pool_proto_modules.h
+++ b/src/include/protocol/pool_proto_modules.h
@@ -28,7 +28,6 @@
 #define POOL_PROTO_MODULES_H
 
 #include "parser/parser.h"
-#include "parser/pool_memory.h"
 #include "parser/pg_list.h"
 #include "parser/parsenodes.h"
 #include "parallel_query/pool_rewrite_query.h"
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
new file mode 100644
index 0000000..f622061
--- /dev/null
+++ b/src/include/utils/elog.h
@@ -0,0 +1,508 @@
+/*-------------------------------------------------------------------------
+ *
+ * elog.h
+ *	  POSTGRES error reporting/logging definitions.
+ *
+ *
+ * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/utils/elog.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef ELOG_H
+#define ELOG_H
+
+#include <setjmp.h>
+#include <stdlib.h>
+#include "parser/stringinfo.h"
+#include "utils/palloc.h"
+#define PG_TEXTDOMAIN(domain) (domain "-PGPOOL")
+
+#define exprLocation(x)  errcode_ign(0)
+#define _(x) (x)
+#define gettext(x) (x)
+#define dgettext(d,x) (x)
+#define ngettext(s,p,n) ((n) == 1 ? (s) : (p))
+#define dngettext(d,s,p,n) ((n) == 1 ? (s) : (p))
+
+typedef enum
+{
+	DestNone,					/* results are discarded */
+	DestDebug,					/* results go to debugging output */
+	DestRemote,					/* results sent to frontend process */
+	DestRemoteExecute,			/* sent to frontend, in Execute command */
+	DestSPI,					/* results sent to SPI manager */
+	DestTuplestore,				/* results sent to Tuplestore */
+	DestIntoRel,				/* results sent to relation (SELECT INTO) */
+	DestCopyOut,				/* results sent to COPY TO code */
+	DestSQLFunction,			/* results sent to SQL-language func mgr */
+	DestTransientRel			/* results sent to transient relation */
+} CommandDest;
+
+/*
+ * Identifiers of error message fields.  Kept here to keep common
+ * between frontend and backend, and also to export them to libpq
+ * applications.
+ */
+#define PG_DIAG_SEVERITY		'S'
+#define PG_DIAG_SQLSTATE		'C'
+#define PG_DIAG_MESSAGE_PRIMARY 'M'
+#define PG_DIAG_MESSAGE_DETAIL	'D'
+#define PG_DIAG_MESSAGE_HINT	'H'
+#define PG_DIAG_STATEMENT_POSITION 'P'
+#define PG_DIAG_INTERNAL_POSITION 'p'
+#define PG_DIAG_INTERNAL_QUERY	'q'
+#define PG_DIAG_CONTEXT			'W'
+#define PG_DIAG_SCHEMA_NAME		's'
+#define PG_DIAG_TABLE_NAME		't'
+#define PG_DIAG_COLUMN_NAME		'c'
+#define PG_DIAG_DATATYPE_NAME	'd'
+#define PG_DIAG_CONSTRAINT_NAME 'n'
+#define PG_DIAG_SOURCE_FILE		'F'
+#define PG_DIAG_SOURCE_LINE		'L'
+#define PG_DIAG_SOURCE_FUNCTION 'R'
+#if defined(WIN32) || defined(__CYGWIN__)
+
+#ifdef BUILDING_DLL
+#define PGDLLIMPORT __declspec (dllexport)
+#else							/* not BUILDING_DLL */
+#define PGDLLIMPORT __declspec (dllimport)
+#endif
+
+#ifdef _MSC_VER
+#define PGDLLEXPORT __declspec (dllexport)
+#else
+#define PGDLLEXPORT
+#endif
+#else							/* not CYGWIN, not MSVC, not MingW */
+#define PGDLLIMPORT
+#define PGDLLEXPORT
+#endif
+
+
+/* Error level codes */
+#define DEBUG5		10			/* Debugging messages, in categories of
+								 * decreasing detail. */
+#define DEBUG4		11
+#define DEBUG3		12
+#define DEBUG2		13
+#define DEBUG1		14			/* used by GUC debug_* variables */
+#define LOG			15			/* Server operational messages; sent only to
+								 * server log by default. */
+#define COMMERROR	16			/* Client communication problems; same as LOG
+								 * for server reporting, but never sent to
+								 * client. */
+#define INFO		17			/* Messages specifically requested by user (eg
+								 * VACUUM VERBOSE output); always sent to
+								 * client regardless of client_min_messages,
+								 * but by default not sent to server log. */
+#define NOTICE		18			/* Helpful messages to users about query
+								 * operation; sent to client and server log by
+								 * default. */
+#define WARNING		19			/* Warnings.  NOTICE is for expected messages
+								 * like implicit sequence creation by SERIAL.
+								 * WARNING is for unexpected messages. */
+#define ERROR		20			/* user error - abort transaction; return to
+								 * known state */
+/* Save ERROR value in PGERROR so it can be restored when Win32 includes
+ * modify it.  We have to use a constant rather than ERROR because macros
+ * are expanded only when referenced outside macros.
+ */
+
+#ifdef WIN32
+#define PGERROR		20
+#endif
+#define FATAL		21			/* fatal error - abort process */
+#define PANIC		22			/* take down the other backends with me */
+
+ /* #define DEBUG DEBUG1 */	/* Backward compatibility with pre-7.3 */
+
+
+
+/* Which __func__ symbol do we have, if any? */
+#ifdef HAVE_FUNCNAME__FUNC
+#define PG_FUNCNAME_MACRO	__func__
+#else
+#ifdef HAVE_FUNCNAME__FUNCTION
+#define PG_FUNCNAME_MACRO	__FUNCTION__
+#else
+#define PG_FUNCNAME_MACRO	NULL
+#endif
+#endif
+
+extern int		log_min_error_statement;
+extern int		log_min_messages;
+extern int		client_min_messages;
+
+/*----------
+ * New-style error reporting API: to be used in this way:
+ *		ereport(ERROR,
+ *				(errcode(ERRCODE_UNDEFINED_CURSOR),
+ *				 errmsg("portal \"%s\" not found", stmt->portalname),
+ *				 ... other errxxx() fields as needed ...));
+ *
+ * The error level is required, and so is a primary error message (errmsg
+ * or errmsg_internal).  All else is optional.	errcode() defaults to
+ * ERRCODE_INTERNAL_ERROR if elevel is ERROR or more, ERRCODE_WARNING
+ * if elevel is WARNING, or ERRCODE_SUCCESSFUL_COMPLETION if elevel is
+ * NOTICE or below.
+ *
+ * ereport_domain() allows a message domain to be specified, for modules that
+ * wish to use a different message catalog from the backend's.	To avoid having
+ * one copy of the default text domain per .o file, we define it as NULL here
+ * and have errstart insert the default text domain.  Modules can either use
+ * ereport_domain() directly, or preferably they can override the TEXTDOMAIN
+ * macro.
+ *
+ * If elevel >= ERROR, the call will not return; we try to inform the compiler
+ * of that via pg_unreachable().  However, no useful optimization effect is
+ * obtained unless the compiler sees elevel as a compile-time constant, else
+ * we're just adding code bloat.  So, if __builtin_constant_p is available,
+ * use that to cause the second if() to vanish completely for non-constant
+ * cases.  We avoid using a local variable because it's not necessary and
+ * prevents gcc from making the unreachability deduction at optlevel -O0.
+ *----------
+ */
+#ifdef HAVE__BUILTIN_CONSTANT_P
+#define ereport_domain(elevel, domain, rest)	\
+	do { \
+		if (errstart(elevel, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \
+			errfinish rest; \
+		if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \
+			pg_unreachable(); \
+	} while(0)
+#else							/* !HAVE__BUILTIN_CONSTANT_P */
+#define ereport_domain(elevel, domain, rest)	\
+	do { \
+		const int elevel_ = (elevel); \
+		if (errstart(elevel_, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \
+			errfinish rest; \
+		if (elevel_ >= ERROR) \
+			pg_unreachable(); \
+	} while(0)
+#endif   /* HAVE__BUILTIN_CONSTANT_P */
+
+#define ereport(elevel, rest)	\
+	ereport_domain(elevel, TEXTDOMAIN, rest)
+
+#define TEXTDOMAIN NULL
+
+extern bool errstart(int elevel, const char *filename, int lineno,
+		 const char *funcname, const char *domain);
+extern void errfinish(int dummy,...);
+
+#define errcode(sqlerrcode) \
+	errcode_ign(0)
+extern int	errcode_ign(int sqlerrcode);
+
+extern int	return_code(int retcode);
+extern int	get_return_code(void);
+
+extern int
+errmsg(const char *fmt,...)
+/* This extension allows gcc to check the format string for consistency with
+   the supplied arguments. */
+__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+
+extern int
+errmsg_internal(const char *fmt,...)
+/* This extension allows gcc to check the format string for consistency with
+   the supplied arguments. */
+__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+
+extern int
+errmsg_plural(const char *fmt_singular, const char *fmt_plural,
+			  unsigned long n,...)
+/* This extension allows gcc to check the format string for consistency with
+   the supplied arguments. */
+__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 4)))
+__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 4)));
+
+extern int
+errdetail(const char *fmt,...)
+/* This extension allows gcc to check the format string for consistency with
+   the supplied arguments. */
+__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+
+extern int
+errdetail_internal(const char *fmt,...)
+/* This extension allows gcc to check the format string for consistency with
+   the supplied arguments. */
+__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+
+extern int
+errdetail_log(const char *fmt,...)
+/* This extension allows gcc to check the format string for consistency with
+   the supplied arguments. */
+__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+
+extern int
+errdetail_plural(const char *fmt_singular, const char *fmt_plural,
+				 unsigned long n,...)
+/* This extension allows gcc to check the format string for consistency with
+   the supplied arguments. */
+__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 4)))
+__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 4)));
+
+extern int
+errhint(const char *fmt,...)
+/* This extension allows gcc to check the format string for consistency with
+   the supplied arguments. */
+__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+
+/*
+ * errcontext() is typically called in error context callback functions, not
+ * within an ereport() invocation. The callback function can be in a different
+ * module than the ereport() call, so the message domain passed in errstart()
+ * is not usually the correct domain for translating the context message.
+ * set_errcontext_domain() first sets the domain to be used, and
+ * errcontext_msg() passes the actual message.
+ */
+#define errcontext	set_errcontext_domain(TEXTDOMAIN),	errcontext_msg
+
+extern int	set_errcontext_domain(const char *domain);
+extern int
+errcontext_msg(const char *fmt,...)
+/* This extension allows gcc to check the format string for consistency with
+   the supplied arguments. */
+__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+
+extern int	errhidestmt(bool hide_stmt);
+
+extern int	errfunction(const char *funcname);
+extern int	errposition(int cursorpos);
+
+#define pg_unreachable() exit(0)
+//extern int	err_generic_string(int field, const char *str);
+
+extern int	geterrcode(void);
+extern int	geterrposition(void);
+extern int	getinternalerrposition(void);
+
+
+/*----------
+ * Old-style error reporting API: to be used in this way:
+ *		elog(ERROR, "portal \"%s\" not found", stmt->portalname);
+ *----------
+ */
+#ifdef HAVE__VA_ARGS
+/*
+ * If we have variadic macros, we can give the compiler a hint about the
+ * call not returning when elevel >= ERROR.  See comments for ereport().
+ * Note that historically elog() has called elog_start (which saves errno)
+ * before evaluating "elevel", so we preserve that behavior here.
+ */
+#ifdef HAVE__BUILTIN_CONSTANT_P
+#define elog(elevel, ...)  \
+	do { \
+		elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO); \
+		elog_finish(elevel, __VA_ARGS__); \
+		if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \
+			pg_unreachable(); \
+	} while(0)
+#else							/* !HAVE__BUILTIN_CONSTANT_P */
+#define elog(elevel, ...)  \
+	do { \
+		int		elevel_; \
+		elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO); \
+		elevel_ = (elevel); \
+		elog_finish(elevel_, __VA_ARGS__); \
+		if (elevel_ >= ERROR) \
+			pg_unreachable(); \
+	} while(0)
+#endif   /* HAVE__BUILTIN_CONSTANT_P */
+#else							/* !HAVE__VA_ARGS */
+#define elog  \
+	elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO), \
+	elog_finish
+#endif   /* HAVE__VA_ARGS */
+
+extern void elog_start(const char *filename, int lineno, const char *funcname);
+extern void
+elog_finish(int elevel, const char *fmt,...)
+/* This extension allows gcc to check the format string for consistency with
+   the supplied arguments. */
+__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+
+
+/* Support for attaching context information to error reports */
+
+typedef struct ErrorContextCallback
+{
+	struct ErrorContextCallback *previous;
+	void		(*callback) (void *arg);
+	void	   *arg;
+} ErrorContextCallback;
+
+extern PGDLLIMPORT ErrorContextCallback *error_context_stack;
+
+
+/*----------
+ * API for catching ereport(ERROR) exits.  Use these macros like so:
+ *
+ *		PG_TRY();
+ *		{
+ *			... code that might throw ereport(ERROR) ...
+ *		}
+ *		PG_CATCH();
+ *		{
+ *			... error recovery code ...
+ *		}
+ *		PG_END_TRY();
+ *
+ * (The braces are not actually necessary, but are recommended so that
+ * pg_indent will indent the construct nicely.)  The error recovery code
+ * can optionally do PG_RE_THROW() to propagate the same error outwards.
+ *
+ * Note: while the system will correctly propagate any new ereport(ERROR)
+ * occurring in the recovery section, there is a small limit on the number
+ * of levels this will work for.  It's best to keep the error recovery
+ * section simple enough that it can't generate any new errors, at least
+ * not before popping the error stack.
+ *
+ * Note: an ereport(FATAL) will not be caught by this construct; control will
+ * exit straight through proc_exit().  Therefore, do NOT put any cleanup
+ * of non-process-local resources into the error recovery section, at least
+ * not without taking thought for what will happen during ereport(FATAL).
+ * The PG_ENSURE_ERROR_CLEANUP macros provided by storage/ipc.h may be
+ * helpful in such cases.
+ *----------
+ */
+#define PG_TRY()  \
+	do { \
+		sigjmp_buf *save_exception_stack = PG_exception_stack; \
+		ErrorContextCallback *save_context_stack = error_context_stack; \
+		sigjmp_buf local_sigjmp_buf; \
+		if (sigsetjmp(local_sigjmp_buf, 0) == 0) \
+		{ \
+			PG_exception_stack = &local_sigjmp_buf
+
+#define PG_CATCH()	\
+		} \
+		else \
+		{ \
+			PG_exception_stack = save_exception_stack; \
+			error_context_stack = save_context_stack
+
+#define PG_END_TRY()  \
+		} \
+		PG_exception_stack = save_exception_stack; \
+		error_context_stack = save_context_stack; \
+	} while (0)
+
+/*
+ * gcc understands __attribute__((noreturn)); for other compilers, insert
+ * pg_unreachable() so that the compiler gets the point.
+ */
+#ifdef __GNUC__
+#define PG_RE_THROW()  \
+	pg_re_throw()
+#else
+#define PG_RE_THROW()  \
+	(pg_re_throw(), pg_unreachable())
+#endif
+
+extern PGDLLIMPORT sigjmp_buf *PG_exception_stack;
+
+
+/* Stuff that error handlers might want to use */
+
+/*
+ * ErrorData holds the data accumulated during any one ereport() cycle.
+ * Any non-NULL pointers must point to palloc'd data.
+ * (The const pointers are an exception; we assume they point at non-freeable
+ * constant strings.)
+ */
+typedef struct ErrorData
+{
+	int			elevel;			/* error level */
+	bool		output_to_server;		/* will report to server log? */
+	bool		output_to_client;		/* will report to client? */
+	bool		show_funcname;	/* true to force funcname inclusion */
+	bool		hide_stmt;		/* true to prevent STATEMENT: inclusion */
+	const char *filename;		/* __FILE__ of ereport() call */
+	int			lineno;			/* __LINE__ of ereport() call */
+	const char *funcname;		/* __func__ of ereport() call */
+	const char *domain;			/* message domain */
+	const char *context_domain; /* message domain for context message */
+	int			sqlerrcode;		/* encoded ERRSTATE */
+	char	   *message;		/* primary error message */
+	char	   *detail;			/* detail error message */
+	char	   *detail_log;		/* detail error message for server log only */
+	char	   *hint;			/* hint message */
+	char	   *context;		/* context message */
+	char	   *schema_name;	/* name of schema */
+	char	   *table_name;		/* name of table */
+	char	   *column_name;	/* name of column */
+	char	   *datatype_name;	/* name of datatype */
+	char	   *constraint_name;	/* name of constraint */
+	int			cursorpos;		/* cursor index into query string */
+	int			retcode;			/* return code to be used in exit() code */
+	int			internalpos;	/* cursor index into internalquery */
+	char	   *internalquery;	/* text of internally-generated query */
+	int			saved_errno;	/* errno at entry */
+
+	/* context containing associated non-constant strings */
+	MemoryContext assoc_context;
+} ErrorData;
+
+extern void EmitErrorReport(void);
+extern ErrorData *CopyErrorData(void);
+extern void FreeErrorData(ErrorData *edata);
+extern void FlushErrorState(void);
+extern void ReThrowError(ErrorData *edata) __attribute__((noreturn));
+extern void pg_re_throw(void) __attribute__((noreturn));
+
+extern char *GetErrorContextStack(void);
+
+/* Hook for intercepting messages before they are sent to the server log */
+typedef void (*emit_log_hook_type) (ErrorData *edata);
+extern PGDLLIMPORT emit_log_hook_type emit_log_hook;
+
+
+/* GUC-configurable parameters */
+
+typedef enum
+{
+	PGERROR_TERSE,				/* single-line error messages */
+	PGERROR_DEFAULT,			/* recommended style */
+	PGERROR_VERBOSE				/* all the facts, ma'am */
+}	PGErrorVerbosity;
+
+extern int	Log_error_verbosity;
+extern char *Log_line_prefix;
+extern int	Log_destination;
+extern char *Log_destination_string;
+
+/* Log destination bitmap */
+#define LOG_DESTINATION_STDERR	 1
+#define LOG_DESTINATION_SYSLOG	 2
+#define LOG_DESTINATION_EVENTLOG 4
+#define LOG_DESTINATION_CSVLOG	 8
+
+extern bool in_error_recursion_trouble(void);
+
+#ifdef HAVE_SYSLOG
+extern void set_syslog_parameters(const char *ident, int facility);
+#endif
+
+/*
+ * Write errors to stderr (or by equal means when stderr is
+ * not available). Used before ereport/elog can be used
+ * safely (memory context, GUC load etc)
+ */
+extern void
+write_stderr(const char *fmt,...)
+/* This extension allows gcc to check the format string for consistency with
+   the supplied arguments. */
+__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+
+void shmem_exit(int code);
+void on_exit_reset(void);
+void cancel_shmem_exit(pg_on_exit_callback function, Datum arg);
+void on_proc_exit(pg_on_exit_callback function, Datum arg);
+void on_shmem_exit(pg_on_exit_callback function, Datum arg);
+
+#endif   /* ELOG_H */
diff --git a/src/include/utils/fe_ports.h b/src/include/utils/fe_ports.h
new file mode 100644
index 0000000..9658fe5
--- /dev/null
+++ b/src/include/utils/fe_ports.h
@@ -0,0 +1,28 @@
+/*-------------------------------------------------------------------------
+ *
+ * fe_memutils.h
+ *	  memory management support for frontend code
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef POOL_PRIVATE
+#error "This file is not expected to be compiled for pgpool utilities only"
+#endif
+
+#ifndef FE_PORTS
+#define FE_PORTS
+
+void *pg_malloc(size_t size);
+
+void *pg_malloc0(size_t size);
+void *pg_realloc(void *ptr, size_t size);
+char *pg_strdup(const char *in);
+void pg_free(void *ptr);
+void *palloc(unsigned int size);
+void *palloc0(unsigned int size);
+void pfree(void *pointer);
+char *pstrdup(const char *in);
+void *repalloc(void *pointer, unsigned int size);
+
+#endif
\ No newline at end of file
diff --git a/src/include/utils/memdebug.h b/src/include/utils/memdebug.h
new file mode 100644
index 0000000..0b95569
--- /dev/null
+++ b/src/include/utils/memdebug.h
@@ -0,0 +1,34 @@
+/*-------------------------------------------------------------------------
+ *
+ * memdebug.h
+ *	  Memory debugging support.
+ *
+ * Currently, this file either wraps <valgrind/memcheck.h> or substitutes
+ * empty definitions for Valgrind client request macros we use.
+ *
+ *
+ * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/utils/memdebug.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef MEMDEBUG_H
+#define MEMDEBUG_H
+
+#ifdef USE_VALGRIND
+#include <valgrind/memcheck.h>
+#else
+#define VALGRIND_CHECK_MEM_IS_DEFINED(addr, size)			do {} while (0)
+#define VALGRIND_CREATE_MEMPOOL(context, redzones, zeroed)	do {} while (0)
+#define VALGRIND_DESTROY_MEMPOOL(context)					do {} while (0)
+#define VALGRIND_MAKE_MEM_DEFINED(addr, size)				do {} while (0)
+#define VALGRIND_MAKE_MEM_NOACCESS(addr, size)				do {} while (0)
+#define VALGRIND_MAKE_MEM_UNDEFINED(addr, size)				do {} while (0)
+#define VALGRIND_MEMPOOL_ALLOC(context, addr, size)			do {} while (0)
+#define VALGRIND_MEMPOOL_FREE(context, addr)				do {} while (0)
+#define VALGRIND_MEMPOOL_CHANGE(context, optr, nptr, size)	do {} while (0)
+#endif
+
+#endif   /* MEMDEBUG_H */
diff --git a/src/include/utils/memnodes.h b/src/include/utils/memnodes.h
new file mode 100644
index 0000000..fe437e2
--- /dev/null
+++ b/src/include/utils/memnodes.h
@@ -0,0 +1,78 @@
+/*-------------------------------------------------------------------------
+ *
+ * memnodes.h
+ *	  POSTGRES memory context node definitions.
+ *
+ *
+ * Portions Copyright (c) 2003-2013, PgPool Global Development Group
+ * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/nodes/memnodes.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef MEMNODES_H
+#define MEMNODES_H
+
+#include "parser/nodes.h"
+
+/*
+ * MemoryContext
+ *		A logical context in which memory allocations occur.
+ *
+ * MemoryContext itself is an abstract type that can have multiple
+ * implementations, though for now we have only AllocSetContext.
+ * The function pointers in MemoryContextMethods define one specific
+ * implementation of MemoryContext --- they are a virtual function table
+ * in C++ terms.
+ *
+ * Node types that are actual implementations of memory contexts must
+ * begin with the same fields as MemoryContext.
+ *
+ * Note: for largely historical reasons, typedef MemoryContext is a pointer
+ * to the context struct rather than the struct type itself.
+ */
+
+typedef struct MemoryContextMethods
+{
+	void	   *(*alloc) (MemoryContext context, Size size);
+	/* call this free_p in case someone #define's free() */
+	void		(*free_p) (MemoryContext context, void *pointer);
+	void	   *(*realloc) (MemoryContext context, void *pointer, Size size);
+	void		(*init) (MemoryContext context);
+	void		(*reset) (MemoryContext context);
+	void		(*delete_context) (MemoryContext context);
+	Size		(*get_chunk_space) (MemoryContext context, void *pointer);
+	bool		(*is_empty) (MemoryContext context);
+	void		(*stats) (MemoryContext context, int level);
+#ifdef MEMORY_CONTEXT_CHECKING
+	void		(*check) (MemoryContext context);
+#endif
+} MemoryContextMethods;
+
+typedef struct MemoryContextData
+{
+	NodeTag		type;			/* identifies exact kind of context */
+	MemoryContextMethods *methods;		/* virtual function table */
+	MemoryContext parent;		/* NULL if no parent (toplevel context) */
+	MemoryContext firstchild;	/* head of linked list of children */
+	MemoryContext nextchild;	/* next child of same parent */
+	char	   *name;			/* context name (just for debugging) */
+	bool		isReset;		/* T = no space alloced since last reset */
+} MemoryContextData;
+
+/* utils/palloc.h contains typedef struct MemoryContextData *MemoryContext */
+
+
+/*
+ * MemoryContextIsValid
+ *		True iff memory context is valid.
+ *
+ * Add new context types to the set accepted by this macro.
+ */
+#define MemoryContextIsValid(context) \
+	((context) != NULL && \
+	 (IsA((context), AllocSetContext)))
+
+#endif   /* MEMNODES_H */
diff --git a/src/include/utils/memutils.h b/src/include/utils/memutils.h
new file mode 100644
index 0000000..0cd89b4
--- /dev/null
+++ b/src/include/utils/memutils.h
@@ -0,0 +1,148 @@
+/*-------------------------------------------------------------------------
+ *
+ * memutils.h
+ *	  This file contains declarations for memory allocation utility
+ *	  functions.  These are functions that are not quite widely used
+ *	  enough to justify going in utils/palloc.h, but are still part
+ *	  of the API of the memory management subsystem.
+ *
+ *
+ * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/utils/memutils.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef MEMUTILS_H
+#define MEMUTILS_H
+
+#include "utils/memnodes.h"
+
+
+/*
+ * MaxAllocSize, MaxAllocHugeSize
+ *		Quasi-arbitrary limits on size of allocations.
+ *
+ * Note:
+ *		There is no guarantee that smaller allocations will succeed, but
+ *		larger requests will be summarily denied.
+ *
+ * palloc() enforces MaxAllocSize, chosen to correspond to the limiting size
+ * of varlena objects under TOAST.  See VARSIZE_4B() and related macros in
+ * postgres.h.  Many datatypes assume that any allocatable size can be
+ * represented in a varlena header.  This limit also permits a caller to use
+ * an "int" variable for an index into or length of an allocation.  Callers
+ * careful to avoid these hazards can access the higher limit with
+ * MemoryContextAllocHuge().  Both limits permit code to assume that it may
+ * compute twice an allocation's size without overflow.
+ */
+#define MaxAllocSize	((Size) 0x3fffffff)		/* 1 gigabyte - 1 */
+
+#define AllocSizeIsValid(size)	((Size) (size) <= MaxAllocSize)
+
+#define MaxAllocHugeSize	((Size) -1 >> 1)	/* SIZE_MAX / 2 */
+
+#define AllocHugeSizeIsValid(size)	((Size) (size) <= MaxAllocHugeSize)
+
+/*
+ * All chunks allocated by any memory context manager are required to be
+ * preceded by a StandardChunkHeader at a spacing of STANDARDCHUNKHEADERSIZE.
+ * A currently-allocated chunk must contain a backpointer to its owning
+ * context as well as the allocated size of the chunk.	The backpointer is
+ * used by pfree() and repalloc() to find the context to call.	The allocated
+ * size is not absolutely essential, but it's expected to be needed by any
+ * reasonable implementation.
+ */
+typedef struct StandardChunkHeader
+{
+	MemoryContext context;		/* owning context */
+	Size		size;			/* size of data space allocated in chunk */
+#ifdef MEMORY_CONTEXT_CHECKING
+	/* when debugging memory usage, also store actual requested size */
+	Size		requested_size;
+#endif
+} StandardChunkHeader;
+
+#define STANDARDCHUNKHEADERSIZE  MAXALIGN(sizeof(StandardChunkHeader))
+
+
+/*
+ * Standard top-level memory contexts.
+ *
+ * Only TopMemoryContext and ErrorContext are initialized by
+ * MemoryContextInit() itself.
+ */
+extern PGDLLIMPORT MemoryContext TopMemoryContext;
+extern PGDLLIMPORT MemoryContext ErrorContext;
+extern PGDLLIMPORT MemoryContext PostmasterContext;
+extern PGDLLIMPORT MemoryContext CacheMemoryContext;
+extern PGDLLIMPORT MemoryContext MessageContext;
+extern PGDLLIMPORT MemoryContext TopTransactionContext;
+extern PGDLLIMPORT MemoryContext CurTransactionContext;
+
+/* This is a transient link to the active portal's memory context: */
+extern PGDLLIMPORT MemoryContext PortalContext;
+
+
+/*
+ * Memory-context-type-independent functions in mcxt.c
+ */
+extern void MemoryContextInit(void);
+extern void MemoryContextReset(MemoryContext context);
+extern void MemoryContextDelete(MemoryContext context);
+extern void MemoryContextResetChildren(MemoryContext context);
+extern void MemoryContextDeleteChildren(MemoryContext context);
+extern void MemoryContextResetAndDeleteChildren(MemoryContext context);
+extern void MemoryContextSetParent(MemoryContext context,
+					   MemoryContext new_parent);
+extern Size GetMemoryChunkSpace(void *pointer);
+extern MemoryContext GetMemoryChunkContext(void *pointer);
+extern MemoryContext MemoryContextGetParent(MemoryContext context);
+extern bool MemoryContextIsEmpty(MemoryContext context);
+extern void MemoryContextStats(MemoryContext context);
+
+#ifdef MEMORY_CONTEXT_CHECKING
+extern void MemoryContextCheck(MemoryContext context);
+#endif
+extern bool MemoryContextContains(MemoryContext context, void *pointer);
+
+/*
+ * This routine handles the context-type-independent part of memory
+ * context creation.  It's intended to be called from context-type-
+ * specific creation routines, and noplace else.
+ */
+extern MemoryContext MemoryContextCreate(NodeTag tag, Size size,
+					MemoryContextMethods *methods,
+					MemoryContext parent,
+					const char *name);
+
+
+/*
+ * Memory-context-type-specific functions
+ */
+
+/* aset.c */
+extern MemoryContext AllocSetContextCreate(MemoryContext parent,
+					  const char *name,
+					  Size minContextSize,
+					  Size initBlockSize,
+					  Size maxBlockSize);
+
+/*
+ * Recommended default alloc parameters, suitable for "ordinary" contexts
+ * that might hold quite a lot of data.
+ */
+#define ALLOCSET_DEFAULT_MINSIZE   0
+#define ALLOCSET_DEFAULT_INITSIZE  (8 * 1024)
+#define ALLOCSET_DEFAULT_MAXSIZE   (8 * 1024 * 1024)
+
+/*
+ * Recommended alloc parameters for "small" contexts that are not expected
+ * to contain much data (for example, a context to contain a query plan).
+ */
+#define ALLOCSET_SMALL_MINSIZE	 0
+#define ALLOCSET_SMALL_INITSIZE  (1 * 1024)
+#define ALLOCSET_SMALL_MAXSIZE	 (8 * 1024)
+
+#endif   /* MEMUTILS_H */
diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h
new file mode 100644
index 0000000..01e7db5
--- /dev/null
+++ b/src/include/utils/palloc.h
@@ -0,0 +1,105 @@
+/*-------------------------------------------------------------------------
+ *
+ * palloc.h
+ *	  POSTGRES memory allocator definitions.
+ *
+ * This file contains the basic memory allocation interface that is
+ * needed by almost every backend module.  It is included directly by
+ * postgres.h, so the definitions here are automatically available
+ * everywhere.	Keep it lean!
+ *
+ * Memory allocation occurs within "contexts".	Every chunk obtained from
+ * palloc()/MemoryContextAlloc() is allocated within a specific context.
+ * The entire contents of a context can be freed easily and quickly by
+ * resetting or deleting the context --- this is both faster and less
+ * prone to memory-leakage bugs than releasing chunks individually.
+ * We organize contexts into context trees to allow fine-grain control
+ * over chunk lifetime while preserving the certainty that we will free
+ * everything that should be freed.  See utils/mmgr/README for more info.
+ *
+ *
+ * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/utils/palloc.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PALLOC_H
+#define PALLOC_H
+
+/*
+ * Type MemoryContextData is declared in nodes/memnodes.h.	Most users
+ * of memory allocation should just treat it as an abstract type, so we
+ * do not provide the struct contents here.
+ */
+typedef struct MemoryContextData *MemoryContext;
+
+#ifndef FRONTEND
+
+/*
+ * CurrentMemoryContext is the default allocation context for palloc().
+ * We declare it here so that palloc() can be a macro.	Avoid accessing it
+ * directly!  Instead, use MemoryContextSwitchTo() to change the setting.
+ */
+extern PGDLLIMPORT MemoryContext CurrentMemoryContext;
+
+/*
+ * Fundamental memory-allocation operations (more are in utils/memutils.h)
+ */
+extern void *MemoryContextAlloc(MemoryContext context, Size size);
+extern void *MemoryContextAllocZero(MemoryContext context, Size size);
+extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size);
+
+/* Higher-limit allocators. */
+extern void *MemoryContextAllocHuge(MemoryContext context, Size size);
+extern void *repalloc_huge(void *pointer, Size size);
+
+/*
+ * The result of palloc() is always word-aligned, so we can skip testing
+ * alignment of the pointer when deciding which MemSet variant to use.
+ * Note that this variant does not offer any advantage, and should not be
+ * used, unless its "sz" argument is a compile-time constant; therefore, the
+ * issue that it evaluates the argument multiple times isn't a problem in
+ * practice.
+ */
+#define palloc0fast(sz) \
+	( MemSetTest(0, sz) ? \
+		MemoryContextAllocZeroAligned(CurrentMemoryContext, sz) : \
+		MemoryContextAllocZero(CurrentMemoryContext, sz) )
+
+/*
+ * MemoryContextSwitchTo can't be a macro in standard C compilers.
+ * But we can make it an inline function if the compiler supports it.
+ * See STATIC_IF_INLINE in c.h.
+ */
+
+#ifndef PG_USE_INLINE
+extern MemoryContext MemoryContextSwitchTo(MemoryContext context);
+#endif   /* !PG_USE_INLINE */
+#if defined(PG_USE_INLINE) || defined(MCXT_INCLUDE_DEFINITIONS)
+STATIC_IF_INLINE MemoryContext
+MemoryContextSwitchTo(MemoryContext context)
+{
+	MemoryContext old = CurrentMemoryContext;
+
+	CurrentMemoryContext = context;
+	return old;
+}
+#endif   /* PG_USE_INLINE || MCXT_INCLUDE_DEFINITIONS */
+
+/*
+ * These are like standard strdup() except the copied string is
+ * allocated in a context, not with malloc().
+ */
+extern char *MemoryContextStrdup(MemoryContext context, const char *string);
+#endif   /* !FRONTEND */
+
+extern char *pstrdup(const char *in);
+extern char *pnstrdup(const char *in, Size len);
+extern void *palloc(Size size);
+extern void *palloc0(Size size);
+extern void pfree(void *pointer);
+extern void *repalloc(void *pointer, Size size);
+
+#endif   /* PALLOC_H */
diff --git a/src/include/utils/pool_ipc.h b/src/include/utils/pool_ipc.h
index 5667446..fff8401 100644
--- a/src/include/utils/pool_ipc.h
+++ b/src/include/utils/pool_ipc.h
@@ -24,7 +24,7 @@
 #define IPC_H
 
 
-typedef unsigned long Datum;	/* XXX sizeof(long) >= sizeof(void *) */
+//typedef unsigned long Datum;	/* XXX sizeof(long) >= sizeof(void *) */
 
 
 #define IPCProtection	(0600)	/* access/modify by user only */
diff --git a/src/include/utils/pool_path.h b/src/include/utils/pool_path.h
index be0ed57..1348cc6 100644
--- a/src/include/utils/pool_path.h
+++ b/src/include/utils/pool_path.h
@@ -45,35 +45,6 @@
     ((filename)[0] == '/') \
 )
 
-/*
- * StrNCpy
- *  Like standard library function strncpy(), except that result string
- *  is guaranteed to be null-terminated --- that is, at most N-1 bytes
- *  of the source string will be kept.
- *  Also, the macro returns no result (too hard to do that without
- *  evaluating the arguments multiple times, which seems worse).
- *
- *  BTW: when you need to copy a non-null-terminated string (like a text
- *  datum) and add a null, do not do it with StrNCpy(..., len+1).  That
- *  might seem to work, but it fetches one byte more than there is in the
- *  text object.  One fine day you'll have a SIGSEGV because there isn't
- *  another byte before the end of memory.  Don't laugh, we've had real
- *  live bug reports from real live users over exactly this mistake.
- *  Do it honestly with "memcpy(dst,src,len); dst[len] = '\0';", instead.
- */
-#define StrNCpy(dst,src,len) \
-    do \
-    { \
-        char * _dst = (dst); \
-        size_t _len = (len); \
-\
-        if (_len > 0) \
-        { \
-            strncpy(_dst, (src), _len); \
-            _dst[_len-1] = '\0'; \
-        } \
-    } while (0)
-
 extern void get_parent_directory(char *path);
 extern void join_path_components(char *ret_path, const char *head, const char *tail);
 extern void canonicalize_path(char *path);
diff --git a/src/include/utils/pool_stream.h b/src/include/utils/pool_stream.h
index d7e15ea..2cabe4e 100644
--- a/src/include/utils/pool_stream.h
+++ b/src/include/utils/pool_stream.h
@@ -45,6 +45,9 @@
 extern POOL_CONNECTION *pool_open(int fd);
 extern void pool_close(POOL_CONNECTION *cp);
 extern int pool_read(POOL_CONNECTION *cp, void *buf, int len);
+extern void pool_read_with_error(POOL_CONNECTION *cp, void *buf, int len,
+                                 const char* err_context );
+
 extern char *pool_read2(POOL_CONNECTION *cp, int len);
 extern int pool_write(POOL_CONNECTION *cp, void *buf, int len);
 extern int pool_flush(POOL_CONNECTION *cp);
diff --git a/src/libs/Makefile.in b/src/libs/Makefile.in
index 8c7ffc2..a30d193 100644
--- a/src/libs/Makefile.in
+++ b/src/libs/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -466,10 +466,15 @@ install-am: all-am
 
 installcheck: installcheck-recursive
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
diff --git a/src/libs/pcp/Makefile.in b/src/libs/pcp/Makefile.in
index b216853..2bdecfb 100644
--- a/src/libs/pcp/Makefile.in
+++ b/src/libs/pcp/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -73,6 +73,12 @@ am__nobase_list = $(am__nobase_strip_setup); \
 am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
 am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"
 LTLIBRARIES = $(lib_LTLIBRARIES)
 libpcp_la_LIBADD =
@@ -295,7 +301,7 @@ clean-libLTLIBRARIES:
 	  echo "rm -f \"$${dir}/so_locations\""; \
 	  rm -f "$${dir}/so_locations"; \
 	done
-libpcp.la: $(libpcp_la_OBJECTS) $(libpcp_la_DEPENDENCIES) 
+libpcp.la: $(libpcp_la_OBJECTS) $(libpcp_la_DEPENDENCIES) $(EXTRA_libpcp_la_DEPENDENCIES) 
 	$(LINK) -rpath $(libdir) $(libpcp_la_OBJECTS) $(libpcp_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
@@ -359,9 +365,7 @@ uninstall-includeHEADERS:
 	@$(NORMAL_UNINSTALL)
 	@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(includedir)" && rm -f $$files
+	dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
 
 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
@@ -462,10 +466,15 @@ install-am: all-am
 
 installcheck: installcheck-am
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
diff --git a/src/main/main.c b/src/main/main.c
index 553b724..5005550 100644
--- a/src/main/main.c
+++ b/src/main/main.c
@@ -20,33 +20,10 @@
  */
 #include "pool.h"
 #include "pool_config.h"
-#include "context/pool_process_context.h"
-
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <sys/un.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <sys/time.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#include <sys/stat.h>
-#include <sys/types.h>
 #include <fcntl.h>
-
-#include <sys/wait.h>
-
-#include <stdio.h>
-#include <errno.h>
+#include <sys/types.h> 
 #include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
 
-#include <signal.h>
 
 #ifdef HAVE_GETOPT_H
 #include <getopt.h>
@@ -54,158 +31,41 @@
 #include "utils/getopt_long.h"
 #endif
 
+#include <errno.h>
+#include <string.h>
 #include <libgen.h>
+#include "utils/elog.h"
+#include "utils/palloc.h"
+#include "utils/memutils.h"
 
 #include "version.h"
-#include "parser/pool_memory.h"
-#include "parser/pool_string.h"
 #include "auth/pool_passwd.h"
 #include "query_cache/pool_memqcache.h"
 #include "watchdog/wd_ext.h"
 
-/*
- * Process pending signal actions.
- */
-#define CHECK_REQUEST \
-	do { \
-		if (wakeup_request) \
-		{ \
-			wakeup_children(); \
-			wakeup_request = 0; \
-		} \
-		if (failover_request) \
-		{ \
-			failover(); \
-			failover_request = 0; \
-		} \
-		if (sigchld_request) \
-		{ \
-			reaper(); \
-		} \
-		if (reload_config_request) \
-		{ \
-			reload_config(); \
-			reload_config_request = 0; \
-		} \
-    } while (0)
-
-#define CLEAR_ALARM \
-	do { \
-			pool_debug("health check: clearing alarm"); \
-    } while (alarm(0) > 0)
-
-#define PGPOOLMAXLITSENQUEUELENGTH 10000
 static void daemonize(void);
 static int read_pid_file(void);
 static void write_pid_file(void);
-static int read_status_file(bool discard_status);
-static int write_status_file(void);
-static pid_t pcp_fork_a_child(int unix_fd, int inet_fd, char *pcp_conf_file);
-static pid_t fork_a_child(int unix_fd, int inet_fd, int id);
-static pid_t worker_fork_a_child(void);
-static int create_unix_domain_socket(struct sockaddr_un un_addr_tmp);
-static int create_inet_domain_socket(const char *hostname, const int port);
-static void myexit(int code);
-static void failover(void);
-static void reaper(void);
-static void wakeup_children(void);
-static void reload_config(void);
-static int pool_pause(struct timeval *timeout);
-static void kill_all_children(int sig);
-static int get_next_master_node(void);
-static pid_t fork_follow_child(int old_master, int new_primary, int old_primary);
-
-static RETSIGTYPE exit_handler(int sig);
-static RETSIGTYPE reap_handler(int sig);
-static RETSIGTYPE failover_handler(int sig);
-static RETSIGTYPE reload_config_handler(int sig);
-static RETSIGTYPE health_check_timer_handler(int sig);
-static RETSIGTYPE wakeup_handler(int sig);
-
-static int health_check(void);
-static int system_db_health_check(void);
-
 static void usage(void);
 static void show_version(void);
 static void stop_me(void);
+static void FileUnlink(int code, Datum path);
 
-static int trigger_failover_command(int node, const char *command_line,
-									int old_master, int new_master, int old_primary);
-
-static int find_primary_node(void);
-static int find_primary_node_repeatedly(void);
-
-static struct sockaddr_un un_addr;		/* unix domain socket path */
-static struct sockaddr_un pcp_un_addr;  /* unix domain socket path for PCP */
-
-ProcessInfo *process_info;	/* Per child info table on shmem */
-
-/*
- * Private copy of backend status
- */
-BACKEND_STATUS private_backend_status[MAX_NUM_BACKENDS];
-
-/*
- * shmem connection info table
- * this is a three dimension array. i.e.:
- * con_info[pool_config->num_init_children][pool_config->max_pool][MAX_NUM_BACKENDS]
- */
-ConnectionInfo *con_info;
-
-static int unix_fd;	/* unix domain socket fd */
-static int inet_fd;	/* inet domain socket fd */
-
-static int follow_pid; /* pid for child process handling follow command */
-static int pcp_pid; /* pid for child process handling PCP */
-static int pcp_unix_fd; /* unix domain socket fd for PCP (not used) */
-static int pcp_inet_fd; /* inet domain socket fd for PCP */
-static char pcp_conf_file[POOLMAXPATHLEN+1]; /* path for pcp.conf */
-static char conf_file[POOLMAXPATHLEN+1];
-static char hba_file[POOLMAXPATHLEN+1];
-
-static int exiting = 0;		/* non 0 if I'm exiting */
-static int switching = 0;		/* non 0 if I'm fail overing or degenerating */
+char pcp_conf_file[POOLMAXPATHLEN+1]; /* path for pcp.conf */
+char conf_file[POOLMAXPATHLEN+1];
+char hba_file[POOLMAXPATHLEN+1];
 
 static int not_detach = 0;		/* non 0 if non detach option (-n) is given */
-
-static int stop_sig = SIGTERM;	/* stopping signal default value */
-
-POOL_REQUEST_INFO *Req_info;		/* request info area in shared memory */
-volatile sig_atomic_t *InRecovery; /* non 0 if recovery is started */
-volatile sig_atomic_t reload_config_request = 0;
-static volatile sig_atomic_t failover_request = 0;
-static volatile sig_atomic_t sigchld_request = 0;
-static volatile sig_atomic_t wakeup_request = 0;
-
-static int pipe_fds[2]; /* for delivering signals */
-
-int my_proc_id;
-
-static BackendStatusRecord backend_rec;	/* Backend status record */
-
-static pid_t worker_pid; /* pid of worker process */
-
-BACKEND_STATUS* my_backend_status[MAX_NUM_BACKENDS];		/* Backend status buffer */
-int my_master_node_id;		/* Master node id buffer */
-
+int stop_sig = SIGTERM;		/* stopping signal default value */
 int myargc;
 char **myargv;
 
-/*
-* pgpool main program
-*/
 int main(int argc, char **argv)
 {
 	int opt;
-	int i;
-	int pid;
-	int size;
-	int retrycnt;
-	int sys_retrycnt;
 	int debug_level = 0;
 	int	optindex;
 	bool discard_status = false;
-	bool retrying;
 	bool clear_memcache_oidmaps = false;
 
 	static struct option long_options[] = {
@@ -317,37 +177,42 @@ int main(int argc, char **argv)
 	SSL_load_error_strings();
 #endif /* USE_SSL */
 
+
+	/* create MemoryContexts */
+	MemoryContextInit();
+
 	mypid = getpid();
 
-	if (pool_init_config())
-		exit(1);
+	pool_init_config();
 
 	/*
 	 * Override debug level
 	 */
 	pool_config->debug_level = debug_level;
 
-	if (pool_get_config(conf_file, INIT_CONFIG))
-	{
-		pool_error("Unable to get configuration. Exiting...");
-		exit(1);
-	}
-
-	/*
-	 * Open syslog connection if required
-	 */
-	if (!strcmp(pool_config->log_destination, "syslog")) {
-		openlog(pool_config->syslog_ident, LOG_PID|LOG_NDELAY|LOG_NOWAIT, pool_config->syslog_facility);
-		/* set a flag to allow pool_error.c to begin writing to syslog
-		   instead of stdout now that pool_get_config() is done */
-		pool_config->logsyslog = 1;
-	}
+	pool_get_config(conf_file, INIT_CONFIG);
 
 	/*
 	 * Override debug level
 	 */
 	if (pool_config->debug_level == 0)
 		pool_config->debug_level = debug_level;
+	/* 
+	 * TODO do it some better way, But till the time we decide
+	 * which min_* gucs we need to maintain lets do it this way
+	 */
+	if(pool_config->debug_level < 5)
+	{
+		log_min_error_statement = LOG - pool_config->debug_level;
+		log_min_messages = LOG - pool_config->debug_level;
+		client_min_messages = LOG - pool_config->debug_level;
+	}
+	else 
+	{
+		log_min_error_statement = DEBUG5;
+		log_min_messages = DEBUG5;
+		client_min_messages = DEBUG5;
+	}
 
 	if (pool_config->enable_pool_hba)
 		load_hba(hba_file);
@@ -364,31 +229,28 @@ int main(int argc, char **argv)
 				pid = read_pid_file();
 				if (pid < 0)
 				{
-					pool_error("could not read pid file");
-					pool_shmem_exit(1);
-					exit(1);
+					ereport(FATAL,
+						(return_code(1),
+						errmsg("could not read pid file")));
 				}
 
 				if (kill(pid, SIGHUP) == -1)
 				{
-					pool_error("could not reload configuration file pid: %d. reason: %s", pid, strerror(errno));
-					pool_shmem_exit(1);
-					exit(1);
+					ereport(FATAL,
+						(return_code(1),
+						errmsg("could not reload configuration file pid: %d. reason: %s", pid, strerror(errno))));
 				}
-				pool_shmem_exit(0);
 				exit(0);
 		}
 		if (!strcmp(argv[optind], "stop"))
 		{
 			stop_me();
 			unlink(pool_config->pid_file_name);
-			pool_shmem_exit(0);
-			exit(0);
+			proc_exit(0);
 		}
 		else
 		{
 			usage();
-			pool_shmem_exit(1);
 			exit(1);
 		}
 	}
@@ -397,16 +259,17 @@ int main(int argc, char **argv)
 	 */
 	else if (optind == argc)
 	{
-		pid = read_pid_file();
+		int pid = read_pid_file();
 		if (pid > 0)
 		{
 			if (kill(pid, 0) == 0)
 			{
-				fprintf(stderr, "pid file found. is another pgpool(%d) is running?\n", pid);
-				exit(1);
+				ereport(FATAL,
+					(errmsg("pid file found. is another pgpool(%d) is running?\n", pid)));
 			}
 			else
-				fprintf(stderr, "pid file found but it seems bogus. Trying to start pgpool anyway...\n");
+				ereport(NOTICE,
+					(errmsg("pid file found but it seems bogus. Trying to start pgpool anyway...\n")));
 		}
 	}
 	/*
@@ -426,7 +289,8 @@ int main(int argc, char **argv)
 		if (wd_chk_setuid() == 1)
 		{
 			/* if_up, if_down and arping command have a setuid bit */
-			pool_log("watchdog might call network commands which using setuid bit.");
+			ereport(LOG,
+				(errmsg("watchdog might call network commands which using setuid bit.")));
 		}
 	}
 
@@ -437,7 +301,7 @@ int main(int argc, char **argv)
 		write_pid_file();
 	else
 		daemonize();
-
+	
 	/*
 	 * Locate pool_passwd
 	 * The default file name "pool_passwd" can be changed by setting
@@ -458,390 +322,14 @@ int main(int argc, char **argv)
 
 	if (pool_semaphore_create(MAX_NUM_SEMAPHORES))
 	{
-		pool_error("Unable to create semaphores. Exiting...");
-		pool_shmem_exit(1);
-		exit(1);
-	}
-
-	/*
-	 * Restore previous backend status if possible
-	 */
-	read_status_file(discard_status);
-
-	/* set unix domain socket path for connections to pgpool */
-	snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/.s.PGSQL.%d",
-			 pool_config->socket_dir,
-			 pool_config->port);
-	/* set unix domain socket path for pgpool PCP communication */
-	snprintf(pcp_un_addr.sun_path, sizeof(pcp_un_addr.sun_path), "%s/.s.PGSQL.%d",
-			 pool_config->pcp_socket_dir,
-			 pool_config->pcp_port);
-
-	/* set up signal handlers */
-	pool_signal(SIGPIPE, SIG_IGN);
-
-	/* create unix domain socket */
-	unix_fd = create_unix_domain_socket(un_addr);
-
-	/* create inet domain socket if any */
-	if (pool_config->listen_addresses[0])
-	{
-		inet_fd = create_inet_domain_socket(pool_config->listen_addresses, pool_config->port);
-	}
-
-	/*
-	 * con_info is a 3 dimension array: i corresponds to pgpool child
-	 * process, j corresponds to connection pool in each process and k
-	 * corresponds to backends in each connection pool.
-	 *
-	 * XXX: Before 2010/4/12 this was a 2 dimension array: i
-	 * corresponds to pgpool child process, j corresponds to
-	 * connection pool in each process. Of course this was wrong.
-	 */
-	size = pool_coninfo_size();
-	con_info = pool_shared_memory_create(size);
-	if (con_info == NULL)
-	{
-		pool_error("failed to allocate connection information");
-		myexit(1);
-	}
-	memset(con_info, 0, size);
-
-	size = pool_config->num_init_children * (sizeof(ProcessInfo));
-	process_info = pool_shared_memory_create(size);
-	if (process_info == NULL)
-	{
-		pool_error("failed to allocate process_info");
-		myexit(1);
-	}
-	memset(process_info, 0, size);
-	for (i = 0; i < pool_config->num_init_children; i++)
-	{
-		process_info[i].connection_info = pool_coninfo(i,0,0);
-	}
-
-	/* create fail over/switch over event area */
-	Req_info = pool_shared_memory_create(sizeof(POOL_REQUEST_INFO));
-	if (Req_info == NULL)
-	{
-		pool_error("failed to allocate Req_info");
-		myexit(1);
-	}
-
-	/*
-	 * Initialize backend status area.
-	 * From now on, VALID_BACKEND macro can be used.
-	 * (get_next_master_node() uses VALID_BACKEND)
-	 */
-
-	for (i=0;i<MAX_NUM_BACKENDS;i++)
-	{
-		my_backend_status[i] = &(BACKEND_INFO(i).backend_status);
-	}
-
-	/* initialize Req_info */
-	Req_info->kind = NODE_UP_REQUEST;
-	memset(Req_info->node_id, -1, sizeof(int) * MAX_NUM_BACKENDS);
-	Req_info->master_node_id = get_next_master_node();
-	Req_info->conn_counter = 0;
-	Req_info->switching = false;
-
-	InRecovery = pool_shared_memory_create(sizeof(int));
-	if (InRecovery == NULL)
-	{
-		pool_error("failed to allocate InRecovery");
-		myexit(1);
-	}
-	*InRecovery = RECOVERY_INIT;
-
-	/*
-	 * Initialize shared memory cache
-	 */
-	if (pool_config->memory_cache_enabled)
-	{
-		if (pool_is_shmem_cache())
-		{
-			size_t size;
-
-			size = pool_shared_memory_cache_size();
-			if (size == 0)
-			{
-				pool_error("pool_shared_memory_cache_size error");
-				myexit(1);
-			}
-
-			if (pool_init_memory_cache(size) < 0)
-			{
-				pool_error("pool_shared_memory_cache_size error");
-				myexit(1);
-			}
-
-			size = pool_shared_memory_fsmm_size();
-			if (size == 0)
-			{
-				pool_error("pool_shared_memory_fsmm_size error");
-				myexit(1);
-			}
-			pool_init_fsmm(size);
-
-			pool_allocate_fsmm_clock_hand();
-
-			pool_discard_oid_maps();
-			pool_log("pool_discard_oid_maps: discarded memqcache oid maps");
-
-			pool_hash_init(pool_config->memqcache_max_num_cache);
-		}
-
-#ifdef USE_MEMCACHED
-		else
-		{
-			if (clear_memcache_oidmaps)
-			{
-				pool_discard_oid_maps();
-				pool_log("pool_discard_oid_maps: discarded memqcache oid maps");
-			}
-			else
-			{
-				pool_debug("skipped discarding memqcache oid maps");
-			}
-		}
-#endif
-
-		if (pool_init_memqcache_stats() < 0)
-		{
-			pool_error("pool_init_memqcache_stats error");
-			myexit(1);
-		}
-	}
-
-	/* start watchdog */
-	if (pool_config->use_watchdog )
-	{
-		if (!wd_main(1))
-		{
-			pool_error("wd_main error");
-			myexit(1);
-		}
-	}
-
-	/*
-	 * We need to block signal here. Otherwise child might send some
-	 * signals, for example SIGUSR1(fail over).  Children will inherit
-	 * signal blocking but they do unblock signals at the very beginning
-	 * of process.  So this is harmless.
-	 */
-	POOL_SETMASK(&BlockSig);
-
-	/* fork the children */
-	for (i=0;i<pool_config->num_init_children;i++)
-	{
-		process_info[i].pid = fork_a_child(unix_fd, inet_fd, i);
-		process_info[i].start_time = time(NULL);
-	}
-
-	/* set up signal handlers */
-
-	pool_signal(SIGTERM, exit_handler);
-	pool_signal(SIGINT, exit_handler);
-	pool_signal(SIGQUIT, exit_handler);
-	pool_signal(SIGCHLD, reap_handler);
-	pool_signal(SIGUSR1, failover_handler);
-	pool_signal(SIGUSR2, wakeup_handler);
-	pool_signal(SIGHUP, reload_config_handler);
-
-	/* create pipe for delivering event */
-	if (pipe(pipe_fds) < 0)
-	{
-		pool_error("failed to create pipe");
-		myexit(1);
+		ereport(FATAL,
+			(errmsg("Unable to create semaphores. Exiting...")));
 	}
 
-	pool_log("%s successfully started. version %s (%s)", PACKAGE, VERSION, PGPOOLVERSION);
-
-	/* fork a child for PCP handling */
-	pcp_unix_fd = create_unix_domain_socket(pcp_un_addr);
-    /* maybe change "*" to pool_config->pcp_listen_addresses */
-	pcp_inet_fd = create_inet_domain_socket("*", pool_config->pcp_port);
-	pcp_pid = pcp_fork_a_child(pcp_unix_fd, pcp_inet_fd, pcp_conf_file);
-
-	/* Fork worker process */
-	worker_pid = worker_fork_a_child();
-
-	retrycnt = 0;		/* reset health check retry counter */
-	sys_retrycnt = 0;	/* reset SystemDB health check retry counter */
-
-	/* Save primary node id */
-	Req_info->primary_node_id = find_primary_node();
-
-	/*
-	 * This is the main loop
-	 */
-
-	retrying = false;
-
-	for (;;)
-	{
-		CHECK_REQUEST;
-
-		/* do we need health checking for PostgreSQL? */
-		if (pool_config->health_check_period > 0)
-		{
-			int sts;
-			int sys_sts = 0;
-			unsigned int sleep_time;
-
-			if (retrycnt == 0)
-			{
-				pool_debug("starting health checking");
-			}
-			else
-			{
-				pool_debug("retrying %d th health checking", retrycnt);
-			}
-
-			if (pool_config->health_check_timeout > 0)
-			{
-				/*
-				 * set health checker timeout. we want to detect
-				 * communication path failure much earlier before
-				 * TCP/IP stack detects it.
-				 */
-				CLEAR_ALARM;
-				pool_signal(SIGALRM, health_check_timer_handler);
-				alarm(pool_config->health_check_timeout);
-			}
-
-			/*
-			 * do actual health check. trying to connect to the backend
-			 */
-			errno = 0;
-			health_check_timer_expired = 0;
-			POOL_SETMASK(&UnBlockSig);
-			sts = health_check();
-			POOL_SETMASK(&BlockSig);
-
-			if (pool_config->parallel_mode)
-				sys_sts = system_db_health_check();
-
-			if ((sts > 0 || sys_sts < 0) && (errno != EINTR || (errno == EINTR && health_check_timer_expired)))
-			{
-				if (sts > 0)
-				{
-					sts--;
-
-					retrycnt++;
-					pool_signal(SIGALRM, SIG_IGN);	/* Cancel timer */
-					CLEAR_ALARM;
-
-					if (!pool_config->parallel_mode)
-					{
-						if (POOL_DISALLOW_TO_FAILOVER(BACKEND_INFO(sts).flag))
-						{
-							pool_log("health_check: %d failover is canceled because failover is disallowed", sts);
-						}
-						else if (retrycnt <= pool_config->health_check_max_retries)
-						{
-							/* continue to retry */
-							sleep_time = pool_config->health_check_retry_delay;
-							pool_log("health check retry sleep time: %d second(s)", sleep_time);
-							pool_sleep(sleep_time);
-							retrying = true;
-							continue;
-						}
-						else
-						{
-							/* retry count over */
-							pool_log("set %d th backend down status", sts);
-							Req_info->kind = NODE_DOWN_REQUEST;
-							Req_info->node_id[0] = sts;
-							health_check_timer_expired = 0;
-							failover();
-							/* need to distribute this info to children */
-							retrying = false;
-						}
-					}
-					else
-					{
-						if (retrycnt > NUM_BACKENDS)
-						{
-							/* retry count over */
-							pool_log("set %d th backend down status", sts);
-							Req_info->kind = NODE_DOWN_REQUEST;
-							Req_info->node_id[0] = sts;
-							health_check_timer_expired = 0;
-							failover();
-							retrycnt = 0;
-							retrying = false;
-						}
-						else
-						{
-							/* continue to retry */
-							sleep_time = pool_config->health_check_period/NUM_BACKENDS;
-							pool_debug("retry sleep time: %d seconds", sleep_time);
-							pool_sleep(sleep_time);
-							continue;
-						}
-					}
-				}
-				if (sys_sts < 0)
-				{
-					sys_retrycnt++;
-					pool_signal(SIGALRM, SIG_IGN);
-					CLEAR_ALARM;
-
-					if (sys_retrycnt > NUM_BACKENDS)
-					{
-						pool_log("set SystemDB down status");
-						SYSDB_STATUS = CON_DOWN;
-						sys_retrycnt = 0;
-					}
-					else if (sts == 0) /* goes to sleep only when SystemDB alone was down */
-					{
-						sleep_time = pool_config->health_check_period/NUM_BACKENDS;
-						pool_debug("retry sleep time: %d seconds", sleep_time);
-						pool_sleep(sleep_time);
-						continue;
-					}
-				}
-			}
-			else
-			{
-				/* success. reset retry count */
-				retrycnt = 0;
-				if (retrying)
-				{
-					pool_log("after some retrying backend returned to healthy state");
-					retrying = false;
-				}
-			}
-
-			if (pool_config->health_check_timeout > 0)
-			{
-				/* seems OK. cancel health check timer */
-				pool_signal(SIGALRM, SIG_IGN);
-				CLEAR_ALARM;
-			}
-
-			sleep_time = pool_config->health_check_period;
-			pool_sleep(sleep_time);
-		}
-		else
-		{
-			for (;;)
-			{
-				int r;
-				struct timeval t = {3, 0};
+	PgpoolMain(discard_status, clear_memcache_oidmaps); /* this is an infinate loop */
 
-				POOL_SETMASK(&UnBlockSig);
-				r = pool_pause(&t);
-				POOL_SETMASK(&BlockSig);
-				if (r > 0)
-					break;
-			}
-		}
-	}
+	exit(0);
 
-	pool_shmem_exit(0);
 }
 
 static void show_version(void)
@@ -898,23 +386,21 @@ static void daemonize(void)
 	pid = fork();
 	if (pid == (pid_t) -1)
 	{
-		pool_error("fork() failed. reason: %s", strerror(errno));
-		pool_shmem_exit(1);
-		exit(1);
-		return;					/* not reached */
+		ereport(FATAL,
+			(errmsg("could not daemonize the pgpool-II"),
+				errdetail("fork() system call failed with reason: \"%s\"", strerror(errno) )));
 	}
 	else if (pid > 0)
 	{			/* parent */
-		pool_shmem_exit(0);
-		exit(0);
+		proc_exit(0);
 	}
 
 #ifdef HAVE_SETSID
 	if (setsid() < 0)
 	{
-		pool_error("setsid() failed. reason:%s", strerror(errno));
-		pool_shmem_exit(1);
-		exit(1);
+		ereport(FATAL,
+			(errmsg("could not daemonize the pgpool-II"),
+				errdetail("setsid() system call failed with reason: \"%s\"", strerror(errno) )));
 	}
 #endif
 
@@ -937,15 +423,8 @@ static void daemonize(void)
     fdlimit = sysconf(_SC_OPEN_MAX);
     for (i = 3; i < fdlimit; i++)
 		close(i);
-
-	/* reopen syslog connection after daemonizing */
-	if (pool_config->logsyslog) {
-		openlog(pool_config->syslog_ident, LOG_PID|LOG_NDELAY|LOG_NOWAIT, pool_config->syslog_facility);
-	}
-
 }
 
-
 /*
 * stop myself
 */
@@ -956,19 +435,18 @@ static void stop_me(void)
 	pid = read_pid_file();
 	if (pid < 0)
 	{
-		pool_error("could not read pid file");
-		pool_shmem_exit(1);
-		exit(1);
+		ereport(FATAL,
+			(errmsg("could not read pid file")));
 	}
 
 	if (kill(pid, stop_sig) == -1)
 	{
-		pool_error("could not stop pid: %d. reason: %s", pid, strerror(errno));
-		pool_shmem_exit(1);
-		exit(1);
+		ereport(FATAL,
+			(errmsg("could not stop process with pid: %d", pid),
+				errdetail("\"%s\"", strerror(errno))));
 	}
-
-	fprintf(stderr, "stop request sent to pgpool. waiting for termination...");
+	ereport(LOG,
+		(errmsg ("stop request sent to pgpool. waiting for termination...")));
 
 	while (kill(pid, 0) == 0)
 	{
@@ -994,17 +472,17 @@ static int read_pid_file(void)
 	}
 	if ((readlen = read(fd, pidbuf, sizeof(pidbuf))) == -1)
 	{
-		pool_error("could not read pid file as %s. reason: %s",
-				   pool_config->pid_file_name, strerror(errno));
 		close(fd);
-		return -1;
+		ereport(FATAL,
+			(errmsg("could not read pid file as \"%s\". reason: %s",
+				   pool_config->pid_file_name, strerror(errno))));
 	}
 	else if (readlen == 0)
 	{
-		pool_error("EOF detected while reading pid file as %s. reason: %s",
-				   pool_config->pid_file_name, strerror(errno));
 		close(fd);
-		return -1;
+		ereport(FATAL,
+			(errmsg("EOF detected while reading pid file \"%s\". reason: %s",
+				   pool_config->pid_file_name, strerror(errno))));
 	}
 	close(fd);
 	return(atoi(pidbuf));
@@ -1021,1934 +499,60 @@ static void write_pid_file(void)
 	fd = open(pool_config->pid_file_name, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
 	if (fd == -1)
 	{
-		pool_error("could not open pid file as %s. reason: %s",
-				   pool_config->pid_file_name, strerror(errno));
-		pool_shmem_exit(1);
-		exit(1);
+		ereport(FATAL,
+			(errmsg("could not open pid file as %s. reason: %s",
+				   pool_config->pid_file_name, strerror(errno))));
 	}
 	snprintf(pidbuf, sizeof(pidbuf), "%d", (int)getpid());
 	if (write(fd, pidbuf, strlen(pidbuf)+1) == -1)
 	{
-		pool_error("could not write pid file as %s. reason: %s",
-				   pool_config->pid_file_name, strerror(errno));
 		close(fd);
-		pool_shmem_exit(1);
-		exit(1);
+		ereport(FATAL,
+			(errmsg("could not write pid file as %s. reason: %s",
+				   pool_config->pid_file_name, strerror(errno))));
 	}
 	if (fsync(fd) == -1)
 	{
-		pool_error("could not fsync pid file as %s. reason: %s",
-				   pool_config->pid_file_name, strerror(errno));
 		close(fd);
-		pool_shmem_exit(1);
-		exit(1);
+		ereport(FATAL,
+			(errmsg("could not fsync pid file as %s. reason: %s",
+				   pool_config->pid_file_name, strerror(errno))));
 	}
 	if (close(fd) == -1)
 	{
-		pool_error("could not close pid file as %s. reason: %s",
-				   pool_config->pid_file_name, strerror(errno));
-		pool_shmem_exit(1);
-		exit(1);
+		ereport(FATAL,
+			(errmsg("could not close pid file as %s. reason: %s",
+				   pool_config->pid_file_name, strerror(errno))));
 	}
+	/* register the call back to delete the pid file at system exit */
+	on_proc_exit(FileUnlink, (Datum) pool_config->pid_file_name);
 }
 
 /*
-* Read the status file
-*/
-static int read_status_file(bool discard_status)
+ * get_config_file_name: return full path of pgpool.conf.
+ */
+char *get_config_file_name(void)
 {
-	FILE *fd;
-	char fnamebuf[POOLMAXPATHLEN];
-	int i;
-	bool someone_wakeup = false;
-
-	snprintf(fnamebuf, sizeof(fnamebuf), "%s/%s", pool_config->logdir, STATUS_FILE_NAME);
-	fd = fopen(fnamebuf, "r");
-	if (!fd)
-	{
-		pool_log("Backend status file %s does not exist", fnamebuf);
-		return -1;
-	}
-
-	/*
-	 * If discard_status is true, unlink pgpool_status and
-	 * do not restore previous status.
-	 */
-	if (discard_status)
-	{
-		fclose(fd);
-		if (unlink(fnamebuf) == 0)
-		{
-			pool_log("Backend status file %s discarded", fnamebuf);
-		}
-		else
-		{
-			pool_error("Failed to discard backend status file %s reason:%s", fnamebuf, strerror(errno));
-		}
-		return 0;
-	}
-
-	if (fread(&backend_rec, 1, sizeof(backend_rec), fd) != sizeof(backend_rec))
-	{
-		pool_error("Could not read backend status file as %s. reason: %s",
-				   fnamebuf, strerror(errno));
-		fclose(fd);
-		return -1;
-	}
-	fclose(fd);
-
-	for (i=0;i< pool_config->backend_desc->num_backends;i++)
-	{
-		if (backend_rec.status[i] == CON_DOWN)
-		{
-			BACKEND_INFO(i).backend_status = CON_DOWN;
-			pool_log("read_status_file: %d th backend is set to down status", i);
-		}
-		else
-		{
-			BACKEND_INFO(i).backend_status = CON_CONNECT_WAIT;
-			someone_wakeup = true;
-		}
-	}
-
-	/*
-	 * If no one woke up, we regard the status file bogus
-	 */
-	if (someone_wakeup == false)
-	{
-		for (i=0;i< pool_config->backend_desc->num_backends;i++)
-		{
-			BACKEND_INFO(i).backend_status = CON_CONNECT_WAIT;
-		}
-	}
-
-	return 0;
+	return conf_file;
 }
 
 /*
-* Write the pid file
-*/
-static int write_status_file(void)
-{
-	FILE *fd;
-	char fnamebuf[POOLMAXPATHLEN];
-	int i;
-
-	snprintf(fnamebuf, sizeof(fnamebuf), "%s/%s", pool_config->logdir, STATUS_FILE_NAME);
-	fd = fopen(fnamebuf, "w");
-	if (!fd)
-	{
-		pool_error("Could not open status file %s", fnamebuf);
-		return -1;
-	}
-
-	memset(&backend_rec, 0, sizeof(backend_rec));
-
-	for (i=0;i< pool_config->backend_desc->num_backends;i++)
-	{
-		backend_rec.status[i] = BACKEND_INFO(i).backend_status;
-	}
-
-	if (fwrite(&backend_rec, 1, sizeof(backend_rec), fd) != sizeof(backend_rec))
-	{
-		pool_error("Could not write backend status file as %s. reason: %s",
-				   fnamebuf, strerror(errno));
-		fclose(fd);
-		return -1;
-	}
-	fclose(fd);
-	return 0;
-}
-
-/*
- * fork a child for PCP
- */
-pid_t pcp_fork_a_child(int unix_fd, int inet_fd, char *pcp_conf_file)
-{
-	pid_t pid;
-
-	pid = fork();
-
-	if (pid == 0)
-	{
-		close(pipe_fds[0]);
-		close(pipe_fds[1]);
-
-		myargv = save_ps_display_args(myargc, myargv);
-
-		/* call PCP child main */
-		POOL_SETMASK(&UnBlockSig);
-		health_check_timer_expired = 0;
-		reload_config_request = 0;
-		run_as_pcp_child = true;
-		pcp_do_child(unix_fd, inet_fd, pcp_conf_file);
-	}
-	else if (pid == -1)
-	{
-		pool_error("fork() failed. reason: %s", strerror(errno));
-		myexit(1);
-	}
-	return pid;
-}
-
-/*
-* fork a child
-*/
-pid_t fork_a_child(int unix_fd, int inet_fd, int id)
-{
-	pid_t pid;
-
-	pid = fork();
-
-	if (pid == 0)
-	{
-		/* Before we unconditionally closed pipe_fds[0] and pipe_fds[1]
-		 * here, which is apparently wrong since in the start up of
-		 * pgpool, pipe(2) is not called yet and it mistakenly closes
-		 * fd 0. Now we check the fd > 0 before close(), expecting
-		 * pipe returns fds greater than 0.  Note that we cannot
-		 * unconditionally remove close(2) calls since fork_a_child()
-		 * may be called *after* pgpool starting up.
-		 */
-		if (pipe_fds[0] > 0)
-		{
-			close(pipe_fds[0]);
-			close(pipe_fds[1]);
-		}
-
-		myargv = save_ps_display_args(myargc, myargv);
-
-		/* call child main */
-		POOL_SETMASK(&UnBlockSig);
-		health_check_timer_expired = 0;
-		reload_config_request = 0;
-		my_proc_id = id;
-		run_as_pcp_child = false;
-		do_child(unix_fd, inet_fd);
-	}
-	else if (pid == -1)
-	{
-		pool_error("fork() failed. reason: %s", strerror(errno));
-		myexit(1);
-	}
-	return pid;
-}
-
-/*
-* fork worker child process
-*/
-pid_t worker_fork_a_child()
-{
-	pid_t pid;
-
-	pid = fork();
-
-	if (pid == 0)
-	{
-		/* Before we unconditionally closed pipe_fds[0] and pipe_fds[1]
-		 * here, which is apparently wrong since in the start up of
-		 * pgpool, pipe(2) is not called yet and it mistakenly closes
-		 * fd 0. Now we check the fd > 0 before close(), expecting
-		 * pipe returns fds greater than 0.  Note that we cannot
-		 * unconditionally remove close(2) calls since fork_a_child()
-		 * may be called *after* pgpool starting up.
-		 */
-		if (pipe_fds[0] > 0)
-		{
-			close(pipe_fds[0]);
-			close(pipe_fds[1]);
-		}
-
-		myargv = save_ps_display_args(myargc, myargv);
-
-		/* call child main */
-		POOL_SETMASK(&UnBlockSig);
-		health_check_timer_expired = 0;
-		reload_config_request = 0;
-		do_worker_child();
-	}
-	else if (pid == -1)
-	{
-		pool_error("fork() failed. reason: %s", strerror(errno));
-		myexit(1);
-	}
-	return pid;
-}
-
-/*
-* create inet domain socket
-*/
-static int create_inet_domain_socket(const char *hostname, const int port)
-{
-	struct sockaddr_in addr;
-	int fd;
-	int status;
-	int one = 1;
-	int len;
-	int backlog;
-
-	fd = socket(AF_INET, SOCK_STREAM, 0);
-	if (fd == -1)
-	{
-		pool_error("Failed to create INET domain socket. reason: %s", strerror(errno));
-		myexit(1);
-	}
-	if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one,
-					sizeof(one))) == -1)
-	{
-		pool_error("setsockopt() failed. reason: %s", strerror(errno));
-		myexit(1);
-	}
-
-	memset((char *) &addr, 0, sizeof(addr));
-	addr.sin_family = AF_INET;
-
-	if (strcmp(hostname, "*")==0)
-	{
-		addr.sin_addr.s_addr = htonl(INADDR_ANY);
-	}
-	else
-	{
-		struct hostent *hostinfo;
-
-		hostinfo = gethostbyname(hostname);
-		if (!hostinfo)
-		{
-			pool_error("could not resolve host name \"%s\": %s", hostname, hstrerror(h_errno));
-			myexit(1);
-		}
-		addr.sin_addr = *(struct in_addr *) hostinfo->h_addr;
-	}
-
-	addr.sin_port = htons(port);
-	len = sizeof(struct sockaddr_in);
-	status = bind(fd, (struct sockaddr *)&addr, len);
-	if (status == -1)
-	{
-		char *host = "", *serv = "";
-		char hostname[NI_MAXHOST], servname[NI_MAXSERV];
-		if (getnameinfo((struct sockaddr *) &addr, len, hostname, sizeof(hostname), servname, sizeof(servname), 0) == 0) {
-			host = hostname;
-			serv = servname;
-		}
-		pool_error("bind(%s:%s) failed. reason: %s", host, serv, strerror(errno));
-		myexit(1);
-	}
-
-	backlog = pool_config->num_init_children * 2;
-	if (backlog > PGPOOLMAXLITSENQUEUELENGTH)
-		backlog = PGPOOLMAXLITSENQUEUELENGTH;
-
-	status = listen(fd, backlog);
-	if (status < 0)
-	{
-		pool_error("listen() failed. reason: %s", strerror(errno));
-		myexit(1);
-	}
-	return fd;
-}
-
-/*
-* create UNIX domain socket
-*/
-static int create_unix_domain_socket(struct sockaddr_un un_addr_tmp)
-{
-	struct sockaddr_un addr;
-	int fd;
-	int status;
-	int len;
-
-	fd = socket(AF_UNIX, SOCK_STREAM, 0);
-	if (fd == -1)
-	{
-		pool_error("Failed to create UNIX domain socket. reason: %s", strerror(errno));
-		myexit(1);
-	}
-	memset((char *) &addr, 0, sizeof(addr));
-	addr.sun_family = AF_UNIX;
-	snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", un_addr_tmp.sun_path);
-	len = sizeof(struct sockaddr_un);
-	status = bind(fd, (struct sockaddr *)&addr, len);
-	if (status == -1)
-	{
-		pool_error("bind(%s) failed. reason: %s", addr.sun_path, strerror(errno));
-		myexit(1);
-	}
-
-	if (chmod(un_addr_tmp.sun_path, 0777) == -1)
-	{
-		pool_error("chmod() failed. reason: %s", strerror(errno));
-		myexit(1);
-	}
-
-	status = listen(fd, PGPOOLMAXLITSENQUEUELENGTH);
-	if (status < 0)
-	{
-		pool_error("listen() failed. reason: %s", strerror(errno));
-		myexit(1);
-	}
-	return fd;
-}
-
-static void myunlink(const char* path)
-{
-	if (unlink(path) == 0) return;
-	pool_error("unlink(%s) failed: %s", path, strerror(errno));
-}
-
-static void myexit(int code)
-{
-	int i;
-
-	if (getpid() != mypid)
-		return;
-
-	if (process_info != NULL) {
-		POOL_SETMASK(&AuthBlockSig);
-		exiting = 1;
-		for (i = 0; i < pool_config->num_init_children; i++)
-		{
-			pid_t pid = process_info[i].pid;
-			if (pid)
-			{
-				kill(pid, SIGTERM);
-			}
-		}
-
-		/* wait for all children to exit */
-		while (wait(NULL) > 0)
-			;
-		if (errno != ECHILD)
-			pool_error("wait() failed. reason:%s", strerror(errno));
-		POOL_SETMASK(&UnBlockSig);
-	}
-
-	myunlink(un_addr.sun_path);
-	myunlink(pcp_un_addr.sun_path);
-	myunlink(pool_config->pid_file_name);
-
-	write_status_file();
-
-	pool_shmem_exit(code);
-	exit(code);
-}
-
-void notice_backend_error(int node_id)
-{
-	int n = node_id;
-
-	if (getpid() == mypid)
-	{
-		pool_log("notice_backend_error: called from pgpool main. ignored.");
-	}
-	else
-	{
-		degenerate_backend_set(&n, 1);
-	}
-}
-
-/* notice backend connection error using SIGUSR1 */
-void degenerate_backend_set(int *node_id_set, int count)
-{
-	pid_t parent = getppid();
-	int i;
-	bool need_signal = false;
-#ifdef HAVE_SIGPROCMASK
-	sigset_t oldmask;
-#else
-	int	oldmask;
-#endif
-
-	if (pool_config->parallel_mode)
-	{
-		return;
-	}
-
-	POOL_SETMASK2(&BlockSig, &oldmask);
-	pool_semaphore_lock(REQUEST_INFO_SEM);
-	Req_info->kind = NODE_DOWN_REQUEST;
-	for (i = 0; i < count; i++)
-	{
-		if (node_id_set[i] < 0 || node_id_set[i] >= MAX_NUM_BACKENDS ||
-			!VALID_BACKEND(node_id_set[i]))
-		{
-			pool_log("degenerate_backend_set: node %d is not valid backend.", i);
-			continue;
-		}
-
-		if (POOL_DISALLOW_TO_FAILOVER(BACKEND_INFO(node_id_set[i]).flag))
-		{
-			pool_log("degenerate_backend_set: %d failover request from pid %d is canceled because failover is disallowed", node_id_set[i], getpid());
-			continue;
-		}
-
-		pool_log("degenerate_backend_set: %d fail over request from pid %d", node_id_set[i], getpid());
-		Req_info->node_id[i] = node_id_set[i];
-		need_signal = true;
-	}
-
-	if (need_signal)
-	{
-		if (!pool_config->use_watchdog || WD_OK == wd_degenerate_backend_set(node_id_set, count))
-		{
-			kill(parent, SIGUSR1);
-		}
-		else
-		{
-			pool_log("degenerate_backend_set: failover request from pid %d is canceled by other pgpool", getpid());
-			memset(Req_info->node_id, -1, sizeof(int) * MAX_NUM_BACKENDS);
-		}
-	}
-
-	pool_semaphore_unlock(REQUEST_INFO_SEM);
-	POOL_SETMASK(&oldmask);
-}
-
-/* send promote node request using SIGUSR1 */
-void promote_backend(int node_id)
-{
-	pid_t parent = getppid();
-
-	if (!MASTER_SLAVE || strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
-	{
-		return;
-	}
-
-	if (node_id < 0 || node_id >= MAX_NUM_BACKENDS || !VALID_BACKEND(node_id))
-	{
-		pool_error("promote_backend: node %d is not valid backend.", node_id);
-		return;
-	}
-
-	pool_semaphore_lock(REQUEST_INFO_SEM);
-	Req_info->kind = PROMOTE_NODE_REQUEST;
-	Req_info->node_id[0] = node_id;
-	pool_log("promote_backend: %d promote node request from pid %d", node_id, getpid());
-
-	if (!pool_config->use_watchdog || WD_OK == wd_promote_backend(node_id))
-	{
-		kill(parent, SIGUSR1);
-	}
-	else
-	{
-		pool_log("promote_backend: promote request from pid %d is canceled by other pgpool", getpid());
-		Req_info->node_id[0] = -1;
-	}
-
-	pool_semaphore_unlock(REQUEST_INFO_SEM);
-}
-
-/* send failback request using SIGUSR1 */
-void send_failback_request(int node_id)
-{
-	pid_t parent = getppid();
-
-	pool_log("send_failback_request: fail back %d th node request from pid %d", node_id, getpid());
-	Req_info->kind = NODE_UP_REQUEST;
-	Req_info->node_id[0] = node_id;
-
-    if (node_id < 0 || node_id >= MAX_NUM_BACKENDS ||
-		(RAW_MODE && BACKEND_INFO(node_id).backend_status != CON_DOWN && VALID_BACKEND(node_id)))
-	{
-		pool_error("send_failback_request: node %d is alive.", node_id);
-		Req_info->node_id[0] = -1;
-		return;
-	}
-
-	if (pool_config->use_watchdog && WD_OK != wd_send_failback_request(node_id))
-	{
-		pool_log("send_failback_request: failback request from pid %d is canceled by other pgpool", getpid());
-		Req_info->node_id[0] = -1;
-		return;
-	}
-	kill(parent, SIGUSR1);
-}
-
-static RETSIGTYPE exit_handler(int sig)
-{
-	int i;
-
-	POOL_SETMASK(&AuthBlockSig);
-
-	/*
-	 * this could happen in a child process if a signal has been sent
-	 * before resetting signal handler
-	 */
-	if (getpid() != mypid)
-	{
-		pool_debug("exit_handler: I am not parent");
-		POOL_SETMASK(&UnBlockSig);
-		pool_shmem_exit(0);
-		exit(0);
-	}
-
-	if (sig == SIGTERM)
-		pool_log("received smart shutdown request");
-	else if (sig == SIGINT)
-		pool_log("received fast shutdown request");
-	else if (sig == SIGQUIT)
-		pool_log("received immediate shutdown request");
-	else
-	{
-		pool_error("exit_handler: unknown signal received %d", sig);
-		POOL_SETMASK(&UnBlockSig);
-		return;
-	}
-
-	exiting = 1;
-
-	for (i = 0; i < pool_config->num_init_children; i++)
-	{
-		pid_t pid = process_info[i].pid;
-		if (pid)
-		{
-			kill(pid, sig);
-		}
-	}
-
-	kill(pcp_pid, sig);
-	kill(worker_pid, sig);
-
-	if (pool_config->use_watchdog)
-	{
-		wd_kill_watchdog(sig);
-	}
-
-	POOL_SETMASK(&UnBlockSig);
-
-	while (wait(NULL) > 0)
-		;
-
-	if (errno != ECHILD)
-		pool_error("wait() failed. reason:%s", strerror(errno));
-
-	process_info = NULL;
-	myexit(0);
-}
-
-/*
- * Calculate next valid master node id.
- * If no valid node found, returns -1.
- */
-static int get_next_master_node(void)
-{
-	int i;
-
-	for (i=0;i<pool_config->backend_desc->num_backends;i++)
-	{
-		/*
-		 * Do not use VALID_BACKEND macro in raw mode.
-		 * VALID_BACKEND return true only if the argument is master
-		 * node id. In other words, standby nodes are false. So need
-		 * to check backend status with VALID_BACKEND_RAW.
-		 */
-		if (RAW_MODE)
-		{
-			if (VALID_BACKEND_RAW(i))
-				break;
-		}
-		else
-		{
-			if (VALID_BACKEND(i))
-				break;
-		}
-	}
-
-	if (i == pool_config->backend_desc->num_backends)
-		i = -1;
-
-	return i;
-}
-
-/*
- * handle SIGUSR1
- *
- */
-static RETSIGTYPE failover_handler(int sig)
-{
-	POOL_SETMASK(&BlockSig);
-	failover_request = 1;
-	write(pipe_fds[1], "\0", 1);
-	POOL_SETMASK(&UnBlockSig);
-}
-
-/*
- * backend connection error, failover/failback request, if possible
- * failover() must be called under protecting signals.
- */
-static void failover(void)
-{
-	int i;
-	int node_id;
-	bool by_health_check;
-	int new_master;
-	int new_primary;
-	int nodes[MAX_NUM_BACKENDS];
-	bool need_to_restart_children;
-	int status;
-	int sts;
-
-	pool_debug("failover_handler called");
-
-	memset(nodes, 0, sizeof(int) * MAX_NUM_BACKENDS);
-
-	/*
-	 * this could happen in a child process if a signal has been sent
-	 * before resetting signal handler
-	 */
-	if (getpid() != mypid)
-	{
-		pool_debug("failover_handler: I am not parent");
-		kill(pcp_pid, SIGUSR2);
-		return;
-	}
-
-	/*
-	 * processing SIGTERM, SIGINT or SIGQUIT
-	 */
-	if (exiting)
-	{
-		pool_debug("failover_handler called while exiting");
-		kill(pcp_pid, SIGUSR2);
-		return;
-	}
-
-	/*
-	 * processing fail over or switch over
-	 */
-	if (switching)
-	{
-		pool_debug("failover_handler called while switching");
-		kill(pcp_pid, SIGUSR2);
-		return;
-	}
-
-	pool_semaphore_lock(REQUEST_INFO_SEM);
-
-	if (Req_info->kind == CLOSE_IDLE_REQUEST)
-	{
-		pool_semaphore_unlock(REQUEST_INFO_SEM);
-		kill_all_children(SIGUSR1);
-		kill(pcp_pid, SIGUSR2);
-		return;
-	}
-
-	/*
-	 * if not in replication mode/master slave mode, we treat this a restart request.
-	 * otherwise we need to check if we have already failovered.
-	 */
-	pool_debug("failover_handler: starting to select new master node");
-	switching = 1;
-	Req_info->switching = true;
-	node_id = Req_info->node_id[0];
-
-	/* start of command inter-lock with watchdog */
-	if (pool_config->use_watchdog)
-	{
-		by_health_check = (!failover_request && Req_info->kind==NODE_DOWN_REQUEST);
-		wd_start_interlock(by_health_check);
-	}
-
-	/* failback request? */
-	if (Req_info->kind == NODE_UP_REQUEST)
-	{
-		if (node_id < 0 || node_id >= MAX_NUM_BACKENDS ||
-			(Req_info->kind == NODE_UP_REQUEST && !(RAW_MODE &&
-            BACKEND_INFO(node_id).backend_status == CON_DOWN) && VALID_BACKEND(node_id)) ||
-			(Req_info->kind == NODE_DOWN_REQUEST && !VALID_BACKEND(node_id)))
-		{
-			pool_semaphore_unlock(REQUEST_INFO_SEM);
-
-			if (node_id < 0 || node_id >= MAX_NUM_BACKENDS)
-				pool_error("failover_handler: invalid node_id %d MAX_NUM_BACKENDS: %d", node_id, MAX_NUM_BACKENDS);
-			else
-				pool_error("failover_handler: invalid node_id %d status:%d MAX_NUM_BACKENDS: %d", node_id,
-						   BACKEND_INFO(node_id).backend_status, MAX_NUM_BACKENDS);
-			kill(pcp_pid, SIGUSR2);
-			switching = 0;
-			Req_info->switching = false;
-
-			/* end of command inter-lock */
-			if (pool_config->use_watchdog)
-				wd_leave_interlock();
-
-			return;
-		}
-
-		pool_log("starting fail back. reconnect host %s(%d)",
-				 BACKEND_INFO(node_id).backend_hostname,
-				 BACKEND_INFO(node_id).backend_port);
-		BACKEND_INFO(node_id).backend_status = CON_CONNECT_WAIT;	/* unset down status */
-
-		/* wait for failback command lock or to be lock holder */
-		if (pool_config->use_watchdog && !wd_am_I_lock_holder())
-		{
-			wd_wait_for_lock(WD_FAILBACK_COMMAND_LOCK);
-		}
-		/* execute failback command if lock holder */
-		if (!pool_config->use_watchdog || wd_am_I_lock_holder())
-		{
-			trigger_failover_command(node_id, pool_config->failback_command,
-								 	MASTER_NODE_ID, get_next_master_node(), PRIMARY_NODE_ID);
-
-			/* unlock failback command */
-			if (pool_config->use_watchdog)
-				wd_unlock(WD_FAILBACK_COMMAND_LOCK);
-		}
-	}
-	else if (Req_info->kind == PROMOTE_NODE_REQUEST)
-	{
-		if (node_id != -1 && VALID_BACKEND(node_id))
-		{
-			pool_log("starting promotion. promote host %s(%d)",
-					 BACKEND_INFO(node_id).backend_hostname,
-					 BACKEND_INFO(node_id).backend_port);
-		}
-		else
-		{
-			pool_log("failover: no backends are promoted");
-			pool_semaphore_unlock(REQUEST_INFO_SEM);
-			kill(pcp_pid, SIGUSR2);
-			switching = 0;
-			Req_info->switching = false;
-
-			/* end of command inter-lock */
-			if (pool_config->use_watchdog)
-				wd_leave_interlock();
-
-			return;
-		}
-	}
-	else
-	{
-		int cnt = 0;
-
-		for (i = 0; i < MAX_NUM_BACKENDS; i++)
-		{
-			if (Req_info->node_id[i] != -1 &&
-				((RAW_MODE && VALID_BACKEND_RAW(Req_info->node_id[i])) ||
-				 VALID_BACKEND(Req_info->node_id[i])))
-			{
-				pool_log("starting degeneration. shutdown host %s(%d)",
-						 BACKEND_INFO(Req_info->node_id[i]).backend_hostname,
-						 BACKEND_INFO(Req_info->node_id[i]).backend_port);
-
-				BACKEND_INFO(Req_info->node_id[i]).backend_status = CON_DOWN;	/* set down status */
-				/* save down node */
-				nodes[Req_info->node_id[i]] = 1;
-				cnt++;
-			}
-		}
-
-		if (cnt == 0)
-		{
-			pool_log("failover: no backends are degenerated");
-			pool_semaphore_unlock(REQUEST_INFO_SEM);
-			kill(pcp_pid, SIGUSR2);
-			switching = 0;
-			Req_info->switching = false;
-
-			/* end of command inter-lock */
-			if (pool_config->use_watchdog)
-				wd_leave_interlock();
-
-			return;
-		}
-	}
-
-	new_master = get_next_master_node();
-
-	if (new_master < 0)
-	{
-		pool_error("failover_handler: no valid DB node found");
-	}
-
-/*
- * Before we tried to minimize restarting pgpool to protect existing
- * connections from clients to pgpool children. What we did here was,
- * if children other than master went down, we did not fail over.
- * This is wrong. Think about following scenario. If someone
- * accidentally plugs out the network cable, the TCP/IP stack keeps
- * retrying for long time (typically 2 hours). The only way to stop
- * the retry is restarting the process.  Bottom line is, we need to
- * restart all children in any case.  See pgpool-general list posting
- * "TCP connections are *not* closed when a backend timeout" on Jul 13
- * 2008 for more details.
- */
-#ifdef NOT_USED
-	else
-	{
-		if (Req_info->master_node_id == new_master && *InRecovery == RECOVERY_INIT)
-		{
-			pool_log("failover_handler: do not restart pgpool. same master node %d was selected", new_master);
-			if (Req_info->kind == NODE_UP_REQUEST)
-			{
-				pool_log("failback done. reconnect host %s(%d)",
-						 BACKEND_INFO(node_id).backend_hostname,
-						 BACKEND_INFO(node_id).backend_port);
-			}
-			else
-			{
-				pool_log("failover done. shutdown host %s(%d)",
-						 BACKEND_INFO(node_id).backend_hostname,
-						 BACKEND_INFO(node_id).backend_port);
-			}
-
-			/* exec failover_command */
-			for (i = 0; i < pool_config->backend_desc->num_backends; i++)
-			{
-				if (nodes[i])
-					trigger_failover_command(i, pool_config->failover_command);
-			}
-
-			pool_semaphore_unlock(REQUEST_INFO_SEM);
-			switching = 0;
-			Req_info->switching = false;
-			kill(pcp_pid, SIGUSR2);
-			switching = 0;
-			Req_info->switching = false;
-			return;
-		}
-	}
-#endif
-
-
-   /* On 2011/5/2 Tatsuo Ishii says: if mode is streaming replication
-	* and request is NODE_UP_REQUEST(failback case) we don't need to
-	* restart all children. Existing session will not use newly
-	* attached node, but load balanced node is not changed until this
-	* session ends, so it's harmless anyway.
-	*/
-	if (MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP)	&&
-		Req_info->kind == NODE_UP_REQUEST)
-	{
-		pool_log("Do not restart children because we are failbacking node id %d host%s port:%d and we are in streaming replication mode", node_id,
-				 BACKEND_INFO(node_id).backend_hostname,
-				 BACKEND_INFO(node_id).backend_port);
-
-		need_to_restart_children = false;
-	}
-	else
-	{
-		pool_log("Restart all children");
-
-		/* kill all children */
-		for (i = 0; i < pool_config->num_init_children; i++)
-		{
-			pid_t pid = process_info[i].pid;
-			if (pid)
-			{
-				kill(pid, SIGQUIT);
-				pool_debug("failover_handler: kill %d", pid);
-			}
-		}
-
-		need_to_restart_children = true;
-	}
-
-	/* wait for failover command lock or to be lock holder*/
-	if (pool_config->use_watchdog && !wd_am_I_lock_holder())
-	{
-		wd_wait_for_lock(WD_FAILOVER_COMMAND_LOCK);
-	}
-
-	/* execute failover command if lock holder */
-	if (!pool_config->use_watchdog || wd_am_I_lock_holder())
-	{
-		/* Exec failover_command if needed */
-		for (i = 0; i < pool_config->backend_desc->num_backends; i++)
-		{
-			if (nodes[i])
-				trigger_failover_command(i, pool_config->failover_command,
-									 		MASTER_NODE_ID, new_master, PRIMARY_NODE_ID);
-		}
-
-		/* unlock failover command */
-		if (pool_config->use_watchdog)
-			wd_unlock(WD_FAILOVER_COMMAND_LOCK);
-	}
-
-
-/* no need to wait since it will be done in reap_handler */
-#ifdef NOT_USED
-	while (wait(NULL) > 0)
-		;
-
-	if (errno != ECHILD)
-		pool_error("failover_handler: wait() failed. reason:%s", strerror(errno));
-#endif
-
-	if (Req_info->kind == PROMOTE_NODE_REQUEST && VALID_BACKEND(node_id))
-		new_primary = node_id;
-
-	/*
-	 * If the down node was a standby node in streaming replication
-	 * mode, we can avoid calling find_primary_node_repeatedly() and
-	 * recognize the former primary as the new primary node, which
-	 * will reduce the time to process standby down.
-	 */
-	else if (MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP) &&
-			 Req_info->kind == NODE_DOWN_REQUEST)
-	{
-		if (Req_info->primary_node_id != node_id)
-			new_primary = Req_info->primary_node_id;
-		else
-			new_primary =  find_primary_node_repeatedly();
-	}
-	else
-		new_primary =  find_primary_node_repeatedly();
-
-	/*
-	 * If follow_master_command is provided and in master/slave
-	 * streaming replication mode, we start degenerating all backends
-	 * as they are not replicated anymore.
-	 */
-	int follow_cnt = 0;
-	if (MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
-	{
-		if (*pool_config->follow_master_command != '\0' ||
-			Req_info->kind == PROMOTE_NODE_REQUEST)
-		{
-			/* only if the failover is against the current primary */
-			if (((Req_info->kind == NODE_DOWN_REQUEST) &&
-				 (nodes[Req_info->primary_node_id])) ||
-				((Req_info->kind == PROMOTE_NODE_REQUEST) &&
-				 (VALID_BACKEND(node_id)))) {
-
-				for (i = 0; i < pool_config->backend_desc->num_backends; i++)
-				{
-					/* do not degenerate the new primary */
-					if ((new_primary >= 0) && (i != new_primary)) {
-						BackendInfo *bkinfo;
-						bkinfo = pool_get_node_info(i);
-						pool_log("starting follow degeneration. shutdown host %s(%d)",
-								 bkinfo->backend_hostname,
-								 bkinfo->backend_port);
-						bkinfo->backend_status = CON_DOWN;	/* set down status */
-						follow_cnt++;
-					}
-				}
-
-				if (follow_cnt == 0)
-				{
-					pool_log("failover: no follow backends are degenerated");
-				}
-				else
-				{
-					/* update new master node */
-					new_master = get_next_master_node();
-					pool_log("failover: %d follow backends have been degenerated", follow_cnt);
-				}
-			}
-		}
-	}
-
-	memset(Req_info->node_id, -1, sizeof(int) * MAX_NUM_BACKENDS);
-	pool_semaphore_unlock(REQUEST_INFO_SEM);
-
-	/* wait for follow_master_command lock or to be lock holder */
-	if (pool_config->use_watchdog && !wd_am_I_lock_holder())
-	{
-		wd_wait_for_lock(WD_FOLLOW_MASTER_COMMAND_LOCK);
-	}
-
-	/* execute follow_master_command */
-	if (!pool_config->use_watchdog || wd_am_I_lock_holder())
-	{
-		if ((follow_cnt > 0) && (*pool_config->follow_master_command != '\0'))
-		{
-			follow_pid = fork_follow_child(Req_info->master_node_id, new_primary,
-									   	Req_info->primary_node_id);
-		}
-
-		/* unlock follow_master_command  */
-		if (pool_config->use_watchdog)
-			wd_unlock(WD_FOLLOW_MASTER_COMMAND_LOCK);
-	}
-
-	/* end of command inter-lock */
-	if (pool_config->use_watchdog)
-		wd_end_interlock();
-
-	/* Save primary node id */
-	Req_info->primary_node_id = new_primary;
-	pool_log("failover: set new primary node: %d", Req_info->primary_node_id);
-
-	if (new_master >= 0)
-	{
-		Req_info->master_node_id = new_master;
-		pool_log("failover: set new master node: %d", Req_info->master_node_id);
-	}
-
-
-	/* Fork the children if needed */
-	if (need_to_restart_children)
-	{
-		for (i=0;i<pool_config->num_init_children;i++)
-		{
-
-			/*
-			 * Try to kill pgpool child because previous kill signal
-			 * may not be received by pgpool child. This could happen
-			 * if multiple PostgreSQL are going down (or even starting
-			 * pgpool, without starting PostgreSQL can trigger this).
-			 * Child calls degenerate_backend() and it tries to aquire
-			 * semaphore to write a failover request. In this case the
-			 * signal mask is set as well, thus signals are never
-			 * received.
-			 */
-			kill(process_info[i].pid, SIGQUIT);
-
-			process_info[i].pid = fork_a_child(unix_fd, inet_fd, i);
-			process_info[i].start_time = time(NULL);
-		}
-	}
-	else
-	{
-		/* Set restart request to each child. Children will exit(1)
-		 * whenever they are idle to restart.
-		 */
-		for (i=0;i<pool_config->num_init_children;i++)
-		{
-			process_info[i].need_to_restart = 1;
-		}
-	}
-
-	/*
-	 * Send restart request to worker child.
-	 */
-	kill(worker_pid, SIGUSR1);
-
-	if (Req_info->kind == NODE_UP_REQUEST)
-	{
-		pool_log("failback done. reconnect host %s(%d)",
-				 BACKEND_INFO(node_id).backend_hostname,
-				 BACKEND_INFO(node_id).backend_port);
-	}
-	else if (Req_info->kind == PROMOTE_NODE_REQUEST)
-	{
-		pool_log("promotion done. promoted host %s(%d)",
-				 BACKEND_INFO(node_id).backend_hostname,
-				 BACKEND_INFO(node_id).backend_port);
-	}
-	else
-	{
-		pool_log("failover done. shutdown host %s(%d)",
-				 BACKEND_INFO(node_id).backend_hostname,
-				 BACKEND_INFO(node_id).backend_port);
-	}
-
-	switching = 0;
-	Req_info->switching = false;
-
-	/* kick wakeup_handler in pcp_child to notice that
-	 * failover/failback done
-	 */
-	kill(pcp_pid, SIGUSR2);
-
-	sleep(1);
-
-	/*
-	 * Send restart request to pcp child.
-	 */
-	kill(pcp_pid, SIGUSR1);
-	for (;;)
-	{
-		sts = waitpid(pcp_pid, &status, 0);
-		if (sts != -1)
-			break;
-		if (sts == -1)
-		{
-			if (errno == EINTR)
-				continue;
-			else
-			{
-				pool_error("failover: waitpid failed. reason: %s", strerror(errno));
-				return;
-			}
-		}
-	}
-	if (WIFSIGNALED(status))
-		pool_log("PCP child %d exits with status %d by signal %d in failover()", pcp_pid, status, WTERMSIG(status));
-	else
-		pool_log("PCP child %d exits with status %d in failover()", pcp_pid, status);
-
-	pcp_pid = pcp_fork_a_child(pcp_unix_fd, pcp_inet_fd, pcp_conf_file);
-	pool_log("fork a new PCP child pid %d in failover()", pcp_pid);
-}
-
-/*
- * health check timer handler
- */
-static RETSIGTYPE health_check_timer_handler(int sig)
-{
-	POOL_SETMASK(&BlockSig);
-	health_check_timer_expired = 1;
-	POOL_SETMASK(&UnBlockSig);
-}
-
-
-/*
- * Check if we can connect to the backend
- * returns 0 for OK. otherwise returns backend id + 1
- */
-static int health_check(void)
-{
-	POOL_CONNECTION_POOL_SLOT *slot;
-	BackendInfo *bkinfo;
-	static bool is_first = true;
-	static char *dbname;
-	int i;
-
-	/* Do not execute health check during recovery */
-	if (*InRecovery)
-		return 0;
-
- Retry:
-	/*
-	 * First we try with "postgres" database.
-	 */
-	if (is_first)
-		dbname = "postgres";
-
-	for (i=0;i<pool_config->backend_desc->num_backends;i++)
-	{
-		/*
-		 * Make sure that health check timer has not been expired.
-		 * Before called health_check(), health_check_timer_expired is
-		 * set to 0.  However it is possible that while processing DB
-		 * nodes health check timer expired.
-		 */
-		if (health_check_timer_expired)
-		{
-			pool_log("health_check: health check timer has been already expired before attempting to connect to %d th backend", i);
-			return i+1;
-		}
-
-		bkinfo = pool_get_node_info(i);
-
-		pool_debug("health_check: %d th DB node status: %d", i, bkinfo->backend_status);
-
-		if (bkinfo->backend_status == CON_UNUSED ||
-			bkinfo->backend_status == CON_DOWN)
-			continue;
-
-		slot = make_persistent_db_connection(bkinfo->backend_hostname,
-											 bkinfo->backend_port,
-											 dbname,
-											 pool_config->health_check_user,
-											 pool_config->health_check_password, false);
-
-		if (is_first)
-			is_first = false;
-
-		if (!slot)
-		{
-			/*
-			 * Retry with template1 unless health check timer is expired.
-			 */
-			if (!strcmp(dbname, "postgres") && health_check_timer_expired == 0)
-			{
-				dbname = "template1";
-				goto Retry;
-			}
-			else
-			{
-				pool_error("health check failed. %d th host %s at port %d is down",
-						   i,
-						   bkinfo->backend_hostname,
-						   bkinfo->backend_port);
-				return i+1;
-			}
-		}
-		else
-		{
-			discard_persistent_db_connection(slot);
-		}
-	}
-
-	return 0;
-}
-
-/*
- * check if we can connect to the SystemDB
- * returns 0 for OK. otherwise returns -1
- */
-static int
-system_db_health_check(void)
-{
-	int fd;
-
-	/* V2 startup packet */
-	typedef struct {
-		int len;		/* startup packet length */
-		StartupPacket_v2 sp;
-	} MySp;
-	MySp mysp;
-	char kind;
-
-	memset(&mysp, 0, sizeof(mysp));
-	mysp.len = htonl(296);
-	mysp.sp.protoVersion = htonl(PROTO_MAJOR_V2 << 16);
-	strcpy(mysp.sp.database, "template1");
-	strncpy(mysp.sp.user, SYSDB_INFO->user, sizeof(mysp.sp.user) - 1);
-	*mysp.sp.options = '\0';
-	*mysp.sp.unused = '\0';
-	*mysp.sp.tty = '\0';
-
-	pool_debug("health_check: SystemDB status: %d", SYSDB_STATUS);
-
-	/* if SystemDB is already down, ignore */
-	if (SYSDB_STATUS == CON_UNUSED || SYSDB_STATUS == CON_DOWN)
-		return 0;
-
-	if (*SYSDB_INFO->hostname == '/')
-		fd = connect_unix_domain_socket_by_port(SYSDB_INFO->port, SYSDB_INFO->hostname, FALSE);
-	else
-		fd = connect_inet_domain_socket_by_port(SYSDB_INFO->hostname, SYSDB_INFO->port, FALSE);
-
-	if (fd < 0)
-	{
-		pool_error("health check failed. SystemDB host %s at port %d is down",
-				   SYSDB_INFO->hostname,
-				   SYSDB_INFO->port);
-
-		return -1;
-	}
-
-	if (write(fd, &mysp, sizeof(mysp)) < 0)
-	{
-		pool_error("health check failed during write. SystemDB host %s at port %d is down",
-				   SYSDB_INFO->hostname,
-				   SYSDB_INFO->port);
-		close(fd);
-		return -1;
-	}
-
-	read(fd, &kind, 1);
-
-	if (write(fd, "X", 1) < 0)
-	{
-		pool_error("health check failed during write. SystemDB host %s at port %d is down",
-				   SYSDB_INFO->hostname,
-				   SYSDB_INFO->port);
-		close(fd);
-		return -1;
-	}
-
-	close(fd);
-	return 0;
-}
-
-/*
- * handle SIGCHLD
- */
-static RETSIGTYPE reap_handler(int sig)
-{
-	POOL_SETMASK(&BlockSig);
-	sigchld_request = 1;
-	write(pipe_fds[1], "\0", 1);
-	POOL_SETMASK(&UnBlockSig);
-}
-
-/*
- * Attach zombie processes and restart child processes.
- * reaper() must be called protected from signals.
- */
-static void reaper(void)
-{
-	pid_t pid;
-	int status;
-	int i;
-
-	pool_debug("reap_handler called");
-
-	if (exiting)
-	{
-		pool_debug("reap_handler: exited due to exiting");
-		return;
-	}
-
-	if (switching)
-	{
-		pool_debug("reap_handler: exited due to switching");
-		return;
-	}
-
-	/* clear SIGCHLD request */
-	sigchld_request = 0;
-
-#ifdef HAVE_WAITPID
-	pool_debug("reap_handler: call waitpid");
-	while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
-#else
-	pool_debug("reap_handler: call wait3");
-	while ((pid = wait3(&status, WNOHANG, NULL)) > 0)
-#endif
-	{
-		if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV)
-		{
-			/* Child terminated by segmentation fault. Report it */
-			pool_error("Child process %d was terminated by segmentation fault", pid);
-		}
-
-		/* if exiting child process was PCP handler */
-		if (pid == pcp_pid)
-		{
-			if (WIFSIGNALED(status))
-				pool_log("PCP child %d exits with status %d by signal %d", pid, status, WTERMSIG(status));
-			else
-				pool_log("PCP child %d exits with status %d", pid, status);
-
-			pcp_pid = pcp_fork_a_child(pcp_unix_fd, pcp_inet_fd, pcp_conf_file);
-			pool_log("fork a new PCP child pid %d", pcp_pid);
-		}
-
-		/* exiting process was worker process */
-		else if (pid == worker_pid)
-		{
-			if (WIFSIGNALED(status))
-				pool_log("worker child %d exits with status %d by signal %d", pid, status, WTERMSIG(status));
-			else
-				pool_log("worker child %d exits with status %d", pid, status);
-
-			if (status)
-				worker_pid = worker_fork_a_child();
-
-			pool_log("fork a new worker child pid %d", worker_pid);
-		}
-
-		/* exiting process was watchdog process */
-		else if (pool_config->use_watchdog && wd_is_watchdog_pid(pid))
-		{
-			if (!wd_reaper_watchdog(pid, status))
-			{
-				pool_error("wd_reaper failed");
-				myexit(1);
-			}
-		}
-
-		else
-		{
-			if (WIFSIGNALED(status))
-				pool_debug("child %d exits with status %d by signal %d", pid, status, WTERMSIG(status));
-			else
-				pool_debug("child %d exits with status %d", pid, status);
-
-			/* look for exiting child's pid */
-			for (i=0;i<pool_config->num_init_children;i++)
-			{
-				if (pid == process_info[i].pid)
-				{
-					/* if found, fork a new child */
-					if (!switching && !exiting && status)
-					{
-						process_info[i].pid = fork_a_child(unix_fd, inet_fd, i);
-						process_info[i].start_time = time(NULL);
-						pool_debug("fork a new child pid %d", process_info[i].pid);
-						break;
-					}
-				}
-			}
-		}
-	}
-	pool_debug("reap_handler: normally exited");
-}
-
-/*
- * get node information specified by node_number
- */
-BackendInfo *
-pool_get_node_info(int node_number)
-{
-	if (node_number < 0 || node_number >= NUM_BACKENDS)
-		return NULL;
-
-	return &BACKEND_INFO(node_number);
-}
-
-/*
- * get number of nodes
- */
-int
-pool_get_node_count(void)
-{
-	return NUM_BACKENDS;
-}
-
-/*
- * get process ids
- */
-int *
-pool_get_process_list(int *array_size)
-{
-	int	   *array;
-	int		i;
-
-	*array_size = pool_config->num_init_children;
-	array = calloc(*array_size, sizeof(int));
-	for (i = 0; i < *array_size; i++)
-		array[i] = process_info[i].pid;
-
-	return array;
-}
-
-/*
- * get process information specified by pid
- */
-ProcessInfo *
-pool_get_process_info(pid_t pid)
-{
-	int		i;
-
-	for (i = 0; i < pool_config->num_init_children; i++)
-		if (process_info[i].pid == pid)
-			return &process_info[i];
-
-	return NULL;
-}
-
-/*
- * get System DB information
- */
-SystemDBInfo *
-pool_get_system_db_info(void)
-{
-	if (system_db_info == NULL)
-		return NULL;
-
-	return system_db_info->info;
-}
-
-
-/*
- * handle SIGUSR2
- * Wakeup all processes
- */
-static void wakeup_children(void)
-{
-	kill_all_children(SIGUSR2);
-}
-
-
-static RETSIGTYPE wakeup_handler(int sig)
-{
-	POOL_SETMASK(&BlockSig);
-	wakeup_request = 1;
-	write(pipe_fds[1], "\0", 1);
-	POOL_SETMASK(&UnBlockSig);
-}
-
-/*
- * handle SIGHUP
- *
- */
-static RETSIGTYPE reload_config_handler(int sig)
-{
-	POOL_SETMASK(&BlockSig);
-	reload_config_request = 1;
-	write(pipe_fds[1], "\0", 1);
-	POOL_SETMASK(&UnBlockSig);
-}
-
-static void reload_config(void)
-{
-	pool_log("reload config files.");
-	pool_get_config(conf_file, RELOAD_CONFIG);
-	if (pool_config->enable_pool_hba)
-		load_hba(hba_file);
-	if (pool_config->parallel_mode)
-		pool_memset_system_db_info(system_db_info->info);
-	kill_all_children(SIGHUP);
-
-	if (worker_pid)
-		kill(worker_pid, SIGHUP);
-}
-
-static void kill_all_children(int sig)
-{
-	int i;
-
-	/* kill all children */
-	for (i = 0; i < pool_config->num_init_children; i++)
-	{
-		pid_t pid = process_info[i].pid;
-		if (pid)
-		{
-			kill(pid, sig);
-		}
-	}
-
-	/* make PCP process reload as well */
-	if (sig == SIGHUP)
-		kill(pcp_pid, sig);
-}
-
-/*
- * pause in a period specified by timeout. If any data is coming
- * through pipe_fds[0], that means one of: failover request(SIGUSR1),
- * SIGCHLD received, children wake up request(SIGUSR2 used in on line
- * recovery processing) or config file reload request(SIGHUP) has been
- * occurred.  In this case this function returns 1.
- * otherwise 0: (no signal event occurred), -1: (error)
- * XXX: is it OK that select(2) error is ignored here?
- */
-static int pool_pause(struct timeval *timeout)
-{
-	fd_set rfds;
-	int n;
-	char dummy;
-
-	FD_ZERO(&rfds);
-	FD_SET(pipe_fds[0], &rfds);
-	n = select(pipe_fds[0]+1, &rfds, NULL, NULL, timeout);
-	if (n == 1)
-		read(pipe_fds[0], &dummy, 1);
-	return n;
-}
-
-/*
- * sleep for seconds specified by "second".  Unlike pool_pause(), this
- * function guarantees that it will sleep for specified seconds.  This
- * function uses pool_pause() internally. If it informs that there is
- * a pending signal event, they are processed using CHECK_REQUEST
- * macro. Note that most of these processes are done while all signals
- * are blocked.
- */
-void pool_sleep(unsigned int second)
-{
-	struct timeval current_time, sleep_time;
-
-	gettimeofday(&current_time, NULL);
-	sleep_time.tv_sec = second + current_time.tv_sec;
-	sleep_time.tv_usec = current_time.tv_usec;
-
-	POOL_SETMASK(&UnBlockSig);
-	while (sleep_time.tv_sec > current_time.tv_sec)
-	{
-		struct timeval timeout;
-		int r;
-
-		timeout.tv_sec = sleep_time.tv_sec - current_time.tv_sec;
-		timeout.tv_usec = sleep_time.tv_usec - current_time.tv_usec;
-		if (timeout.tv_usec < 0)
-		{
-			timeout.tv_sec--;
-			timeout.tv_usec += 1000000;
-		}
-
-		r = pool_pause(&timeout);
-		POOL_SETMASK(&BlockSig);
-		if (r > 0)
-			CHECK_REQUEST;
-		POOL_SETMASK(&UnBlockSig);
-		gettimeofday(&current_time, NULL);
-	}
-	POOL_SETMASK(&BlockSig);
-}
-
-/*
- * get_config_file_name: return full path of pgpool.conf.
- */
-char *get_config_file_name(void)
-{
-	return conf_file;
-}
-
-/*
- * get_config_file_name: return full path of pool_hba.conf.
- */
-char *get_hba_file_name(void)
+ * get_hba_file_name: return full path of pool_hba.conf.
+ */
+char *get_hba_file_name(void)
 {
 	return hba_file;
 }
-
-/*
- * trigger_failover_command: execute specified command at failover.
- *                           command_line is null-terminated string.
- */
-static int trigger_failover_command(int node, const char *command_line,
-									int old_master, int new_master, int old_primary)
-{
-	int r = 0;
-	String *exec_cmd;
-	char port_buf[6];
-	char buf[2];
-	BackendInfo *info;
-	BackendInfo *newmaster;
-
-	if (command_line == NULL || (strlen(command_line) == 0))
-		return 0;
-
-	/* check failed nodeID */
-	if (node < 0 || node > NUM_BACKENDS)
-		return -1;
-
-	info = pool_get_node_info(node);
-	if (!info)
-		return -1;
-
-	buf[1] = '\0';
-	pool_memory = pool_memory_create(PREPARE_BLOCK_SIZE);
-	if (!pool_memory)
-	{
-		pool_error("trigger_failover_command: pool_memory_create() failed");
-		return -1;
-	}
-	exec_cmd = init_string("");
-
-	while (*command_line)
-	{
-		if (*command_line == '%')
-		{
-			if (*(command_line + 1))
-			{
-				char val = *(command_line + 1);
-				switch (val)
-				{
-					case 'p': /* failed node port */
-						snprintf(port_buf, sizeof(port_buf), "%d", info->backend_port);
-						string_append_char(exec_cmd, port_buf);
-						break;
-
-					case 'D': /* failed node database directory */
-						string_append_char(exec_cmd, info->backend_data_directory);
-						break;
-
-					case 'd': /* failed node id */
-						snprintf(port_buf, sizeof(port_buf), "%d", node);
-						string_append_char(exec_cmd, port_buf);
-						break;
-
-					case 'h': /* failed host name */
-						string_append_char(exec_cmd, info->backend_hostname);
-						break;
-
-					case 'H': /* new master host name */
-						newmaster = pool_get_node_info(new_master);
-						if (newmaster)
-							string_append_char(exec_cmd, newmaster->backend_hostname);
-						else
-							/* no valid new master */
-							string_append_char(exec_cmd, "");
-						break;
-
-					case 'm': /* new master node id */
-						snprintf(port_buf, sizeof(port_buf), "%d", new_master);
-						string_append_char(exec_cmd, port_buf);
-						break;
-
-					case 'r': /* new master port */
-						newmaster = pool_get_node_info(get_next_master_node());
-						if (newmaster)
-						{
-							snprintf(port_buf, sizeof(port_buf), "%d", newmaster->backend_port);
-							string_append_char(exec_cmd, port_buf);
-						}
-						else
-							/* no valid new master */
-							string_append_char(exec_cmd, "");
-						break;
-
-					case 'R': /* new master database directory */
-						newmaster = pool_get_node_info(get_next_master_node());
-						if (newmaster)
-							string_append_char(exec_cmd, newmaster->backend_data_directory);
-						else
-							/* no valid new master */
-							string_append_char(exec_cmd, "");
-						break;
-
-					case 'M': /* old master node id */
-						snprintf(port_buf, sizeof(port_buf), "%d", old_master);
-						string_append_char(exec_cmd, port_buf);
-						break;
-
-					case 'P': /* old primary node id */
-						snprintf(port_buf, sizeof(port_buf), "%d", old_primary);
-						string_append_char(exec_cmd, port_buf);
-						break;
-
-					case '%': /* escape */
-						string_append_char(exec_cmd, "%");
-						break;
-
-					default: /* ignore */
-						break;
-				}
-				command_line++;
-			}
-		} else {
-			buf[0] = *command_line;
-			string_append_char(exec_cmd, buf);
-		}
-		command_line++;
-	}
-
-	if (strlen(exec_cmd->data) != 0)
-	{
-		pool_log("execute command: %s", exec_cmd->data);
-		r = system(exec_cmd->data);
-	}
-
-	pool_memory_delete(pool_memory, 0);
-	pool_memory = NULL;
-
-	return r;
-}
-
-/*
- * Find the primary node (i.e. not standby node) and returns its node
- * id. If no primary node is found, returns -1.
- */
-static int find_primary_node(void)
-{
-	BackendInfo *bkinfo;
-	POOL_CONNECTION_POOL_SLOT *s;
-	POOL_CONNECTION *con;
-	POOL_STATUS status;
-	POOL_SELECT_RESULT *res;
-	bool is_standby;
-	int i;
-
-	/* Streaming replication mode? */
-	if (pool_config->master_slave_mode == 0 ||
-		strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
-	{
-		/* No point to look for primary node if not in streaming
-		 * replication mode.
-		 */
-		pool_debug("find_primary_node: not in streaming replication mode");
-		return -1;
-	}
-
-	for(i=0;i<NUM_BACKENDS;i++)
-	{
-		if (!VALID_BACKEND(i))
-			continue;
-
-		/*
-		 * Check to see if this is a standby node or not.
-		 */
-		is_standby = false;
-
-		bkinfo = pool_get_node_info(i);
-		s = make_persistent_db_connection(bkinfo->backend_hostname,
-										  bkinfo->backend_port,
-										  "postgres",
-										  pool_config->sr_check_user,
-										  pool_config->sr_check_password, true);
-		if (!s)
-		{
-			pool_error("find_primary_node: make_persistent_connection failed");
-			return -1;
-		}
-		con = s->con;
-		status = do_query(con, "SELECT pg_is_in_recovery()",
-						  &res, PROTO_MAJOR_V3);
-		if (res->numrows <= 0)
-		{
-			pool_log("find_primary_node: do_query returns no rows");
-		}
-		if (res->data[0] == NULL)
-		{
-			pool_log("find_primary_node: do_query returns no data");
-		}
-		if (res->nullflags[0] == -1)
-		{
-			pool_log("find_primary_node: do_query returns NULL");
-		}
-		if (res->data[0] && !strcmp(res->data[0], "t"))
-		{
-			is_standby = true;
-		}
-		free_select_result(res);
-		discard_persistent_db_connection(s);
-
-		/*
-		 * If this is a standby, we continue to look for primary node.
-		 */
-		if (is_standby)
-		{
-			pool_debug("find_primary_node: %d node is standby", i);
-		}
-		else
-		{
-			break;
-		}
-	}
-
-	if (i == NUM_BACKENDS)
-	{
-		pool_debug("find_primary_node: no primary node found");
-		return -1;
-	}
-
-	pool_log("find_primary_node: primary node id is %d", i);
-	return i;
-}
-
-static int find_primary_node_repeatedly(void)
+/* Call back function to unlink the file */
+/* Call back function to unlink the file */
+static void FileUnlink(int code, Datum path)
 {
-	int sec;
-	int node_id = -1;
-
-	/* Streaming replication mode? */
-	if (pool_config->master_slave_mode == 0 ||
-		strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
-	{
-		/* No point to look for primary node if not in streaming
-		 * replication mode.
-		 */
-		pool_debug("find_primary_node: not in streaming replication mode");
-		return -1;
-	}
-
-	/*
-	 * Try to find the new primary node and keep trying for
-	 * search_primary_node_timeout seconds.
-	 * search_primary_node_timeout = 0 means never timeout and keep searching
-	 * indefinitely
+	char* filePath = (char*)path; 
+	if (unlink(filePath) == 0) return;
+	/* 
+	 * We are already exiting the system just produce a log entry to report an error
 	 */
-	pool_log("find_primary_node_repeatedly: waiting for finding a primary node");
-	for (sec = 0; (pool_config->search_primary_node_timeout == 0 ||
-				sec < pool_config->search_primary_node_timeout); sec++)
-	{
-		node_id = find_primary_node();
-		if (node_id != -1)
-			break;
-		pool_sleep(1);
-	}
-	return node_id;
-}
-
-/*
-* fork a follow child
-*/
-pid_t fork_follow_child(int old_master, int new_primary, int old_primary)
-{
-	pid_t pid;
-	int i;
-
-	pid = fork();
-
-	if (pid == 0)
-	{
-		pool_log("start triggering follow command.");
-		for (i = 0; i < pool_config->backend_desc->num_backends; i++)
-		{
-			BackendInfo *bkinfo;
-			bkinfo = pool_get_node_info(i);
-			if (bkinfo->backend_status == CON_DOWN)
-				trigger_failover_command(i, pool_config->follow_master_command,
-										 old_master, new_primary, old_primary);
-		}
-		exit(0);
-	}
-	else if (pid == -1)
-	{
-		pool_error("follow fork() failed. reason: %s", strerror(errno));
-		exit(1);
-	}
-	return pid;
+	ereport(LOG,
+		(errmsg("unlink failed for file at path \"%s\"", filePath),
+			errdetail("\"%s\"", strerror(errno))));
 }
diff --git a/src/main/pgpool_main.c b/src/main/pgpool_main.c
new file mode 100644
index 0000000..ad27dbf
--- /dev/null
+++ b/src/main/pgpool_main.c
@@ -0,0 +1,2425 @@
+/* -*-pgpool_main-c-*- */
+/*
+ * $Header$
+ *
+ * pgpool: a language independent connection pool server for PostgreSQL
+ * written by Tatsuo Ishii
+ *
+ * Copyright (c) 2003-2013	PgPool Global Development Group
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice appear in all
+ * copies and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of the
+ * author not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The author makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ */
+
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include <sys/wait.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <signal.h>
+
+#include <libgen.h>
+#include "utils/elog.h"
+#include "utils/palloc.h"
+
+#include "pool.h"
+#include "utils/palloc.h"
+#include "utils/memutils.h"
+#include "pool_config.h"
+#include "context/pool_process_context.h"
+#include "version.h"
+#include "parser/pool_string.h"
+#include "auth/pool_passwd.h"
+#include "query_cache/pool_memqcache.h"
+#include "watchdog/wd_ext.h"
+
+/*
+ * Process pending signal actions.
+ */
+#define CHECK_REQUEST \
+	do { \
+		if (wakeup_request) \
+		{ \
+			wakeup_children(); \
+			wakeup_request = 0; \
+		} \
+		if (failover_request) \
+		{ \
+			failover(); \
+			failover_request = 0; \
+		} \
+		if (sigchld_request) \
+		{ \
+			reaper(); \
+		} \
+		if (reload_config_request) \
+		{ \
+			reload_config(); \
+			reload_config_request = 0; \
+		} \
+    } while (0)
+
+#define CLEAR_ALARM \
+	do { \
+			pool_debug("health check: clearing alarm"); \
+    } while (alarm(0) > 0)
+
+
+#define PGPOOLMAXLITSENQUEUELENGTH 10000
+
+static int process_backend_health_check_failure(int health_check_node_id, int retrycnt);
+static bool do_health_check(bool use_template_db, volatile int *health_check_node_id);
+
+static void FileUnlink(int code, Datum path);
+static int write_status_file(void);
+static pid_t pcp_fork_a_child(int unix_fd, int inet_fd, char *pcp_conf_file);
+static pid_t fork_a_child(int unix_fd, int inet_fd, int id);
+static pid_t worker_fork_a_child(void);
+static int create_unix_domain_socket(struct sockaddr_un un_addr_tmp);
+static int create_inet_domain_socket(const char *hostname, const int port);
+static void myexit(int code);
+static void failover(void);
+static void reaper(void);
+static void wakeup_children(void);
+static void reload_config(void);
+static int pool_pause(struct timeval *timeout);
+static void kill_all_children(int sig);
+static int get_next_master_node(void);
+static pid_t fork_follow_child(int old_master, int new_primary, int old_primary);
+static int read_status_file(bool discard_status);
+static int write_status_file(void);
+static RETSIGTYPE exit_handler(int sig);
+static RETSIGTYPE reap_handler(int sig);
+static RETSIGTYPE failover_handler(int sig);
+static RETSIGTYPE reload_config_handler(int sig);
+static RETSIGTYPE health_check_timer_handler(int sig);
+static RETSIGTYPE wakeup_handler(int sig);
+
+static void initialize_shared_mem_objects(void);
+static int trigger_failover_command(int node, const char *command_line,
+									int old_master, int new_master, int old_primary);
+static int find_primary_node(void);
+static int find_primary_node_repeatedly(void);
+
+static struct sockaddr_un un_addr;		/* unix domain socket path */
+static struct sockaddr_un pcp_un_addr;  /* unix domain socket path for PCP */
+ProcessInfo *process_info;	/* Per child info table on shmem */
+
+/*
+ * Private copy of backend status
+ */
+BACKEND_STATUS private_backend_status[MAX_NUM_BACKENDS];
+
+/*
+ * shmem connection info table
+ * this is a three dimension array. i.e.:
+ * con_info[pool_config->num_init_children][pool_config->max_pool][MAX_NUM_BACKENDS]
+ */
+ConnectionInfo *con_info;
+
+static int unix_fd;	/* unix domain socket fd */
+static int inet_fd;	/* inet domain socket fd */
+
+static int follow_pid; /* pid for child process handling follow command */
+static int pcp_pid; /* pid for child process handling PCP */
+static int pcp_unix_fd; /* unix domain socket fd for PCP (not used) */
+static int pcp_inet_fd; /* inet domain socket fd for PCP */
+extern char pcp_conf_file[POOLMAXPATHLEN+1]; /* path for pcp.conf */
+extern char conf_file[POOLMAXPATHLEN+1];
+extern char hba_file[POOLMAXPATHLEN+1];
+
+static int exiting = 0;		/* non 0 if I'm exiting */
+static int switching = 0;		/* non 0 if I'm fail overing or degenerating */
+
+POOL_REQUEST_INFO *Req_info;		/* request info area in shared memory */
+volatile sig_atomic_t *InRecovery; /* non 0 if recovery is started */
+volatile sig_atomic_t reload_config_request = 0;
+static volatile sig_atomic_t failover_request = 0;
+static volatile sig_atomic_t sigchld_request = 0;
+static volatile sig_atomic_t wakeup_request = 0;
+
+static int pipe_fds[2]; /* for delivering signals */
+
+int my_proc_id;
+
+static BackendStatusRecord backend_rec;	/* Backend status record */
+
+static pid_t worker_pid; /* pid of worker process */
+
+BACKEND_STATUS* my_backend_status[MAX_NUM_BACKENDS];		/* Backend status buffer */
+int my_master_node_id;		/* Master node id buffer */
+
+/*
+* pgpool main program
+*/
+
+int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps)
+{
+	int i;
+	volatile int health_check_node_id = 0;
+	volatile bool use_template_db = false;
+	volatile int retrycnt;
+	volatile int sys_retrycnt;
+
+	MemoryContext MainLoopMemoryContext;
+	sigjmp_buf	local_sigjmp_buf;
+	
+	/* Set the process type variable */
+	processType = PT_MAIN;
+	processState = INITIALIZING;
+
+	/*
+	 * Restore previous backend status if possible
+	 */
+	read_status_file(discard_status);
+
+	/* set unix domain socket path for connections to pgpool */
+	snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/.s.PGSQL.%d",
+			 pool_config->socket_dir,
+			 pool_config->port);
+	/* set unix domain socket path for pgpool PCP communication */
+	snprintf(pcp_un_addr.sun_path, sizeof(pcp_un_addr.sun_path), "%s/.s.PGSQL.%d",
+			 pool_config->pcp_socket_dir,
+			 pool_config->pcp_port);
+
+	/* set up signal handlers */
+	pool_signal(SIGPIPE, SIG_IGN);
+
+	/* create unix domain socket */
+	unix_fd = create_unix_domain_socket(un_addr);
+	on_proc_exit(FileUnlink, (Datum) un_addr.sun_path);
+
+	/* create inet domain socket if any */
+	if (pool_config->listen_addresses[0])
+		inet_fd = create_inet_domain_socket(pool_config->listen_addresses, pool_config->port);
+
+	initialize_shared_mem_objects();
+
+	/* start watchdog */
+	if (pool_config->use_watchdog )
+	{
+		if (!wd_main(1))
+		{
+			pool_error("wd_main error");
+			myexit(1);
+		}
+	}
+
+	/*
+	 * We need to block signal here. Otherwise child might send some
+	 * signals, for example SIGUSR1(fail over).  Children will inherit
+	 * signal blocking but they do unblock signals at the very beginning
+	 * of process.  So this is harmless.
+	 */
+	POOL_SETMASK(&BlockSig);
+
+	/* fork the children */
+	for (i=0;i<pool_config->num_init_children;i++)
+	{
+		process_info[i].pid = fork_a_child(unix_fd, inet_fd, i);
+		process_info[i].start_time = time(NULL);
+	}
+
+	/* set up signal handlers */
+
+	pool_signal(SIGTERM, exit_handler);
+	pool_signal(SIGINT, exit_handler);
+	pool_signal(SIGQUIT, exit_handler);
+	pool_signal(SIGCHLD, reap_handler);
+	pool_signal(SIGUSR1, failover_handler);
+	pool_signal(SIGUSR2, wakeup_handler);
+	pool_signal(SIGHUP, reload_config_handler);
+
+	/* create pipe for delivering event */
+	if (pipe(pipe_fds) < 0)
+	{
+		ereport(FATAL,
+			(errmsg("failed to create pipe")));
+	}
+	
+	MemoryContextSwitchTo(TopMemoryContext);
+
+	/* Create per loop iteration memory context */
+	MainLoopMemoryContext = AllocSetContextCreate(TopMemoryContext,
+											  "pgpool_main_loop",
+											  ALLOCSET_DEFAULT_MINSIZE,
+											  ALLOCSET_DEFAULT_INITSIZE,
+											  ALLOCSET_DEFAULT_MAXSIZE);
+	
+	ereport(LOG,
+		(errmsg("%s successfully started. version %s (%s)", PACKAGE, VERSION, PGPOOLVERSION)));
+
+	/* fork a child for PCP handling */
+	pcp_unix_fd = create_unix_domain_socket(pcp_un_addr);
+	/* Add onproc exit to clean up the unix domain socket at exit */
+	on_proc_exit(FileUnlink, (Datum)pcp_un_addr.sun_path);
+
+    /* maybe change "*" to pool_config->pcp_listen_addresses */
+	pcp_inet_fd = create_inet_domain_socket("*", pool_config->pcp_port);
+	pcp_pid = pcp_fork_a_child(pcp_unix_fd, pcp_inet_fd, pcp_conf_file);
+
+	/* Fork worker process */
+	worker_pid = worker_fork_a_child();
+
+	retrycnt = 0;		/* reset health check retry counter */
+	sys_retrycnt = 0;	/* reset SystemDB health check retry counter */
+
+	/* Save primary node id */
+	Req_info->primary_node_id = find_primary_node();
+
+	if (sigsetjmp(local_sigjmp_buf, 1) != 0)
+	{
+		/* Since not using PG_TRY, must reset error stack by hand */
+		error_context_stack = NULL;
+		EmitErrorReport();
+		FlushErrorState();
+		POOL_SETMASK(&BlockSig);
+
+		/* Check if we are failed during health check
+		 * perform the necessary actions in case
+		 */
+		if(processState == PERFORMING_HEALTH_CHECK)
+		{
+			if(errno != EINTR || health_check_timer_expired)
+			{
+				if(use_template_db == false)
+				{
+					/* Health check was performed on 'postgres' database
+					 * lets try to perform health check with template1 db
+					 * before marking the health check as failed
+					 */
+					use_template_db = true;
+
+				}
+				else
+				{
+					retrycnt++;
+					if(process_backend_health_check_failure(health_check_node_id, retrycnt))
+					{
+						health_check_node_id = 0;
+						use_template_db = false;
+					}
+				}
+			}
+		}
+		else if(processState == PERFORMING_SYSDB_CHECK)
+		{
+			if ( errno != EINTR || health_check_timer_expired)
+			{
+				sys_retrycnt++;
+				pool_signal(SIGALRM, SIG_IGN);
+				CLEAR_ALARM;
+
+				if (sys_retrycnt > NUM_BACKENDS)
+				{
+					pool_log("set SystemDB down status");
+					SYSDB_STATUS = CON_DOWN;
+					sys_retrycnt = 0;
+				}
+				int sleep_time = pool_config->health_check_period/NUM_BACKENDS;
+				pool_debug("retry sleep time: %d seconds", sleep_time);
+				pool_sleep(sleep_time);
+			}
+		}
+	}
+	/* We can now handle ereport(ERROR) */
+	PG_exception_stack = &local_sigjmp_buf;
+	
+	/* This is the main loop */
+	for (;;)
+	{
+		bool all_nodes_healthy;
+		CHECK_REQUEST;
+
+		/* do we need health checking for PostgreSQL? */
+		if (pool_config->health_check_period > 0)
+		{
+			/* rest per iteration memory context */
+			MemoryContextSwitchTo(MainLoopMemoryContext);
+			MemoryContextResetAndDeleteChildren(MainLoopMemoryContext);
+
+			if (retrycnt == 0 && !use_template_db)
+				ereport(LOG,
+					(errmsg("starting health check")));
+			else
+				ereport(LOG,
+					(errmsg("health checking retry count %d", retrycnt)));
+
+			if (pool_config->health_check_timeout > 0)
+			{
+				/*
+				 * set health checker timeout. we want to detect
+				 * communication path failure much earlier before
+				 * TCP/IP stack detects it.
+				 */
+				CLEAR_ALARM;
+				pool_signal(SIGALRM, health_check_timer_handler);
+				alarm(pool_config->health_check_timeout);
+			}
+			/*
+			 * do actual health check. trying to connect to the backend
+			 */
+			errno = 0;
+			health_check_timer_expired = 0;
+
+			if (pool_config->parallel_mode)
+			{
+				processState = PERFORMING_SYSDB_CHECK;
+				system_db_health_check();
+				sys_retrycnt = 0;
+				errno = 0;
+			}
+
+			POOL_SETMASK(&UnBlockSig);
+
+			processState = PERFORMING_HEALTH_CHECK;
+			all_nodes_healthy = do_health_check(use_template_db,&health_check_node_id);
+			POOL_SETMASK(&BlockSig);
+
+			health_check_node_id = 0;
+			use_template_db = false;
+			retrycnt = 0;
+
+			if (all_nodes_healthy)
+				ereport(LOG,
+					(errmsg("after retry %d, All backends are returned to healthy state",retrycnt)));
+
+
+			processState = SLEEPING;
+
+			if (pool_config->health_check_timeout > 0)
+			{
+				/* seems OK. cancel health check timer */
+				pool_signal(SIGALRM, SIG_IGN);
+				CLEAR_ALARM;
+			}
+			pool_sleep(pool_config->health_check_period);
+		}
+		else /* Health Check is not enable and we have not much to do */
+		{
+			processState = SLEEPING;
+			for (;;)
+			{
+				int r;
+				struct timeval t = {3, 0};
+
+				POOL_SETMASK(&UnBlockSig);
+				r = pool_pause(&t);
+				POOL_SETMASK(&BlockSig);
+				if (r > 0)
+					break;
+			}
+		}
+	}
+}
+
+/*
+ * Function process the backend node failure captured by the health check
+ * since this function is called from the exception handler so ereport(ERROR)
+ * is not allowed from this function
+ * Function returns non zero if failover is performed and 0 otherwise.
+ */
+static int
+process_backend_health_check_failure(int health_check_node_id, int retrycnt)
+{
+	/*
+	 *  health check is failed on template1 database as well
+	 */
+	int sleep_time = pool_config->parallel_mode ?
+			pool_config->health_check_period/NUM_BACKENDS : pool_config->health_check_retry_delay;
+
+	int health_check_max_retries = pool_config->parallel_mode ?
+			(NUM_BACKENDS - 1) : pool_config->health_check_retry_delay;
+
+	pool_signal(SIGALRM, SIG_IGN);	/* Cancel timer */
+	CLEAR_ALARM;
+
+	if (retrycnt <= health_check_max_retries)
+	{
+		/* Keep retrying and sleep a little in between */
+		ereport(DEBUG1,
+			(errmsg("Sleeping for %d seconds from process backend health check failure", sleep_time),
+					errdetail("health check failed retry no is %d while max retries are %d",retrycnt,health_check_max_retries) ));
+
+		pool_sleep(sleep_time);
+	}
+	else
+	{
+		/* No more retries left, proceed to failover if allowed */
+		if ((!pool_config->parallel_mode) &&
+			POOL_DISALLOW_TO_FAILOVER(BACKEND_INFO(health_check_node_id).flag))
+		{
+			pool_log("health check failed on node %d but failover is disallowed for the node", health_check_node_id);
+		}
+		else
+		{
+			pool_log("setting backend node %d status to NODE DOWN", health_check_node_id);
+			Req_info->kind = NODE_DOWN_REQUEST;
+			Req_info->node_id[0] = health_check_node_id;
+			health_check_timer_expired = 0;
+			failover();
+			return 1;
+			/* need to distribute this info to children ??*/
+		}
+	}
+	return 0;
+}
+/*
+ * fork a child for PCP
+ */
+pid_t pcp_fork_a_child(int unix_fd, int inet_fd, char *pcp_conf_file)
+{
+	pid_t pid;
+
+	pid = fork();
+
+	if (pid == 0)
+	{
+		on_exit_reset();
+
+		close(pipe_fds[0]);
+		close(pipe_fds[1]);
+
+		myargv = save_ps_display_args(myargc, myargv);
+		/* Set the process type variable */
+		processType = PT_PCP;
+
+		/* call PCP child main */
+		POOL_SETMASK(&UnBlockSig);
+		health_check_timer_expired = 0;
+		reload_config_request = 0;
+		run_as_pcp_child = true;
+		pcp_do_child(unix_fd, inet_fd, pcp_conf_file);
+	}
+	else if (pid == -1)
+	{
+		ereport(FATAL,
+			(errmsg("fork() failed. reason: %s", strerror(errno))));
+	}
+
+	return pid;
+}
+
+/*
+* fork a child
+*/
+pid_t fork_a_child(int unix_fd, int inet_fd, int id)
+{
+	pid_t pid;
+
+	pid = fork();
+
+	if (pid == 0)
+	{
+		on_exit_reset();
+
+		/* Before we unconditionally closed pipe_fds[0] and pipe_fds[1]
+		 * here, which is apparently wrong since in the start up of
+		 * pgpool, pipe(2) is not called yet and it mistakenly closes
+		 * fd 0. Now we check the fd > 0 before close(), expecting
+		 * pipe returns fds greater than 0.  Note that we cannot
+		 * unconditionally remove close(2) calls since fork_a_child()
+		 * may be called *after* pgpool starting up.
+		 */
+		if (pipe_fds[0] > 0)
+		{
+			close(pipe_fds[0]);
+			close(pipe_fds[1]);
+		}
+
+		myargv = save_ps_display_args(myargc, myargv);
+		/* Set the process type variable */
+		processType = PT_CHILD;
+
+		/* call child main */
+		POOL_SETMASK(&UnBlockSig);
+		health_check_timer_expired = 0;
+		reload_config_request = 0;
+		my_proc_id = id;
+		run_as_pcp_child = false;
+		do_child(unix_fd, inet_fd);
+	}
+	else if (pid == -1)
+	{
+		pool_error("fork() failed. reason: %s", strerror(errno));
+		myexit(1);
+	}
+
+	return pid;
+}
+
+/*
+* fork worker child process
+*/
+pid_t worker_fork_a_child()
+{
+	pid_t pid;
+	
+	pid = fork();
+
+	if (pid == 0)
+	{
+		on_exit_reset();
+
+		/* Before we unconditionally closed pipe_fds[0] and pipe_fds[1]
+		 * here, which is apparently wrong since in the start up of
+		 * pgpool, pipe(2) is not called yet and it mistakenly closes
+		 * fd 0. Now we check the fd > 0 before close(), expecting
+		 * pipe returns fds greater than 0.  Note that we cannot
+		 * unconditionally remove close(2) calls since fork_a_child()
+		 * may be called *after* pgpool starting up.
+		 */
+		if (pipe_fds[0] > 0)
+		{
+			close(pipe_fds[0]);
+			close(pipe_fds[1]);
+		}
+
+		myargv = save_ps_display_args(myargc, myargv);
+		/* Set the process type variable */
+		processType = PT_WORKER;
+
+		/* call child main */
+		POOL_SETMASK(&UnBlockSig);
+		health_check_timer_expired = 0;
+		reload_config_request = 0;
+		do_worker_child();
+	}
+	else if (pid == -1)
+	{
+		myexit(1);
+	}
+	
+	return pid;
+}
+
+/*
+* create inet domain socket
+*/
+static int create_inet_domain_socket(const char *hostname, const int port)
+{
+	struct sockaddr_in addr;
+	int fd;
+	int status;
+	int one = 1;
+	int len;
+	int backlog;
+
+	fd = socket(AF_INET, SOCK_STREAM, 0);
+	if (fd == -1)
+	{
+		ereport(FATAL,
+			(errmsg("failed to create INET domain socket"),
+			errdetail("socket error \"%s\"",strerror(errno))));
+	}
+	if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one,
+					sizeof(one))) == -1)
+	{
+		ereport(FATAL,
+			(errmsg("failed to create INET domain socket"),
+			errdetail("socket error \"%s\"",strerror(errno))));
+	}
+
+	memset((char *) &addr, 0, sizeof(addr));
+	addr.sin_family = AF_INET;
+
+	if (strcmp(hostname, "*")==0)
+	{
+		addr.sin_addr.s_addr = htonl(INADDR_ANY);
+	}
+	else
+	{
+		struct hostent *hostinfo;
+
+		hostinfo = gethostbyname(hostname);
+		if (!hostinfo)
+		{
+			ereport(FATAL,
+				(errmsg("failed to create INET domain socket"),
+				errdetail("could not resolve hostname \"%s\": error \"%s\"",hostname,hstrerror(h_errno))));
+
+		}
+		addr.sin_addr = *(struct in_addr *) hostinfo->h_addr;
+	}
+
+	addr.sin_port = htons(port);
+	len = sizeof(struct sockaddr_in);
+	status = bind(fd, (struct sockaddr *)&addr, len);
+	if (status == -1)
+	{
+		char *host = "", *serv = "";
+		char hostname[NI_MAXHOST], servname[NI_MAXSERV];
+		if (getnameinfo((struct sockaddr *) &addr, len, hostname, sizeof(hostname), servname, sizeof(servname), 0) == 0) 
+		{
+			host = hostname;
+			serv = servname;
+		}
+		ereport(FATAL,
+			(errmsg("failed to create INET domain socket"),
+			errdetail("bind on host:\"%s\" server:\"%s\" failed with error \"%s\"",host, serv,strerror(errno))));
+	}
+
+	backlog = pool_config->num_init_children * 2;
+	if (backlog > PGPOOLMAXLITSENQUEUELENGTH)
+		backlog = PGPOOLMAXLITSENQUEUELENGTH;
+
+	status = listen(fd, backlog);
+	if (status < 0)
+		ereport(FATAL,
+			(errmsg("failed to create INET domain socket"),
+			errdetail("listen on socket failed with error \"%s\"",strerror(errno))));
+
+	return fd;
+}
+
+/*
+* create UNIX domain socket
+*/
+static int create_unix_domain_socket(struct sockaddr_un un_addr_tmp)
+{
+	struct sockaddr_un addr;
+	int fd;
+	int status;
+	int len;
+
+	fd = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (fd == -1)
+	{
+		pool_error("Failed to create UNIX domain socket. reason: %s", strerror(errno));
+		myexit(1);
+	}
+	memset((char *) &addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+	snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", un_addr_tmp.sun_path);
+	len = sizeof(struct sockaddr_un);
+	status = bind(fd, (struct sockaddr *)&addr, len);
+	if (status == -1)
+	{
+		pool_error("bind(%s) failed. reason: %s", addr.sun_path, strerror(errno));
+		myexit(1);
+	}
+
+	if (chmod(un_addr_tmp.sun_path, 0777) == -1)
+	{
+		pool_error("chmod() failed. reason: %s", strerror(errno));
+		myexit(1);
+	}
+
+	status = listen(fd, PGPOOLMAXLITSENQUEUELENGTH);
+	if (status < 0)
+	{
+		pool_error("listen() failed. reason: %s", strerror(errno));
+		myexit(1);
+	}
+	return fd;
+}
+
+static void myexit(int code)
+{
+	int i;
+
+	if(processType != PT_MAIN)
+		return;
+
+	if (process_info != NULL) {
+		POOL_SETMASK(&AuthBlockSig);
+		exiting = 1;
+		for (i = 0; i < pool_config->num_init_children; i++)
+		{
+			pid_t pid = process_info[i].pid;
+			if (pid)
+			{
+				kill(pid, SIGTERM);
+			}
+		}
+
+		/* wait for all children to exit */
+		while (wait(NULL) > 0);
+		if (errno != ECHILD)
+			pool_error("wait() failed. reason:%s", strerror(errno));
+		POOL_SETMASK(&UnBlockSig);
+	}
+
+    write_status_file();
+
+    proc_exit(code);
+
+}
+
+void notice_backend_error(int node_id)
+{
+	int n = node_id;
+
+	if (getpid() == mypid)
+	{
+		pool_log("notice_backend_error: called from pgpool main. ignored.");
+	}
+	else
+	{
+		degenerate_backend_set(&n, 1);
+	}
+}
+
+/* notice backend connection error using SIGUSR1 */
+void degenerate_backend_set(int *node_id_set, int count)
+{
+	pid_t parent = getppid();
+	int i;
+	bool need_signal = false;
+#ifdef HAVE_SIGPROCMASK
+	sigset_t oldmask;
+#else
+	int	oldmask;
+#endif
+
+	if (pool_config->parallel_mode)
+	{
+		return;
+	}
+
+	POOL_SETMASK2(&BlockSig, &oldmask);
+	pool_semaphore_lock(REQUEST_INFO_SEM);
+	Req_info->kind = NODE_DOWN_REQUEST;
+	for (i = 0; i < count; i++)
+	{
+		if (node_id_set[i] < 0 || node_id_set[i] >= MAX_NUM_BACKENDS ||
+			!VALID_BACKEND(node_id_set[i]))
+		{
+			pool_log("degenerate_backend_set: node %d is not valid backend.", i);
+			continue;
+		}
+
+		if (POOL_DISALLOW_TO_FAILOVER(BACKEND_INFO(node_id_set[i]).flag))
+		{
+			pool_log("degenerate_backend_set: %d failover request from pid %d is canceled because failover is disallowed", node_id_set[i], getpid());
+			continue;
+		}
+
+		pool_log("degenerate_backend_set: %d fail over request from pid %d", node_id_set[i], getpid());
+		Req_info->node_id[i] = node_id_set[i];
+		need_signal = true;
+	}
+
+	if (need_signal)
+	{
+		if (!pool_config->use_watchdog || WD_OK == wd_degenerate_backend_set(node_id_set, count))
+		{
+			kill(parent, SIGUSR1);
+		}
+		else
+		{
+			pool_log("degenerate_backend_set: failover request from pid %d is canceled by other pgpool", getpid());
+			memset(Req_info->node_id, -1, sizeof(int) * MAX_NUM_BACKENDS);
+		}
+	}
+
+	pool_semaphore_unlock(REQUEST_INFO_SEM);
+	POOL_SETMASK(&oldmask);
+}
+
+/* send promote node request using SIGUSR1 */
+void promote_backend(int node_id)
+{
+	pid_t parent = getppid();
+
+	if (!MASTER_SLAVE || strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
+	{
+		return;
+	}
+
+	if (node_id < 0 || node_id >= MAX_NUM_BACKENDS || !VALID_BACKEND(node_id))
+	{
+		pool_error("promote_backend: node %d is not valid backend.", node_id);
+		return;
+	}
+
+	pool_semaphore_lock(REQUEST_INFO_SEM);
+	Req_info->kind = PROMOTE_NODE_REQUEST;
+	Req_info->node_id[0] = node_id;
+	pool_log("promote_backend: %d promote node request from pid %d", node_id, getpid());
+
+	if (!pool_config->use_watchdog || WD_OK == wd_promote_backend(node_id))
+	{
+		kill(parent, SIGUSR1);
+	}
+	else
+	{
+		pool_log("promote_backend: promote request from pid %d is canceled by other pgpool", getpid());
+		Req_info->node_id[0] = -1;
+	}
+
+	pool_semaphore_unlock(REQUEST_INFO_SEM);
+}
+
+/* send failback request using SIGUSR1 */
+void send_failback_request(int node_id)
+{
+	pid_t parent = getppid();
+
+	pool_log("send_failback_request: fail back %d th node request from pid %d", node_id, getpid());
+	Req_info->kind = NODE_UP_REQUEST;
+	Req_info->node_id[0] = node_id;
+
+    if (node_id < 0 || node_id >= MAX_NUM_BACKENDS ||
+		(RAW_MODE && BACKEND_INFO(node_id).backend_status != CON_DOWN && VALID_BACKEND(node_id)))
+	{
+		pool_error("send_failback_request: node %d is alive.", node_id);
+		Req_info->node_id[0] = -1;
+		return;
+	}
+
+	if (pool_config->use_watchdog && WD_OK != wd_send_failback_request(node_id))
+	{
+		pool_log("send_failback_request: failback request from pid %d is canceled by other pgpool", getpid());
+		Req_info->node_id[0] = -1;
+		return;
+	}
+	kill(parent, SIGUSR1);
+}
+
+static RETSIGTYPE exit_handler(int sig)
+{
+	int i;
+	POOL_SETMASK(&AuthBlockSig);
+
+	/*
+	 * this could happen in a child process if a signal has been sent
+	 * before resetting signal handler
+	 */
+	if (getpid() != mypid)
+	{
+		pool_debug("exit_handler: I am not parent");
+		POOL_SETMASK(&UnBlockSig);
+		proc_exit(0);
+	}
+
+	if (sig == SIGTERM)
+		pool_log("received smart shutdown request");
+	else if (sig == SIGINT)
+		pool_log("received fast shutdown request");
+	else if (sig == SIGQUIT)
+		pool_log("received immediate shutdown request");
+	else
+	{
+		pool_error("exit_handler: unknown signal received %d", sig);
+		POOL_SETMASK(&UnBlockSig);
+		return;
+	}
+	exiting = 1;
+
+	for (i = 0; i < pool_config->num_init_children; i++)
+	{
+
+		pid_t pid = process_info[i].pid;
+		if (pid)
+		{
+			kill(pid, sig);
+		}
+	}
+	kill(pcp_pid, sig);
+	kill(worker_pid, sig);
+
+	if (pool_config->use_watchdog)
+	{
+		wd_kill_watchdog(sig);
+	}
+
+	POOL_SETMASK(&UnBlockSig);
+
+	while (wait(NULL) > 0);
+
+	if (errno != ECHILD)
+		pool_error("wait() failed. reason:%s", strerror(errno));
+
+	process_info = NULL;
+	myexit(0);
+}
+
+/*
+ * Calculate next valid master node id.
+ * If no valid node found, returns -1.
+ */
+static int get_next_master_node(void)
+{
+	int i;
+
+	for (i=0;i<pool_config->backend_desc->num_backends;i++)
+	{
+		/*
+		 * Do not use VALID_BACKEND macro in raw mode.
+		 * VALID_BACKEND return true only if the argument is master
+		 * node id. In other words, standby nodes are false. So need
+		 * to check backend status with VALID_BACKEND_RAW.
+		 */
+		if (RAW_MODE)
+		{
+			if (VALID_BACKEND_RAW(i))
+				break;
+		}
+		else
+		{
+			if (VALID_BACKEND(i))
+				break;
+		}
+	}
+
+	if (i == pool_config->backend_desc->num_backends)
+		i = -1;
+
+	return i;
+}
+
+/*
+ * handle SIGUSR1
+ *
+ */
+static RETSIGTYPE failover_handler(int sig)
+{
+	POOL_SETMASK(&BlockSig);
+	failover_request = 1;
+	write(pipe_fds[1], "\0", 1);
+	POOL_SETMASK(&UnBlockSig);
+}
+
+/*
+ * backend connection error, failover/failback request, if possible
+ * failover() must be called under protecting signals.
+ */
+static void failover(void)
+{
+	int i;
+	int node_id;
+	bool by_health_check;
+	int new_master;
+	int new_primary;
+	int nodes[MAX_NUM_BACKENDS];
+	bool need_to_restart_children;
+	int status;
+	int sts;
+
+	pool_debug("failover_handler called");
+
+	memset(nodes, 0, sizeof(int) * MAX_NUM_BACKENDS);
+
+	/*
+	 * this could happen in a child process if a signal has been sent
+	 * before resetting signal handler
+	 */
+	if (getpid() != mypid)
+	{
+		pool_debug("failover_handler: I am not parent");
+		kill(pcp_pid, SIGUSR2);
+		return;
+	}
+
+	/*
+	 * processing SIGTERM, SIGINT or SIGQUIT
+	 */
+	if (exiting)
+	{
+		pool_debug("failover_handler called while exiting");
+		kill(pcp_pid, SIGUSR2);
+		return;
+	}
+
+	/*
+	 * processing fail over or switch over
+	 */
+	if (switching)
+	{
+		pool_debug("failover_handler called while switching");
+		kill(pcp_pid, SIGUSR2);
+		return;
+	}
+
+	pool_semaphore_lock(REQUEST_INFO_SEM);
+
+	if (Req_info->kind == CLOSE_IDLE_REQUEST)
+	{
+		pool_semaphore_unlock(REQUEST_INFO_SEM);
+		kill_all_children(SIGUSR1);
+		kill(pcp_pid, SIGUSR2);
+		return;
+	}
+
+	/*
+	 * if not in replication mode/master slave mode, we treat this a restart request.
+	 * otherwise we need to check if we have already failovered.
+	 */
+	pool_debug("failover_handler: starting to select new master node");
+	switching = 1;
+	Req_info->switching = true;
+	node_id = Req_info->node_id[0];
+
+	/* start of command inter-lock with watchdog */
+	if (pool_config->use_watchdog)
+	{
+		by_health_check = (!failover_request && Req_info->kind==NODE_DOWN_REQUEST);
+		wd_start_interlock(by_health_check);
+	}
+
+	/* failback request? */
+	if (Req_info->kind == NODE_UP_REQUEST)
+	{
+		if (node_id < 0 || node_id >= MAX_NUM_BACKENDS ||
+			(Req_info->kind == NODE_UP_REQUEST && !(RAW_MODE &&
+            BACKEND_INFO(node_id).backend_status == CON_DOWN) && VALID_BACKEND(node_id)) ||
+			(Req_info->kind == NODE_DOWN_REQUEST && !VALID_BACKEND(node_id)))
+		{
+			pool_semaphore_unlock(REQUEST_INFO_SEM);
+
+			if (node_id < 0 || node_id >= MAX_NUM_BACKENDS)
+				pool_error("failover_handler: invalid node_id %d MAX_NUM_BACKENDS: %d", node_id, MAX_NUM_BACKENDS);
+			else
+				pool_error("failover_handler: invalid node_id %d status:%d MAX_NUM_BACKENDS: %d", node_id,
+						   BACKEND_INFO(node_id).backend_status, MAX_NUM_BACKENDS);
+			kill(pcp_pid, SIGUSR2);
+			switching = 0;
+			Req_info->switching = false;
+
+			/* end of command inter-lock */
+			if (pool_config->use_watchdog)
+				wd_leave_interlock();
+
+			return;
+		}
+
+		pool_log("starting fail back. reconnect host %s(%d)",
+				 BACKEND_INFO(node_id).backend_hostname,
+				 BACKEND_INFO(node_id).backend_port);
+		BACKEND_INFO(node_id).backend_status = CON_CONNECT_WAIT;	/* unset down status */
+
+		/* wait for failback command lock or to be lock holder */
+		if (pool_config->use_watchdog && !wd_am_I_lock_holder())
+		{
+			wd_wait_for_lock(WD_FAILBACK_COMMAND_LOCK);
+		}
+		/* execute failback command if lock holder */
+		if (!pool_config->use_watchdog || wd_am_I_lock_holder())
+		{
+			trigger_failover_command(node_id, pool_config->failback_command,
+								 	MASTER_NODE_ID, get_next_master_node(), PRIMARY_NODE_ID);
+
+			/* unlock failback command */
+			if (pool_config->use_watchdog)
+				wd_unlock(WD_FAILBACK_COMMAND_LOCK);
+		}
+	}
+	else if (Req_info->kind == PROMOTE_NODE_REQUEST)
+	{
+		if (node_id != -1 && VALID_BACKEND(node_id))
+		{
+			pool_log("starting promotion. promote host %s(%d)",
+					 BACKEND_INFO(node_id).backend_hostname,
+					 BACKEND_INFO(node_id).backend_port);
+		}
+		else
+		{
+			pool_log("failover: no backends are promoted");
+			pool_semaphore_unlock(REQUEST_INFO_SEM);
+			kill(pcp_pid, SIGUSR2);
+			switching = 0;
+			Req_info->switching = false;
+
+			/* end of command inter-lock */
+			if (pool_config->use_watchdog)
+				wd_leave_interlock();
+
+			return;
+		}
+	}
+	else
+	{
+		int cnt = 0;
+
+		for (i = 0; i < MAX_NUM_BACKENDS; i++)
+		{
+			if (Req_info->node_id[i] != -1 &&
+				((RAW_MODE && VALID_BACKEND_RAW(Req_info->node_id[i])) ||
+				 VALID_BACKEND(Req_info->node_id[i])))
+			{
+				pool_log("starting degeneration. shutdown host %s(%d)",
+						 BACKEND_INFO(Req_info->node_id[i]).backend_hostname,
+						 BACKEND_INFO(Req_info->node_id[i]).backend_port);
+
+				BACKEND_INFO(Req_info->node_id[i]).backend_status = CON_DOWN;	/* set down status */
+				/* save down node */
+				nodes[Req_info->node_id[i]] = 1;
+				cnt++;
+			}
+		}
+
+		if (cnt == 0)
+		{
+			pool_log("failover: no backends are degenerated");
+			pool_semaphore_unlock(REQUEST_INFO_SEM);
+			kill(pcp_pid, SIGUSR2);
+			switching = 0;
+			Req_info->switching = false;
+
+			/* end of command inter-lock */
+			if (pool_config->use_watchdog)
+				wd_leave_interlock();
+
+			return;
+		}
+	}
+
+	new_master = get_next_master_node();
+
+	if (new_master < 0)
+	{
+		pool_error("failover_handler: no valid DB node found");
+	}
+
+/*
+ * Before we tried to minimize restarting pgpool to protect existing
+ * connections from clients to pgpool children. What we did here was,
+ * if children other than master went down, we did not fail over.
+ * This is wrong. Think about following scenario. If someone
+ * accidentally plugs out the network cable, the TCP/IP stack keeps
+ * retrying for long time (typically 2 hours). The only way to stop
+ * the retry is restarting the process.  Bottom line is, we need to
+ * restart all children in any case.  See pgpool-general list posting
+ * "TCP connections are *not* closed when a backend timeout" on Jul 13
+ * 2008 for more details.
+ */
+#ifdef NOT_USED
+	else
+	{
+		if (Req_info->master_node_id == new_master && *InRecovery == RECOVERY_INIT)
+		{
+			pool_log("failover_handler: do not restart pgpool. same master node %d was selected", new_master);
+			if (Req_info->kind == NODE_UP_REQUEST)
+			{
+				pool_log("failback done. reconnect host %s(%d)",
+						 BACKEND_INFO(node_id).backend_hostname,
+						 BACKEND_INFO(node_id).backend_port);
+			}
+			else
+			{
+				pool_log("failover done. shutdown host %s(%d)",
+						 BACKEND_INFO(node_id).backend_hostname,
+						 BACKEND_INFO(node_id).backend_port);
+			}
+
+			/* exec failover_command */
+			for (i = 0; i < pool_config->backend_desc->num_backends; i++)
+			{
+				if (nodes[i])
+					trigger_failover_command(i, pool_config->failover_command);
+			}
+
+			pool_semaphore_unlock(REQUEST_INFO_SEM);
+			switching = 0;
+			Req_info->switching = false;
+			kill(pcp_pid, SIGUSR2);
+			switching = 0;
+			Req_info->switching = false;
+			return;
+		}
+	}
+#endif
+
+
+   /* On 2011/5/2 Tatsuo Ishii says: if mode is streaming replication
+	* and request is NODE_UP_REQUEST(failback case) we don't need to
+	* restart all children. Existing session will not use newly
+	* attached node, but load balanced node is not changed until this
+	* session ends, so it's harmless anyway.
+	*/
+	if (MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP)	&&
+		Req_info->kind == NODE_UP_REQUEST)
+	{
+		pool_log("Do not restart children because we are failbacking node id %d host%s port:%d and we are in streaming replication mode", node_id,
+				 BACKEND_INFO(node_id).backend_hostname,
+				 BACKEND_INFO(node_id).backend_port);
+
+		need_to_restart_children = false;
+	}
+	else
+	{
+		pool_log("Restart all children");
+
+		/* kill all children */
+		for (i = 0; i < pool_config->num_init_children; i++)
+		{
+			pid_t pid = process_info[i].pid;
+			if (pid)
+			{
+				kill(pid, SIGQUIT);
+				pool_debug("failover_handler: kill %d", pid);
+			}
+		}
+
+		need_to_restart_children = true;
+	}
+
+	/* wait for failover command lock or to be lock holder*/
+	if (pool_config->use_watchdog && !wd_am_I_lock_holder())
+	{
+		wd_wait_for_lock(WD_FAILOVER_COMMAND_LOCK);
+	}
+
+	/* execute failover command if lock holder */
+	if (!pool_config->use_watchdog || wd_am_I_lock_holder())
+	{
+		/* Exec failover_command if needed */
+		for (i = 0; i < pool_config->backend_desc->num_backends; i++)
+		{
+			if (nodes[i])
+				trigger_failover_command(i, pool_config->failover_command,
+									 		MASTER_NODE_ID, new_master, PRIMARY_NODE_ID);
+		}
+
+		/* unlock failover command */
+		if (pool_config->use_watchdog)
+			wd_unlock(WD_FAILOVER_COMMAND_LOCK);
+	}
+
+
+/* no need to wait since it will be done in reap_handler */
+#ifdef NOT_USED
+	while (wait(NULL) > 0)
+		;
+
+	if (errno != ECHILD)
+		pool_error("failover_handler: wait() failed. reason:%s", strerror(errno));
+#endif
+
+	if (Req_info->kind == PROMOTE_NODE_REQUEST && VALID_BACKEND(node_id))
+		new_primary = node_id;
+
+	/*
+	 * If the down node was a standby node in streaming replication
+	 * mode, we can avoid calling find_primary_node_repeatedly() and
+	 * recognize the former primary as the new primary node, which
+	 * will reduce the time to process standby down.
+	 */
+	else if (MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP) &&
+			 Req_info->kind == NODE_DOWN_REQUEST)
+	{
+		if (Req_info->primary_node_id != node_id)
+			new_primary = Req_info->primary_node_id;
+		else
+			new_primary =  find_primary_node_repeatedly();
+	}
+	else
+		new_primary =  find_primary_node_repeatedly();
+
+	/*
+	 * If follow_master_command is provided and in master/slave
+	 * streaming replication mode, we start degenerating all backends
+	 * as they are not replicated anymore.
+	 */
+	int follow_cnt = 0;
+	if (MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
+	{
+		if (*pool_config->follow_master_command != '\0' ||
+			Req_info->kind == PROMOTE_NODE_REQUEST)
+		{
+			/* only if the failover is against the current primary */
+			if (((Req_info->kind == NODE_DOWN_REQUEST) &&
+				 (nodes[Req_info->primary_node_id])) ||
+				((Req_info->kind == PROMOTE_NODE_REQUEST) &&
+				 (VALID_BACKEND(node_id)))) {
+
+				for (i = 0; i < pool_config->backend_desc->num_backends; i++)
+				{
+					/* do not degenerate the new primary */
+					if ((new_primary >= 0) && (i != new_primary)) {
+						BackendInfo *bkinfo;
+						bkinfo = pool_get_node_info(i);
+						pool_log("starting follow degeneration. shutdown host %s(%d)",
+								 bkinfo->backend_hostname,
+								 bkinfo->backend_port);
+						bkinfo->backend_status = CON_DOWN;	/* set down status */
+						follow_cnt++;
+					}
+				}
+
+				if (follow_cnt == 0)
+				{
+					pool_log("failover: no follow backends are degenerated");
+				}
+				else
+				{
+					/* update new master node */
+					new_master = get_next_master_node();
+					pool_log("failover: %d follow backends have been degenerated", follow_cnt);
+				}
+			}
+		}
+	}
+
+	memset(Req_info->node_id, -1, sizeof(int) * MAX_NUM_BACKENDS);
+	pool_semaphore_unlock(REQUEST_INFO_SEM);
+
+	/* wait for follow_master_command lock or to be lock holder */
+	if (pool_config->use_watchdog && !wd_am_I_lock_holder())
+	{
+		wd_wait_for_lock(WD_FOLLOW_MASTER_COMMAND_LOCK);
+	}
+
+	/* execute follow_master_command */
+	if (!pool_config->use_watchdog || wd_am_I_lock_holder())
+	{
+		if ((follow_cnt > 0) && (*pool_config->follow_master_command != '\0'))
+		{
+			follow_pid = fork_follow_child(Req_info->master_node_id, new_primary,
+									   	Req_info->primary_node_id);
+		}
+
+		/* unlock follow_master_command  */
+		if (pool_config->use_watchdog)
+			wd_unlock(WD_FOLLOW_MASTER_COMMAND_LOCK);
+	}
+
+	/* end of command inter-lock */
+	if (pool_config->use_watchdog)
+		wd_end_interlock();
+
+	/* Save primary node id */
+	Req_info->primary_node_id = new_primary;
+	pool_log("failover: set new primary node: %d", Req_info->primary_node_id);
+
+	if (new_master >= 0)
+	{
+		Req_info->master_node_id = new_master;
+		pool_log("failover: set new master node: %d", Req_info->master_node_id);
+	}
+
+
+	/* Fork the children if needed */
+	if (need_to_restart_children)
+	{
+		for (i=0;i<pool_config->num_init_children;i++)
+		{
+
+			/*
+			 * Try to kill pgpool child because previous kill signal
+			 * may not be received by pgpool child. This could happen
+			 * if multiple PostgreSQL are going down (or even starting
+			 * pgpool, without starting PostgreSQL can trigger this).
+			 * Child calls degenerate_backend() and it tries to aquire
+			 * semaphore to write a failover request. In this case the
+			 * signal mask is set as well, thus signals are never
+			 * received.
+			 */
+			kill(process_info[i].pid, SIGQUIT);
+
+			process_info[i].pid = fork_a_child(unix_fd, inet_fd, i);
+			process_info[i].start_time = time(NULL);
+		}
+	}
+	else
+	{
+		/* Set restart request to each child. Children will exit(1)
+		 * whenever they are idle to restart.
+		 */
+		for (i=0;i<pool_config->num_init_children;i++)
+		{
+			process_info[i].need_to_restart = 1;
+		}
+	}
+
+	/*
+	 * Send restart request to worker child.
+	 */
+	kill(worker_pid, SIGUSR1);
+
+	if (Req_info->kind == NODE_UP_REQUEST)
+	{
+		pool_log("failback done. reconnect host %s(%d)",
+				 BACKEND_INFO(node_id).backend_hostname,
+				 BACKEND_INFO(node_id).backend_port);
+	}
+	else if (Req_info->kind == PROMOTE_NODE_REQUEST)
+	{
+		pool_log("promotion done. promoted host %s(%d)",
+				 BACKEND_INFO(node_id).backend_hostname,
+				 BACKEND_INFO(node_id).backend_port);
+	}
+	else
+	{
+		pool_log("failover done. shutdown host %s(%d)",
+				 BACKEND_INFO(node_id).backend_hostname,
+				 BACKEND_INFO(node_id).backend_port);
+	}
+
+	switching = 0;
+	Req_info->switching = false;
+
+	/* kick wakeup_handler in pcp_child to notice that
+	 * failover/failback done
+	 */
+	kill(pcp_pid, SIGUSR2);
+
+	sleep(1);
+
+	/*
+	 * Send restart request to pcp child.
+	 */
+	kill(pcp_pid, SIGUSR1);
+	for (;;)
+	{
+		sts = waitpid(pcp_pid, &status, 0);
+		if (sts != -1)
+			break;
+		if (sts == -1)
+		{
+			if (errno == EINTR)
+				continue;
+			else
+			{
+				pool_error("failover: waitpid failed. reason: %s", strerror(errno));
+				return;
+			}
+		}
+	}
+	if (WIFSIGNALED(status))
+		pool_log("PCP child %d exits with status %d by signal %d in failover()", pcp_pid, status, WTERMSIG(status));
+	else
+		pool_log("PCP child %d exits with status %d in failover()", pcp_pid, status);
+
+	pcp_pid = pcp_fork_a_child(pcp_unix_fd, pcp_inet_fd, pcp_conf_file);
+	pool_log("fork a new PCP child pid %d in failover()", pcp_pid);
+}
+
+/*
+ * health check timer handler
+ */
+static RETSIGTYPE health_check_timer_handler(int sig)
+{
+	POOL_SETMASK(&BlockSig);
+	health_check_timer_expired = 1;
+	POOL_SETMASK(&UnBlockSig);
+}
+
+
+
+/*
+ * do_health_check() performs the health check on all backend nodes.
+ * The inout parameter health_check_node_id is the starting backend
+ * node number for health check and when the function returns or
+ * exits with an error health_check_node_id contains the value
+ * of last backend node number on which health check was performed.
+ *
+ * Function returns false if all backend nodes are down and true if all
+ * backend nodes are in healthy state
+ */
+static bool
+do_health_check(bool use_template_db, volatile int *health_check_node_id)
+{
+	POOL_CONNECTION_POOL_SLOT *slot;
+	BackendInfo *bkinfo;
+	static char *dbname;
+	int i;
+	bool all_nodes_healthy = false;
+
+	/* Do not execute health check during recovery */
+	if (*InRecovery)
+		return false;
+
+	dbname = use_template_db ? "template1" : "postgres";
+	/*
+	 * Start checking the backed nodes starting from the
+	 * previously failed node
+	 */
+	for (i=*health_check_node_id;i<pool_config->backend_desc->num_backends;i++)
+	{
+		*health_check_node_id = i;
+		/*
+		 * Make sure that health check timer has not been expired.
+		 * Before called health_check(), health_check_timer_expired is
+		 * set to 0.  However it is possible that while processing DB
+		 * nodes health check timer expired.
+		 */
+		if (health_check_timer_expired)
+		{
+			ereport(ERROR,
+				(errmsg("health check timer has been already expired before attempting to connect backend node %d", i)));
+		}
+
+		bkinfo = pool_get_node_info(i);
+
+		ereport(DEBUG1,
+			(errmsg("Backend DB node %d status is %d", i, bkinfo->backend_status)));
+
+
+		if (bkinfo->backend_status == CON_UNUSED ||
+			bkinfo->backend_status == CON_DOWN)
+			continue;
+
+		all_nodes_healthy = true;
+		ereport(DEBUG1,
+			(errmsg("Trying to make persistent DB connection to backend node %d having status %d", i, bkinfo->backend_status)));
+
+		slot = make_persistent_db_connection(bkinfo->backend_hostname,
+											 bkinfo->backend_port,
+											 dbname,
+											 pool_config->health_check_user,
+											 pool_config->health_check_password, false);
+
+		ereport(DEBUG1,
+			(errmsg("persistent DB connection to backend node %d having status %d is successful", i, bkinfo->backend_status)));
+
+		discard_persistent_db_connection(slot);
+	}
+	return all_nodes_healthy;
+}
+
+/*
+ * handle SIGCHLD
+ */
+static RETSIGTYPE reap_handler(int sig)
+{
+	POOL_SETMASK(&BlockSig);
+	sigchld_request = 1;
+	write(pipe_fds[1], "\0", 1);
+	POOL_SETMASK(&UnBlockSig);
+}
+
+/*
+ * Attach zombie processes and restart child processes.
+ * reaper() must be called protected from signals.
+ */
+static void reaper(void)
+{
+	pid_t pid;
+	int status;
+	int i;
+
+	pool_debug("reap_handler called");
+
+	if (exiting)
+	{
+		pool_debug("reap_handler: exited due to exiting");
+		return;
+	}
+
+	if (switching)
+	{
+		pool_debug("reap_handler: exited due to switching");
+		return;
+	}
+
+	/* clear SIGCHLD request */
+	sigchld_request = 0;
+
+#ifdef HAVE_WAITPID
+	pool_debug("reap_handler: call waitpid");
+	while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
+#else
+	pool_debug("reap_handler: call wait3");
+	while ((pid = wait3(&status, WNOHANG, NULL)) > 0)
+#endif
+	{
+		if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV)
+		{
+			/* Child terminated by segmentation fault. Report it */
+			pool_error("Child process %d was terminated by segmentation fault", pid);
+		}
+
+		/* if exiting child process was PCP handler */
+		if (pid == pcp_pid)
+		{
+			if (WIFSIGNALED(status))
+				pool_log("PCP child %d exits with status %d by signal %d", pid, status, WTERMSIG(status));
+			else
+				pool_log("PCP child %d exits with status %d", pid, status);
+
+			pcp_pid = pcp_fork_a_child(pcp_unix_fd, pcp_inet_fd, pcp_conf_file);
+			pool_log("fork a new PCP child pid %d", pcp_pid);
+		}
+
+		/* exiting process was worker process */
+		else if (pid == worker_pid)
+		{
+			if (WIFSIGNALED(status))
+				pool_log("worker child %d exits with status %d by signal %d", pid, status, WTERMSIG(status));
+			else
+				pool_log("worker child %d exits with status %d", pid, status);
+
+			if (status)
+				worker_pid = worker_fork_a_child();
+
+			pool_log("fork a new worker child pid %d", worker_pid);
+		}
+
+		/* exiting process was watchdog process */
+		else if (pool_config->use_watchdog && wd_is_watchdog_pid(pid))
+		{
+			if (!wd_reaper_watchdog(pid, status))
+			{
+				pool_error("wd_reaper failed");
+				myexit(1);
+			}
+		}
+
+		else
+		{
+			if (WIFSIGNALED(status))
+				pool_debug("child %d exits with status %d by signal %d", pid, status, WTERMSIG(status));
+			else
+				pool_debug("child %d exits with status %d", pid, status);
+
+			/* look for exiting child's pid */
+			for (i=0;i<pool_config->num_init_children;i++)
+			{
+				if (pid == process_info[i].pid)
+				{
+					/* if found, fork a new child */
+					if (!switching && !exiting && status)
+					{
+						process_info[i].pid = fork_a_child(unix_fd, inet_fd, i);
+						process_info[i].start_time = time(NULL);
+						pool_debug("fork a new child pid %d", process_info[i].pid);
+						break;
+					}
+				}
+			}
+		}
+	}
+	pool_debug("reap_handler: normally exited");
+}
+
+/*
+ * get node information specified by node_number
+ */
+BackendInfo *
+pool_get_node_info(int node_number)
+{
+	if (node_number < 0 || node_number >= NUM_BACKENDS)
+		return NULL;
+
+	return &BACKEND_INFO(node_number);
+}
+
+/*
+ * get number of nodes
+ */
+int
+pool_get_node_count(void)
+{
+	return NUM_BACKENDS;
+}
+
+/*
+ * get process ids
+ */
+int *
+pool_get_process_list(int *array_size)
+{
+	int	   *array;
+	int		i;
+
+	*array_size = pool_config->num_init_children;
+	array = palloc0(*array_size * sizeof(int));
+	for (i = 0; i < *array_size; i++)
+		array[i] = process_info[i].pid;
+
+	return array;
+}
+
+/*
+ * get process information specified by pid
+ */
+ProcessInfo *
+pool_get_process_info(pid_t pid)
+{
+	int		i;
+
+	for (i = 0; i < pool_config->num_init_children; i++)
+		if (process_info[i].pid == pid)
+			return &process_info[i];
+
+	return NULL;
+}
+
+/*
+ * handle SIGUSR2
+ * Wakeup all processes
+ */
+static void wakeup_children(void)
+{
+	kill_all_children(SIGUSR2);
+}
+
+
+static RETSIGTYPE wakeup_handler(int sig)
+{
+	POOL_SETMASK(&BlockSig);
+	wakeup_request = 1;
+	write(pipe_fds[1], "\0", 1);
+	POOL_SETMASK(&UnBlockSig);
+}
+
+/*
+ * handle SIGHUP
+ *
+ */
+static RETSIGTYPE reload_config_handler(int sig)
+{
+	POOL_SETMASK(&BlockSig);
+	reload_config_request = 1;
+	write(pipe_fds[1], "\0", 1);
+	POOL_SETMASK(&UnBlockSig);
+}
+
+static void kill_all_children(int sig)
+{
+	int i;
+
+	/* kill all children */
+	for (i = 0; i < pool_config->num_init_children; i++)
+	{
+		pid_t pid = process_info[i].pid;
+		if (pid)
+		{
+			kill(pid, sig);
+		}
+	}
+
+	/* make PCP process reload as well */
+	if (sig == SIGHUP)
+		kill(pcp_pid, sig);
+}
+
+/*
+ * pause in a period specified by timeout. If any data is coming
+ * through pipe_fds[0], that means one of: failover request(SIGUSR1),
+ * SIGCHLD received, children wake up request(SIGUSR2 used in on line
+ * recovery processing) or config file reload request(SIGHUP) has been
+ * occurred.  In this case this function returns 1.
+ * otherwise 0: (no signal event occurred), -1: (error)
+ * XXX: is it OK that select(2) error is ignored here?
+ */
+static int pool_pause(struct timeval *timeout)
+{
+	fd_set rfds;
+	int n;
+	char dummy;
+
+	FD_ZERO(&rfds);
+	FD_SET(pipe_fds[0], &rfds);
+	n = select(pipe_fds[0]+1, &rfds, NULL, NULL, timeout);
+	if (n == 1)
+		read(pipe_fds[0], &dummy, 1);
+	return n;
+}
+
+/*
+ * sleep for seconds specified by "second".  Unlike pool_pause(), this
+ * function guarantees that it will sleep for specified seconds.  This
+ * function uses pool_pause() internally. If it informs that there is
+ * a pending signal event, they are processed using CHECK_REQUEST
+ * macro. Note that most of these processes are done while all signals
+ * are blocked.
+ */
+void pool_sleep(unsigned int second)
+{
+	struct timeval current_time, sleep_time;
+
+	gettimeofday(&current_time, NULL);
+	sleep_time.tv_sec = second + current_time.tv_sec;
+	sleep_time.tv_usec = current_time.tv_usec;
+
+	POOL_SETMASK(&UnBlockSig);
+	while (sleep_time.tv_sec > current_time.tv_sec)
+	{
+		struct timeval timeout;
+		int r;
+
+		timeout.tv_sec = sleep_time.tv_sec - current_time.tv_sec;
+		timeout.tv_usec = sleep_time.tv_usec - current_time.tv_usec;
+		if (timeout.tv_usec < 0)
+		{
+			timeout.tv_sec--;
+			timeout.tv_usec += 1000000;
+		}
+
+		r = pool_pause(&timeout);
+		POOL_SETMASK(&BlockSig);
+		if (r > 0)
+			CHECK_REQUEST;
+		POOL_SETMASK(&UnBlockSig);
+		gettimeofday(&current_time, NULL);
+	}
+	POOL_SETMASK(&BlockSig);
+}
+
+/*
+ * trigger_failover_command: execute specified command at failover.
+ *                           command_line is null-terminated string.
+ */
+static int trigger_failover_command(int node, const char *command_line,
+									int old_master, int new_master, int old_primary)
+{
+	int r = 0;
+	String *exec_cmd;
+	char port_buf[6];
+	char buf[2];
+	BackendInfo *info;
+	BackendInfo *newmaster;
+	if (command_line == NULL || (strlen(command_line) == 0))
+		return 0;
+
+	/* check failed nodeID */
+	if (node < 0 || node > NUM_BACKENDS)
+		return -1;
+
+	info = pool_get_node_info(node);
+	if (!info)
+		return -1;
+
+	buf[1] = '\0';
+	exec_cmd = init_string("");
+
+	while (*command_line)
+	{
+		if (*command_line == '%')
+		{
+			if (*(command_line + 1))
+			{
+				char val = *(command_line + 1);
+				switch (val)
+				{
+					case 'p': /* failed node port */
+						snprintf(port_buf, sizeof(port_buf), "%d", info->backend_port);
+						string_append_char(exec_cmd, port_buf);
+						break;
+
+					case 'D': /* failed node database directory */
+						string_append_char(exec_cmd, info->backend_data_directory);
+						break;
+
+					case 'd': /* failed node id */
+						snprintf(port_buf, sizeof(port_buf), "%d", node);
+						string_append_char(exec_cmd, port_buf);
+						break;
+
+					case 'h': /* failed host name */
+						string_append_char(exec_cmd, info->backend_hostname);
+						break;
+
+					case 'H': /* new master host name */
+						newmaster = pool_get_node_info(new_master);
+						if (newmaster)
+							string_append_char(exec_cmd, newmaster->backend_hostname);
+						else
+							/* no valid new master */
+							string_append_char(exec_cmd, "");
+						break;
+
+					case 'm': /* new master node id */
+						snprintf(port_buf, sizeof(port_buf), "%d", new_master);
+						string_append_char(exec_cmd, port_buf);
+						break;
+
+					case 'r': /* new master port */
+						newmaster = pool_get_node_info(get_next_master_node());
+						if (newmaster)
+						{
+							snprintf(port_buf, sizeof(port_buf), "%d", newmaster->backend_port);
+							string_append_char(exec_cmd, port_buf);
+						}
+						else
+							/* no valid new master */
+							string_append_char(exec_cmd, "");
+						break;
+
+					case 'R': /* new master database directory */
+						newmaster = pool_get_node_info(get_next_master_node());
+						if (newmaster)
+							string_append_char(exec_cmd, newmaster->backend_data_directory);
+						else
+							/* no valid new master */
+							string_append_char(exec_cmd, "");
+						break;
+
+					case 'M': /* old master node id */
+						snprintf(port_buf, sizeof(port_buf), "%d", old_master);
+						string_append_char(exec_cmd, port_buf);
+						break;
+
+					case 'P': /* old primary node id */
+						snprintf(port_buf, sizeof(port_buf), "%d", old_primary);
+						string_append_char(exec_cmd, port_buf);
+						break;
+
+					case '%': /* escape */
+						string_append_char(exec_cmd, "%");
+						break;
+
+					default: /* ignore */
+						break;
+				}
+				command_line++;
+			}
+		} else {
+			buf[0] = *command_line;
+			string_append_char(exec_cmd, buf);
+		}
+		command_line++;
+	}
+
+	if (strlen(exec_cmd->data) != 0)
+	{
+		pool_log("execute command: %s", exec_cmd->data);
+		r = system(exec_cmd->data);
+	}
+
+	return r;
+}
+
+/*
+ * Find the primary node (i.e. not standby node) and returns its node
+ * id. If no primary node is found, returns -1.
+ */
+static int find_primary_node(void)
+{
+	BackendInfo *bkinfo;
+	POOL_CONNECTION_POOL_SLOT *s;
+	POOL_CONNECTION *con;
+	POOL_STATUS status;
+	POOL_SELECT_RESULT *res;
+	bool is_standby;
+	int i;
+
+	/* Streaming replication mode? */
+	if (pool_config->master_slave_mode == 0 ||
+		strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
+	{
+		/* No point to look for primary node if not in streaming
+		 * replication mode.
+		 */
+		pool_debug("find_primary_node: not in streaming replication mode");
+		return -1;
+	}
+
+	for(i=0;i<NUM_BACKENDS;i++)
+	{
+		if (!VALID_BACKEND(i))
+			continue;
+
+		/*
+		 * Check to see if this is a standby node or not.
+		 */
+		is_standby = false;
+        PG_TRY();
+        {
+
+        	bkinfo = pool_get_node_info(i);
+			s = make_persistent_db_connection(bkinfo->backend_hostname,
+										  bkinfo->backend_port,
+										  "postgres",
+										  pool_config->sr_check_user,
+										  pool_config->sr_check_password, true);
+			if (!s)
+			{
+				pool_error("find_primary_node: make_persistent_connection failed");
+				return -1;
+			}
+			con = s->con;
+			status = do_query(con, "SELECT pg_is_in_recovery()",
+						  &res, PROTO_MAJOR_V3);
+			if (res->numrows <= 0)
+			{
+				pool_log("find_primary_node: do_query returns no rows");
+			}
+			if (res->data[0] == NULL)
+			{
+				pool_log("find_primary_node: do_query returns no data");
+			}
+			if (res->nullflags[0] == -1)
+			{
+				pool_log("find_primary_node: do_query returns NULL");
+			}
+			if (res->data[0] && !strcmp(res->data[0], "t"))
+			{
+				is_standby = true;
+			}
+			free_select_result(res);
+			discard_persistent_db_connection(s);
+        }
+        PG_CATCH();
+        {
+        	ErrorData  *edata;
+        	edata = CopyErrorData();
+        	FlushErrorState();
+        	printf("%s",edata->message);
+        	return -1;
+        }
+        PG_END_TRY();
+
+		/*
+		 * If this is a standby, we continue to look for primary node.
+		 */
+		if (is_standby)
+		{
+			pool_debug("find_primary_node: %d node is standby", i);
+		}
+		else
+		{
+			break;
+		}
+	}
+
+	if (i == NUM_BACKENDS)
+	{
+		pool_debug("find_primary_node: no primary node found");
+		return -1;
+	}
+
+	pool_log("find_primary_node: primary node id is %d", i);
+	return i;
+}
+
+static int find_primary_node_repeatedly(void)
+{
+	int sec;
+	int node_id = -1;
+
+	/* Streaming replication mode? */
+	if (pool_config->master_slave_mode == 0 ||
+		strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
+	{
+		/* No point to look for primary node if not in streaming
+		 * replication mode.
+		 */
+		ereport(DEBUG1, 
+			(errmsg("find_primary_node: not in streaming replication mode")));
+		return -1;
+	}
+
+	/*
+	 * Try to find the new primary node and keep trying for
+	 * search_primary_node_timeout seconds.
+	 * search_primary_node_timeout = 0 means never timeout and keep searching
+	 * indefinitely
+	 */
+	ereport(LOG,
+		(errmsg("find_primary_node_repeatedly: waiting for finding a primary node")));
+	for (sec = 0; (pool_config->search_primary_node_timeout == 0 ||
+				sec < pool_config->search_primary_node_timeout); sec++)
+	{
+		node_id = find_primary_node();
+		if (node_id != -1)
+			break;
+		pool_sleep(1);
+	}
+	return node_id;
+}
+
+/*
+* fork a follow child
+*/
+pid_t fork_follow_child(int old_master, int new_primary, int old_primary)
+{
+	pid_t pid;
+	int i;
+
+	pid = fork();
+
+	if (pid == 0)
+	{
+		on_exit_reset();
+		ereport(LOG,
+			(errmsg("start triggering follow command.")));
+		for (i = 0; i < pool_config->backend_desc->num_backends; i++)
+		{
+			BackendInfo *bkinfo;
+			bkinfo = pool_get_node_info(i);
+			if (bkinfo->backend_status == CON_DOWN)
+				trigger_failover_command(i, pool_config->follow_master_command,
+										 old_master, new_primary, old_primary);
+		}
+		exit(0);
+	}
+	else if (pid == -1)
+	{
+		pool_error("follow fork() failed. reason: %s", strerror(errno));
+		exit(1);
+	}
+	return pid;
+}
+
+
+static void initialize_shared_mem_objects()
+{
+	int size,i;
+	/*
+	 * con_info is a 3 dimension array: i corresponds to pgpool child
+	 * process, j corresponds to connection pool in each process and k
+	 * corresponds to backends in each connection pool.
+	 *
+	 * XXX: Before 2010/4/12 this was a 2 dimension array: i
+	 * corresponds to pgpool child process, j corresponds to
+	 * connection pool in each process. Of course this was wrong.
+	 */
+	size = pool_coninfo_size();
+	con_info = pool_shared_memory_create(size);
+	memset(con_info, 0, size);
+
+	size = pool_config->num_init_children * (sizeof(ProcessInfo));
+	process_info = pool_shared_memory_create(size);
+	memset(process_info, 0, size);
+
+	for (i = 0; i < pool_config->num_init_children; i++)
+	{
+		process_info[i].connection_info = pool_coninfo(i,0,0);
+	}
+
+	/* create fail over/switch over event area */
+	Req_info = pool_shared_memory_create(sizeof(POOL_REQUEST_INFO));
+
+	/*
+	 * Initialize backend status area.
+	 * From now on, VALID_BACKEND macro can be used.
+	 * (get_next_master_node() uses VALID_BACKEND)
+	 */
+
+	for (i=0;i<MAX_NUM_BACKENDS;i++)
+	{
+		my_backend_status[i] = &(BACKEND_INFO(i).backend_status);
+	}
+
+	/* initialize Req_info */
+	Req_info->kind = NODE_UP_REQUEST;
+	memset(Req_info->node_id, -1, sizeof(int) * MAX_NUM_BACKENDS);
+	Req_info->master_node_id = get_next_master_node();
+	Req_info->conn_counter = 0;
+	Req_info->switching = false;
+
+	InRecovery = pool_shared_memory_create(sizeof(int));
+	*InRecovery = RECOVERY_INIT;
+
+	/*
+	 * Initialize shared memory cache
+	 */
+	if (pool_config->memory_cache_enabled)
+	{
+		if (pool_is_shmem_cache())
+		{
+			size_t size;
+
+			size = pool_shared_memory_cache_size();
+			pool_init_memory_cache(size);
+
+			size = pool_shared_memory_fsmm_size();
+			if (size == 0)
+				ereport(FATAL,
+					(errmsg("invalid shared memory size"),
+						errdetail("pool_shared_memory_fsmm_size error")));
+	
+			pool_init_fsmm(size);
+
+			pool_allocate_fsmm_clock_hand();
+
+			pool_discard_oid_maps();
+
+			ereport(LOG,
+				(errmsg("pool_discard_oid_maps: discarded memqcache oid maps")));
+
+			pool_hash_init(pool_config->memqcache_max_num_cache);
+		}
+
+#ifdef USE_MEMCACHED
+		else
+		{
+			if (clear_memcache_oidmaps)
+			{
+				pool_discard_oid_maps();
+				ereport(LOG,
+					(errmsg("discarded memqcache oid maps")));
+			}
+			else
+			{
+				ereport(DEBUG1,
+					(errmsg("skipped discarding memqcache oid maps")));
+			}
+		}
+#endif
+
+		pool_init_memqcache_stats();
+	}
+}
+
+/*
+* Read the status file
+*/
+static int read_status_file(bool discard_status)
+{
+	FILE *fd;
+	char fnamebuf[POOLMAXPATHLEN];
+	int i;
+	bool someone_wakeup = false;
+
+	snprintf(fnamebuf, sizeof(fnamebuf), "%s/%s", pool_config->logdir, STATUS_FILE_NAME);
+	fd = fopen(fnamebuf, "r");
+	if (!fd)
+	{
+		pool_log("Backend status file %s does not exist", fnamebuf);
+		return -1;
+	}
+
+	/*
+	 * If discard_status is true, unlink pgpool_status and
+	 * do not restore previous status.
+	 */
+	if (discard_status)
+	{
+		fclose(fd);
+		if (unlink(fnamebuf) == 0)
+		{
+			pool_log("Backend status file %s discarded", fnamebuf);
+		}
+		else
+		{
+			pool_error("Failed to discard backend status file %s reason:%s", fnamebuf, strerror(errno));
+		}
+		return 0;
+	}
+
+	if (fread(&backend_rec, 1, sizeof(backend_rec), fd) != sizeof(backend_rec))
+	{
+		pool_error("Could not read backend status file as %s. reason: %s",
+				   fnamebuf, strerror(errno));
+		fclose(fd);
+		return -1;
+	}
+	fclose(fd);
+
+	for (i=0;i< pool_config->backend_desc->num_backends;i++)
+	{
+		if (backend_rec.status[i] == CON_DOWN)
+		{
+			BACKEND_INFO(i).backend_status = CON_DOWN;
+			pool_log("read_status_file: %d th backend is set to down status", i);
+		}
+		else
+		{
+			BACKEND_INFO(i).backend_status = CON_CONNECT_WAIT;
+			someone_wakeup = true;
+		}
+	}
+
+	/*
+	 * If no one woke up, we regard the status file bogus
+	 */
+	if (someone_wakeup == false)
+	{
+		for (i=0;i< pool_config->backend_desc->num_backends;i++)
+		{
+			BACKEND_INFO(i).backend_status = CON_CONNECT_WAIT;
+		}
+	}
+
+	return 0;
+}
+
+/*
+* Write the pid file
+*/
+static int write_status_file(void)
+{
+	FILE *fd;
+	char fnamebuf[POOLMAXPATHLEN];
+	int i;
+
+	snprintf(fnamebuf, sizeof(fnamebuf), "%s/%s", pool_config->logdir, STATUS_FILE_NAME);
+	fd = fopen(fnamebuf, "w");
+	if (!fd)
+	{
+		pool_error("Could not open status file %s", fnamebuf);
+		return -1;
+	}
+
+	memset(&backend_rec, 0, sizeof(backend_rec));
+
+	for (i=0;i< pool_config->backend_desc->num_backends;i++)
+	{
+		backend_rec.status[i] = BACKEND_INFO(i).backend_status;
+	}
+
+	if (fwrite(&backend_rec, 1, sizeof(backend_rec), fd) != sizeof(backend_rec))
+	{
+		pool_error("Could not write backend status file as %s. reason: %s",
+				   fnamebuf, strerror(errno));
+		fclose(fd);
+		return -1;
+	}
+	fclose(fd);
+	return 0;
+}
+
+
+static void reload_config(void)
+{
+	pool_log("reload config files.");
+	pool_get_config(conf_file, RELOAD_CONFIG);
+	if (pool_config->enable_pool_hba)
+		load_hba(hba_file);
+	if (pool_config->parallel_mode)
+		pool_memset_system_db_info(system_db_info->info);
+	kill_all_children(SIGHUP);
+
+	if (worker_pid)
+		kill(worker_pid, SIGHUP);
+}
+
+#ifdef NOT_USED
+/*
+ * This is the function called by elog.c in case of
+ * Fatal error
+ */
+void
+proc_exit(int code)
+{
+	if(processType == PT_CHILD)
+		child_exit(code);
+	else if(processType == PT_MAIN)
+		myexit(code);
+	exit(code);
+}
+#endif //NOT_USED
+
+/* Call back function to unlink the file */
+static void FileUnlink(int code, Datum path)
+{
+	char* filePath = (char*)path; 
+	if (unlink(filePath) == 0) return;
+	/* 
+	 * We are already exiting the system just produce a log entry to report an error
+	 */
+	ereport(LOG,
+		(errmsg("unlink failed for file at path \"%s\"", filePath),
+		errdetail("%s", strerror(errno))));
+}
diff --git a/src/main/pool_globals.c b/src/main/pool_globals.c
index 7da658e..208e0e0 100644
--- a/src/main/pool_globals.c
+++ b/src/main/pool_globals.c
@@ -25,3 +25,5 @@
 int debug = 0;	/* non 0 if debug option is given (-d). pcp only */
 pid_t mypid;	/* pgpool parent process id */
 bool run_as_pcp_child;
+ProcessType processType;
+ProcessState processState;
diff --git a/src/parallel_query/pool_rewrite_outfuncs.c b/src/parallel_query/pool_rewrite_outfuncs.c
index e865f48..be0b4c6 100644
--- a/src/parallel_query/pool_rewrite_outfuncs.c
+++ b/src/parallel_query/pool_rewrite_outfuncs.c
@@ -48,6 +48,7 @@
 #include <limits.h>
 
 #include "pool.h"
+#include "utils/palloc.h"
 #include "parser/parser.h"
 #include "parser/pool_string.h"
 #include "parser/pg_list.h"
diff --git a/src/parser/Makefile.am b/src/parser/Makefile.am
index a543e65..83a88e6 100644
--- a/src/parser/Makefile.am
+++ b/src/parser/Makefile.am
@@ -12,12 +12,14 @@ libsql_parser_a_SOURCES  = \
 	nodes.c \
 	outfuncs.c \
 	parser.c \
-	pool_memory.c \
 	pool_string.c \
 	scansup.c \
 	snprintf.c \
 	stringinfo.c \
 	value.c \
+	$(top_srcdir)/src/utils/mmgr/mcxt.c \
+	$(top_srcdir)/src/utils/mmgr/aset.c \
+	$(top_srcdir)/src/utils/error/elog.c \
 	wchar.c
 
 EXTRA_DIST = scan.c scan.l
diff --git a/src/parser/Makefile.in b/src/parser/Makefile.in
index 9cb5f71..8c77cce 100644
--- a/src/parser/Makefile.in
+++ b/src/parser/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -58,9 +58,9 @@ libsql_parser_a_LIBADD =
 am_libsql_parser_a_OBJECTS = copyfuncs.$(OBJEXT) gram.$(OBJEXT) \
 	keywords.$(OBJEXT) kwlookup.$(OBJEXT) list.$(OBJEXT) \
 	makefuncs.$(OBJEXT) nodes.$(OBJEXT) outfuncs.$(OBJEXT) \
-	parser.$(OBJEXT) pool_memory.$(OBJEXT) pool_string.$(OBJEXT) \
-	scansup.$(OBJEXT) snprintf.$(OBJEXT) stringinfo.$(OBJEXT) \
-	value.$(OBJEXT) wchar.$(OBJEXT)
+	parser.$(OBJEXT) pool_string.$(OBJEXT) scansup.$(OBJEXT) \
+	snprintf.$(OBJEXT) stringinfo.$(OBJEXT) value.$(OBJEXT) \
+	mcxt.$(OBJEXT) aset.$(OBJEXT) elog.$(OBJEXT) wchar.$(OBJEXT)
 libsql_parser_a_OBJECTS = $(am_libsql_parser_a_OBJECTS)
 DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)/src/include
 depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -75,9 +75,9 @@ CCLD = $(CC)
 LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
 	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
 	$(LDFLAGS) -o $@
-YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
+YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS)
 LTYACCCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-	--mode=compile $(YACC) $(YFLAGS) $(AM_YFLAGS)
+	--mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS)
 YLWRAP = $(top_srcdir)/ylwrap
 SOURCES = $(libsql_parser_a_SOURCES)
 DIST_SOURCES = $(libsql_parser_a_SOURCES)
@@ -222,12 +222,14 @@ libsql_parser_a_SOURCES = \
 	nodes.c \
 	outfuncs.c \
 	parser.c \
-	pool_memory.c \
 	pool_string.c \
 	scansup.c \
 	snprintf.c \
 	stringinfo.c \
 	value.c \
+	$(top_srcdir)/src/utils/mmgr/mcxt.c \
+	$(top_srcdir)/src/utils/mmgr/aset.c \
+	$(top_srcdir)/src/utils/error/elog.c \
 	wchar.c
 
 EXTRA_DIST = scan.c scan.l
@@ -270,11 +272,9 @@ $(am__aclocal_m4_deps):
 clean-noinstLIBRARIES:
 	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
 gram.h: gram.c
-	@if test ! -f $@; then \
-	  rm -f gram.c; \
-	  $(MAKE) $(AM_MAKEFLAGS) gram.c; \
-	else :; fi
-libsql-parser.a: $(libsql_parser_a_OBJECTS) $(libsql_parser_a_DEPENDENCIES) 
+	@if test ! -f $@; then rm -f gram.c; else :; fi
+	@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) gram.c; else :; fi
+libsql-parser.a: $(libsql_parser_a_OBJECTS) $(libsql_parser_a_DEPENDENCIES) $(EXTRA_libsql_parser_a_DEPENDENCIES) 
 	-rm -f libsql-parser.a
 	$(libsql_parser_a_AR) libsql-parser.a $(libsql_parser_a_OBJECTS) $(libsql_parser_a_LIBADD)
 	$(RANLIB) libsql-parser.a
@@ -285,16 +285,18 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/aset.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/copyfuncs.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/elog.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gram.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/keywords.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/kwlookup.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/list.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/makefuncs.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mcxt.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/nodes.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/outfuncs.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/parser.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pool_memory.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pool_string.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/scansup.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/snprintf.Po at am__quote@
@@ -323,6 +325,48 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
 
+mcxt.o: $(top_srcdir)/src/utils/mmgr/mcxt.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mcxt.o -MD -MP -MF $(DEPDIR)/mcxt.Tpo -c -o mcxt.o `test -f '$(top_srcdir)/src/utils/mmgr/mcxt.c' || echo '$(srcdir)/'`$(top_srcdir)/src/utils/mmgr/mcxt.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/mcxt.Tpo $(DEPDIR)/mcxt.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/src/utils/mmgr/mcxt.c' object='mcxt.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mcxt.o `test -f '$(top_srcdir)/src/utils/mmgr/mcxt.c' || echo '$(srcdir)/'`$(top_srcdir)/src/utils/mmgr/mcxt.c
+
+mcxt.obj: $(top_srcdir)/src/utils/mmgr/mcxt.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mcxt.obj -MD -MP -MF $(DEPDIR)/mcxt.Tpo -c -o mcxt.obj `if test -f '$(top_srcdir)/src/utils/mmgr/mcxt.c'; then $(CYGPATH_W) '$(top_srcdir)/src/utils/mmgr/mcxt.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/utils/mmgr/mcxt.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/mcxt.Tpo $(DEPDIR)/mcxt.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/src/utils/mmgr/mcxt.c' object='mcxt.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mcxt.obj `if test -f '$(top_srcdir)/src/utils/mmgr/mcxt.c'; then $(CYGPATH_W) '$(top_srcdir)/src/utils/mmgr/mcxt.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/utils/mmgr/mcxt.c'; fi`
+
+aset.o: $(top_srcdir)/src/utils/mmgr/aset.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT aset.o -MD -MP -MF $(DEPDIR)/aset.Tpo -c -o aset.o `test -f '$(top_srcdir)/src/utils/mmgr/aset.c' || echo '$(srcdir)/'`$(top_srcdir)/src/utils/mmgr/aset.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/aset.Tpo $(DEPDIR)/aset.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/src/utils/mmgr/aset.c' object='aset.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o aset.o `test -f '$(top_srcdir)/src/utils/mmgr/aset.c' || echo '$(srcdir)/'`$(top_srcdir)/src/utils/mmgr/aset.c
+
+aset.obj: $(top_srcdir)/src/utils/mmgr/aset.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT aset.obj -MD -MP -MF $(DEPDIR)/aset.Tpo -c -o aset.obj `if test -f '$(top_srcdir)/src/utils/mmgr/aset.c'; then $(CYGPATH_W) '$(top_srcdir)/src/utils/mmgr/aset.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/utils/mmgr/aset.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/aset.Tpo $(DEPDIR)/aset.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/src/utils/mmgr/aset.c' object='aset.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o aset.obj `if test -f '$(top_srcdir)/src/utils/mmgr/aset.c'; then $(CYGPATH_W) '$(top_srcdir)/src/utils/mmgr/aset.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/utils/mmgr/aset.c'; fi`
+
+elog.o: $(top_srcdir)/src/utils/error/elog.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT elog.o -MD -MP -MF $(DEPDIR)/elog.Tpo -c -o elog.o `test -f '$(top_srcdir)/src/utils/error/elog.c' || echo '$(srcdir)/'`$(top_srcdir)/src/utils/error/elog.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/elog.Tpo $(DEPDIR)/elog.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/src/utils/error/elog.c' object='elog.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o elog.o `test -f '$(top_srcdir)/src/utils/error/elog.c' || echo '$(srcdir)/'`$(top_srcdir)/src/utils/error/elog.c
+
+elog.obj: $(top_srcdir)/src/utils/error/elog.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT elog.obj -MD -MP -MF $(DEPDIR)/elog.Tpo -c -o elog.obj `if test -f '$(top_srcdir)/src/utils/error/elog.c'; then $(CYGPATH_W) '$(top_srcdir)/src/utils/error/elog.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/utils/error/elog.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/elog.Tpo $(DEPDIR)/elog.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/src/utils/error/elog.c' object='elog.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o elog.obj `if test -f '$(top_srcdir)/src/utils/error/elog.c'; then $(CYGPATH_W) '$(top_srcdir)/src/utils/error/elog.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/utils/error/elog.c'; fi`
+
 .y.c:
 	$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE)
 
@@ -428,10 +472,15 @@ install-am: all-am
 
 installcheck: installcheck-am
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
diff --git a/src/parser/copyfuncs.c b/src/parser/copyfuncs.c
index 731ff71..c3b50d5 100644
--- a/src/parser/copyfuncs.c
+++ b/src/parser/copyfuncs.c
@@ -25,7 +25,7 @@
 
 #include <string.h>
 #include <stddef.h>
-#include "pool_memory.h"
+#include "utils/palloc.h"
 #include "parsenodes.h"
 
 
diff --git a/src/parser/gram.c b/src/parser/gram.c
index ebf2715..8808ab4 100644
--- a/src/parser/gram.c
+++ b/src/parser/gram.c
@@ -1,21 +1,24 @@
-/* A Bison parser, made by GNU Bison 2.5.  */
+/* A Bison parser, made by GNU Bison 2.3.  */
 
-/* Bison implementation for Yacc-like parsers in C
-   
-      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-   
-   This program is free software: you can redistribute it and/or modify
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-   
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 /* As a special exception, you may create a larger work that contains
    part or all of the Bison parser skeleton and distribute that work
@@ -26,7 +29,7 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-   
+
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
@@ -44,7 +47,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.5"
+#define YYBISON_VERSION "2.3"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -52,211 +55,18 @@
 /* Pure parsers.  */
 #define YYPURE 1
 
-/* Push parsers.  */
-#define YYPUSH 0
-
-/* Pull parsers.  */
-#define YYPULL 1
-
 /* Using locations.  */
 #define YYLSP_NEEDED 1
 
 /* Substitute the variable and function names.  */
-#define yyparse         base_yyparse
-#define yylex           base_yylex
-#define yyerror         base_yyerror
-#define yylval          base_yylval
-#define yychar          base_yychar
-#define yydebug         base_yydebug
-#define yynerrs         base_yynerrs
-#define yylloc          base_yylloc
-
-/* Copy the first part of user declarations.  */
-
-/* Line 268 of yacc.c  */
-#line 1 "gram.y"
-
-
-/*#define YYDEBUG 1*/
-/*-------------------------------------------------------------------------
- *
- * gram.y
- *	  POSTGRESQL BISON rules/actions
- *
- * Portions Copyright (c) 2003-2013, PgPool Global Development Group
- * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- *	  src/backend/parser/gram.y
- *
- * HISTORY
- *	  AUTHOR			DATE			MAJOR EVENT
- *	  Andrew Yu			Sept, 1994		POSTQUEL to SQL conversion
- *	  Andrew Yu			Oct, 1994		lispy code conversion
- *
- * NOTES
- *	  CAPITALS are used to represent terminal symbols.
- *	  non-capitals are used to represent non-terminals.
- *	  SQL92-specific syntax is separated from plain SQL/Postgres syntax
- *	  to help isolate the non-extensible portions of the parser.
- *
- *	  In general, nothing in this file should initiate database accesses
- *	  nor depend on changeable state (such as SET variables).  If you do
- *	  database accesses, your code will fail when we have aborted the
- *	  current transaction and are just parsing commands to find the next
- *	  ROLLBACK or COMMIT.  If you make use of SET variables, then you
- *	  will do the wrong thing in multi-query strings like this:
- *			SET SQL_inheritance TO off; SELECT * FROM foo;
- *	  because the entire string is parsed by gram.y before the SET gets
- *	  executed.  Anything that depends on the database or changeable state
- *	  should be handled during parse analysis so that it happens at the
- *	  right time not the wrong time.  The handling of SQL_inheritance is
- *	  a good example.
- *
- * WARNINGS
- *	  If you use a list, make sure the datum is a node so that the printing
- *	  routines work.
- *
- *	  Sometimes we assign constants to makeStrings. Make sure we don't free
- *	  those.
- *
- *-------------------------------------------------------------------------
- */
-#include "pool_parser.h"
-
-#include <ctype.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "nodes.h"
-#include "keywords.h"
-#include "pool_memory.h"
-#include "gramparse.h"
-#include "makefuncs.h"
-#include "pool_string.h"
-#include "parser.h"
-#include "pg_class.h"
-#include "pg_trigger.h"
-
-
-/* for XML data type */
-typedef enum
-{
-        XML_STANDALONE_YES,
-        XML_STANDALONE_NO,
-        XML_STANDALONE_NO_VALUE,
-        XML_STANDALONE_OMITTED
-} XmlStandaloneType;
-
-static DefElem *defWithOids(bool value);
-
-/* Location tracking support --- simpler than bison's default */
-#define YYLLOC_DEFAULT(Current, Rhs, N) \
-	do { \
-		if (N) \
-			(Current) = (Rhs)[1]; \
-		else \
-			(Current) = (Rhs)[0]; \
-	} while (0)
-
-/*
- * Bison doesn't allocate anything that needs to live across parser calls,
- * so we can easily have it use palloc instead of malloc.  This prevents
- * memory leaks if we error out during parsing.  Note this only works with
- * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
- * if possible, so there's not really much problem anyhow, at least if
- * you're building with gcc.
- */
-#define YYMALLOC palloc
-#define YYFREE   pfree
-
-/* Private struct for the result of privilege_target production */
-typedef struct PrivTarget
-{
-	GrantTargetType targtype;
-	GrantObjectType objtype;
-	List	   *objs;
-} PrivTarget;
-
-/* ConstraintAttributeSpec yields an integer bitmask of these flags: */
-#define CAS_NOT_DEFERRABLE			0x01
-#define CAS_DEFERRABLE				0x02
-#define CAS_INITIALLY_IMMEDIATE		0x04
-#define CAS_INITIALLY_DEFERRED		0x08
-#define CAS_NOT_VALID				0x10
-#define CAS_NO_INHERIT				0x20
-
-
-#define parser_yyerror(msg)  scanner_yyerror(msg, yyscanner)
-#define parser_errposition(pos)  scanner_errposition(pos, yyscanner)
-
-static void base_yyerror(YYLTYPE *yylloc, core_yyscan_t yyscanner,
-						 const char *msg);
-static Node *makeColumnRef(char *colname, List *indirection,
-						   int location, core_yyscan_t yyscanner);
-static Node *makeTypeCast(Node *arg, TypeName *typename, int location);
-static Node *makeStringConst(char *str, int location);
-static Node *makeStringConstCast(char *str, int location, TypeName *typename);
-static Node *makeIntConst(int val, int location);
-static Node *makeFloatConst(char *str, int location);
-static Node *makeBitStringConst(char *str, int location);
-static Node *makeNullAConst(int location);
-static Node *makeAConst(Value *v, int location);
-static Node *makeBoolAConst(bool state, int location);
-static FuncCall *makeOverlaps(List *largs, List *rargs,
-							  int location, core_yyscan_t yyscanner);
-static void check_qualified_name(List *names, core_yyscan_t yyscanner);
-static List *check_func_name(List *names, core_yyscan_t yyscanner);
-static List *check_indirection(List *indirection, core_yyscan_t yyscanner);
-static List *extractArgTypes(List *parameters);
-static void insertSelectOptions(SelectStmt *stmt,
-								List *sortClause, List *lockingClause,
-								Node *limitOffset, Node *limitCount,
-								WithClause *withClause,
-								core_yyscan_t yyscanner);
-static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg);
-static Node *doNegate(Node *n, int location);
-static void doNegateFloat(Value *v);
-static Node *makeAArrayExpr(List *elements, int location);
-static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args,
-						 List *args, int location);
-static List *mergeTableFuncParameters(List *func_args, List *columns);
-static TypeName *TableFuncTypeName(List *columns);
-static RangeVar *makeRangeVarFromAnyName(List *names, int position, core_yyscan_t yyscanner);
-static void SplitColQualList(List *qualList,
-							 List **constraintList, CollateClause **collClause,
-							 core_yyscan_t yyscanner);
-static void processCASbits(int cas_bits, int location, const char *constrType,
-			   bool *deferrable, bool *initdeferred, bool *not_valid,
-			   bool *no_inherit, core_yyscan_t yyscanner);
-
-
-
-/* Line 268 of yacc.c  */
-#line 241 "gram.c"
-
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages.  */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
+#define yyparse base_yyparse
+#define yylex   base_yylex
+#define yyerror base_yyerror
+#define yylval  base_yylval
+#define yychar  base_yychar
+#define yydebug base_yydebug
+#define yynerrs base_yynerrs
+#define yylloc base_yylloc
 
 /* Tokens.  */
 #ifndef YYTOKENTYPE
@@ -1095,13 +905,192 @@ static void processCASbits(int cas_bits, int location, const char *constrType,
 
 
 
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
+/* Copy the first part of user declarations.  */
+#line 1 "gram.y"
+
+
+/*#define YYDEBUG 1*/
+/*-------------------------------------------------------------------------
+ *
+ * gram.y
+ *	  POSTGRESQL BISON rules/actions
+ *
+ * Portions Copyright (c) 2003-2013, PgPool Global Development Group
+ * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *	  src/backend/parser/gram.y
+ *
+ * HISTORY
+ *	  AUTHOR			DATE			MAJOR EVENT
+ *	  Andrew Yu			Sept, 1994		POSTQUEL to SQL conversion
+ *	  Andrew Yu			Oct, 1994		lispy code conversion
+ *
+ * NOTES
+ *	  CAPITALS are used to represent terminal symbols.
+ *	  non-capitals are used to represent non-terminals.
+ *	  SQL92-specific syntax is separated from plain SQL/Postgres syntax
+ *	  to help isolate the non-extensible portions of the parser.
+ *
+ *	  In general, nothing in this file should initiate database accesses
+ *	  nor depend on changeable state (such as SET variables).  If you do
+ *	  database accesses, your code will fail when we have aborted the
+ *	  current transaction and are just parsing commands to find the next
+ *	  ROLLBACK or COMMIT.  If you make use of SET variables, then you
+ *	  will do the wrong thing in multi-query strings like this:
+ *			SET SQL_inheritance TO off; SELECT * FROM foo;
+ *	  because the entire string is parsed by gram.y before the SET gets
+ *	  executed.  Anything that depends on the database or changeable state
+ *	  should be handled during parse analysis so that it happens at the
+ *	  right time not the wrong time.  The handling of SQL_inheritance is
+ *	  a good example.
+ *
+ * WARNINGS
+ *	  If you use a list, make sure the datum is a node so that the printing
+ *	  routines work.
+ *
+ *	  Sometimes we assign constants to makeStrings. Make sure we don't free
+ *	  those.
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "pool_parser.h"
+#include "utils/elog.h"
+#include "utils/palloc.h"
+#include <ctype.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "nodes.h"
+#include "keywords.h"
+//#include "pool_memory.h"
+#include "gramparse.h"
+#include "makefuncs.h"
+#include "pool_string.h"
+#include "parser.h"
+#include "pg_class.h"
+#include "pg_trigger.h"
+
+
+/* for XML data type */
+typedef enum
 {
+        XML_STANDALONE_YES,
+        XML_STANDALONE_NO,
+        XML_STANDALONE_NO_VALUE,
+        XML_STANDALONE_OMITTED
+} XmlStandaloneType;
 
-/* Line 293 of yacc.c  */
-#line 171 "gram.y"
+static DefElem *defWithOids(bool value);
 
+/* Location tracking support --- simpler than bison's default */
+#define YYLLOC_DEFAULT(Current, Rhs, N) \
+	do { \
+		if (N) \
+			(Current) = (Rhs)[1]; \
+		else \
+			(Current) = (Rhs)[0]; \
+	} while (0)
+
+/*
+ * Bison doesn't allocate anything that needs to live across parser calls,
+ * so we can easily have it use palloc instead of malloc.  This prevents
+ * memory leaks if we error out during parsing.  Note this only works with
+ * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
+ * if possible, so there's not really much problem anyhow, at least if
+ * you're building with gcc.
+ */
+#define YYMALLOC palloc
+#define YYFREE   pfree
+
+/* Private struct for the result of privilege_target production */
+typedef struct PrivTarget
+{
+	GrantTargetType targtype;
+	GrantObjectType objtype;
+	List	   *objs;
+} PrivTarget;
+
+/* ConstraintAttributeSpec yields an integer bitmask of these flags: */
+#define CAS_NOT_DEFERRABLE			0x01
+#define CAS_DEFERRABLE				0x02
+#define CAS_INITIALLY_IMMEDIATE		0x04
+#define CAS_INITIALLY_DEFERRED		0x08
+#define CAS_NOT_VALID				0x10
+#define CAS_NO_INHERIT				0x20
+
+
+#define parser_yyerror(msg)  scanner_yyerror(msg, yyscanner)
+#define parser_errposition(pos)  scanner_errposition(pos, yyscanner)
+
+static void base_yyerror(YYLTYPE *yylloc, core_yyscan_t yyscanner,
+						 const char *msg);
+static Node *makeColumnRef(char *colname, List *indirection,
+						   int location, core_yyscan_t yyscanner);
+static Node *makeTypeCast(Node *arg, TypeName *typename, int location);
+static Node *makeStringConst(char *str, int location);
+static Node *makeStringConstCast(char *str, int location, TypeName *typename);
+static Node *makeIntConst(int val, int location);
+static Node *makeFloatConst(char *str, int location);
+static Node *makeBitStringConst(char *str, int location);
+static Node *makeNullAConst(int location);
+static Node *makeAConst(Value *v, int location);
+static Node *makeBoolAConst(bool state, int location);
+static FuncCall *makeOverlaps(List *largs, List *rargs,
+							  int location, core_yyscan_t yyscanner);
+static void check_qualified_name(List *names, core_yyscan_t yyscanner);
+static List *check_func_name(List *names, core_yyscan_t yyscanner);
+static List *check_indirection(List *indirection, core_yyscan_t yyscanner);
+static List *extractArgTypes(List *parameters);
+static void insertSelectOptions(SelectStmt *stmt,
+								List *sortClause, List *lockingClause,
+								Node *limitOffset, Node *limitCount,
+								WithClause *withClause,
+								core_yyscan_t yyscanner);
+static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg);
+static Node *doNegate(Node *n, int location);
+static void doNegateFloat(Value *v);
+static Node *makeAArrayExpr(List *elements, int location);
+static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args,
+						 List *args, int location);
+static List *mergeTableFuncParameters(List *func_args, List *columns);
+static TypeName *TableFuncTypeName(List *columns);
+static RangeVar *makeRangeVarFromAnyName(List *names, int position, core_yyscan_t yyscanner);
+static void SplitColQualList(List *qualList,
+							 List **constraintList, CollateClause **collClause,
+							 core_yyscan_t yyscanner);
+static void processCASbits(int cas_bits, int location, const char *constrType,
+			   bool *deferrable, bool *initdeferred, bool *not_valid,
+			   bool *no_inherit, core_yyscan_t yyscanner);
+
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 172 "gram.y"
+{
 	core_YYSTYPE		core_yystype;
 	/* these fields must match core_YYSTYPE: */
 	int					ival;
@@ -1136,15 +1125,13 @@ typedef union YYSTYPE
 	AccessPriv			*accesspriv;
 	InsertStmt			*istmt;
 	VariableSetStmt		*vsetstmt;
-
-
-
-/* Line 293 of yacc.c  */
-#line 1144 "gram.c"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+}
+/* Line 193 of yacc.c.  */
+#line 1131 "gram.c"
+	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
@@ -1164,8 +1151,8 @@ typedef struct YYLTYPE
 /* Copy the second part of user declarations.  */
 
 
-/* Line 343 of yacc.c  */
-#line 1169 "gram.c"
+/* Line 216 of yacc.c.  */
+#line 1156 "gram.c"
 
 #ifdef short
 # undef short
@@ -1240,14 +1227,14 @@ typedef short int yytype_int16;
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static int
-YYID (int yyi)
+YYID (int i)
 #else
 static int
-YYID (yyi)
-    int yyi;
+YYID (i)
+    int i;
 #endif
 {
-  return yyi;
+  return i;
 }
 #endif
 
@@ -1268,11 +1255,11 @@ YYID (yyi)
 #    define alloca _alloca
 #   else
 #    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#     ifndef EXIT_SUCCESS
-#      define EXIT_SUCCESS 0
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
 #     endif
 #    endif
 #   endif
@@ -1295,24 +1282,24 @@ YYID (yyi)
 #  ifndef YYSTACK_ALLOC_MAXIMUM
 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
 #  endif
-#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
+#  if (defined __cplusplus && ! defined _STDLIB_H \
        && ! ((defined YYMALLOC || defined malloc) \
 	     && (defined YYFREE || defined free)))
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef EXIT_SUCCESS
-#    define EXIT_SUCCESS 0
+#   ifndef _STDLIB_H
+#    define _STDLIB_H 1
 #   endif
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
 #  ifndef YYFREE
 #   define YYFREE free
-#   if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
@@ -1329,9 +1316,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
 {
-  yytype_int16 yyss_alloc;
-  YYSTYPE yyvs_alloc;
-  YYLTYPE yyls_alloc;
+  yytype_int16 yyss;
+  YYSTYPE yyvs;
+    YYLTYPE yyls;
 };
 
 /* The size of the maximum gap between one aligned stack and the next.  */
@@ -1343,27 +1330,6 @@ union yyalloc
      ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
       + 2 * YYSTACK_GAP_MAXIMUM)
 
-# define YYCOPY_NEEDED 1
-
-/* Relocate STACK from its old location to the new one.  The
-   local variables YYSIZE and YYSTACKSIZE give the old and new number of
-   elements in the stack, and YYPTR gives the new location of the
-   stack.  Advance YYPTR to a properly aligned location for the next
-   stack.  */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack)				\
-    do									\
-      {									\
-	YYSIZE_T yynewbytes;						\
-	YYCOPY (&yyptr->Stack_alloc, Stack, yysize);			\
-	Stack = &yyptr->Stack_alloc;					\
-	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
-	yyptr += yynewbytes / sizeof (*yyptr);				\
-      }									\
-    while (YYID (0))
-
-#endif
-
-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
 /* Copy COUNT objects from FROM to TO.  The source and destination do
    not overlap.  */
 # ifndef YYCOPY
@@ -1381,7 +1347,24 @@ union yyalloc
       while (YYID (0))
 #  endif
 # endif
-#endif /* !YYCOPY_NEEDED */
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)					\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (YYID (0))
+
+#endif
 
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  696
@@ -2507,232 +2490,232 @@ static const yytype_int16 yyrhs[] =
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   665,   665,   672,   679,   689,   690,   691,   692,   693,
-     694,   695,   696,   697,   698,   699,   700,   701,   702,   703,
-     704,   705,   706,   707,   708,   709,   710,   711,   712,   713,
-     714,   715,   716,   717,   718,   719,   720,   721,   722,   723,
-     724,   725,   726,   727,   728,   729,   730,   731,   732,   733,
-     734,   735,   736,   737,   738,   739,   740,   741,   742,   743,
-     744,   745,   746,   747,   748,   749,   750,   751,   752,   753,
-     754,   755,   756,   757,   758,   759,   760,   761,   762,   763,
-     764,   765,   766,   767,   768,   769,   770,   771,   772,   773,
-     774,   775,   776,   777,   778,   779,   780,   781,   782,   783,
-     784,   785,   786,   787,   788,   789,   790,   791,   792,   793,
-     794,   795,   796,   797,   798,   800,   810,   821,   822,   831,
-     832,   836,   837,   841,   846,   850,   855,   860,   864,   868,
-     873,   877,   931,   933,   937,   941,   945,   949,   963,   981,
-     992,   993,   997,  1015,  1027,  1048,  1055,  1074,  1081,  1098,
-    1116,  1127,  1128,  1140,  1147,  1164,  1176,  1188,  1189,  1193,
-    1194,  1202,  1203,  1204,  1205,  1206,  1207,  1221,  1227,  1233,
-    1242,  1250,  1258,  1262,  1270,  1278,  1285,  1292,  1300,  1311,
-    1319,  1327,  1338,  1346,  1354,  1361,  1370,  1380,  1381,  1388,
-    1389,  1392,  1394,  1398,  1399,  1400,  1401,  1405,  1406,  1407,
-    1413,  1425,  1429,  1433,  1448,  1471,  1472,  1473,  1477,  1478,
-    1479,  1483,  1484,  1488,  1495,  1502,  1509,  1516,  1526,  1527,
-    1532,  1533,  1538,  1544,  1550,  1556,  1562,  1572,  1582,  1583,
-    1587,  1588,  1596,  1611,  1617,  1623,  1629,  1647,  1656,  1665,
-    1674,  1683,  1692,  1701,  1710,  1722,  1723,  1728,  1736,  1744,
-    1753,  1761,  1769,  1778,  1787,  1796,  1805,  1815,  1828,  1842,
-    1851,  1859,  1867,  1877,  1887,  1894,  1901,  1909,  1917,  1925,
-    1933,  1941,  1948,  1955,  1963,  1970,  1977,  1985,  1993,  2001,
-    2009,  2017,  2025,  2035,  2042,  2050,  2058,  2066,  2073,  2083,
-    2084,  2088,  2089,  2090,  2094,  2102,  2106,  2107,  2111,  2114,
-    2115,  2119,  2120,  2125,  2129,  2133,  2138,  2153,  2166,  2167,
-    2172,  2181,  2191,  2201,  2226,  2232,  2259,  2281,  2295,  2296,
-    2305,  2306,  2307,  2310,  2311,  2316,  2317,  2321,  2325,  2329,
-    2333,  2337,  2341,  2345,  2349,  2353,  2357,  2361,  2365,  2374,
-    2378,  2382,  2386,  2390,  2394,  2398,  2399,  2404,  2408,  2415,
-    2422,  2423,  2424,  2425,  2426,  2430,  2434,  2442,  2453,  2468,
-    2484,  2500,  2529,  2530,  2531,  2532,  2533,  2540,  2547,  2548,
-    2552,  2553,  2557,  2558,  2562,  2566,  2573,  2577,  2584,  2585,
-    2586,  2590,  2591,  2594,  2614,  2634,  2635,  2639,  2647,  2648,
-    2649,  2680,  2687,  2694,  2705,  2716,  2726,  2735,  2768,  2775,
-    2782,  2789,  2800,  2810,  2811,  2812,  2816,  2817,  2818,  2819,
-    2820,  2821,  2830,  2838,  2842,  2855,  2870,  2884,  2899,  2913,
-    2931,  2952,  2953,  2957,  2958,  2962,  2963,  2966,  2972,  2976,
-    2984,  2989,  2995,  2996,  3000,  3005,  3012,  3013,  3023,  3025,
-    3027,  3029,  3032,  3035,  3038,  3042,  3043,  3044,  3045,  3046,
-    3049,  3050,  3055,  3056,  3057,  3058,  3061,  3062,  3063,  3064,
-    3067,  3068,  3071,  3072,  3075,  3090,  3104,  3117,  3118,  3119,
-    3132,  3144,  3152,  3163,  3164,  3167,  3168,  3171,  3175,  3179,
-    3183,  3187,  3191,  3195,  3199,  3203,  3207,  3211,  3215,  3221,
-    3222,  3226,  3227,  3232,  3235,  3236,  3248,  3260,  3275,  3276,
-    3284,  3285,  3289,  3290,  3294,  3295,  3299,  3300,  3304,  3315,
-    3328,  3329,  3339,  3349,  3350,  3363,  3370,  3387,  3395,  3406,
-    3409,  3413,  3417,  3421,  3433,  3443,  3446,  3450,  3463,  3473,
-    3483,  3492,  3501,  3510,  3520,  3529,  3539,  3549,  3559,  3568,
-    3577,  3586,  3595,  3604,  3613,  3622,  3631,  3640,  3649,  3658,
-    3676,  3687,  3688,  3689,  3690,  3694,  3695,  3699,  3700,  3710,
-    3721,  3741,  3749,  3761,  3762,  3766,  3770,  3778,  3782,  3786,
-    3793,  3797,  3802,  3807,  3814,  3821,  3826,  3836,  3850,  3851,
-    3856,  3857,  3861,  3862,  3872,  3883,  3903,  3912,  3920,  3937,
-    3952,  3970,  3971,  3975,  3979,  3986,  3997,  4006,  4024,  4036,
-    4037,  4038,  4048,  4056,  4073,  4092,  4112,  4137,  4138,  4139,
-    4143,  4145,  4167,  4169,  4171,  4173,  4175,  4180,  4185,  4195,
-    4196,  4200,  4201,  4205,  4206,  4210,  4211,  4212,  4216,  4222,
-    4223,  4224,  4228,  4229,  4234,  4235,  4262,  4263,  4264,  4265,
-    4266,  4267,  4272,  4283,  4306,  4326,  4349,  4359,  4370,  4380,
-    4390,  4401,  4410,  4417,  4424,  4433,  4442,  4451,  4460,  4469,
-    4480,  4483,  4484,  4487,  4491,  4498,  4499,  4500,  4501,  4502,
-    4505,  4506,  4509,  4512,  4513,  4521,  4528,  4529,  4532,  4534,
-    4545,  4554,  4563,  4587,  4602,  4603,  4607,  4617,  4628,  4637,
-    4647,  4656,  4657,  4660,  4661,  4664,  4665,  4666,  4669,  4683,
-    4688,  4698,  4707,  4719,  4720,  4724,  4732,  4744,  4755,  4769,
-    4780,  4803,  4813,  4831,  4842,  4853,  4864,  4878,  4879,  4880,
-    4881,  4882,  4883,  4884,  4885,  4886,  4887,  4888,  4889,  4890,
-    4891,  4892,  4896,  4897,  4900,  4901,  4904,  4906,  4919,  4930,
-    4931,  4932,  4958,  4967,  4976,  4985,  4994,  5003,  5012,  5022,
-    5031,  5040,  5049,  5058,  5067,  5076,  5084,  5092,  5100,  5111,
-    5112,  5113,  5114,  5115,  5116,  5117,  5118,  5119,  5120,  5121,
-    5122,  5123,  5124,  5125,  5126,  5127,  5131,  5132,  5146,  5157,
-    5168,  5179,  5190,  5203,  5204,  5208,  5209,  5210,  5211,  5212,
-    5213,  5214,  5215,  5216,  5217,  5218,  5221,  5222,  5232,  5238,
-    5246,  5254,  5262,  5270,  5278,  5286,  5294,  5302,  5310,  5318,
-    5326,  5334,  5342,  5350,  5358,  5366,  5376,  5377,  5380,  5381,
-    5391,  5407,  5421,  5447,  5449,  5451,  5453,  5460,  5469,  5470,
-    5473,  5480,  5487,  5494,  5508,  5516,  5524,  5532,  5540,  5548,
-    5556,  5564,  5572,  5580,  5588,  5596,  5604,  5612,  5620,  5628,
-    5640,  5641,  5644,  5654,  5668,  5669,  5673,  5674,  5679,  5695,
-    5708,  5718,  5730,  5731,  5734,  5735,  5745,  5755,  5756,  5760,
-    5764,  5768,  5779,  5792,  5806,  5823,  5824,  5825,  5826,  5838,
-    5865,  5866,  5870,  5871,  5875,  5876,  5880,  5881,  5884,  5885,
-    5893,  5904,  5915,  5928,  5929,  5932,  5933,  5934,  5937,  5938,
-    5939,  5942,  5943,  5944,  5960,  5972,  5985,  6000,  6001,  6004,
-    6005,  6009,  6010,  6018,  6019,  6023,  6024,  6039,  6048,  6057,
-    6066,  6075,  6087,  6088,  6089,  6090,  6091,  6097,  6101,  6116,
-    6117,  6123,  6133,  6137,  6142,  6152,  6153,  6160,  6164,  6168,
-    6172,  6176,  6180,  6184,  6188,  6192,  6196,  6200,  6204,  6208,
-    6212,  6216,  6224,  6228,  6232,  6236,  6242,  6243,  6250,  6251,
-    6254,  6266,  6270,  6285,  6296,  6297,  6302,  6303,  6318,  6329,
-    6343,  6354,  6368,  6379,  6393,  6401,  6403,  6405,  6410,  6412,
-    6425,  6434,  6435,  6439,  6443,  6455,  6466,  6477,  6490,  6491,
-    6492,  6496,  6509,  6510,  6524,  6532,  6542,  6555,  6556,  6559,
-    6560,  6570,  6580,  6589,  6598,  6607,  6616,  6626,  6635,  6645,
-    6654,  6663,  6673,  6683,  6692,  6701,  6711,  6721,  6731,  6741,
-    6751,  6761,  6771,  6781,  6791,  6801,  6812,  6823,  6833,  6844,
-    6855,  6865,  6874,  6883,  6892,  6901,  6910,  6919,  6928,  6937,
-    6946,  6955,  6969,  6970,  6973,  6974,  6984,  6994,  7003,  7012,
-    7021,  7030,  7040,  7050,  7060,  7070,  7079,  7088,  7097,  7106,
-    7115,  7124,  7133,  7142,  7151,  7160,  7169,  7178,  7195,  7204,
-    7212,  7220,  7228,  7236,  7245,  7253,  7261,  7270,  7279,  7288,
-    7296,  7304,  7312,  7320,  7328,  7336,  7353,  7370,  7371,  7372,
-    7377,  7383,  7392,  7393,  7394,  7395,  7396,  7400,  7401,  7404,
-    7405,  7406,  7407,  7411,  7412,  7413,  7418,  7429,  7451,  7461,
-    7462,  7465,  7474,  7480,  7499,  7506,  7513,  7520,  7527,  7534,
-    7541,  7549,  7557,  7565,  7573,  7581,  7588,  7595,  7604,  7605,
-    7606,  7610,  7613,  7616,  7619,  7622,  7629,  7631,  7633,  7638,
-    7640,  7652,  7664,  7679,  7685,  7691,  7697,  7707,  7723,  7733,
-    7734,  7738,  7742,  7746,  7750,  7754,  7758,  7762,  7766,  7770,
-    7774,  7778,  7782,  7786,  7790,  7794,  7798,  7808,  7809,  7820,
-    7827,  7838,  7849,  7850,  7854,  7868,  7875,  7892,  7905,  7914,
-    7922,  7930,  7939,  7950,  7961,  7971,  7972,  7983,  7993,  8003,
-    8013,  8023,  8033,  8041,  8062,  8085,  8093,  8102,  8113,  8114,
-    8126,  8140,  8154,  8166,  8178,  8195,  8196,  8200,  8201,  8202,
-    8203,  8207,  8219,  8234,  8235,  8239,  8240,  8243,  8244,  8247,
-    8248,  8252,  8253,  8266,  8273,  8283,  8290,  8300,  8301,  8302,
-    8303,  8304,  8305,  8306,  8310,  8314,  8321,  8328,  8329,  8330,
-    8334,  8335,  8336,  8346,  8356,  8357,  8361,  8362,  8363,  8364,
-    8374,  8381,  8398,  8399,  8409,  8415,  8421,  8427,  8443,  8453,
-    8459,  8465,  8474,  8476,  8481,  8492,  8493,  8504,  8518,  8519,
-    8530,  8541,  8542,  8545,  8546,  8547,  8548,  8549,  8550,  8551,
-    8552,  8555,  8556,  8567,  8585,  8586,  8590,  8591,  8595,  8603,
-    8631,  8642,  8643,  8653,  8664,  8667,  8668,  8669,  8670,  8671,
-    8674,  8675,  8676,  8724,  8725,  8729,  8730,  8744,  8745,  8752,
-    8760,  8768,  8776,  8784,  8792,  8803,  8804,  8831,  8846,  8847,
-    8866,  8870,  8874,  8889,  8896,  8906,  8907,  8910,  8922,  8923,
-    8927,  8938,  8946,  8951,  8956,  8961,  8966,  8974,  8982,  8987,
-    8992,  8999,  9000,  9003,  9004,  9005,  9012,  9013,  9014,  9015,
-    9019,  9020,  9024,  9028,  9029,  9032,  9041,  9054,  9055,  9056,
-    9057,  9061,  9062,  9066,  9068,  9078,  9083,  9086,  9091,  9092,
-    9100,  9110,  9111,  9112,  9120,  9124,  9125,  9128,  9129,  9134,
-    9135,  9139,  9140,  9144,  9145,  9149,  9150,  9154,  9155,  9159,
-    9167,  9178,  9179,  9184,  9190,  9208,  9209,  9213,  9214,  9224,
-    9228,  9233,  9240,  9248,  9255,  9265,  9275,  9303,  9310,  9314,
-    9340,  9344,  9356,  9369,  9383,  9394,  9409,  9415,  9420,  9426,
-    9433,  9434,  9435,  9436,  9440,  9441,  9453,  9454,  9459,  9466,
-    9473,  9480,  9491,  9492,  9505,  9509,  9516,  9526,  9531,  9532,
-    9537,  9538,  9546,  9551,  9552,  9556,  9560,  9566,  9595,  9600,
-    9607,  9612,  9618,  9623,  9632,  9634,  9637,  9641,  9642,  9643,
-    9644,  9645,  9646,  9651,  9681,  9682,  9683,  9684,  9695,  9701,
-    9709,  9710,  9716,  9721,  9726,  9731,  9736,  9741,  9746,  9751,
-    9757,  9763,  9769,  9776,  9798,  9807,  9811,  9819,  9823,  9831,
-    9843,  9864,  9868,  9874,  9878,  9891,  9910,  9933,  9935,  9937,
-    9939,  9941,  9943,  9948,  9949,  9953,  9954,  9961,  9970,  9978,
-    9987,  9998, 10006, 10007, 10008, 10012, 10014, 10016, 10018, 10020,
-   10022, 10024, 10029, 10034, 10040, 10048, 10053, 10060, 10067, 10071,
-   10075, 10105, 10106, 10108, 10116, 10138, 10140, 10142, 10144, 10146,
-   10148, 10150, 10152, 10154, 10156, 10158, 10161, 10163, 10165, 10168,
-   10170, 10172, 10175, 10177, 10190, 10192, 10205, 10207, 10220, 10222,
-   10236, 10249, 10262, 10275, 10298, 10305, 10312, 10319, 10326, 10330,
-   10337, 10344, 10351, 10358, 10365, 10372, 10376, 10384, 10388, 10398,
-   10405, 10412, 10425, 10438, 10457, 10478, 10488, 10495, 10511, 10516,
-   10534, 10536, 10538, 10540, 10542, 10544, 10546, 10548, 10550, 10552,
-   10554, 10556, 10558, 10560, 10562, 10564, 10566, 10570, 10575, 10579,
-   10583, 10588, 10605, 10606, 10607, 10622, 10634, 10636, 10638, 10648,
-   10671, 10681, 10691, 10699, 10718, 10731, 10744, 10757, 10770, 10783,
-   10800, 10813, 10836, 10849, 10870, 10880, 10893, 10910, 10923, 10933,
-   10946, 10956, 10969, 10982, 10995, 11008, 11021, 11034, 11047, 11049,
-   11062, 11080, 11094, 11110, 11132, 11148, 11161, 11174, 11187, 11191,
-   11198, 11206, 11214, 11218, 11222, 11226, 11230, 11234, 11249, 11253,
-   11262, 11266, 11270, 11275, 11289, 11291, 11295, 11297, 11299, 11302,
-   11305, 11308, 11309, 11312, 11320, 11330, 11331, 11334, 11335, 11336,
-   11341, 11345, 11349, 11353, 11364, 11365, 11369, 11370, 11375, 11383,
-   11385, 11399, 11402, 11429, 11430, 11433, 11434, 11445, 11463, 11470,
-   11479, 11496, 11541, 11549, 11557, 11565, 11573, 11594, 11595, 11596,
-   11599, 11600, 11601, 11604, 11605, 11608, 11609, 11610, 11611, 11612,
-   11613, 11614, 11615, 11616, 11619, 11621, 11626, 11628, 11633, 11635,
-   11637, 11639, 11641, 11643, 11655, 11659, 11666, 11670, 11676, 11680,
-   11691, 11692, 11695, 11699, 11703, 11709, 11710, 11715, 11719, 11726,
-   11727, 11728, 11729, 11730, 11731, 11732, 11733, 11743, 11747, 11754,
-   11761, 11762, 11778, 11782, 11787, 11791, 11806, 11811, 11815, 11818,
-   11821, 11822, 11823, 11826, 11833, 11843, 11857, 11858, 11862, 11873,
-   11874, 11877, 11878, 11881, 11885, 11892, 11896, 11900, 11907, 11917,
-   11918, 11922, 11923, 11926, 11927, 11938, 11939, 11948, 11949, 11957,
-   11968, 11969, 11972, 11988, 11996, 12004, 12026, 12027, 12038, 12042,
-   12069, 12071, 12076, 12079, 12082, 12084, 12086, 12088, 12098, 12100,
-   12111, 12115, 12119, 12123, 12127, 12136, 12143, 12168, 12172, 12178,
-   12195, 12199, 12203, 12209, 12210, 12211, 12213, 12214, 12215, 12231,
-   12232, 12233, 12238, 12239, 12240, 12246, 12247, 12248, 12249, 12250,
-   12270, 12271, 12272, 12273, 12274, 12275, 12276, 12277, 12278, 12279,
-   12280, 12281, 12282, 12283, 12284, 12285, 12286, 12287, 12288, 12289,
-   12290, 12291, 12292, 12293, 12294, 12295, 12296, 12297, 12298, 12299,
-   12300, 12301, 12302, 12303, 12304, 12305, 12306, 12307, 12308, 12309,
-   12310, 12311, 12312, 12313, 12314, 12315, 12316, 12317, 12318, 12319,
-   12320, 12321, 12322, 12323, 12324, 12325, 12326, 12327, 12328, 12329,
-   12330, 12331, 12332, 12333, 12334, 12335, 12336, 12337, 12338, 12339,
-   12340, 12341, 12342, 12343, 12344, 12345, 12346, 12347, 12348, 12349,
-   12350, 12351, 12352, 12353, 12354, 12355, 12356, 12357, 12358, 12359,
-   12360, 12361, 12362, 12363, 12364, 12365, 12366, 12367, 12368, 12369,
-   12370, 12371, 12372, 12373, 12374, 12375, 12376, 12377, 12378, 12379,
-   12380, 12381, 12382, 12383, 12384, 12385, 12386, 12387, 12388, 12389,
-   12390, 12391, 12392, 12393, 12394, 12395, 12396, 12397, 12398, 12399,
-   12400, 12401, 12402, 12403, 12404, 12405, 12406, 12407, 12408, 12409,
-   12410, 12411, 12412, 12413, 12414, 12415, 12416, 12417, 12418, 12419,
-   12420, 12421, 12422, 12423, 12424, 12425, 12426, 12427, 12428, 12429,
-   12430, 12431, 12432, 12433, 12434, 12435, 12436, 12437, 12438, 12439,
-   12440, 12441, 12442, 12443, 12444, 12445, 12446, 12447, 12448, 12449,
-   12450, 12451, 12452, 12453, 12454, 12455, 12456, 12457, 12458, 12459,
-   12460, 12461, 12462, 12463, 12464, 12465, 12466, 12467, 12468, 12469,
-   12470, 12471, 12472, 12473, 12474, 12475, 12476, 12477, 12478, 12479,
-   12480, 12481, 12482, 12483, 12484, 12485, 12486, 12487, 12488, 12489,
-   12490, 12491, 12492, 12493, 12494, 12495, 12496, 12497, 12498, 12499,
-   12500, 12501, 12502, 12503, 12504, 12505, 12506, 12507, 12508, 12509,
-   12510, 12511, 12512, 12513, 12514, 12515, 12516, 12517, 12518, 12519,
-   12533, 12534, 12535, 12536, 12537, 12538, 12539, 12540, 12541, 12542,
-   12543, 12544, 12545, 12546, 12547, 12548, 12549, 12550, 12551, 12552,
-   12553, 12554, 12555, 12556, 12557, 12558, 12559, 12560, 12561, 12562,
-   12563, 12564, 12565, 12566, 12567, 12568, 12569, 12570, 12571, 12572,
-   12573, 12574, 12575, 12576, 12577, 12578, 12579, 12593, 12594, 12595,
-   12596, 12597, 12598, 12599, 12600, 12601, 12602, 12603, 12604, 12605,
-   12606, 12607, 12608, 12609, 12610, 12611, 12612, 12613, 12614, 12615,
-   12625, 12626, 12627, 12628, 12629, 12630, 12631, 12632, 12633, 12634,
-   12635, 12636, 12637, 12638, 12639, 12640, 12641, 12642, 12643, 12644,
-   12645, 12646, 12647, 12648, 12649, 12650, 12651, 12652, 12653, 12654,
-   12655, 12656, 12657, 12658, 12659, 12660, 12661, 12662, 12663, 12664,
-   12665, 12666, 12667, 12668, 12669, 12670, 12671, 12672, 12673, 12674,
-   12675, 12676, 12677, 12678, 12679, 12680, 12681, 12682, 12683, 12684,
-   12685, 12686, 12687, 12688, 12689, 12690, 12691, 12692, 12693, 12694,
-   12695, 12696, 12697, 12698, 12699, 12700
+       0,   666,   666,   673,   680,   690,   691,   692,   693,   694,
+     695,   696,   697,   698,   699,   700,   701,   702,   703,   704,
+     705,   706,   707,   708,   709,   710,   711,   712,   713,   714,
+     715,   716,   717,   718,   719,   720,   721,   722,   723,   724,
+     725,   726,   727,   728,   729,   730,   731,   732,   733,   734,
+     735,   736,   737,   738,   739,   740,   741,   742,   743,   744,
+     745,   746,   747,   748,   749,   750,   751,   752,   753,   754,
+     755,   756,   757,   758,   759,   760,   761,   762,   763,   764,
+     765,   766,   767,   768,   769,   770,   771,   772,   773,   774,
+     775,   776,   777,   778,   779,   780,   781,   782,   783,   784,
+     785,   786,   787,   788,   789,   790,   791,   792,   793,   794,
+     795,   796,   797,   798,   799,   801,   811,   822,   823,   832,
+     833,   837,   838,   842,   847,   851,   856,   861,   865,   869,
+     874,   878,   932,   934,   938,   942,   946,   950,   964,   982,
+     993,   994,   998,  1016,  1028,  1049,  1056,  1075,  1082,  1099,
+    1117,  1128,  1129,  1141,  1148,  1165,  1177,  1189,  1190,  1194,
+    1195,  1203,  1204,  1205,  1206,  1207,  1208,  1222,  1228,  1234,
+    1243,  1251,  1259,  1263,  1271,  1279,  1286,  1293,  1301,  1312,
+    1320,  1328,  1339,  1347,  1355,  1362,  1371,  1381,  1382,  1389,
+    1390,  1393,  1395,  1399,  1400,  1401,  1402,  1406,  1407,  1408,
+    1414,  1426,  1430,  1434,  1449,  1472,  1473,  1474,  1478,  1479,
+    1480,  1484,  1485,  1489,  1496,  1503,  1510,  1517,  1527,  1528,
+    1533,  1534,  1539,  1545,  1551,  1557,  1563,  1573,  1583,  1584,
+    1588,  1589,  1597,  1612,  1618,  1624,  1630,  1648,  1657,  1666,
+    1675,  1684,  1693,  1702,  1711,  1723,  1724,  1729,  1737,  1745,
+    1754,  1762,  1770,  1779,  1788,  1797,  1806,  1816,  1829,  1843,
+    1852,  1860,  1868,  1878,  1888,  1895,  1902,  1910,  1918,  1926,
+    1934,  1942,  1949,  1956,  1964,  1971,  1978,  1986,  1994,  2002,
+    2010,  2018,  2026,  2036,  2043,  2051,  2059,  2067,  2074,  2084,
+    2085,  2089,  2090,  2091,  2095,  2103,  2107,  2108,  2112,  2115,
+    2116,  2120,  2121,  2126,  2130,  2134,  2139,  2154,  2167,  2168,
+    2173,  2182,  2192,  2202,  2227,  2233,  2260,  2282,  2296,  2297,
+    2306,  2307,  2308,  2311,  2312,  2317,  2318,  2322,  2326,  2330,
+    2334,  2338,  2342,  2346,  2350,  2354,  2358,  2362,  2366,  2375,
+    2379,  2383,  2387,  2391,  2395,  2399,  2400,  2405,  2409,  2416,
+    2423,  2424,  2425,  2426,  2427,  2431,  2435,  2443,  2454,  2469,
+    2485,  2501,  2530,  2531,  2532,  2533,  2534,  2541,  2548,  2549,
+    2553,  2554,  2558,  2559,  2563,  2567,  2574,  2578,  2585,  2586,
+    2587,  2591,  2592,  2595,  2615,  2635,  2636,  2640,  2648,  2649,
+    2650,  2681,  2688,  2695,  2706,  2717,  2727,  2736,  2769,  2776,
+    2783,  2790,  2801,  2811,  2812,  2813,  2817,  2818,  2819,  2820,
+    2821,  2822,  2831,  2839,  2843,  2856,  2871,  2885,  2900,  2914,
+    2932,  2953,  2954,  2958,  2959,  2963,  2964,  2967,  2973,  2977,
+    2985,  2990,  2996,  2997,  3001,  3006,  3013,  3014,  3024,  3026,
+    3028,  3030,  3033,  3036,  3039,  3043,  3044,  3045,  3046,  3047,
+    3050,  3051,  3056,  3057,  3058,  3059,  3062,  3063,  3064,  3065,
+    3068,  3069,  3072,  3073,  3076,  3091,  3105,  3118,  3119,  3120,
+    3133,  3145,  3153,  3164,  3165,  3168,  3169,  3172,  3176,  3180,
+    3184,  3188,  3192,  3196,  3200,  3204,  3208,  3212,  3216,  3222,
+    3223,  3227,  3228,  3233,  3236,  3237,  3249,  3261,  3276,  3277,
+    3285,  3286,  3290,  3291,  3295,  3296,  3300,  3301,  3305,  3316,
+    3329,  3330,  3340,  3350,  3351,  3364,  3371,  3388,  3396,  3407,
+    3410,  3414,  3418,  3422,  3434,  3444,  3447,  3451,  3464,  3474,
+    3484,  3493,  3502,  3511,  3521,  3530,  3540,  3550,  3560,  3569,
+    3578,  3587,  3596,  3605,  3614,  3623,  3632,  3641,  3650,  3659,
+    3677,  3688,  3689,  3690,  3691,  3695,  3696,  3700,  3701,  3711,
+    3722,  3742,  3750,  3762,  3763,  3767,  3771,  3779,  3783,  3787,
+    3794,  3798,  3803,  3808,  3815,  3822,  3827,  3837,  3851,  3852,
+    3857,  3858,  3862,  3863,  3873,  3884,  3904,  3913,  3921,  3938,
+    3953,  3971,  3972,  3976,  3980,  3987,  3998,  4007,  4025,  4037,
+    4038,  4039,  4049,  4057,  4074,  4093,  4113,  4138,  4139,  4140,
+    4144,  4146,  4168,  4170,  4172,  4174,  4176,  4181,  4186,  4196,
+    4197,  4201,  4202,  4206,  4207,  4211,  4212,  4213,  4217,  4223,
+    4224,  4225,  4229,  4230,  4235,  4236,  4263,  4264,  4265,  4266,
+    4267,  4268,  4273,  4284,  4307,  4327,  4350,  4360,  4371,  4381,
+    4391,  4402,  4411,  4418,  4425,  4434,  4443,  4452,  4461,  4470,
+    4481,  4484,  4485,  4488,  4492,  4499,  4500,  4501,  4502,  4503,
+    4506,  4507,  4510,  4513,  4514,  4522,  4529,  4530,  4533,  4535,
+    4546,  4555,  4564,  4588,  4603,  4604,  4608,  4618,  4629,  4638,
+    4648,  4657,  4658,  4661,  4662,  4665,  4666,  4667,  4670,  4684,
+    4689,  4699,  4708,  4720,  4721,  4725,  4733,  4745,  4756,  4770,
+    4781,  4804,  4814,  4832,  4843,  4854,  4865,  4879,  4880,  4881,
+    4882,  4883,  4884,  4885,  4886,  4887,  4888,  4889,  4890,  4891,
+    4892,  4893,  4897,  4898,  4901,  4902,  4905,  4907,  4920,  4931,
+    4932,  4933,  4959,  4968,  4977,  4986,  4995,  5004,  5013,  5023,
+    5032,  5041,  5050,  5059,  5068,  5077,  5085,  5093,  5101,  5112,
+    5113,  5114,  5115,  5116,  5117,  5118,  5119,  5120,  5121,  5122,
+    5123,  5124,  5125,  5126,  5127,  5128,  5132,  5133,  5147,  5158,
+    5169,  5180,  5191,  5204,  5205,  5209,  5210,  5211,  5212,  5213,
+    5214,  5215,  5216,  5217,  5218,  5219,  5222,  5223,  5233,  5239,
+    5247,  5255,  5263,  5271,  5279,  5287,  5295,  5303,  5311,  5319,
+    5327,  5335,  5343,  5351,  5359,  5367,  5377,  5378,  5381,  5382,
+    5392,  5408,  5422,  5448,  5450,  5452,  5454,  5461,  5470,  5471,
+    5474,  5481,  5488,  5495,  5509,  5517,  5525,  5533,  5541,  5549,
+    5557,  5565,  5573,  5581,  5589,  5597,  5605,  5613,  5621,  5629,
+    5641,  5642,  5645,  5655,  5669,  5670,  5674,  5675,  5680,  5696,
+    5709,  5719,  5731,  5732,  5735,  5736,  5746,  5756,  5757,  5761,
+    5765,  5769,  5780,  5793,  5807,  5824,  5825,  5826,  5827,  5839,
+    5866,  5867,  5871,  5872,  5876,  5877,  5881,  5882,  5885,  5886,
+    5894,  5905,  5916,  5929,  5930,  5933,  5934,  5935,  5938,  5939,
+    5940,  5943,  5944,  5945,  5961,  5973,  5986,  6001,  6002,  6005,
+    6006,  6010,  6011,  6019,  6020,  6024,  6025,  6040,  6049,  6058,
+    6067,  6076,  6088,  6089,  6090,  6091,  6092,  6098,  6102,  6117,
+    6118,  6124,  6134,  6138,  6143,  6153,  6154,  6161,  6165,  6169,
+    6173,  6177,  6181,  6185,  6189,  6193,  6197,  6201,  6205,  6209,
+    6213,  6217,  6225,  6229,  6233,  6237,  6243,  6244,  6251,  6252,
+    6255,  6267,  6271,  6286,  6297,  6298,  6303,  6304,  6319,  6330,
+    6344,  6355,  6369,  6380,  6394,  6402,  6404,  6406,  6411,  6413,
+    6426,  6435,  6436,  6440,  6444,  6456,  6467,  6478,  6491,  6492,
+    6493,  6497,  6510,  6511,  6525,  6533,  6543,  6556,  6557,  6560,
+    6561,  6571,  6581,  6590,  6599,  6608,  6617,  6627,  6636,  6646,
+    6655,  6664,  6674,  6684,  6693,  6702,  6712,  6722,  6732,  6742,
+    6752,  6762,  6772,  6782,  6792,  6802,  6813,  6824,  6834,  6845,
+    6856,  6866,  6875,  6884,  6893,  6902,  6911,  6920,  6929,  6938,
+    6947,  6956,  6970,  6971,  6974,  6975,  6985,  6995,  7004,  7013,
+    7022,  7031,  7041,  7051,  7061,  7071,  7080,  7089,  7098,  7107,
+    7116,  7125,  7134,  7143,  7152,  7161,  7170,  7179,  7196,  7205,
+    7213,  7221,  7229,  7237,  7246,  7254,  7262,  7271,  7280,  7289,
+    7297,  7305,  7313,  7321,  7329,  7337,  7354,  7371,  7372,  7373,
+    7378,  7384,  7393,  7394,  7395,  7396,  7397,  7401,  7402,  7405,
+    7406,  7407,  7408,  7412,  7413,  7414,  7419,  7430,  7452,  7462,
+    7463,  7466,  7475,  7481,  7500,  7507,  7514,  7521,  7528,  7535,
+    7542,  7550,  7558,  7566,  7574,  7582,  7589,  7596,  7605,  7606,
+    7607,  7611,  7614,  7617,  7620,  7623,  7630,  7632,  7634,  7639,
+    7641,  7653,  7665,  7680,  7686,  7692,  7698,  7708,  7724,  7734,
+    7735,  7739,  7743,  7747,  7751,  7755,  7759,  7763,  7767,  7771,
+    7775,  7779,  7783,  7787,  7791,  7795,  7799,  7809,  7810,  7821,
+    7828,  7839,  7850,  7851,  7855,  7869,  7876,  7893,  7906,  7915,
+    7923,  7931,  7940,  7951,  7962,  7972,  7973,  7984,  7994,  8004,
+    8014,  8024,  8034,  8042,  8063,  8086,  8094,  8103,  8114,  8115,
+    8127,  8141,  8155,  8167,  8179,  8196,  8197,  8201,  8202,  8203,
+    8204,  8208,  8220,  8235,  8236,  8240,  8241,  8244,  8245,  8248,
+    8249,  8253,  8254,  8267,  8274,  8284,  8291,  8301,  8302,  8303,
+    8304,  8305,  8306,  8307,  8311,  8315,  8322,  8329,  8330,  8331,
+    8335,  8336,  8337,  8347,  8357,  8358,  8362,  8363,  8364,  8365,
+    8375,  8382,  8399,  8400,  8410,  8416,  8422,  8428,  8444,  8454,
+    8460,  8466,  8475,  8477,  8482,  8493,  8494,  8505,  8519,  8520,
+    8531,  8542,  8543,  8546,  8547,  8548,  8549,  8550,  8551,  8552,
+    8553,  8556,  8557,  8568,  8586,  8587,  8591,  8592,  8596,  8604,
+    8632,  8643,  8644,  8654,  8665,  8668,  8669,  8670,  8671,  8672,
+    8675,  8676,  8677,  8725,  8726,  8730,  8731,  8745,  8746,  8753,
+    8761,  8769,  8777,  8785,  8793,  8804,  8805,  8832,  8847,  8848,
+    8867,  8871,  8875,  8890,  8897,  8907,  8908,  8911,  8923,  8924,
+    8928,  8939,  8947,  8952,  8957,  8962,  8967,  8975,  8983,  8988,
+    8993,  9000,  9001,  9004,  9005,  9006,  9013,  9014,  9015,  9016,
+    9020,  9021,  9025,  9029,  9030,  9033,  9042,  9055,  9056,  9057,
+    9058,  9062,  9063,  9067,  9069,  9079,  9084,  9087,  9092,  9093,
+    9101,  9111,  9112,  9113,  9121,  9125,  9126,  9129,  9130,  9135,
+    9136,  9140,  9141,  9145,  9146,  9150,  9151,  9155,  9156,  9160,
+    9168,  9179,  9180,  9185,  9191,  9209,  9210,  9214,  9215,  9225,
+    9229,  9234,  9241,  9249,  9256,  9266,  9276,  9304,  9311,  9315,
+    9341,  9345,  9357,  9370,  9384,  9395,  9410,  9416,  9421,  9427,
+    9434,  9435,  9436,  9437,  9441,  9442,  9454,  9455,  9460,  9467,
+    9474,  9481,  9492,  9493,  9506,  9510,  9517,  9527,  9532,  9533,
+    9538,  9539,  9547,  9552,  9553,  9557,  9561,  9567,  9596,  9601,
+    9608,  9613,  9619,  9624,  9633,  9635,  9638,  9642,  9643,  9644,
+    9645,  9646,  9647,  9652,  9682,  9683,  9684,  9685,  9696,  9702,
+    9710,  9711,  9717,  9722,  9727,  9732,  9737,  9742,  9747,  9752,
+    9758,  9764,  9770,  9777,  9799,  9808,  9812,  9820,  9824,  9832,
+    9844,  9865,  9869,  9875,  9879,  9892,  9911,  9934,  9936,  9938,
+    9940,  9942,  9944,  9949,  9950,  9954,  9955,  9962,  9971,  9979,
+    9988,  9999, 10007, 10008, 10009, 10013, 10015, 10017, 10019, 10021,
+   10023, 10025, 10030, 10035, 10041, 10049, 10054, 10061, 10068, 10072,
+   10076, 10106, 10107, 10109, 10117, 10139, 10141, 10143, 10145, 10147,
+   10149, 10151, 10153, 10155, 10157, 10159, 10162, 10164, 10166, 10169,
+   10171, 10173, 10176, 10178, 10191, 10193, 10206, 10208, 10221, 10223,
+   10237, 10250, 10263, 10276, 10299, 10306, 10313, 10320, 10327, 10331,
+   10338, 10345, 10352, 10359, 10366, 10373, 10377, 10385, 10389, 10399,
+   10406, 10413, 10426, 10439, 10458, 10479, 10489, 10496, 10512, 10517,
+   10535, 10537, 10539, 10541, 10543, 10545, 10547, 10549, 10551, 10553,
+   10555, 10557, 10559, 10561, 10563, 10565, 10567, 10571, 10576, 10580,
+   10584, 10589, 10606, 10607, 10608, 10623, 10635, 10637, 10639, 10649,
+   10672, 10682, 10692, 10700, 10719, 10732, 10745, 10758, 10771, 10784,
+   10801, 10814, 10837, 10850, 10871, 10881, 10894, 10911, 10924, 10934,
+   10947, 10957, 10970, 10983, 10996, 11009, 11022, 11035, 11048, 11050,
+   11063, 11081, 11095, 11111, 11133, 11149, 11162, 11175, 11188, 11192,
+   11199, 11207, 11215, 11219, 11223, 11227, 11231, 11235, 11250, 11254,
+   11263, 11267, 11271, 11276, 11290, 11292, 11296, 11298, 11300, 11303,
+   11306, 11309, 11310, 11313, 11321, 11331, 11332, 11335, 11336, 11337,
+   11342, 11346, 11350, 11354, 11365, 11366, 11370, 11371, 11376, 11384,
+   11386, 11400, 11403, 11430, 11431, 11434, 11435, 11446, 11464, 11471,
+   11480, 11497, 11542, 11550, 11558, 11566, 11574, 11595, 11596, 11597,
+   11600, 11601, 11602, 11605, 11606, 11609, 11610, 11611, 11612, 11613,
+   11614, 11615, 11616, 11617, 11620, 11622, 11627, 11629, 11634, 11636,
+   11638, 11640, 11642, 11644, 11656, 11660, 11667, 11671, 11677, 11681,
+   11692, 11693, 11696, 11700, 11704, 11710, 11711, 11716, 11720, 11727,
+   11728, 11729, 11730, 11731, 11732, 11733, 11734, 11744, 11748, 11755,
+   11762, 11763, 11779, 11783, 11788, 11792, 11807, 11812, 11816, 11819,
+   11822, 11823, 11824, 11827, 11834, 11844, 11858, 11859, 11863, 11874,
+   11875, 11878, 11879, 11882, 11886, 11893, 11897, 11901, 11908, 11918,
+   11919, 11923, 11924, 11927, 11928, 11939, 11940, 11949, 11950, 11958,
+   11969, 11970, 11973, 11989, 11997, 12005, 12027, 12028, 12039, 12043,
+   12070, 12072, 12077, 12080, 12083, 12085, 12087, 12089, 12099, 12101,
+   12112, 12116, 12120, 12124, 12128, 12137, 12144, 12169, 12173, 12179,
+   12196, 12200, 12204, 12210, 12211, 12212, 12214, 12215, 12216, 12232,
+   12233, 12234, 12239, 12240, 12241, 12247, 12248, 12249, 12250, 12251,
+   12271, 12272, 12273, 12274, 12275, 12276, 12277, 12278, 12279, 12280,
+   12281, 12282, 12283, 12284, 12285, 12286, 12287, 12288, 12289, 12290,
+   12291, 12292, 12293, 12294, 12295, 12296, 12297, 12298, 12299, 12300,
+   12301, 12302, 12303, 12304, 12305, 12306, 12307, 12308, 12309, 12310,
+   12311, 12312, 12313, 12314, 12315, 12316, 12317, 12318, 12319, 12320,
+   12321, 12322, 12323, 12324, 12325, 12326, 12327, 12328, 12329, 12330,
+   12331, 12332, 12333, 12334, 12335, 12336, 12337, 12338, 12339, 12340,
+   12341, 12342, 12343, 12344, 12345, 12346, 12347, 12348, 12349, 12350,
+   12351, 12352, 12353, 12354, 12355, 12356, 12357, 12358, 12359, 12360,
+   12361, 12362, 12363, 12364, 12365, 12366, 12367, 12368, 12369, 12370,
+   12371, 12372, 12373, 12374, 12375, 12376, 12377, 12378, 12379, 12380,
+   12381, 12382, 12383, 12384, 12385, 12386, 12387, 12388, 12389, 12390,
+   12391, 12392, 12393, 12394, 12395, 12396, 12397, 12398, 12399, 12400,
+   12401, 12402, 12403, 12404, 12405, 12406, 12407, 12408, 12409, 12410,
+   12411, 12412, 12413, 12414, 12415, 12416, 12417, 12418, 12419, 12420,
+   12421, 12422, 12423, 12424, 12425, 12426, 12427, 12428, 12429, 12430,
+   12431, 12432, 12433, 12434, 12435, 12436, 12437, 12438, 12439, 12440,
+   12441, 12442, 12443, 12444, 12445, 12446, 12447, 12448, 12449, 12450,
+   12451, 12452, 12453, 12454, 12455, 12456, 12457, 12458, 12459, 12460,
+   12461, 12462, 12463, 12464, 12465, 12466, 12467, 12468, 12469, 12470,
+   12471, 12472, 12473, 12474, 12475, 12476, 12477, 12478, 12479, 12480,
+   12481, 12482, 12483, 12484, 12485, 12486, 12487, 12488, 12489, 12490,
+   12491, 12492, 12493, 12494, 12495, 12496, 12497, 12498, 12499, 12500,
+   12501, 12502, 12503, 12504, 12505, 12506, 12507, 12508, 12509, 12510,
+   12511, 12512, 12513, 12514, 12515, 12516, 12517, 12518, 12519, 12520,
+   12534, 12535, 12536, 12537, 12538, 12539, 12540, 12541, 12542, 12543,
+   12544, 12545, 12546, 12547, 12548, 12549, 12550, 12551, 12552, 12553,
+   12554, 12555, 12556, 12557, 12558, 12559, 12560, 12561, 12562, 12563,
+   12564, 12565, 12566, 12567, 12568, 12569, 12570, 12571, 12572, 12573,
+   12574, 12575, 12576, 12577, 12578, 12579, 12580, 12594, 12595, 12596,
+   12597, 12598, 12599, 12600, 12601, 12602, 12603, 12604, 12605, 12606,
+   12607, 12608, 12609, 12610, 12611, 12612, 12613, 12614, 12615, 12616,
+   12626, 12627, 12628, 12629, 12630, 12631, 12632, 12633, 12634, 12635,
+   12636, 12637, 12638, 12639, 12640, 12641, 12642, 12643, 12644, 12645,
+   12646, 12647, 12648, 12649, 12650, 12651, 12652, 12653, 12654, 12655,
+   12656, 12657, 12658, 12659, 12660, 12661, 12662, 12663, 12664, 12665,
+   12666, 12667, 12668, 12669, 12670, 12671, 12672, 12673, 12674, 12675,
+   12676, 12677, 12678, 12679, 12680, 12681, 12682, 12683, 12684, 12685,
+   12686, 12687, 12688, 12689, 12690, 12691, 12692, 12693, 12694, 12695,
+   12696, 12697, 12698, 12699, 12700, 12701
 };
 #endif
 
@@ -3477,8 +3460,8 @@ static const yytype_uint8 yyr2[] =
        1,     1,     1,     1,     1,     1
 };
 
-/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
-   Performed when YYTABLE doesn't specify something else to do.  Zero
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
    means the default is an error.  */
 static const yytype_uint16 yydefact[] =
 {
@@ -4473,7 +4456,8 @@ static const yytype_int16 yypgoto[] =
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
-   number is the opposite.  If YYTABLE_NINF, syntax error.  */
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
 #define YYTABLE_NINF -2163
 static const yytype_int16 yytable[] =
 {
@@ -11747,12 +11731,6 @@ static const yytype_int16 yytable[] =
        0,     0,     0,     0,   495,   496,   497
 };
 
-#define yypact_value_is_default(yystate) \
-  ((yystate) == (-3866))
-
-#define yytable_value_is_error(yytable_value) \
-  ((yytable_value) == (-2163))
-
 static const yytype_int16 yycheck[] =
 {
        0,     0,     0,     0,     0,     0,    47,    16,   164,   524,
@@ -19473,18 +19451,9 @@ static const yytype_uint16 yystos[] =
 
 /* Like YYERROR except do call yyerror.  This remains here temporarily
    to ease the transition to the new meaning of YYERROR, for GCC.
-   Once GCC version 2 has supplanted version 1, this can go.  However,
-   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
-   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
-   discussed.  */
+   Once GCC version 2 has supplanted version 1, this can go.  */
 
 #define YYFAIL		goto yyerrlab
-#if defined YYFAIL
-  /* This is here to suppress warnings from the GCC cpp's
-     -Wunused-macros.  Normally we don't worry about that warning, but
-     some users do, and we want to make it easy for users to remove
-     YYFAIL uses, which will produce warnings from Bison 2.5.  */
-#endif
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
@@ -19494,6 +19463,7 @@ do								\
     {								\
       yychar = (Token);						\
       yylval = (Value);						\
+      yytoken = YYTRANSLATE (yychar);				\
       YYPOPSTACK (1);						\
       goto yybackup;						\
     }								\
@@ -19659,20 +19629,17 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, yyscanner)
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static void
-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
 #else
 static void
-yy_stack_print (yybottom, yytop)
-    yytype_int16 *yybottom;
-    yytype_int16 *yytop;
+yy_stack_print (bottom, top)
+    yytype_int16 *bottom;
+    yytype_int16 *top;
 #endif
 {
   YYFPRINTF (stderr, "Stack now");
-  for (; yybottom <= yytop; yybottom++)
-    {
-      int yybot = *yybottom;
-      YYFPRINTF (stderr, " %d", yybot);
-    }
+  for (; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
   YYFPRINTF (stderr, "\n");
 }
 
@@ -19708,11 +19675,11 @@ yy_reduce_print (yyvsp, yylsp, yyrule, yyscanner)
   /* The symbols being reduced.  */
   for (yyi = 0; yyi < yynrhs; yyi++)
     {
-      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
+      fprintf (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
 		       &(yyvsp[(yyi + 1) - (yynrhs)])
 		       , &(yylsp[(yyi + 1) - (yynrhs)])		       , yyscanner);
-      YYFPRINTF (stderr, "\n");
+      fprintf (stderr, "\n");
     }
 }
 
@@ -19749,6 +19716,7 @@ int yydebug;
 # define YYMAXDEPTH 10000
 #endif
 
+
 
 #if YYERROR_VERBOSE
 
@@ -19851,142 +19819,115 @@ yytnamerr (char *yyres, const char *yystr)
 }
 # endif
 
-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
-   about the unexpected token YYTOKEN for the state stack whose top is
-   YYSSP.
-
-   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
-   not large enough to hold the message.  In that case, also set
-   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
-   required number of bytes is too large to store.  */
-static int
-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
-                yytype_int16 *yyssp, int yytoken)
+/* Copy into YYRESULT an error message about the unexpected token
+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
+   including the terminating null byte.  If YYRESULT is null, do not
+   copy anything; just return the number of bytes that would be
+   copied.  As a special case, return 0 if an ordinary "syntax error"
+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
+   size calculation.  */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
 {
-  YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
-  YYSIZE_T yysize = yysize0;
-  YYSIZE_T yysize1;
-  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-  /* Internationalized format string. */
-  const char *yyformat = 0;
-  /* Arguments of yyformat. */
-  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-  /* Number of reported tokens (one for the "unexpected", one per
-     "expected"). */
-  int yycount = 0;
-
-  /* There are many possibilities here to consider:
-     - Assume YYFAIL is not used.  It's too flawed to consider.  See
-       <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
-       for details.  YYERROR is fine as it does not invoke this
-       function.
-     - If this state is a consistent state with a default action, then
-       the only way this function was invoked is if the default action
-       is an error action.  In that case, don't check for expected
-       tokens because there are none.
-     - The only way there can be no lookahead present (in yychar) is if
-       this state is a consistent state with a default action.  Thus,
-       detecting the absence of a lookahead is sufficient to determine
-       that there is no unexpected or expected token to report.  In that
-       case, just report a simple "syntax error".
-     - Don't assume there isn't a lookahead just because this state is a
-       consistent state with a default action.  There might have been a
-       previous inconsistent state, consistent state with a non-default
-       action, or user semantic action that manipulated yychar.
-     - Of course, the expected token list depends on states to have
-       correct lookahead information, and it depends on the parser not
-       to perform extra reductions after fetching a lookahead from the
-       scanner and before detecting a syntax error.  Thus, state merging
-       (from LALR or IELR) and default reductions corrupt the expected
-       token list.  However, the list is correct for canonical LR with
-       one exception: it will still contain any token that will not be
-       accepted due to an error action in a later state.
-  */
-  if (yytoken != YYEMPTY)
-    {
-      int yyn = yypact[*yyssp];
-      yyarg[yycount++] = yytname[yytoken];
-      if (!yypact_value_is_default (yyn))
-        {
-          /* Start YYX at -YYN if negative to avoid negative indexes in
-             YYCHECK.  In other words, skip the first -YYN actions for
-             this state because they are default actions.  */
-          int yyxbegin = yyn < 0 ? -yyn : 0;
-          /* Stay within bounds of both yycheck and yytname.  */
-          int yychecklim = YYLAST - yyn + 1;
-          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-          int yyx;
-
-          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
-                && !yytable_value_is_error (yytable[yyx + yyn]))
-              {
-                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-                  {
-                    yycount = 1;
-                    yysize = yysize0;
-                    break;
-                  }
-                yyarg[yycount++] = yytname[yyx];
-                yysize1 = yysize + yytnamerr (0, yytname[yyx]);
-                if (! (yysize <= yysize1
-                       && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-                  return 2;
-                yysize = yysize1;
-              }
-        }
-    }
+  int yyn = yypact[yystate];
 
-  switch (yycount)
-    {
-# define YYCASE_(N, S)                      \
-      case N:                               \
-        yyformat = S;                       \
-      break
-      YYCASE_(0, YY_("syntax error"));
-      YYCASE_(1, YY_("syntax error, unexpected %s"));
-      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
-      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
-      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
-      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
-# undef YYCASE_
-    }
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+    return 0;
+  else
+    {
+      int yytype = YYTRANSLATE (yychar);
+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+      YYSIZE_T yysize = yysize0;
+      YYSIZE_T yysize1;
+      int yysize_overflow = 0;
+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+      int yyx;
+
+# if 0
+      /* This is so xgettext sees the translatable formats that are
+	 constructed on the fly.  */
+      YY_("syntax error, unexpected %s");
+      YY_("syntax error, unexpected %s, expecting %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+      char *yyfmt;
+      char const *yyf;
+      static char const yyunexpected[] = "syntax error, unexpected %s";
+      static char const yyexpecting[] = ", expecting %s";
+      static char const yyor[] = " or %s";
+      char yyformat[sizeof yyunexpected
+		    + sizeof yyexpecting - 1
+		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+		       * (sizeof yyor - 1))];
+      char const *yyprefix = yyexpecting;
+
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+	 YYCHECK.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yycount = 1;
+
+      yyarg[0] = yytname[yytype];
+      yyfmt = yystpcpy (yyformat, yyunexpected);
+
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	  {
+	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+	      {
+		yycount = 1;
+		yysize = yysize0;
+		yyformat[sizeof yyunexpected - 1] = '\0';
+		break;
+	      }
+	    yyarg[yycount++] = yytname[yyx];
+	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+	    yysize_overflow |= (yysize1 < yysize);
+	    yysize = yysize1;
+	    yyfmt = yystpcpy (yyfmt, yyprefix);
+	    yyprefix = yyor;
+	  }
 
-  yysize1 = yysize + yystrlen (yyformat);
-  if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-    return 2;
-  yysize = yysize1;
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
 
-  if (*yymsg_alloc < yysize)
-    {
-      *yymsg_alloc = 2 * yysize;
-      if (! (yysize <= *yymsg_alloc
-             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
-        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
-      return 1;
-    }
+      if (yysize_overflow)
+	return YYSIZE_MAXIMUM;
 
-  /* Avoid sprintf, as that infringes on the user's name space.
-     Don't have undefined behavior even if the translation
-     produced a string with the wrong number of "%s"s.  */
-  {
-    char *yyp = *yymsg;
-    int yyi = 0;
-    while ((*yyp = *yyformat) != '\0')
-      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
-        {
-          yyp += yytnamerr (yyp, yyarg[yyi++]);
-          yyformat += 2;
-        }
-      else
-        {
-          yyp++;
-          yyformat++;
-        }
-  }
-  return 0;
+      if (yyresult)
+	{
+	  /* Avoid sprintf, as that infringes on the user's name space.
+	     Don't have undefined behavior even if the translation
+	     produced a string with the wrong number of "%s"s.  */
+	  char *yyp = yyresult;
+	  int yyi = 0;
+	  while ((*yyp = *yyf) != '\0')
+	    {
+	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+		{
+		  yyp += yytnamerr (yyp, yyarg[yyi++]);
+		  yyf += 2;
+		}
+	      else
+		{
+		  yyp++;
+		  yyf++;
+		}
+	    }
+	}
+      return yysize;
+    }
 }
 #endif /* YYERROR_VERBOSE */
+
 
 /*-----------------------------------------------.
 | Release the memory associated to this symbol.  |
@@ -20022,9 +19963,10 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp, yyscanner)
 	break;
     }
 }
-
+
 
 /* Prevent warnings from -Wmissing-prototypes.  */
+
 #ifdef YYPARSE_PARAM
 #if defined __STDC__ || defined __cplusplus
 int yyparse (void *YYPARSE_PARAM);
@@ -20040,6 +19982,10 @@ int yyparse ();
 #endif /* ! YYPARSE_PARAM */
 
 
+
+
+
+
 /*----------.
 | yyparse.  |
 `----------*/
@@ -20066,97 +20012,88 @@ yyparse (yyscanner)
 #endif
 #endif
 {
-/* The lookahead symbol.  */
+  /* The look-ahead symbol.  */
 int yychar;
 
-/* The semantic value of the lookahead symbol.  */
+/* The semantic value of the look-ahead symbol.  */
 YYSTYPE yylval;
 
-/* Location data for the lookahead symbol.  */
+/* Number of syntax errors so far.  */
+int yynerrs;
+/* Location data for the look-ahead symbol.  */
 YYLTYPE yylloc;
 
-    /* Number of syntax errors so far.  */
-    int yynerrs;
-
-    int yystate;
-    /* Number of tokens to shift before error messages enabled.  */
-    int yyerrstatus;
+  int yystate;
+  int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
 
-    /* The stacks and their tools:
-       `yyss': related to states.
-       `yyvs': related to semantic values.
-       `yyls': related to locations.
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
 
-       Refer to the stacks thru separate pointers, to allow yyoverflow
-       to reallocate them elsewhere.  */
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
 
-    /* The state stack.  */
-    yytype_int16 yyssa[YYINITDEPTH];
-    yytype_int16 *yyss;
-    yytype_int16 *yyssp;
+  /* The state stack.  */
+  yytype_int16 yyssa[YYINITDEPTH];
+  yytype_int16 *yyss = yyssa;
+  yytype_int16 *yyssp;
 
-    /* The semantic value stack.  */
-    YYSTYPE yyvsa[YYINITDEPTH];
-    YYSTYPE *yyvs;
-    YYSTYPE *yyvsp;
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  YYSTYPE *yyvsp;
 
-    /* The location stack.  */
-    YYLTYPE yylsa[YYINITDEPTH];
-    YYLTYPE *yyls;
-    YYLTYPE *yylsp;
+  /* The location stack.  */
+  YYLTYPE yylsa[YYINITDEPTH];
+  YYLTYPE *yyls = yylsa;
+  YYLTYPE *yylsp;
+  /* The locations where the error started and ended.  */
+  YYLTYPE yyerror_range[2];
 
-    /* The locations where the error started and ended.  */
-    YYLTYPE yyerror_range[3];
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
 
-    YYSIZE_T yystacksize;
+  YYSIZE_T yystacksize = YYINITDEPTH;
 
-  int yyn;
-  int yyresult;
-  /* Lookahead token as an internal (translated) token number.  */
-  int yytoken;
   /* The variables used to return semantic value and location from the
      action routines.  */
   YYSTYPE yyval;
   YYLTYPE yyloc;
 
-#if YYERROR_VERBOSE
-  /* Buffer for error messages, and its allocated size.  */
-  char yymsgbuf[128];
-  char *yymsg = yymsgbuf;
-  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-#endif
-
-#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
-
   /* The number of symbols on the RHS of the reduced rule.
      Keep to zero when no symbol should be popped.  */
   int yylen = 0;
 
-  yytoken = 0;
-  yyss = yyssa;
-  yyvs = yyvsa;
-  yyls = yylsa;
-  yystacksize = YYINITDEPTH;
-
   YYDPRINTF ((stderr, "Starting parse\n"));
 
   yystate = 0;
   yyerrstatus = 0;
   yynerrs = 0;
-  yychar = YYEMPTY; /* Cause a token to be read.  */
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
 
   /* Initialize stack pointers.
      Waste one element of value and location stack
      so that they stay on the same level as the state stack.
      The wasted elements are never initialized.  */
+
   yyssp = yyss;
   yyvsp = yyvs;
   yylsp = yyls;
-
 #if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
   /* Initialize the default location before parsing starts.  */
   yylloc.first_line   = yylloc.last_line   = 1;
-  yylloc.first_column = yylloc.last_column = 1;
+  yylloc.first_column = yylloc.last_column = 0;
 #endif
 
   goto yysetstate;
@@ -20195,7 +20132,6 @@ YYLTYPE yylloc;
 		    &yyvs1, yysize * sizeof (*yyvsp),
 		    &yyls1, yysize * sizeof (*yylsp),
 		    &yystacksize);
-
 	yyls = yyls1;
 	yyss = yyss1;
 	yyvs = yyvs1;
@@ -20217,9 +20153,9 @@ YYLTYPE yylloc;
 	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
 	if (! yyptr)
 	  goto yyexhaustedlab;
-	YYSTACK_RELOCATE (yyss_alloc, yyss);
-	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-	YYSTACK_RELOCATE (yyls_alloc, yyls);
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+	YYSTACK_RELOCATE (yyls);
 #  undef YYSTACK_RELOCATE
 	if (yyss1 != yyssa)
 	  YYSTACK_FREE (yyss1);
@@ -20240,9 +20176,6 @@ YYLTYPE yylloc;
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
 
-  if (yystate == YYFINAL)
-    YYACCEPT;
-
   goto yybackup;
 
 /*-----------.
@@ -20251,16 +20184,16 @@ YYLTYPE yylloc;
 yybackup:
 
   /* Do appropriate processing given the current state.  Read a
-     lookahead token if we need one and don't already have one.  */
+     look-ahead token if we need one and don't already have one.  */
 
-  /* First try to decide what to do without reference to lookahead token.  */
+  /* First try to decide what to do without reference to look-ahead token.  */
   yyn = yypact[yystate];
-  if (yypact_value_is_default (yyn))
+  if (yyn == YYPACT_NINF)
     goto yydefault;
 
-  /* Not known => get a lookahead token if don't already have one.  */
+  /* Not known => get a look-ahead token if don't already have one.  */
 
-  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
   if (yychar == YYEMPTY)
     {
       YYDPRINTF ((stderr, "Reading a token: "));
@@ -20286,22 +20219,26 @@ yybackup:
   yyn = yytable[yyn];
   if (yyn <= 0)
     {
-      if (yytable_value_is_error (yyn))
-        goto yyerrlab;
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
       yyn = -yyn;
       goto yyreduce;
     }
 
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
   /* Count tokens shifted since error; after three, turn off error
      status.  */
   if (yyerrstatus)
     yyerrstatus--;
 
-  /* Shift the lookahead token.  */
+  /* Shift the look-ahead token.  */
   YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
 
-  /* Discard the shifted token.  */
-  yychar = YYEMPTY;
+  /* Discard the shifted token unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
 
   yystate = yyn;
   *++yyvsp = yylval;
@@ -20342,18 +20279,14 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-
-/* Line 1806 of yacc.c  */
-#line 666 "gram.y"
+#line 667 "gram.y"
     {
 				pg_yyget_extra(yyscanner)->parsetree = (yyvsp[(1) - (1)].list);
 			}
     break;
 
   case 3:
-
-/* Line 1806 of yacc.c  */
-#line 673 "gram.y"
+#line 674 "gram.y"
     {
 					if ((yyvsp[(3) - (3)].node) != NULL)
 						(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
@@ -20363,9 +20296,7 @@ yyreduce:
     break;
 
   case 4:
-
-/* Line 1806 of yacc.c  */
-#line 680 "gram.y"
+#line 681 "gram.y"
     {
 					if ((yyvsp[(1) - (1)].node) != NULL)
 						(yyval.list) = list_make1((yyvsp[(1) - (1)].node));
@@ -20375,16 +20306,12 @@ yyreduce:
     break;
 
   case 115:
-
-/* Line 1806 of yacc.c  */
-#line 800 "gram.y"
+#line 801 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 116:
-
-/* Line 1806 of yacc.c  */
-#line 811 "gram.y"
+#line 812 "gram.y"
     {
 					CreateRoleStmt *n = makeNode(CreateRoleStmt);
 					n->stmt_type = ROLESTMT_ROLE;
@@ -20395,51 +20322,37 @@ yyreduce:
     break;
 
   case 117:
-
-/* Line 1806 of yacc.c  */
-#line 821 "gram.y"
+#line 822 "gram.y"
     {}
     break;
 
   case 118:
-
-/* Line 1806 of yacc.c  */
-#line 822 "gram.y"
+#line 823 "gram.y"
     {}
     break;
 
   case 119:
-
-/* Line 1806 of yacc.c  */
-#line 831 "gram.y"
+#line 832 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); }
     break;
 
   case 120:
-
-/* Line 1806 of yacc.c  */
-#line 832 "gram.y"
+#line 833 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 121:
-
-/* Line 1806 of yacc.c  */
-#line 836 "gram.y"
+#line 837 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); }
     break;
 
   case 122:
-
-/* Line 1806 of yacc.c  */
-#line 837 "gram.y"
+#line 838 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 123:
-
-/* Line 1806 of yacc.c  */
-#line 842 "gram.y"
+#line 843 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("password",
 									 (Node *)makeString((yyvsp[(2) - (2)].str)));
@@ -20447,18 +20360,14 @@ yyreduce:
     break;
 
   case 124:
-
-/* Line 1806 of yacc.c  */
-#line 847 "gram.y"
+#line 848 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("password", NULL);
 				}
     break;
 
   case 125:
-
-/* Line 1806 of yacc.c  */
-#line 851 "gram.y"
+#line 852 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("encryptedPassword",
 									 (Node *)makeString((yyvsp[(3) - (3)].str)));
@@ -20466,9 +20375,7 @@ yyreduce:
     break;
 
   case 126:
-
-/* Line 1806 of yacc.c  */
-#line 856 "gram.y"
+#line 857 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("unencryptedPassword",
 									 (Node *)makeString((yyvsp[(3) - (3)].str)));
@@ -20476,45 +20383,35 @@ yyreduce:
     break;
 
   case 127:
-
-/* Line 1806 of yacc.c  */
-#line 861 "gram.y"
+#line 862 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("inherit", (Node *)makeInteger(TRUE));
 				}
     break;
 
   case 128:
-
-/* Line 1806 of yacc.c  */
-#line 865 "gram.y"
+#line 866 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("connectionlimit", (Node *)makeInteger((yyvsp[(3) - (3)].ival)));
 				}
     break;
 
   case 129:
-
-/* Line 1806 of yacc.c  */
-#line 869 "gram.y"
+#line 870 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("validUntil", (Node *)makeString((yyvsp[(3) - (3)].str)));
 				}
     break;
 
   case 130:
-
-/* Line 1806 of yacc.c  */
-#line 874 "gram.y"
+#line 875 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("rolemembers", (Node *)(yyvsp[(2) - (2)].list));
 				}
     break;
 
   case 131:
-
-/* Line 1806 of yacc.c  */
-#line 878 "gram.y"
+#line 879 "gram.y"
     {
 					/*
 					 * We handle identifiers that aren't parser keywords with
@@ -20568,61 +20465,47 @@ yyreduce:
     break;
 
   case 132:
-
-/* Line 1806 of yacc.c  */
-#line 931 "gram.y"
+#line 932 "gram.y"
     { (yyval.defelt) = (yyvsp[(1) - (1)].defelt); }
     break;
 
   case 133:
-
-/* Line 1806 of yacc.c  */
-#line 934 "gram.y"
+#line 935 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("sysid", (Node *)makeInteger((yyvsp[(2) - (2)].ival)));
 				}
     break;
 
   case 134:
-
-/* Line 1806 of yacc.c  */
-#line 938 "gram.y"
+#line 939 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("adminmembers", (Node *)(yyvsp[(2) - (2)].list));
 				}
     break;
 
   case 135:
-
-/* Line 1806 of yacc.c  */
-#line 942 "gram.y"
+#line 943 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("rolemembers", (Node *)(yyvsp[(2) - (2)].list));
 				}
     break;
 
   case 136:
-
-/* Line 1806 of yacc.c  */
-#line 946 "gram.y"
+#line 947 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("addroleto", (Node *)(yyvsp[(3) - (3)].list));
 				}
     break;
 
   case 137:
-
-/* Line 1806 of yacc.c  */
-#line 950 "gram.y"
+#line 951 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("addroleto", (Node *)(yyvsp[(3) - (3)].list));
 				}
     break;
 
   case 138:
-
-/* Line 1806 of yacc.c  */
-#line 964 "gram.y"
+#line 965 "gram.y"
     {
 					CreateRoleStmt *n = makeNode(CreateRoleStmt);
 					n->stmt_type = ROLESTMT_USER;
@@ -20633,9 +20516,7 @@ yyreduce:
     break;
 
   case 139:
-
-/* Line 1806 of yacc.c  */
-#line 982 "gram.y"
+#line 983 "gram.y"
     {
 					AlterRoleStmt *n = makeNode(AlterRoleStmt);
 					n->role = (yyvsp[(3) - (5)].str);
@@ -20646,23 +20527,17 @@ yyreduce:
     break;
 
   case 140:
-
-/* Line 1806 of yacc.c  */
-#line 992 "gram.y"
+#line 993 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 141:
-
-/* Line 1806 of yacc.c  */
-#line 993 "gram.y"
+#line 994 "gram.y"
     { (yyval.str) = (yyvsp[(3) - (3)].str); }
     break;
 
   case 142:
-
-/* Line 1806 of yacc.c  */
-#line 998 "gram.y"
+#line 999 "gram.y"
     {
 					AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
 					n->role = (yyvsp[(3) - (5)].str);
@@ -20673,9 +20548,7 @@ yyreduce:
     break;
 
   case 143:
-
-/* Line 1806 of yacc.c  */
-#line 1016 "gram.y"
+#line 1017 "gram.y"
     {
 					AlterRoleStmt *n = makeNode(AlterRoleStmt);
 					n->role = (yyvsp[(3) - (5)].str);
@@ -20686,9 +20559,7 @@ yyreduce:
     break;
 
   case 144:
-
-/* Line 1806 of yacc.c  */
-#line 1028 "gram.y"
+#line 1029 "gram.y"
     {
 					AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
 					n->role = (yyvsp[(3) - (4)].str);
@@ -20699,9 +20570,7 @@ yyreduce:
     break;
 
   case 145:
-
-/* Line 1806 of yacc.c  */
-#line 1049 "gram.y"
+#line 1050 "gram.y"
     {
 					DropRoleStmt *n = makeNode(DropRoleStmt);
 					n->missing_ok = FALSE;
@@ -20711,9 +20580,7 @@ yyreduce:
     break;
 
   case 146:
-
-/* Line 1806 of yacc.c  */
-#line 1056 "gram.y"
+#line 1057 "gram.y"
     {
 					DropRoleStmt *n = makeNode(DropRoleStmt);
 					n->missing_ok = TRUE;
@@ -20723,9 +20590,7 @@ yyreduce:
     break;
 
   case 147:
-
-/* Line 1806 of yacc.c  */
-#line 1075 "gram.y"
+#line 1076 "gram.y"
     {
 					DropRoleStmt *n = makeNode(DropRoleStmt);
 					n->missing_ok = FALSE;
@@ -20735,9 +20600,7 @@ yyreduce:
     break;
 
   case 148:
-
-/* Line 1806 of yacc.c  */
-#line 1082 "gram.y"
+#line 1083 "gram.y"
     {
 					DropRoleStmt *n = makeNode(DropRoleStmt);
 					n->roles = (yyvsp[(5) - (5)].list);
@@ -20747,9 +20610,7 @@ yyreduce:
     break;
 
   case 149:
-
-/* Line 1806 of yacc.c  */
-#line 1099 "gram.y"
+#line 1100 "gram.y"
     {
 					CreateRoleStmt *n = makeNode(CreateRoleStmt);
 					n->stmt_type = ROLESTMT_GROUP;
@@ -20760,9 +20621,7 @@ yyreduce:
     break;
 
   case 150:
-
-/* Line 1806 of yacc.c  */
-#line 1117 "gram.y"
+#line 1118 "gram.y"
     {
 					AlterRoleStmt *n = makeNode(AlterRoleStmt);
 					n->role = (yyvsp[(3) - (6)].str);
@@ -20774,23 +20633,17 @@ yyreduce:
     break;
 
   case 151:
-
-/* Line 1806 of yacc.c  */
-#line 1127 "gram.y"
+#line 1128 "gram.y"
     { (yyval.ival) = +1; }
     break;
 
   case 152:
-
-/* Line 1806 of yacc.c  */
-#line 1128 "gram.y"
+#line 1129 "gram.y"
     { (yyval.ival) = -1; }
     break;
 
   case 153:
-
-/* Line 1806 of yacc.c  */
-#line 1141 "gram.y"
+#line 1142 "gram.y"
     {
 					DropRoleStmt *n = makeNode(DropRoleStmt);
 					n->missing_ok = FALSE;
@@ -20800,9 +20653,7 @@ yyreduce:
     break;
 
   case 154:
-
-/* Line 1806 of yacc.c  */
-#line 1148 "gram.y"
+#line 1149 "gram.y"
     {
 					DropRoleStmt *n = makeNode(DropRoleStmt);
 					n->missing_ok = TRUE;
@@ -20812,9 +20663,7 @@ yyreduce:
     break;
 
   case 155:
-
-/* Line 1806 of yacc.c  */
-#line 1165 "gram.y"
+#line 1166 "gram.y"
     {
 					CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
 					/* One can omit the schema name or the authorization id. */
@@ -20829,9 +20678,7 @@ yyreduce:
     break;
 
   case 156:
-
-/* Line 1806 of yacc.c  */
-#line 1177 "gram.y"
+#line 1178 "gram.y"
     {
 					CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
 					/* ...but not both */
@@ -20843,37 +20690,27 @@ yyreduce:
     break;
 
   case 157:
-
-/* Line 1806 of yacc.c  */
-#line 1188 "gram.y"
+#line 1189 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 158:
-
-/* Line 1806 of yacc.c  */
-#line 1189 "gram.y"
+#line 1190 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 159:
-
-/* Line 1806 of yacc.c  */
-#line 1193 "gram.y"
+#line 1194 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); }
     break;
 
   case 160:
-
-/* Line 1806 of yacc.c  */
-#line 1194 "gram.y"
+#line 1195 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 167:
-
-/* Line 1806 of yacc.c  */
-#line 1222 "gram.y"
+#line 1223 "gram.y"
     {
 					VariableSetStmt *n = (yyvsp[(2) - (2)].vsetstmt);
 					n->is_local = false;
@@ -20882,9 +20719,7 @@ yyreduce:
     break;
 
   case 168:
-
-/* Line 1806 of yacc.c  */
-#line 1228 "gram.y"
+#line 1229 "gram.y"
     {
 					VariableSetStmt *n = (yyvsp[(3) - (3)].vsetstmt);
 					n->is_local = true;
@@ -20893,9 +20728,7 @@ yyreduce:
     break;
 
   case 169:
-
-/* Line 1806 of yacc.c  */
-#line 1234 "gram.y"
+#line 1235 "gram.y"
     {
 					VariableSetStmt *n = (yyvsp[(3) - (3)].vsetstmt);
 					n->is_local = false;
@@ -20904,9 +20737,7 @@ yyreduce:
     break;
 
   case 170:
-
-/* Line 1806 of yacc.c  */
-#line 1243 "gram.y"
+#line 1244 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_SET_MULTI;
@@ -20917,9 +20748,7 @@ yyreduce:
     break;
 
   case 171:
-
-/* Line 1806 of yacc.c  */
-#line 1251 "gram.y"
+#line 1252 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_SET_MULTI;
@@ -20930,9 +20759,7 @@ yyreduce:
     break;
 
   case 173:
-
-/* Line 1806 of yacc.c  */
-#line 1263 "gram.y"
+#line 1264 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_SET_VALUE;
@@ -20943,9 +20770,7 @@ yyreduce:
     break;
 
   case 174:
-
-/* Line 1806 of yacc.c  */
-#line 1271 "gram.y"
+#line 1272 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_SET_VALUE;
@@ -20956,9 +20781,7 @@ yyreduce:
     break;
 
   case 175:
-
-/* Line 1806 of yacc.c  */
-#line 1279 "gram.y"
+#line 1280 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_SET_DEFAULT;
@@ -20968,9 +20791,7 @@ yyreduce:
     break;
 
   case 176:
-
-/* Line 1806 of yacc.c  */
-#line 1286 "gram.y"
+#line 1287 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_SET_DEFAULT;
@@ -20980,9 +20801,7 @@ yyreduce:
     break;
 
   case 177:
-
-/* Line 1806 of yacc.c  */
-#line 1293 "gram.y"
+#line 1294 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_SET_CURRENT;
@@ -20992,9 +20811,7 @@ yyreduce:
     break;
 
   case 178:
-
-/* Line 1806 of yacc.c  */
-#line 1301 "gram.y"
+#line 1302 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_SET_VALUE;
@@ -21008,9 +20825,7 @@ yyreduce:
     break;
 
   case 179:
-
-/* Line 1806 of yacc.c  */
-#line 1312 "gram.y"
+#line 1313 "gram.y"
     {
 					ereport(ERROR,
 							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -21021,9 +20836,7 @@ yyreduce:
     break;
 
   case 180:
-
-/* Line 1806 of yacc.c  */
-#line 1320 "gram.y"
+#line 1321 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_SET_VALUE;
@@ -21034,9 +20847,7 @@ yyreduce:
     break;
 
   case 181:
-
-/* Line 1806 of yacc.c  */
-#line 1328 "gram.y"
+#line 1329 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_SET_VALUE;
@@ -21050,9 +20861,7 @@ yyreduce:
     break;
 
   case 182:
-
-/* Line 1806 of yacc.c  */
-#line 1339 "gram.y"
+#line 1340 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_SET_VALUE;
@@ -21063,9 +20872,7 @@ yyreduce:
     break;
 
   case 183:
-
-/* Line 1806 of yacc.c  */
-#line 1347 "gram.y"
+#line 1348 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_SET_VALUE;
@@ -21076,9 +20883,7 @@ yyreduce:
     break;
 
   case 184:
-
-/* Line 1806 of yacc.c  */
-#line 1355 "gram.y"
+#line 1356 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_SET_DEFAULT;
@@ -21088,9 +20893,7 @@ yyreduce:
     break;
 
   case 185:
-
-/* Line 1806 of yacc.c  */
-#line 1362 "gram.y"
+#line 1363 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_SET_VALUE;
@@ -21101,9 +20904,7 @@ yyreduce:
     break;
 
   case 186:
-
-/* Line 1806 of yacc.c  */
-#line 1371 "gram.y"
+#line 1372 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_SET_MULTI;
@@ -21114,16 +20915,12 @@ yyreduce:
     break;
 
   case 187:
-
-/* Line 1806 of yacc.c  */
-#line 1380 "gram.y"
+#line 1381 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 188:
-
-/* Line 1806 of yacc.c  */
-#line 1382 "gram.y"
+#line 1383 "gram.y"
     {
 					(yyval.str) = palloc(strlen((yyvsp[(1) - (3)].str)) + strlen((yyvsp[(3) - (3)].str)) + 2);
 					sprintf((yyval.str), "%s.%s", (yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str));
@@ -21131,111 +20928,81 @@ yyreduce:
     break;
 
   case 189:
-
-/* Line 1806 of yacc.c  */
-#line 1388 "gram.y"
+#line 1389 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); }
     break;
 
   case 190:
-
-/* Line 1806 of yacc.c  */
-#line 1389 "gram.y"
+#line 1390 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); }
     break;
 
   case 191:
-
-/* Line 1806 of yacc.c  */
-#line 1393 "gram.y"
+#line 1394 "gram.y"
     { (yyval.node) = makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); }
     break;
 
   case 192:
-
-/* Line 1806 of yacc.c  */
-#line 1395 "gram.y"
+#line 1396 "gram.y"
     { (yyval.node) = makeAConst((yyvsp[(1) - (1)].value), (yylsp[(1) - (1)])); }
     break;
 
   case 193:
-
-/* Line 1806 of yacc.c  */
-#line 1398 "gram.y"
+#line 1399 "gram.y"
     { (yyval.str) = "read uncommitted"; }
     break;
 
   case 194:
-
-/* Line 1806 of yacc.c  */
-#line 1399 "gram.y"
+#line 1400 "gram.y"
     { (yyval.str) = "read committed"; }
     break;
 
   case 195:
-
-/* Line 1806 of yacc.c  */
-#line 1400 "gram.y"
+#line 1401 "gram.y"
     { (yyval.str) = "repeatable read"; }
     break;
 
   case 196:
-
-/* Line 1806 of yacc.c  */
-#line 1401 "gram.y"
+#line 1402 "gram.y"
     { (yyval.str) = "serializable"; }
     break;
 
   case 197:
-
-/* Line 1806 of yacc.c  */
-#line 1405 "gram.y"
+#line 1406 "gram.y"
     { (yyval.str) = "true"; }
     break;
 
   case 198:
-
-/* Line 1806 of yacc.c  */
-#line 1406 "gram.y"
+#line 1407 "gram.y"
     { (yyval.str) = "false"; }
     break;
 
   case 199:
-
-/* Line 1806 of yacc.c  */
-#line 1407 "gram.y"
+#line 1408 "gram.y"
     { (yyval.str) = "on"; }
     break;
 
   case 200:
-
-/* Line 1806 of yacc.c  */
-#line 1413 "gram.y"
+#line 1414 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 201:
-
-/* Line 1806 of yacc.c  */
-#line 1426 "gram.y"
+#line 1427 "gram.y"
     {
 					(yyval.node) = makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)]));
 				}
     break;
 
   case 202:
-
-/* Line 1806 of yacc.c  */
-#line 1430 "gram.y"
+#line 1431 "gram.y"
     {
 					(yyval.node) = makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)]));
 				}
     break;
 
   case 203:
-
-/* Line 1806 of yacc.c  */
-#line 1434 "gram.y"
+#line 1435 "gram.y"
     {
 					TypeName *t = (yyvsp[(1) - (3)].typnam);
 					if ((yyvsp[(3) - (3)].list) != NIL)
@@ -21253,9 +21020,7 @@ yyreduce:
     break;
 
   case 204:
-
-/* Line 1806 of yacc.c  */
-#line 1449 "gram.y"
+#line 1450 "gram.y"
     {
 					TypeName *t = (yyvsp[(1) - (6)].typnam);
 					if ((yyvsp[(6) - (6)].list) != NIL)
@@ -21281,65 +21046,47 @@ yyreduce:
     break;
 
   case 205:
-
-/* Line 1806 of yacc.c  */
-#line 1471 "gram.y"
+#line 1472 "gram.y"
     { (yyval.node) = makeAConst((yyvsp[(1) - (1)].value), (yylsp[(1) - (1)])); }
     break;
 
   case 206:
-
-/* Line 1806 of yacc.c  */
-#line 1472 "gram.y"
+#line 1473 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 207:
-
-/* Line 1806 of yacc.c  */
-#line 1473 "gram.y"
+#line 1474 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 208:
-
-/* Line 1806 of yacc.c  */
-#line 1477 "gram.y"
+#line 1478 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 209:
-
-/* Line 1806 of yacc.c  */
-#line 1478 "gram.y"
+#line 1479 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 210:
-
-/* Line 1806 of yacc.c  */
-#line 1479 "gram.y"
+#line 1480 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 211:
-
-/* Line 1806 of yacc.c  */
-#line 1483 "gram.y"
+#line 1484 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 212:
-
-/* Line 1806 of yacc.c  */
-#line 1484 "gram.y"
+#line 1485 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 213:
-
-/* Line 1806 of yacc.c  */
-#line 1489 "gram.y"
+#line 1490 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_RESET;
@@ -21349,9 +21096,7 @@ yyreduce:
     break;
 
   case 214:
-
-/* Line 1806 of yacc.c  */
-#line 1496 "gram.y"
+#line 1497 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_RESET;
@@ -21361,9 +21106,7 @@ yyreduce:
     break;
 
   case 215:
-
-/* Line 1806 of yacc.c  */
-#line 1503 "gram.y"
+#line 1504 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_RESET;
@@ -21373,9 +21116,7 @@ yyreduce:
     break;
 
   case 216:
-
-/* Line 1806 of yacc.c  */
-#line 1510 "gram.y"
+#line 1511 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_RESET;
@@ -21385,9 +21126,7 @@ yyreduce:
     break;
 
   case 217:
-
-/* Line 1806 of yacc.c  */
-#line 1517 "gram.y"
+#line 1518 "gram.y"
     {
 					VariableSetStmt *n = makeNode(VariableSetStmt);
 					n->kind = VAR_RESET_ALL;
@@ -21396,37 +21135,27 @@ yyreduce:
     break;
 
   case 218:
-
-/* Line 1806 of yacc.c  */
-#line 1526 "gram.y"
+#line 1527 "gram.y"
     { (yyval.vsetstmt) = (yyvsp[(2) - (2)].vsetstmt); }
     break;
 
   case 219:
-
-/* Line 1806 of yacc.c  */
-#line 1527 "gram.y"
+#line 1528 "gram.y"
     { (yyval.vsetstmt) = (VariableSetStmt *) (yyvsp[(1) - (1)].node); }
     break;
 
   case 220:
-
-/* Line 1806 of yacc.c  */
-#line 1532 "gram.y"
+#line 1533 "gram.y"
     { (yyval.vsetstmt) = (yyvsp[(2) - (2)].vsetstmt); }
     break;
 
   case 221:
-
-/* Line 1806 of yacc.c  */
-#line 1533 "gram.y"
+#line 1534 "gram.y"
     { (yyval.vsetstmt) = (VariableSetStmt *) (yyvsp[(1) - (1)].node); }
     break;
 
   case 222:
-
-/* Line 1806 of yacc.c  */
-#line 1539 "gram.y"
+#line 1540 "gram.y"
     {
 					VariableShowStmt *n = makeNode(VariableShowStmt);
 					n->name = (yyvsp[(2) - (2)].str);
@@ -21435,9 +21164,7 @@ yyreduce:
     break;
 
   case 223:
-
-/* Line 1806 of yacc.c  */
-#line 1545 "gram.y"
+#line 1546 "gram.y"
     {
 					VariableShowStmt *n = makeNode(VariableShowStmt);
 					n->name = "timezone";
@@ -21446,9 +21173,7 @@ yyreduce:
     break;
 
   case 224:
-
-/* Line 1806 of yacc.c  */
-#line 1551 "gram.y"
+#line 1552 "gram.y"
     {
 					VariableShowStmt *n = makeNode(VariableShowStmt);
 					n->name = "transaction_isolation";
@@ -21457,9 +21182,7 @@ yyreduce:
     break;
 
   case 225:
-
-/* Line 1806 of yacc.c  */
-#line 1557 "gram.y"
+#line 1558 "gram.y"
     {
 					VariableShowStmt *n = makeNode(VariableShowStmt);
 					n->name = "session_authorization";
@@ -21468,9 +21191,7 @@ yyreduce:
     break;
 
   case 226:
-
-/* Line 1806 of yacc.c  */
-#line 1563 "gram.y"
+#line 1564 "gram.y"
     {
 					VariableShowStmt *n = makeNode(VariableShowStmt);
 					n->name = "all";
@@ -21479,9 +21200,7 @@ yyreduce:
     break;
 
   case 227:
-
-/* Line 1806 of yacc.c  */
-#line 1573 "gram.y"
+#line 1574 "gram.y"
     {
 					ConstraintsSetStmt *n = makeNode(ConstraintsSetStmt);
 					n->constraints = (yyvsp[(3) - (4)].list);
@@ -21491,37 +21210,27 @@ yyreduce:
     break;
 
   case 228:
-
-/* Line 1806 of yacc.c  */
-#line 1582 "gram.y"
+#line 1583 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 229:
-
-/* Line 1806 of yacc.c  */
-#line 1583 "gram.y"
+#line 1584 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 230:
-
-/* Line 1806 of yacc.c  */
-#line 1587 "gram.y"
+#line 1588 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 231:
-
-/* Line 1806 of yacc.c  */
-#line 1588 "gram.y"
+#line 1589 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 232:
-
-/* Line 1806 of yacc.c  */
-#line 1597 "gram.y"
+#line 1598 "gram.y"
     {
 					CheckPointStmt *n = makeNode(CheckPointStmt);
 					(yyval.node) = (Node *)n;
@@ -21529,9 +21238,7 @@ yyreduce:
     break;
 
   case 233:
-
-/* Line 1806 of yacc.c  */
-#line 1612 "gram.y"
+#line 1613 "gram.y"
     {
 					DiscardStmt *n = makeNode(DiscardStmt);
 					n->target = DISCARD_ALL;
@@ -21540,9 +21247,7 @@ yyreduce:
     break;
 
   case 234:
-
-/* Line 1806 of yacc.c  */
-#line 1618 "gram.y"
+#line 1619 "gram.y"
     {
 					DiscardStmt *n = makeNode(DiscardStmt);
 					n->target = DISCARD_TEMP;
@@ -21551,9 +21256,7 @@ yyreduce:
     break;
 
   case 235:
-
-/* Line 1806 of yacc.c  */
-#line 1624 "gram.y"
+#line 1625 "gram.y"
     {
 					DiscardStmt *n = makeNode(DiscardStmt);
 					n->target = DISCARD_TEMP;
@@ -21562,9 +21265,7 @@ yyreduce:
     break;
 
   case 236:
-
-/* Line 1806 of yacc.c  */
-#line 1630 "gram.y"
+#line 1631 "gram.y"
     {
 					DiscardStmt *n = makeNode(DiscardStmt);
 					n->target = DISCARD_PLANS;
@@ -21573,9 +21274,7 @@ yyreduce:
     break;
 
   case 237:
-
-/* Line 1806 of yacc.c  */
-#line 1648 "gram.y"
+#line 1649 "gram.y"
     {
 					AlterTableStmt *n = makeNode(AlterTableStmt);
 					n->relation = (yyvsp[(3) - (4)].range);
@@ -21587,9 +21286,7 @@ yyreduce:
     break;
 
   case 238:
-
-/* Line 1806 of yacc.c  */
-#line 1657 "gram.y"
+#line 1658 "gram.y"
     {
 					AlterTableStmt *n = makeNode(AlterTableStmt);
 					n->relation = (yyvsp[(5) - (6)].range);
@@ -21601,9 +21298,7 @@ yyreduce:
     break;
 
   case 239:
-
-/* Line 1806 of yacc.c  */
-#line 1666 "gram.y"
+#line 1667 "gram.y"
     {
 					AlterTableStmt *n = makeNode(AlterTableStmt);
 					n->relation = (yyvsp[(3) - (4)].range);
@@ -21615,9 +21310,7 @@ yyreduce:
     break;
 
   case 240:
-
-/* Line 1806 of yacc.c  */
-#line 1675 "gram.y"
+#line 1676 "gram.y"
     {
 					AlterTableStmt *n = makeNode(AlterTableStmt);
 					n->relation = (yyvsp[(5) - (6)].range);
@@ -21629,9 +21322,7 @@ yyreduce:
     break;
 
   case 241:
-
-/* Line 1806 of yacc.c  */
-#line 1684 "gram.y"
+#line 1685 "gram.y"
     {
 					AlterTableStmt *n = makeNode(AlterTableStmt);
 					n->relation = (yyvsp[(3) - (4)].range);
@@ -21643,9 +21334,7 @@ yyreduce:
     break;
 
   case 242:
-
-/* Line 1806 of yacc.c  */
-#line 1693 "gram.y"
+#line 1694 "gram.y"
     {
 					AlterTableStmt *n = makeNode(AlterTableStmt);
 					n->relation = (yyvsp[(5) - (6)].range);
@@ -21657,9 +21346,7 @@ yyreduce:
     break;
 
   case 243:
-
-/* Line 1806 of yacc.c  */
-#line 1702 "gram.y"
+#line 1703 "gram.y"
     {
 					AlterTableStmt *n = makeNode(AlterTableStmt);
 					n->relation = (yyvsp[(3) - (4)].range);
@@ -21671,9 +21358,7 @@ yyreduce:
     break;
 
   case 244:
-
-/* Line 1806 of yacc.c  */
-#line 1711 "gram.y"
+#line 1712 "gram.y"
     {
 					AlterTableStmt *n = makeNode(AlterTableStmt);
 					n->relation = (yyvsp[(5) - (6)].range);
@@ -21685,23 +21370,17 @@ yyreduce:
     break;
 
   case 245:
-
-/* Line 1806 of yacc.c  */
-#line 1722 "gram.y"
+#line 1723 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); }
     break;
 
   case 246:
-
-/* Line 1806 of yacc.c  */
-#line 1723 "gram.y"
+#line 1724 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); }
     break;
 
   case 247:
-
-/* Line 1806 of yacc.c  */
-#line 1729 "gram.y"
+#line 1730 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_AddColumn;
@@ -21711,9 +21390,7 @@ yyreduce:
     break;
 
   case 248:
-
-/* Line 1806 of yacc.c  */
-#line 1737 "gram.y"
+#line 1738 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_AddColumn;
@@ -21723,9 +21400,7 @@ yyreduce:
     break;
 
   case 249:
-
-/* Line 1806 of yacc.c  */
-#line 1745 "gram.y"
+#line 1746 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_ColumnDefault;
@@ -21736,9 +21411,7 @@ yyreduce:
     break;
 
   case 250:
-
-/* Line 1806 of yacc.c  */
-#line 1754 "gram.y"
+#line 1755 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_DropNotNull;
@@ -21748,9 +21421,7 @@ yyreduce:
     break;
 
   case 251:
-
-/* Line 1806 of yacc.c  */
-#line 1762 "gram.y"
+#line 1763 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_SetNotNull;
@@ -21760,9 +21431,7 @@ yyreduce:
     break;
 
   case 252:
-
-/* Line 1806 of yacc.c  */
-#line 1770 "gram.y"
+#line 1771 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_SetStatistics;
@@ -21773,9 +21442,7 @@ yyreduce:
     break;
 
   case 253:
-
-/* Line 1806 of yacc.c  */
-#line 1779 "gram.y"
+#line 1780 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_SetOptions;
@@ -21786,9 +21453,7 @@ yyreduce:
     break;
 
   case 254:
-
-/* Line 1806 of yacc.c  */
-#line 1788 "gram.y"
+#line 1789 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_ResetOptions;
@@ -21799,9 +21464,7 @@ yyreduce:
     break;
 
   case 255:
-
-/* Line 1806 of yacc.c  */
-#line 1797 "gram.y"
+#line 1798 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_SetStorage;
@@ -21812,9 +21475,7 @@ yyreduce:
     break;
 
   case 256:
-
-/* Line 1806 of yacc.c  */
-#line 1806 "gram.y"
+#line 1807 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_DropColumn;
@@ -21826,9 +21487,7 @@ yyreduce:
     break;
 
   case 257:
-
-/* Line 1806 of yacc.c  */
-#line 1816 "gram.y"
+#line 1817 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_DropColumn;
@@ -21840,9 +21499,7 @@ yyreduce:
     break;
 
   case 258:
-
-/* Line 1806 of yacc.c  */
-#line 1829 "gram.y"
+#line 1830 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					ColumnDef *def = makeNode(ColumnDef);
@@ -21858,9 +21515,7 @@ yyreduce:
     break;
 
   case 259:
-
-/* Line 1806 of yacc.c  */
-#line 1843 "gram.y"
+#line 1844 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_AlterColumnGenericOptions;
@@ -21871,9 +21526,7 @@ yyreduce:
     break;
 
   case 260:
-
-/* Line 1806 of yacc.c  */
-#line 1852 "gram.y"
+#line 1853 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_AddConstraint;
@@ -21883,9 +21536,7 @@ yyreduce:
     break;
 
   case 261:
-
-/* Line 1806 of yacc.c  */
-#line 1860 "gram.y"
+#line 1861 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_ValidateConstraint;
@@ -21895,9 +21546,7 @@ yyreduce:
     break;
 
   case 262:
-
-/* Line 1806 of yacc.c  */
-#line 1868 "gram.y"
+#line 1869 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_DropConstraint;
@@ -21909,9 +21558,7 @@ yyreduce:
     break;
 
   case 263:
-
-/* Line 1806 of yacc.c  */
-#line 1878 "gram.y"
+#line 1879 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_DropConstraint;
@@ -21923,9 +21570,7 @@ yyreduce:
     break;
 
   case 264:
-
-/* Line 1806 of yacc.c  */
-#line 1888 "gram.y"
+#line 1889 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_AddOids;
@@ -21934,9 +21579,7 @@ yyreduce:
     break;
 
   case 265:
-
-/* Line 1806 of yacc.c  */
-#line 1895 "gram.y"
+#line 1896 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_DropOids;
@@ -21945,9 +21588,7 @@ yyreduce:
     break;
 
   case 266:
-
-/* Line 1806 of yacc.c  */
-#line 1902 "gram.y"
+#line 1903 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_ClusterOn;
@@ -21957,9 +21598,7 @@ yyreduce:
     break;
 
   case 267:
-
-/* Line 1806 of yacc.c  */
-#line 1910 "gram.y"
+#line 1911 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_DropCluster;
@@ -21969,9 +21608,7 @@ yyreduce:
     break;
 
   case 268:
-
-/* Line 1806 of yacc.c  */
-#line 1918 "gram.y"
+#line 1919 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_EnableTrig;
@@ -21981,9 +21618,7 @@ yyreduce:
     break;
 
   case 269:
-
-/* Line 1806 of yacc.c  */
-#line 1926 "gram.y"
+#line 1927 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_EnableAlwaysTrig;
@@ -21993,9 +21628,7 @@ yyreduce:
     break;
 
   case 270:
-
-/* Line 1806 of yacc.c  */
-#line 1934 "gram.y"
+#line 1935 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_EnableReplicaTrig;
@@ -22005,9 +21638,7 @@ yyreduce:
     break;
 
   case 271:
-
-/* Line 1806 of yacc.c  */
-#line 1942 "gram.y"
+#line 1943 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_EnableTrigAll;
@@ -22016,9 +21647,7 @@ yyreduce:
     break;
 
   case 272:
-
-/* Line 1806 of yacc.c  */
-#line 1949 "gram.y"
+#line 1950 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_EnableTrigUser;
@@ -22027,9 +21656,7 @@ yyreduce:
     break;
 
   case 273:
-
-/* Line 1806 of yacc.c  */
-#line 1956 "gram.y"
+#line 1957 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_DisableTrig;
@@ -22039,9 +21666,7 @@ yyreduce:
     break;
 
   case 274:
-
-/* Line 1806 of yacc.c  */
-#line 1964 "gram.y"
+#line 1965 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_DisableTrigAll;
@@ -22050,9 +21675,7 @@ yyreduce:
     break;
 
   case 275:
-
-/* Line 1806 of yacc.c  */
-#line 1971 "gram.y"
+#line 1972 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_DisableTrigUser;
@@ -22061,9 +21684,7 @@ yyreduce:
     break;
 
   case 276:
-
-/* Line 1806 of yacc.c  */
-#line 1978 "gram.y"
+#line 1979 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_EnableRule;
@@ -22073,9 +21694,7 @@ yyreduce:
     break;
 
   case 277:
-
-/* Line 1806 of yacc.c  */
-#line 1986 "gram.y"
+#line 1987 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_EnableAlwaysRule;
@@ -22085,9 +21704,7 @@ yyreduce:
     break;
 
   case 278:
-
-/* Line 1806 of yacc.c  */
-#line 1994 "gram.y"
+#line 1995 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_EnableReplicaRule;
@@ -22097,9 +21714,7 @@ yyreduce:
     break;
 
   case 279:
-
-/* Line 1806 of yacc.c  */
-#line 2002 "gram.y"
+#line 2003 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_DisableRule;
@@ -22109,9 +21724,7 @@ yyreduce:
     break;
 
   case 280:
-
-/* Line 1806 of yacc.c  */
-#line 2010 "gram.y"
+#line 2011 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_AddInherit;
@@ -22121,9 +21734,7 @@ yyreduce:
     break;
 
   case 281:
-
-/* Line 1806 of yacc.c  */
-#line 2018 "gram.y"
+#line 2019 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_DropInherit;
@@ -22133,9 +21744,7 @@ yyreduce:
     break;
 
   case 282:
-
-/* Line 1806 of yacc.c  */
-#line 2026 "gram.y"
+#line 2027 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					TypeName *def = makeTypeNameFromNameList((yyvsp[(2) - (2)].list));
@@ -22147,9 +21756,7 @@ yyreduce:
     break;
 
   case 283:
-
-/* Line 1806 of yacc.c  */
-#line 2036 "gram.y"
+#line 2037 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_DropOf;
@@ -22158,9 +21765,7 @@ yyreduce:
     break;
 
   case 284:
-
-/* Line 1806 of yacc.c  */
-#line 2043 "gram.y"
+#line 2044 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_ChangeOwner;
@@ -22170,9 +21775,7 @@ yyreduce:
     break;
 
   case 285:
-
-/* Line 1806 of yacc.c  */
-#line 2051 "gram.y"
+#line 2052 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_SetTableSpace;
@@ -22182,9 +21785,7 @@ yyreduce:
     break;
 
   case 286:
-
-/* Line 1806 of yacc.c  */
-#line 2059 "gram.y"
+#line 2060 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_SetRelOptions;
@@ -22194,9 +21795,7 @@ yyreduce:
     break;
 
   case 287:
-
-/* Line 1806 of yacc.c  */
-#line 2067 "gram.y"
+#line 2068 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_ResetRelOptions;
@@ -22206,9 +21805,7 @@ yyreduce:
     break;
 
   case 288:
-
-/* Line 1806 of yacc.c  */
-#line 2074 "gram.y"
+#line 2075 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_GenericOptions;
@@ -22218,44 +21815,32 @@ yyreduce:
     break;
 
   case 289:
-
-/* Line 1806 of yacc.c  */
-#line 2083 "gram.y"
+#line 2084 "gram.y"
     { (yyval.node) = (yyvsp[(3) - (3)].node); }
     break;
 
   case 290:
-
-/* Line 1806 of yacc.c  */
-#line 2084 "gram.y"
+#line 2085 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 291:
-
-/* Line 1806 of yacc.c  */
-#line 2088 "gram.y"
+#line 2089 "gram.y"
     { (yyval.dbehavior) = DROP_CASCADE; }
     break;
 
   case 292:
-
-/* Line 1806 of yacc.c  */
-#line 2089 "gram.y"
+#line 2090 "gram.y"
     { (yyval.dbehavior) = DROP_RESTRICT; }
     break;
 
   case 293:
-
-/* Line 1806 of yacc.c  */
-#line 2090 "gram.y"
+#line 2091 "gram.y"
     { (yyval.dbehavior) = DROP_RESTRICT; /* default */ }
     break;
 
   case 294:
-
-/* Line 1806 of yacc.c  */
-#line 2095 "gram.y"
+#line 2096 "gram.y"
     {
 					CollateClause *n = makeNode(CollateClause);
 					n->arg = NULL;
@@ -22266,83 +21851,61 @@ yyreduce:
     break;
 
   case 295:
-
-/* Line 1806 of yacc.c  */
-#line 2102 "gram.y"
+#line 2103 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 296:
-
-/* Line 1806 of yacc.c  */
-#line 2106 "gram.y"
+#line 2107 "gram.y"
     { (yyval.node) = (yyvsp[(2) - (2)].node); }
     break;
 
   case 297:
-
-/* Line 1806 of yacc.c  */
-#line 2107 "gram.y"
+#line 2108 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 298:
-
-/* Line 1806 of yacc.c  */
-#line 2111 "gram.y"
+#line 2112 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (3)].list); }
     break;
 
   case 299:
-
-/* Line 1806 of yacc.c  */
-#line 2114 "gram.y"
+#line 2115 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (2)].list); }
     break;
 
   case 300:
-
-/* Line 1806 of yacc.c  */
-#line 2115 "gram.y"
+#line 2116 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 301:
-
-/* Line 1806 of yacc.c  */
-#line 2119 "gram.y"
+#line 2120 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); }
     break;
 
   case 302:
-
-/* Line 1806 of yacc.c  */
-#line 2120 "gram.y"
+#line 2121 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt)); }
     break;
 
   case 303:
-
-/* Line 1806 of yacc.c  */
-#line 2126 "gram.y"
+#line 2127 "gram.y"
     {
 					(yyval.defelt) = makeDefElem((yyvsp[(1) - (3)].str), (Node *) (yyvsp[(3) - (3)].node));
 				}
     break;
 
   case 304:
-
-/* Line 1806 of yacc.c  */
-#line 2130 "gram.y"
+#line 2131 "gram.y"
     {
 					(yyval.defelt) = makeDefElem((yyvsp[(1) - (1)].str), NULL);
 				}
     break;
 
   case 305:
-
-/* Line 1806 of yacc.c  */
-#line 2134 "gram.y"
+#line 2135 "gram.y"
     {
 					(yyval.defelt) = makeDefElemExtended((yyvsp[(1) - (5)].str), (yyvsp[(3) - (5)].str), (Node *) (yyvsp[(5) - (5)].node),
 											 DEFELEM_UNSPEC);
@@ -22350,18 +21913,14 @@ yyreduce:
     break;
 
   case 306:
-
-/* Line 1806 of yacc.c  */
-#line 2139 "gram.y"
+#line 2140 "gram.y"
     {
 					(yyval.defelt) = makeDefElemExtended((yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str), NULL, DEFELEM_UNSPEC);
 				}
     break;
 
   case 307:
-
-/* Line 1806 of yacc.c  */
-#line 2154 "gram.y"
+#line 2155 "gram.y"
     {
 					AlterTableStmt *n = makeNode(AlterTableStmt);
 
@@ -22374,23 +21933,17 @@ yyreduce:
     break;
 
   case 308:
-
-/* Line 1806 of yacc.c  */
-#line 2166 "gram.y"
+#line 2167 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); }
     break;
 
   case 309:
-
-/* Line 1806 of yacc.c  */
-#line 2167 "gram.y"
+#line 2168 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); }
     break;
 
   case 310:
-
-/* Line 1806 of yacc.c  */
-#line 2173 "gram.y"
+#line 2174 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_AddColumn;
@@ -22401,9 +21954,7 @@ yyreduce:
     break;
 
   case 311:
-
-/* Line 1806 of yacc.c  */
-#line 2182 "gram.y"
+#line 2183 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_DropColumn;
@@ -22415,9 +21966,7 @@ yyreduce:
     break;
 
   case 312:
-
-/* Line 1806 of yacc.c  */
-#line 2192 "gram.y"
+#line 2193 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					n->subtype = AT_DropColumn;
@@ -22429,9 +21978,7 @@ yyreduce:
     break;
 
   case 313:
-
-/* Line 1806 of yacc.c  */
-#line 2202 "gram.y"
+#line 2203 "gram.y"
     {
 					AlterTableCmd *n = makeNode(AlterTableCmd);
 					ColumnDef *def = makeNode(ColumnDef);
@@ -22448,9 +21995,7 @@ yyreduce:
     break;
 
   case 314:
-
-/* Line 1806 of yacc.c  */
-#line 2227 "gram.y"
+#line 2228 "gram.y"
     {
 					ClosePortalStmt *n = makeNode(ClosePortalStmt);
 					n->portalname = (yyvsp[(2) - (2)].str);
@@ -22459,9 +22004,7 @@ yyreduce:
     break;
 
   case 315:
-
-/* Line 1806 of yacc.c  */
-#line 2233 "gram.y"
+#line 2234 "gram.y"
     {
 					ClosePortalStmt *n = makeNode(ClosePortalStmt);
 					n->portalname = NULL;
@@ -22470,9 +22013,7 @@ yyreduce:
     break;
 
   case 316:
-
-/* Line 1806 of yacc.c  */
-#line 2261 "gram.y"
+#line 2262 "gram.y"
     {
 					CopyStmt *n = makeNode(CopyStmt);
 					n->relation = (yyvsp[(3) - (10)].range);
@@ -22496,9 +22037,7 @@ yyreduce:
     break;
 
   case 317:
-
-/* Line 1806 of yacc.c  */
-#line 2282 "gram.y"
+#line 2283 "gram.y"
     {
 					CopyStmt *n = makeNode(CopyStmt);
 					n->relation = NULL;
@@ -22512,329 +22051,247 @@ yyreduce:
     break;
 
   case 318:
-
-/* Line 1806 of yacc.c  */
-#line 2295 "gram.y"
+#line 2296 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 319:
-
-/* Line 1806 of yacc.c  */
-#line 2296 "gram.y"
+#line 2297 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 320:
-
-/* Line 1806 of yacc.c  */
-#line 2305 "gram.y"
+#line 2306 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 321:
-
-/* Line 1806 of yacc.c  */
-#line 2306 "gram.y"
+#line 2307 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 322:
-
-/* Line 1806 of yacc.c  */
-#line 2307 "gram.y"
+#line 2308 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 323:
-
-/* Line 1806 of yacc.c  */
-#line 2310 "gram.y"
+#line 2311 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 324:
-
-/* Line 1806 of yacc.c  */
-#line 2311 "gram.y"
+#line 2312 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (3)].list); }
     break;
 
   case 325:
-
-/* Line 1806 of yacc.c  */
-#line 2316 "gram.y"
+#line 2317 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); }
     break;
 
   case 326:
-
-/* Line 1806 of yacc.c  */
-#line 2317 "gram.y"
+#line 2318 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 327:
-
-/* Line 1806 of yacc.c  */
-#line 2322 "gram.y"
+#line 2323 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("format", (Node *)makeString("binary"));
 				}
     break;
 
   case 328:
-
-/* Line 1806 of yacc.c  */
-#line 2326 "gram.y"
+#line 2327 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("oids", (Node *)makeInteger(TRUE));
 				}
     break;
 
   case 329:
-
-/* Line 1806 of yacc.c  */
-#line 2330 "gram.y"
+#line 2331 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("delimiter", (Node *)makeString((yyvsp[(3) - (3)].str)));
 				}
     break;
 
   case 330:
-
-/* Line 1806 of yacc.c  */
-#line 2334 "gram.y"
+#line 2335 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("null", (Node *)makeString((yyvsp[(3) - (3)].str)));
 				}
     break;
 
   case 331:
-
-/* Line 1806 of yacc.c  */
-#line 2338 "gram.y"
+#line 2339 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("format", (Node *)makeString("csv"));
 				}
     break;
 
   case 332:
-
-/* Line 1806 of yacc.c  */
-#line 2342 "gram.y"
+#line 2343 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("header", (Node *)makeInteger(TRUE));
 				}
     break;
 
   case 333:
-
-/* Line 1806 of yacc.c  */
-#line 2346 "gram.y"
+#line 2347 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("quote", (Node *)makeString((yyvsp[(3) - (3)].str)));
 				}
     break;
 
   case 334:
-
-/* Line 1806 of yacc.c  */
-#line 2350 "gram.y"
+#line 2351 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("escape", (Node *)makeString((yyvsp[(3) - (3)].str)));
 				}
     break;
 
   case 335:
-
-/* Line 1806 of yacc.c  */
-#line 2354 "gram.y"
+#line 2355 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("force_quote", (Node *)(yyvsp[(3) - (3)].list));
 				}
     break;
 
   case 336:
-
-/* Line 1806 of yacc.c  */
-#line 2358 "gram.y"
+#line 2359 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("force_quote", (Node *)makeNode(A_Star));
 				}
     break;
 
   case 337:
-
-/* Line 1806 of yacc.c  */
-#line 2362 "gram.y"
+#line 2363 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("force_not_null", (Node *)(yyvsp[(4) - (4)].list));
 				}
     break;
 
   case 338:
-
-/* Line 1806 of yacc.c  */
-#line 2366 "gram.y"
+#line 2367 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("encoding", (Node *)makeString((yyvsp[(2) - (2)].str)));
 				}
     break;
 
   case 339:
-
-/* Line 1806 of yacc.c  */
-#line 2375 "gram.y"
+#line 2376 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("format", (Node *)makeString("binary"));
 				}
     break;
 
   case 340:
-
-/* Line 1806 of yacc.c  */
-#line 2378 "gram.y"
+#line 2379 "gram.y"
     { (yyval.defelt) = NULL; }
     break;
 
   case 341:
-
-/* Line 1806 of yacc.c  */
-#line 2383 "gram.y"
+#line 2384 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("oids", (Node *)makeInteger(TRUE));
 				}
     break;
 
   case 342:
-
-/* Line 1806 of yacc.c  */
-#line 2386 "gram.y"
+#line 2387 "gram.y"
     { (yyval.defelt) = NULL; }
     break;
 
   case 343:
-
-/* Line 1806 of yacc.c  */
-#line 2391 "gram.y"
+#line 2392 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("delimiter", (Node *)makeString((yyvsp[(3) - (3)].str)));
 				}
     break;
 
   case 344:
-
-/* Line 1806 of yacc.c  */
-#line 2394 "gram.y"
+#line 2395 "gram.y"
     { (yyval.defelt) = NULL; }
     break;
 
   case 345:
-
-/* Line 1806 of yacc.c  */
-#line 2398 "gram.y"
+#line 2399 "gram.y"
     {}
     break;
 
   case 346:
-
-/* Line 1806 of yacc.c  */
-#line 2399 "gram.y"
+#line 2400 "gram.y"
     {}
     break;
 
   case 347:
-
-/* Line 1806 of yacc.c  */
-#line 2405 "gram.y"
+#line 2406 "gram.y"
     {
 					(yyval.list) = list_make1((yyvsp[(1) - (1)].defelt));
 				}
     break;
 
   case 348:
-
-/* Line 1806 of yacc.c  */
-#line 2409 "gram.y"
+#line 2410 "gram.y"
     {
 					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt));
 				}
     break;
 
   case 349:
-
-/* Line 1806 of yacc.c  */
-#line 2416 "gram.y"
+#line 2417 "gram.y"
     {
 					(yyval.defelt) = makeDefElem((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].node));
 				}
     break;
 
   case 350:
-
-/* Line 1806 of yacc.c  */
-#line 2422 "gram.y"
+#line 2423 "gram.y"
     { (yyval.node) = (Node *) makeString((yyvsp[(1) - (1)].str)); }
     break;
 
   case 351:
-
-/* Line 1806 of yacc.c  */
-#line 2423 "gram.y"
+#line 2424 "gram.y"
     { (yyval.node) = (Node *) (yyvsp[(1) - (1)].value); }
     break;
 
   case 352:
-
-/* Line 1806 of yacc.c  */
-#line 2424 "gram.y"
+#line 2425 "gram.y"
     { (yyval.node) = (Node *) makeNode(A_Star); }
     break;
 
   case 353:
-
-/* Line 1806 of yacc.c  */
-#line 2425 "gram.y"
+#line 2426 "gram.y"
     { (yyval.node) = (Node *) (yyvsp[(2) - (3)].list); }
     break;
 
   case 354:
-
-/* Line 1806 of yacc.c  */
-#line 2426 "gram.y"
+#line 2427 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 355:
-
-/* Line 1806 of yacc.c  */
-#line 2431 "gram.y"
+#line 2432 "gram.y"
     {
 					(yyval.list) = list_make1((yyvsp[(1) - (1)].node));
 				}
     break;
 
   case 356:
-
-/* Line 1806 of yacc.c  */
-#line 2435 "gram.y"
+#line 2436 "gram.y"
     {
 					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 				}
     break;
 
   case 357:
-
-/* Line 1806 of yacc.c  */
-#line 2442 "gram.y"
+#line 2443 "gram.y"
     { (yyval.node) = (Node *) makeString((yyvsp[(1) - (1)].str)); }
     break;
 
   case 358:
-
-/* Line 1806 of yacc.c  */
-#line 2455 "gram.y"
+#line 2456 "gram.y"
     {
 					CreateStmt *n = makeNode(CreateStmt);
 					(yyvsp[(4) - (11)].range)->relpersistence = (yyvsp[(2) - (11)].ival);
@@ -22851,9 +22308,7 @@ yyreduce:
     break;
 
   case 359:
-
-/* Line 1806 of yacc.c  */
-#line 2471 "gram.y"
+#line 2472 "gram.y"
     {
 					CreateStmt *n = makeNode(CreateStmt);
 					(yyvsp[(7) - (14)].range)->relpersistence = (yyvsp[(2) - (14)].ival);
@@ -22870,9 +22325,7 @@ yyreduce:
     break;
 
   case 360:
-
-/* Line 1806 of yacc.c  */
-#line 2486 "gram.y"
+#line 2487 "gram.y"
     {
 					CreateStmt *n = makeNode(CreateStmt);
 					(yyvsp[(4) - (10)].range)->relpersistence = (yyvsp[(2) - (10)].ival);
@@ -22890,9 +22343,7 @@ yyreduce:
     break;
 
   case 361:
-
-/* Line 1806 of yacc.c  */
-#line 2502 "gram.y"
+#line 2503 "gram.y"
     {
 					CreateStmt *n = makeNode(CreateStmt);
 					(yyvsp[(7) - (13)].range)->relpersistence = (yyvsp[(2) - (13)].ival);
@@ -22910,37 +22361,27 @@ yyreduce:
     break;
 
   case 362:
-
-/* Line 1806 of yacc.c  */
-#line 2529 "gram.y"
+#line 2530 "gram.y"
     { (yyval.ival) = RELPERSISTENCE_TEMP; }
     break;
 
   case 363:
-
-/* Line 1806 of yacc.c  */
-#line 2530 "gram.y"
+#line 2531 "gram.y"
     { (yyval.ival) = RELPERSISTENCE_TEMP; }
     break;
 
   case 364:
-
-/* Line 1806 of yacc.c  */
-#line 2531 "gram.y"
+#line 2532 "gram.y"
     { (yyval.ival) = RELPERSISTENCE_TEMP; }
     break;
 
   case 365:
-
-/* Line 1806 of yacc.c  */
-#line 2532 "gram.y"
+#line 2533 "gram.y"
     { (yyval.ival) = RELPERSISTENCE_TEMP; }
     break;
 
   case 366:
-
-/* Line 1806 of yacc.c  */
-#line 2534 "gram.y"
+#line 2535 "gram.y"
     {
 					ereport(WARNING,
 							(errmsg("GLOBAL is deprecated in temporary table creation"),
@@ -22950,9 +22391,7 @@ yyreduce:
     break;
 
   case 367:
-
-/* Line 1806 of yacc.c  */
-#line 2541 "gram.y"
+#line 2542 "gram.y"
     {
 					ereport(WARNING,
 							(errmsg("GLOBAL is deprecated in temporary table creation"),
@@ -22962,122 +22401,90 @@ yyreduce:
     break;
 
   case 368:
-
-/* Line 1806 of yacc.c  */
-#line 2547 "gram.y"
+#line 2548 "gram.y"
     { (yyval.ival) = RELPERSISTENCE_UNLOGGED; }
     break;
 
   case 369:
-
-/* Line 1806 of yacc.c  */
-#line 2548 "gram.y"
+#line 2549 "gram.y"
     { (yyval.ival) = RELPERSISTENCE_PERMANENT; }
     break;
 
   case 370:
-
-/* Line 1806 of yacc.c  */
-#line 2552 "gram.y"
+#line 2553 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 371:
-
-/* Line 1806 of yacc.c  */
-#line 2553 "gram.y"
+#line 2554 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 372:
-
-/* Line 1806 of yacc.c  */
-#line 2557 "gram.y"
+#line 2558 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (3)].list); }
     break;
 
   case 373:
-
-/* Line 1806 of yacc.c  */
-#line 2558 "gram.y"
+#line 2559 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 374:
-
-/* Line 1806 of yacc.c  */
-#line 2563 "gram.y"
+#line 2564 "gram.y"
     {
 					(yyval.list) = list_make1((yyvsp[(1) - (1)].node));
 				}
     break;
 
   case 375:
-
-/* Line 1806 of yacc.c  */
-#line 2567 "gram.y"
+#line 2568 "gram.y"
     {
 					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 				}
     break;
 
   case 376:
-
-/* Line 1806 of yacc.c  */
-#line 2574 "gram.y"
+#line 2575 "gram.y"
     {
 					(yyval.list) = list_make1((yyvsp[(1) - (1)].node));
 				}
     break;
 
   case 377:
-
-/* Line 1806 of yacc.c  */
-#line 2578 "gram.y"
+#line 2579 "gram.y"
     {
 					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 				}
     break;
 
   case 378:
-
-/* Line 1806 of yacc.c  */
-#line 2584 "gram.y"
+#line 2585 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 379:
-
-/* Line 1806 of yacc.c  */
-#line 2585 "gram.y"
+#line 2586 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 380:
-
-/* Line 1806 of yacc.c  */
-#line 2586 "gram.y"
+#line 2587 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 381:
-
-/* Line 1806 of yacc.c  */
-#line 2590 "gram.y"
+#line 2591 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 382:
-
-/* Line 1806 of yacc.c  */
-#line 2591 "gram.y"
+#line 2592 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 383:
-
-/* Line 1806 of yacc.c  */
-#line 2595 "gram.y"
+#line 2596 "gram.y"
     {
 					ColumnDef *n = makeNode(ColumnDef);
 					n->colname = (yyvsp[(1) - (4)].str);
@@ -23098,9 +22505,7 @@ yyreduce:
     break;
 
   case 384:
-
-/* Line 1806 of yacc.c  */
-#line 2615 "gram.y"
+#line 2616 "gram.y"
     {
 					ColumnDef *n = makeNode(ColumnDef);
 					n->colname = (yyvsp[(1) - (4)].str);
@@ -23120,23 +22525,17 @@ yyreduce:
     break;
 
   case 385:
-
-/* Line 1806 of yacc.c  */
-#line 2634 "gram.y"
+#line 2635 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); }
     break;
 
   case 386:
-
-/* Line 1806 of yacc.c  */
-#line 2635 "gram.y"
+#line 2636 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 387:
-
-/* Line 1806 of yacc.c  */
-#line 2640 "gram.y"
+#line 2641 "gram.y"
     {
 					Constraint *n = (Constraint *) (yyvsp[(3) - (3)].node);
 					Assert(IsA(n, Constraint));
@@ -23147,23 +22546,17 @@ yyreduce:
     break;
 
   case 388:
-
-/* Line 1806 of yacc.c  */
-#line 2647 "gram.y"
+#line 2648 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 389:
-
-/* Line 1806 of yacc.c  */
-#line 2648 "gram.y"
+#line 2649 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 390:
-
-/* Line 1806 of yacc.c  */
-#line 2650 "gram.y"
+#line 2651 "gram.y"
     {
 					/*
 					 * Note: the CollateClause is momentarily included in
@@ -23179,9 +22572,7 @@ yyreduce:
     break;
 
   case 391:
-
-/* Line 1806 of yacc.c  */
-#line 2681 "gram.y"
+#line 2682 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_NOTNULL;
@@ -23191,9 +22582,7 @@ yyreduce:
     break;
 
   case 392:
-
-/* Line 1806 of yacc.c  */
-#line 2688 "gram.y"
+#line 2689 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_NULL;
@@ -23203,9 +22592,7 @@ yyreduce:
     break;
 
   case 393:
-
-/* Line 1806 of yacc.c  */
-#line 2695 "gram.y"
+#line 2696 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_UNIQUE;
@@ -23219,9 +22606,7 @@ yyreduce:
     break;
 
   case 394:
-
-/* Line 1806 of yacc.c  */
-#line 2706 "gram.y"
+#line 2707 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_PRIMARY;
@@ -23235,9 +22620,7 @@ yyreduce:
     break;
 
   case 395:
-
-/* Line 1806 of yacc.c  */
-#line 2717 "gram.y"
+#line 2718 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_CHECK;
@@ -23250,9 +22633,7 @@ yyreduce:
     break;
 
   case 396:
-
-/* Line 1806 of yacc.c  */
-#line 2727 "gram.y"
+#line 2728 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_DEFAULT;
@@ -23264,9 +22645,7 @@ yyreduce:
     break;
 
   case 397:
-
-/* Line 1806 of yacc.c  */
-#line 2736 "gram.y"
+#line 2737 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_FOREIGN;
@@ -23284,9 +22663,7 @@ yyreduce:
     break;
 
   case 398:
-
-/* Line 1806 of yacc.c  */
-#line 2769 "gram.y"
+#line 2770 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_ATTR_DEFERRABLE;
@@ -23296,9 +22673,7 @@ yyreduce:
     break;
 
   case 399:
-
-/* Line 1806 of yacc.c  */
-#line 2776 "gram.y"
+#line 2777 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_ATTR_NOT_DEFERRABLE;
@@ -23308,9 +22683,7 @@ yyreduce:
     break;
 
   case 400:
-
-/* Line 1806 of yacc.c  */
-#line 2783 "gram.y"
+#line 2784 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_ATTR_DEFERRED;
@@ -23320,9 +22693,7 @@ yyreduce:
     break;
 
   case 401:
-
-/* Line 1806 of yacc.c  */
-#line 2790 "gram.y"
+#line 2791 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_ATTR_IMMEDIATE;
@@ -23332,9 +22703,7 @@ yyreduce:
     break;
 
   case 402:
-
-/* Line 1806 of yacc.c  */
-#line 2801 "gram.y"
+#line 2802 "gram.y"
     {
 					TableLikeClause *n = makeNode(TableLikeClause);
 					n->relation = (yyvsp[(2) - (3)].range);
@@ -23344,72 +22713,52 @@ yyreduce:
     break;
 
   case 403:
-
-/* Line 1806 of yacc.c  */
-#line 2810 "gram.y"
+#line 2811 "gram.y"
     { (yyval.ival) = (yyvsp[(1) - (3)].ival) | (yyvsp[(3) - (3)].ival); }
     break;
 
   case 404:
-
-/* Line 1806 of yacc.c  */
-#line 2811 "gram.y"
+#line 2812 "gram.y"
     { (yyval.ival) = (yyvsp[(1) - (3)].ival) & ~(yyvsp[(3) - (3)].ival); }
     break;
 
   case 405:
-
-/* Line 1806 of yacc.c  */
-#line 2812 "gram.y"
+#line 2813 "gram.y"
     { (yyval.ival) = 0; }
     break;
 
   case 406:
-
-/* Line 1806 of yacc.c  */
-#line 2816 "gram.y"
+#line 2817 "gram.y"
     { (yyval.ival) = CREATE_TABLE_LIKE_DEFAULTS; }
     break;
 
   case 407:
-
-/* Line 1806 of yacc.c  */
-#line 2817 "gram.y"
+#line 2818 "gram.y"
     { (yyval.ival) = CREATE_TABLE_LIKE_CONSTRAINTS; }
     break;
 
   case 408:
-
-/* Line 1806 of yacc.c  */
-#line 2818 "gram.y"
+#line 2819 "gram.y"
     { (yyval.ival) = CREATE_TABLE_LIKE_INDEXES; }
     break;
 
   case 409:
-
-/* Line 1806 of yacc.c  */
-#line 2819 "gram.y"
+#line 2820 "gram.y"
     { (yyval.ival) = CREATE_TABLE_LIKE_STORAGE; }
     break;
 
   case 410:
-
-/* Line 1806 of yacc.c  */
-#line 2820 "gram.y"
+#line 2821 "gram.y"
     { (yyval.ival) = CREATE_TABLE_LIKE_COMMENTS; }
     break;
 
   case 411:
-
-/* Line 1806 of yacc.c  */
-#line 2821 "gram.y"
+#line 2822 "gram.y"
     { (yyval.ival) = CREATE_TABLE_LIKE_ALL; }
     break;
 
   case 412:
-
-/* Line 1806 of yacc.c  */
-#line 2831 "gram.y"
+#line 2832 "gram.y"
     {
 					Constraint *n = (Constraint *) (yyvsp[(3) - (3)].node);
 					Assert(IsA(n, Constraint));
@@ -23420,16 +22769,12 @@ yyreduce:
     break;
 
   case 413:
-
-/* Line 1806 of yacc.c  */
-#line 2838 "gram.y"
+#line 2839 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 414:
-
-/* Line 1806 of yacc.c  */
-#line 2843 "gram.y"
+#line 2844 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_CHECK;
@@ -23445,9 +22790,7 @@ yyreduce:
     break;
 
   case 415:
-
-/* Line 1806 of yacc.c  */
-#line 2857 "gram.y"
+#line 2858 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_UNIQUE;
@@ -23464,9 +22807,7 @@ yyreduce:
     break;
 
   case 416:
-
-/* Line 1806 of yacc.c  */
-#line 2871 "gram.y"
+#line 2872 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_UNIQUE;
@@ -23483,9 +22824,7 @@ yyreduce:
     break;
 
   case 417:
-
-/* Line 1806 of yacc.c  */
-#line 2886 "gram.y"
+#line 2887 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_PRIMARY;
@@ -23502,9 +22841,7 @@ yyreduce:
     break;
 
   case 418:
-
-/* Line 1806 of yacc.c  */
-#line 2900 "gram.y"
+#line 2901 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_PRIMARY;
@@ -23521,9 +22858,7 @@ yyreduce:
     break;
 
   case 419:
-
-/* Line 1806 of yacc.c  */
-#line 2916 "gram.y"
+#line 2917 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_EXCLUSION;
@@ -23542,9 +22877,7 @@ yyreduce:
     break;
 
   case 420:
-
-/* Line 1806 of yacc.c  */
-#line 2933 "gram.y"
+#line 2934 "gram.y"
     {
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_FOREIGN;
@@ -23565,69 +22898,51 @@ yyreduce:
     break;
 
   case 421:
-
-/* Line 1806 of yacc.c  */
-#line 2952 "gram.y"
+#line 2953 "gram.y"
     {  (yyval.boolean) = TRUE; }
     break;
 
   case 422:
-
-/* Line 1806 of yacc.c  */
-#line 2953 "gram.y"
+#line 2954 "gram.y"
     {  (yyval.boolean) = FALSE; }
     break;
 
   case 423:
-
-/* Line 1806 of yacc.c  */
-#line 2957 "gram.y"
+#line 2958 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (3)].list); }
     break;
 
   case 424:
-
-/* Line 1806 of yacc.c  */
-#line 2958 "gram.y"
+#line 2959 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 425:
-
-/* Line 1806 of yacc.c  */
-#line 2962 "gram.y"
+#line 2963 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); }
     break;
 
   case 426:
-
-/* Line 1806 of yacc.c  */
-#line 2963 "gram.y"
+#line 2964 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); }
     break;
 
   case 427:
-
-/* Line 1806 of yacc.c  */
-#line 2967 "gram.y"
+#line 2968 "gram.y"
     {
 					(yyval.node) = (Node *) makeString((yyvsp[(1) - (1)].str));
 				}
     break;
 
   case 428:
-
-/* Line 1806 of yacc.c  */
-#line 2973 "gram.y"
+#line 2974 "gram.y"
     {
 				(yyval.ival) = FKCONSTR_MATCH_FULL;
 			}
     break;
 
   case 429:
-
-/* Line 1806 of yacc.c  */
-#line 2977 "gram.y"
+#line 2978 "gram.y"
     {
 				ereport(ERROR,
 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -23638,262 +22953,190 @@ yyreduce:
     break;
 
   case 430:
-
-/* Line 1806 of yacc.c  */
-#line 2985 "gram.y"
+#line 2986 "gram.y"
     {
 				(yyval.ival) = FKCONSTR_MATCH_UNSPECIFIED;
 			}
     break;
 
   case 431:
-
-/* Line 1806 of yacc.c  */
-#line 2989 "gram.y"
+#line 2990 "gram.y"
     {
 				(yyval.ival) = FKCONSTR_MATCH_UNSPECIFIED;
 			}
     break;
 
   case 432:
-
-/* Line 1806 of yacc.c  */
-#line 2995 "gram.y"
+#line 2996 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].list)); }
     break;
 
   case 433:
-
-/* Line 1806 of yacc.c  */
-#line 2997 "gram.y"
+#line 2998 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); }
     break;
 
   case 434:
-
-/* Line 1806 of yacc.c  */
-#line 3001 "gram.y"
+#line 3002 "gram.y"
     {
 				(yyval.list) = list_make2((yyvsp[(1) - (3)].ielem), (yyvsp[(3) - (3)].list));
 			}
     break;
 
   case 435:
-
-/* Line 1806 of yacc.c  */
-#line 3006 "gram.y"
+#line 3007 "gram.y"
     {
 				(yyval.list) = list_make2((yyvsp[(1) - (6)].ielem), (yyvsp[(5) - (6)].list));
 			}
     break;
 
   case 436:
-
-/* Line 1806 of yacc.c  */
-#line 3012 "gram.y"
+#line 3013 "gram.y"
     { (yyval.node) = (yyvsp[(3) - (4)].node); }
     break;
 
   case 437:
-
-/* Line 1806 of yacc.c  */
-#line 3013 "gram.y"
+#line 3014 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 438:
-
-/* Line 1806 of yacc.c  */
-#line 3024 "gram.y"
+#line 3025 "gram.y"
     { (yyval.ival) = ((yyvsp[(1) - (1)].ival) << 8) | (FKCONSTR_ACTION_NOACTION & 0xFF); }
     break;
 
   case 439:
-
-/* Line 1806 of yacc.c  */
-#line 3026 "gram.y"
+#line 3027 "gram.y"
     { (yyval.ival) = (FKCONSTR_ACTION_NOACTION << 8) | ((yyvsp[(1) - (1)].ival) & 0xFF); }
     break;
 
   case 440:
-
-/* Line 1806 of yacc.c  */
-#line 3028 "gram.y"
+#line 3029 "gram.y"
     { (yyval.ival) = ((yyvsp[(1) - (2)].ival) << 8) | ((yyvsp[(2) - (2)].ival) & 0xFF); }
     break;
 
   case 441:
-
-/* Line 1806 of yacc.c  */
-#line 3030 "gram.y"
+#line 3031 "gram.y"
     { (yyval.ival) = ((yyvsp[(2) - (2)].ival) << 8) | ((yyvsp[(1) - (2)].ival) & 0xFF); }
     break;
 
   case 442:
-
-/* Line 1806 of yacc.c  */
-#line 3032 "gram.y"
+#line 3033 "gram.y"
     { (yyval.ival) = (FKCONSTR_ACTION_NOACTION << 8) | (FKCONSTR_ACTION_NOACTION & 0xFF); }
     break;
 
   case 443:
-
-/* Line 1806 of yacc.c  */
-#line 3035 "gram.y"
+#line 3036 "gram.y"
     { (yyval.ival) = (yyvsp[(3) - (3)].ival); }
     break;
 
   case 444:
-
-/* Line 1806 of yacc.c  */
-#line 3038 "gram.y"
+#line 3039 "gram.y"
     { (yyval.ival) = (yyvsp[(3) - (3)].ival); }
     break;
 
   case 445:
-
-/* Line 1806 of yacc.c  */
-#line 3042 "gram.y"
+#line 3043 "gram.y"
     { (yyval.ival) = FKCONSTR_ACTION_NOACTION; }
     break;
 
   case 446:
-
-/* Line 1806 of yacc.c  */
-#line 3043 "gram.y"
+#line 3044 "gram.y"
     { (yyval.ival) = FKCONSTR_ACTION_RESTRICT; }
     break;
 
   case 447:
-
-/* Line 1806 of yacc.c  */
-#line 3044 "gram.y"
+#line 3045 "gram.y"
     { (yyval.ival) = FKCONSTR_ACTION_CASCADE; }
     break;
 
   case 448:
-
-/* Line 1806 of yacc.c  */
-#line 3045 "gram.y"
+#line 3046 "gram.y"
     { (yyval.ival) = FKCONSTR_ACTION_SETNULL; }
     break;
 
   case 449:
-
-/* Line 1806 of yacc.c  */
-#line 3046 "gram.y"
+#line 3047 "gram.y"
     { (yyval.ival) = FKCONSTR_ACTION_SETDEFAULT; }
     break;
 
   case 450:
-
-/* Line 1806 of yacc.c  */
-#line 3049 "gram.y"
+#line 3050 "gram.y"
     { (yyval.list) = (yyvsp[(3) - (4)].list); }
     break;
 
   case 451:
-
-/* Line 1806 of yacc.c  */
-#line 3050 "gram.y"
+#line 3051 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 452:
-
-/* Line 1806 of yacc.c  */
-#line 3055 "gram.y"
+#line 3056 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (2)].list); }
     break;
 
   case 453:
-
-/* Line 1806 of yacc.c  */
-#line 3056 "gram.y"
+#line 3057 "gram.y"
     { (yyval.list) = list_make1(defWithOids(true)); }
     break;
 
   case 454:
-
-/* Line 1806 of yacc.c  */
-#line 3057 "gram.y"
+#line 3058 "gram.y"
     { (yyval.list) = list_make1(defWithOids(false)); }
     break;
 
   case 455:
-
-/* Line 1806 of yacc.c  */
-#line 3058 "gram.y"
+#line 3059 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 456:
-
-/* Line 1806 of yacc.c  */
-#line 3061 "gram.y"
+#line 3062 "gram.y"
     { (yyval.oncommit) = ONCOMMIT_DROP; }
     break;
 
   case 457:
-
-/* Line 1806 of yacc.c  */
-#line 3062 "gram.y"
+#line 3063 "gram.y"
     { (yyval.oncommit) = ONCOMMIT_DELETE_ROWS; }
     break;
 
   case 458:
-
-/* Line 1806 of yacc.c  */
-#line 3063 "gram.y"
+#line 3064 "gram.y"
     { (yyval.oncommit) = ONCOMMIT_PRESERVE_ROWS; }
     break;
 
   case 459:
-
-/* Line 1806 of yacc.c  */
-#line 3064 "gram.y"
+#line 3065 "gram.y"
     { (yyval.oncommit) = ONCOMMIT_NOOP; }
     break;
 
   case 460:
-
-/* Line 1806 of yacc.c  */
-#line 3067 "gram.y"
+#line 3068 "gram.y"
     { (yyval.str) = (yyvsp[(2) - (2)].str); }
     break;
 
   case 461:
-
-/* Line 1806 of yacc.c  */
-#line 3068 "gram.y"
+#line 3069 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 462:
-
-/* Line 1806 of yacc.c  */
-#line 3071 "gram.y"
+#line 3072 "gram.y"
     { (yyval.str) = (yyvsp[(4) - (4)].str); }
     break;
 
   case 463:
-
-/* Line 1806 of yacc.c  */
-#line 3072 "gram.y"
+#line 3073 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 464:
-
-/* Line 1806 of yacc.c  */
-#line 3075 "gram.y"
+#line 3076 "gram.y"
     { (yyval.str) = (yyvsp[(3) - (3)].str); }
     break;
 
   case 465:
-
-/* Line 1806 of yacc.c  */
-#line 3091 "gram.y"
+#line 3092 "gram.y"
     {
 					CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt);
 					ctas->query = (yyvsp[(6) - (7)].node);
@@ -23907,9 +23150,7 @@ yyreduce:
     break;
 
   case 466:
-
-/* Line 1806 of yacc.c  */
-#line 3105 "gram.y"
+#line 3106 "gram.y"
     {
 					(yyval.into) = makeNode(IntoClause);
 					(yyval.into)->rel = (yyvsp[(1) - (5)].range);
@@ -23922,30 +23163,22 @@ yyreduce:
     break;
 
   case 467:
-
-/* Line 1806 of yacc.c  */
-#line 3117 "gram.y"
+#line 3118 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 468:
-
-/* Line 1806 of yacc.c  */
-#line 3118 "gram.y"
+#line 3119 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 469:
-
-/* Line 1806 of yacc.c  */
-#line 3119 "gram.y"
+#line 3120 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 470:
-
-/* Line 1806 of yacc.c  */
-#line 3133 "gram.y"
+#line 3134 "gram.y"
     {
 					CreateSeqStmt *n = makeNode(CreateSeqStmt);
 					(yyvsp[(4) - (5)].range)->relpersistence = (yyvsp[(2) - (5)].ival);
@@ -23957,9 +23190,7 @@ yyreduce:
     break;
 
   case 471:
-
-/* Line 1806 of yacc.c  */
-#line 3145 "gram.y"
+#line 3146 "gram.y"
     {
 					AlterSeqStmt *n = makeNode(AlterSeqStmt);
 					n->sequence = (yyvsp[(3) - (4)].range);
@@ -23970,9 +23201,7 @@ yyreduce:
     break;
 
   case 472:
-
-/* Line 1806 of yacc.c  */
-#line 3153 "gram.y"
+#line 3154 "gram.y"
     {
 					AlterSeqStmt *n = makeNode(AlterSeqStmt);
 					n->sequence = (yyvsp[(5) - (6)].range);
@@ -23983,166 +23212,126 @@ yyreduce:
     break;
 
   case 473:
-
-/* Line 1806 of yacc.c  */
-#line 3163 "gram.y"
+#line 3164 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 474:
-
-/* Line 1806 of yacc.c  */
-#line 3164 "gram.y"
+#line 3165 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 475:
-
-/* Line 1806 of yacc.c  */
-#line 3167 "gram.y"
+#line 3168 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); }
     break;
 
   case 476:
-
-/* Line 1806 of yacc.c  */
-#line 3168 "gram.y"
+#line 3169 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); }
     break;
 
   case 477:
-
-/* Line 1806 of yacc.c  */
-#line 3172 "gram.y"
+#line 3173 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("cache", (Node *)(yyvsp[(2) - (2)].value));
 				}
     break;
 
   case 478:
-
-/* Line 1806 of yacc.c  */
-#line 3176 "gram.y"
+#line 3177 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("cycle", (Node *)makeInteger(TRUE));
 				}
     break;
 
   case 479:
-
-/* Line 1806 of yacc.c  */
-#line 3180 "gram.y"
+#line 3181 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("cycle", (Node *)makeInteger(FALSE));
 				}
     break;
 
   case 480:
-
-/* Line 1806 of yacc.c  */
-#line 3184 "gram.y"
+#line 3185 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("increment", (Node *)(yyvsp[(3) - (3)].value));
 				}
     break;
 
   case 481:
-
-/* Line 1806 of yacc.c  */
-#line 3188 "gram.y"
+#line 3189 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("maxvalue", (Node *)(yyvsp[(2) - (2)].value));
 				}
     break;
 
   case 482:
-
-/* Line 1806 of yacc.c  */
-#line 3192 "gram.y"
+#line 3193 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("minvalue", (Node *)(yyvsp[(2) - (2)].value));
 				}
     break;
 
   case 483:
-
-/* Line 1806 of yacc.c  */
-#line 3196 "gram.y"
+#line 3197 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("maxvalue", NULL);
 				}
     break;
 
   case 484:
-
-/* Line 1806 of yacc.c  */
-#line 3200 "gram.y"
+#line 3201 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("minvalue", NULL);
 				}
     break;
 
   case 485:
-
-/* Line 1806 of yacc.c  */
-#line 3204 "gram.y"
+#line 3205 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("owned_by", (Node *)(yyvsp[(3) - (3)].list));
 				}
     break;
 
   case 486:
-
-/* Line 1806 of yacc.c  */
-#line 3208 "gram.y"
+#line 3209 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("start", (Node *)(yyvsp[(3) - (3)].value));
 				}
     break;
 
   case 487:
-
-/* Line 1806 of yacc.c  */
-#line 3212 "gram.y"
+#line 3213 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("restart", NULL);
 				}
     break;
 
   case 488:
-
-/* Line 1806 of yacc.c  */
-#line 3216 "gram.y"
+#line 3217 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("restart", (Node *)(yyvsp[(3) - (3)].value));
 				}
     break;
 
   case 489:
-
-/* Line 1806 of yacc.c  */
-#line 3221 "gram.y"
+#line 3222 "gram.y"
     {}
     break;
 
   case 490:
-
-/* Line 1806 of yacc.c  */
-#line 3222 "gram.y"
+#line 3223 "gram.y"
     {}
     break;
 
   case 491:
-
-/* Line 1806 of yacc.c  */
-#line 3226 "gram.y"
+#line 3227 "gram.y"
     { (yyval.value) = makeFloat((yyvsp[(1) - (1)].str)); }
     break;
 
   case 492:
-
-/* Line 1806 of yacc.c  */
-#line 3228 "gram.y"
+#line 3229 "gram.y"
     {
 					(yyval.value) = makeFloat((yyvsp[(2) - (2)].str));
 					doNegateFloat((yyval.value));
@@ -24150,30 +23339,22 @@ yyreduce:
     break;
 
   case 493:
-
-/* Line 1806 of yacc.c  */
-#line 3232 "gram.y"
+#line 3233 "gram.y"
     { (yyval.value) = makeInteger((yyvsp[(1) - (1)].ival)); }
     break;
 
   case 494:
-
-/* Line 1806 of yacc.c  */
-#line 3235 "gram.y"
+#line 3236 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].value)); }
     break;
 
   case 495:
-
-/* Line 1806 of yacc.c  */
-#line 3236 "gram.y"
+#line 3237 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].value)); }
     break;
 
   case 496:
-
-/* Line 1806 of yacc.c  */
-#line 3249 "gram.y"
+#line 3250 "gram.y"
     {
 				CreatePLangStmt *n = makeNode(CreatePLangStmt);
 				n->replace = (yyvsp[(2) - (6)].boolean);
@@ -24188,9 +23369,7 @@ yyreduce:
     break;
 
   case 497:
-
-/* Line 1806 of yacc.c  */
-#line 3262 "gram.y"
+#line 3263 "gram.y"
     {
 				CreatePLangStmt *n = makeNode(CreatePLangStmt);
 				n->replace = (yyvsp[(2) - (10)].boolean);
@@ -24204,79 +23383,57 @@ yyreduce:
     break;
 
   case 498:
-
-/* Line 1806 of yacc.c  */
-#line 3275 "gram.y"
+#line 3276 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 499:
-
-/* Line 1806 of yacc.c  */
-#line 3276 "gram.y"
+#line 3277 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 500:
-
-/* Line 1806 of yacc.c  */
-#line 3284 "gram.y"
+#line 3285 "gram.y"
     { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); }
     break;
 
   case 501:
-
-/* Line 1806 of yacc.c  */
-#line 3285 "gram.y"
+#line 3286 "gram.y"
     { (yyval.list) = lcons(makeString((yyvsp[(1) - (2)].str)), (yyvsp[(2) - (2)].list)); }
     break;
 
   case 502:
-
-/* Line 1806 of yacc.c  */
-#line 3289 "gram.y"
+#line 3290 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (2)].list); }
     break;
 
   case 503:
-
-/* Line 1806 of yacc.c  */
-#line 3290 "gram.y"
+#line 3291 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 504:
-
-/* Line 1806 of yacc.c  */
-#line 3294 "gram.y"
+#line 3295 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (2)].list); }
     break;
 
   case 505:
-
-/* Line 1806 of yacc.c  */
-#line 3295 "gram.y"
+#line 3296 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 506:
-
-/* Line 1806 of yacc.c  */
-#line 3299 "gram.y"
+#line 3300 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 507:
-
-/* Line 1806 of yacc.c  */
-#line 3300 "gram.y"
+#line 3301 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 508:
-
-/* Line 1806 of yacc.c  */
-#line 3305 "gram.y"
+#line 3306 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_LANGUAGE;
@@ -24290,9 +23447,7 @@ yyreduce:
     break;
 
   case 509:
-
-/* Line 1806 of yacc.c  */
-#line 3316 "gram.y"
+#line 3317 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_LANGUAGE;
@@ -24305,23 +23460,17 @@ yyreduce:
     break;
 
   case 510:
-
-/* Line 1806 of yacc.c  */
-#line 3328 "gram.y"
+#line 3329 "gram.y"
     {}
     break;
 
   case 511:
-
-/* Line 1806 of yacc.c  */
-#line 3329 "gram.y"
+#line 3330 "gram.y"
     {}
     break;
 
   case 512:
-
-/* Line 1806 of yacc.c  */
-#line 3340 "gram.y"
+#line 3341 "gram.y"
     {
 					CreateTableSpaceStmt *n = makeNode(CreateTableSpaceStmt);
 					n->tablespacename = (yyvsp[(3) - (6)].str);
@@ -24332,23 +23481,17 @@ yyreduce:
     break;
 
   case 513:
-
-/* Line 1806 of yacc.c  */
-#line 3349 "gram.y"
+#line 3350 "gram.y"
     { (yyval.str) = (yyvsp[(2) - (2)].str); }
     break;
 
   case 514:
-
-/* Line 1806 of yacc.c  */
-#line 3350 "gram.y"
+#line 3351 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 515:
-
-/* Line 1806 of yacc.c  */
-#line 3364 "gram.y"
+#line 3365 "gram.y"
     {
 					DropTableSpaceStmt *n = makeNode(DropTableSpaceStmt);
 					n->tablespacename = (yyvsp[(3) - (3)].str);
@@ -24358,9 +23501,7 @@ yyreduce:
     break;
 
   case 516:
-
-/* Line 1806 of yacc.c  */
-#line 3371 "gram.y"
+#line 3372 "gram.y"
     {
 					DropTableSpaceStmt *n = makeNode(DropTableSpaceStmt);
 					n->tablespacename = (yyvsp[(5) - (5)].str);
@@ -24370,9 +23511,7 @@ yyreduce:
     break;
 
   case 517:
-
-/* Line 1806 of yacc.c  */
-#line 3388 "gram.y"
+#line 3389 "gram.y"
     {
 					CreateExtensionStmt *n = makeNode(CreateExtensionStmt);
 					n->extname = (yyvsp[(3) - (5)].str);
@@ -24383,9 +23522,7 @@ yyreduce:
     break;
 
   case 518:
-
-/* Line 1806 of yacc.c  */
-#line 3396 "gram.y"
+#line 3397 "gram.y"
     {
 					CreateExtensionStmt *n = makeNode(CreateExtensionStmt);
 					n->extname = (yyvsp[(6) - (8)].str);
@@ -24396,50 +23533,38 @@ yyreduce:
     break;
 
   case 519:
-
-/* Line 1806 of yacc.c  */
-#line 3407 "gram.y"
+#line 3408 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); }
     break;
 
   case 520:
-
-/* Line 1806 of yacc.c  */
-#line 3409 "gram.y"
+#line 3410 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 521:
-
-/* Line 1806 of yacc.c  */
-#line 3414 "gram.y"
+#line 3415 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("schema", (Node *)makeString((yyvsp[(2) - (2)].str)));
 				}
     break;
 
   case 522:
-
-/* Line 1806 of yacc.c  */
-#line 3418 "gram.y"
+#line 3419 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("new_version", (Node *)makeString((yyvsp[(2) - (2)].str)));
 				}
     break;
 
   case 523:
-
-/* Line 1806 of yacc.c  */
-#line 3422 "gram.y"
+#line 3423 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("old_version", (Node *)makeString((yyvsp[(2) - (2)].str)));
 				}
     break;
 
   case 524:
-
-/* Line 1806 of yacc.c  */
-#line 3434 "gram.y"
+#line 3435 "gram.y"
     {
 					AlterExtensionStmt *n = makeNode(AlterExtensionStmt);
 					n->extname = (yyvsp[(3) - (5)].str);
@@ -24449,32 +23574,24 @@ yyreduce:
     break;
 
   case 525:
-
-/* Line 1806 of yacc.c  */
-#line 3444 "gram.y"
+#line 3445 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); }
     break;
 
   case 526:
-
-/* Line 1806 of yacc.c  */
-#line 3446 "gram.y"
+#line 3447 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 527:
-
-/* Line 1806 of yacc.c  */
-#line 3451 "gram.y"
+#line 3452 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("new_version", (Node *)makeString((yyvsp[(2) - (2)].str)));
 				}
     break;
 
   case 528:
-
-/* Line 1806 of yacc.c  */
-#line 3464 "gram.y"
+#line 3465 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (7)].str);
@@ -24487,9 +23604,7 @@ yyreduce:
     break;
 
   case 529:
-
-/* Line 1806 of yacc.c  */
-#line 3474 "gram.y"
+#line 3475 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (10)].str);
@@ -24502,9 +23617,7 @@ yyreduce:
     break;
 
   case 530:
-
-/* Line 1806 of yacc.c  */
-#line 3484 "gram.y"
+#line 3485 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (6)].str);
@@ -24516,9 +23629,7 @@ yyreduce:
     break;
 
   case 531:
-
-/* Line 1806 of yacc.c  */
-#line 3493 "gram.y"
+#line 3494 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (6)].str);
@@ -24530,9 +23641,7 @@ yyreduce:
     break;
 
   case 532:
-
-/* Line 1806 of yacc.c  */
-#line 3502 "gram.y"
+#line 3503 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (6)].str);
@@ -24544,9 +23653,7 @@ yyreduce:
     break;
 
   case 533:
-
-/* Line 1806 of yacc.c  */
-#line 3511 "gram.y"
+#line 3512 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (6)].str);
@@ -24559,9 +23666,7 @@ yyreduce:
     break;
 
   case 534:
-
-/* Line 1806 of yacc.c  */
-#line 3521 "gram.y"
+#line 3522 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (7)].str);
@@ -24573,9 +23678,7 @@ yyreduce:
     break;
 
   case 535:
-
-/* Line 1806 of yacc.c  */
-#line 3530 "gram.y"
+#line 3531 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (7)].str);
@@ -24588,9 +23691,7 @@ yyreduce:
     break;
 
   case 536:
-
-/* Line 1806 of yacc.c  */
-#line 3540 "gram.y"
+#line 3541 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (9)].str);
@@ -24603,9 +23704,7 @@ yyreduce:
     break;
 
   case 537:
-
-/* Line 1806 of yacc.c  */
-#line 3550 "gram.y"
+#line 3551 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (9)].str);
@@ -24618,9 +23717,7 @@ yyreduce:
     break;
 
   case 538:
-
-/* Line 1806 of yacc.c  */
-#line 3560 "gram.y"
+#line 3561 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (6)].str);
@@ -24632,9 +23729,7 @@ yyreduce:
     break;
 
   case 539:
-
-/* Line 1806 of yacc.c  */
-#line 3569 "gram.y"
+#line 3570 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (6)].str);
@@ -24646,9 +23741,7 @@ yyreduce:
     break;
 
   case 540:
-
-/* Line 1806 of yacc.c  */
-#line 3578 "gram.y"
+#line 3579 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (8)].str);
@@ -24660,9 +23753,7 @@ yyreduce:
     break;
 
   case 541:
-
-/* Line 1806 of yacc.c  */
-#line 3587 "gram.y"
+#line 3588 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (8)].str);
@@ -24674,9 +23765,7 @@ yyreduce:
     break;
 
   case 542:
-
-/* Line 1806 of yacc.c  */
-#line 3596 "gram.y"
+#line 3597 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (8)].str);
@@ -24688,9 +23777,7 @@ yyreduce:
     break;
 
   case 543:
-
-/* Line 1806 of yacc.c  */
-#line 3605 "gram.y"
+#line 3606 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (8)].str);
@@ -24702,9 +23789,7 @@ yyreduce:
     break;
 
   case 544:
-
-/* Line 1806 of yacc.c  */
-#line 3614 "gram.y"
+#line 3615 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (6)].str);
@@ -24716,9 +23801,7 @@ yyreduce:
     break;
 
   case 545:
-
-/* Line 1806 of yacc.c  */
-#line 3623 "gram.y"
+#line 3624 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (6)].str);
@@ -24730,9 +23813,7 @@ yyreduce:
     break;
 
   case 546:
-
-/* Line 1806 of yacc.c  */
-#line 3632 "gram.y"
+#line 3633 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (7)].str);
@@ -24744,9 +23825,7 @@ yyreduce:
     break;
 
   case 547:
-
-/* Line 1806 of yacc.c  */
-#line 3641 "gram.y"
+#line 3642 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (8)].str);
@@ -24758,9 +23837,7 @@ yyreduce:
     break;
 
   case 548:
-
-/* Line 1806 of yacc.c  */
-#line 3650 "gram.y"
+#line 3651 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (6)].str);
@@ -24772,9 +23849,7 @@ yyreduce:
     break;
 
   case 549:
-
-/* Line 1806 of yacc.c  */
-#line 3659 "gram.y"
+#line 3660 "gram.y"
     {
 					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
 					n->extname = (yyvsp[(3) - (6)].str);
@@ -24786,9 +23861,7 @@ yyreduce:
     break;
 
   case 550:
-
-/* Line 1806 of yacc.c  */
-#line 3677 "gram.y"
+#line 3678 "gram.y"
     {
 					CreateFdwStmt *n = makeNode(CreateFdwStmt);
 					n->fdwname = (yyvsp[(5) - (7)].str);
@@ -24799,65 +23872,47 @@ yyreduce:
     break;
 
   case 551:
-
-/* Line 1806 of yacc.c  */
-#line 3687 "gram.y"
+#line 3688 "gram.y"
     { (yyval.defelt) = makeDefElem("handler", (Node *)(yyvsp[(2) - (2)].list)); }
     break;
 
   case 552:
-
-/* Line 1806 of yacc.c  */
-#line 3688 "gram.y"
+#line 3689 "gram.y"
     { (yyval.defelt) = makeDefElem("handler", NULL); }
     break;
 
   case 553:
-
-/* Line 1806 of yacc.c  */
-#line 3689 "gram.y"
+#line 3690 "gram.y"
     { (yyval.defelt) = makeDefElem("validator", (Node *)(yyvsp[(2) - (2)].list)); }
     break;
 
   case 554:
-
-/* Line 1806 of yacc.c  */
-#line 3690 "gram.y"
+#line 3691 "gram.y"
     { (yyval.defelt) = makeDefElem("validator", NULL); }
     break;
 
   case 555:
-
-/* Line 1806 of yacc.c  */
-#line 3694 "gram.y"
+#line 3695 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); }
     break;
 
   case 556:
-
-/* Line 1806 of yacc.c  */
-#line 3695 "gram.y"
+#line 3696 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); }
     break;
 
   case 557:
-
-/* Line 1806 of yacc.c  */
-#line 3699 "gram.y"
+#line 3700 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 558:
-
-/* Line 1806 of yacc.c  */
-#line 3700 "gram.y"
+#line 3701 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 559:
-
-/* Line 1806 of yacc.c  */
-#line 3711 "gram.y"
+#line 3712 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_FDW;
@@ -24871,9 +23926,7 @@ yyreduce:
     break;
 
   case 560:
-
-/* Line 1806 of yacc.c  */
-#line 3722 "gram.y"
+#line 3723 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_FDW;
@@ -24887,9 +23940,7 @@ yyreduce:
     break;
 
   case 561:
-
-/* Line 1806 of yacc.c  */
-#line 3742 "gram.y"
+#line 3743 "gram.y"
     {
 					AlterFdwStmt *n = makeNode(AlterFdwStmt);
 					n->fdwname = (yyvsp[(5) - (7)].str);
@@ -24900,9 +23951,7 @@ yyreduce:
     break;
 
   case 562:
-
-/* Line 1806 of yacc.c  */
-#line 3750 "gram.y"
+#line 3751 "gram.y"
     {
 					AlterFdwStmt *n = makeNode(AlterFdwStmt);
 					n->fdwname = (yyvsp[(5) - (6)].str);
@@ -24913,75 +23962,57 @@ yyreduce:
     break;
 
   case 563:
-
-/* Line 1806 of yacc.c  */
-#line 3761 "gram.y"
+#line 3762 "gram.y"
     { (yyval.list) = (yyvsp[(3) - (4)].list); }
     break;
 
   case 564:
-
-/* Line 1806 of yacc.c  */
-#line 3762 "gram.y"
+#line 3763 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 565:
-
-/* Line 1806 of yacc.c  */
-#line 3767 "gram.y"
+#line 3768 "gram.y"
     {
 					(yyval.list) = list_make1((yyvsp[(1) - (1)].defelt));
 				}
     break;
 
   case 566:
-
-/* Line 1806 of yacc.c  */
-#line 3771 "gram.y"
+#line 3772 "gram.y"
     {
 					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt));
 				}
     break;
 
   case 567:
-
-/* Line 1806 of yacc.c  */
-#line 3778 "gram.y"
+#line 3779 "gram.y"
     { (yyval.list) = (yyvsp[(3) - (4)].list); }
     break;
 
   case 568:
-
-/* Line 1806 of yacc.c  */
-#line 3783 "gram.y"
+#line 3784 "gram.y"
     {
 					(yyval.list) = list_make1((yyvsp[(1) - (1)].defelt));
 				}
     break;
 
   case 569:
-
-/* Line 1806 of yacc.c  */
-#line 3787 "gram.y"
+#line 3788 "gram.y"
     {
 					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt));
 				}
     break;
 
   case 570:
-
-/* Line 1806 of yacc.c  */
-#line 3794 "gram.y"
+#line 3795 "gram.y"
     {
 					(yyval.defelt) = (yyvsp[(1) - (1)].defelt);
 				}
     break;
 
   case 571:
-
-/* Line 1806 of yacc.c  */
-#line 3798 "gram.y"
+#line 3799 "gram.y"
     {
 					(yyval.defelt) = (yyvsp[(2) - (2)].defelt);
 					(yyval.defelt)->defaction = DEFELEM_SET;
@@ -24989,9 +24020,7 @@ yyreduce:
     break;
 
   case 572:
-
-/* Line 1806 of yacc.c  */
-#line 3803 "gram.y"
+#line 3804 "gram.y"
     {
 					(yyval.defelt) = (yyvsp[(2) - (2)].defelt);
 					(yyval.defelt)->defaction = DEFELEM_ADD;
@@ -24999,41 +24028,31 @@ yyreduce:
     break;
 
   case 573:
-
-/* Line 1806 of yacc.c  */
-#line 3808 "gram.y"
+#line 3809 "gram.y"
     {
 					(yyval.defelt) = makeDefElemExtended(NULL, (yyvsp[(2) - (2)].str), NULL, DEFELEM_DROP);
 				}
     break;
 
   case 574:
-
-/* Line 1806 of yacc.c  */
-#line 3815 "gram.y"
+#line 3816 "gram.y"
     {
 					(yyval.defelt) = makeDefElem((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].node));
 				}
     break;
 
   case 575:
-
-/* Line 1806 of yacc.c  */
-#line 3821 "gram.y"
+#line 3822 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 576:
-
-/* Line 1806 of yacc.c  */
-#line 3826 "gram.y"
+#line 3827 "gram.y"
     { (yyval.node) = (Node *) makeString((yyvsp[(1) - (1)].str)); }
     break;
 
   case 577:
-
-/* Line 1806 of yacc.c  */
-#line 3838 "gram.y"
+#line 3839 "gram.y"
     {
 					CreateForeignServerStmt *n = makeNode(CreateForeignServerStmt);
 					n->servername = (yyvsp[(3) - (10)].str);
@@ -25046,51 +24065,37 @@ yyreduce:
     break;
 
   case 578:
-
-/* Line 1806 of yacc.c  */
-#line 3850 "gram.y"
+#line 3851 "gram.y"
     { (yyval.str) = (yyvsp[(2) - (2)].str); }
     break;
 
   case 579:
-
-/* Line 1806 of yacc.c  */
-#line 3851 "gram.y"
+#line 3852 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 580:
-
-/* Line 1806 of yacc.c  */
-#line 3856 "gram.y"
+#line 3857 "gram.y"
     { (yyval.str) = (yyvsp[(2) - (2)].str); }
     break;
 
   case 581:
-
-/* Line 1806 of yacc.c  */
-#line 3857 "gram.y"
+#line 3858 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 582:
-
-/* Line 1806 of yacc.c  */
-#line 3861 "gram.y"
+#line 3862 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 583:
-
-/* Line 1806 of yacc.c  */
-#line 3862 "gram.y"
+#line 3863 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 584:
-
-/* Line 1806 of yacc.c  */
-#line 3873 "gram.y"
+#line 3874 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_FOREIGN_SERVER;
@@ -25104,9 +24109,7 @@ yyreduce:
     break;
 
   case 585:
-
-/* Line 1806 of yacc.c  */
-#line 3884 "gram.y"
+#line 3885 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_FOREIGN_SERVER;
@@ -25120,9 +24123,7 @@ yyreduce:
     break;
 
   case 586:
-
-/* Line 1806 of yacc.c  */
-#line 3904 "gram.y"
+#line 3905 "gram.y"
     {
 					AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt);
 					n->servername = (yyvsp[(3) - (5)].str);
@@ -25134,9 +24135,7 @@ yyreduce:
     break;
 
   case 587:
-
-/* Line 1806 of yacc.c  */
-#line 3913 "gram.y"
+#line 3914 "gram.y"
     {
 					AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt);
 					n->servername = (yyvsp[(3) - (4)].str);
@@ -25147,9 +24146,7 @@ yyreduce:
     break;
 
   case 588:
-
-/* Line 1806 of yacc.c  */
-#line 3921 "gram.y"
+#line 3922 "gram.y"
     {
 					AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt);
 					n->servername = (yyvsp[(3) - (4)].str);
@@ -25159,9 +24156,7 @@ yyreduce:
     break;
 
   case 589:
-
-/* Line 1806 of yacc.c  */
-#line 3940 "gram.y"
+#line 3941 "gram.y"
     {
 					CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt);
 					(yyvsp[(4) - (8)].range)->relpersistence = RELPERSISTENCE_PERMANENT;
@@ -25177,9 +24172,7 @@ yyreduce:
     break;
 
   case 590:
-
-/* Line 1806 of yacc.c  */
-#line 3955 "gram.y"
+#line 3956 "gram.y"
     {
 					CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt);
 					(yyvsp[(7) - (11)].range)->relpersistence = RELPERSISTENCE_PERMANENT;
@@ -25195,48 +24188,36 @@ yyreduce:
     break;
 
   case 591:
-
-/* Line 1806 of yacc.c  */
-#line 3970 "gram.y"
+#line 3971 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (3)].list); }
     break;
 
   case 592:
-
-/* Line 1806 of yacc.c  */
-#line 3971 "gram.y"
+#line 3972 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 593:
-
-/* Line 1806 of yacc.c  */
-#line 3976 "gram.y"
+#line 3977 "gram.y"
     {
 					(yyval.list) = list_make1((yyvsp[(1) - (1)].node));
 				}
     break;
 
   case 594:
-
-/* Line 1806 of yacc.c  */
-#line 3980 "gram.y"
+#line 3981 "gram.y"
     {
 					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 				}
     break;
 
   case 595:
-
-/* Line 1806 of yacc.c  */
-#line 3986 "gram.y"
+#line 3987 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 596:
-
-/* Line 1806 of yacc.c  */
-#line 3998 "gram.y"
+#line 3999 "gram.y"
     {
 					AlterTableStmt *n = makeNode(AlterTableStmt);
 					n->relation = (yyvsp[(4) - (5)].range);
@@ -25248,9 +24229,7 @@ yyreduce:
     break;
 
   case 597:
-
-/* Line 1806 of yacc.c  */
-#line 4007 "gram.y"
+#line 4008 "gram.y"
     {
 					AlterTableStmt *n = makeNode(AlterTableStmt);
 					n->relation = (yyvsp[(6) - (7)].range);
@@ -25262,9 +24241,7 @@ yyreduce:
     break;
 
   case 598:
-
-/* Line 1806 of yacc.c  */
-#line 4025 "gram.y"
+#line 4026 "gram.y"
     {
 					CreateUserMappingStmt *n = makeNode(CreateUserMappingStmt);
 					n->username = (yyvsp[(5) - (8)].str);
@@ -25275,30 +24252,22 @@ yyreduce:
     break;
 
   case 599:
-
-/* Line 1806 of yacc.c  */
-#line 4036 "gram.y"
+#line 4037 "gram.y"
     { (yyval.str) = "current_user"; }
     break;
 
   case 600:
-
-/* Line 1806 of yacc.c  */
-#line 4037 "gram.y"
+#line 4038 "gram.y"
     { (yyval.str) = "current_user"; }
     break;
 
   case 601:
-
-/* Line 1806 of yacc.c  */
-#line 4038 "gram.y"
+#line 4039 "gram.y"
     { (yyval.str) = (strcmp((yyvsp[(1) - (1)].str), "public") == 0) ? NULL : (yyvsp[(1) - (1)].str); }
     break;
 
   case 602:
-
-/* Line 1806 of yacc.c  */
-#line 4049 "gram.y"
+#line 4050 "gram.y"
     {
 					DropUserMappingStmt *n = makeNode(DropUserMappingStmt);
 					n->username = (yyvsp[(5) - (7)].str);
@@ -25309,9 +24278,7 @@ yyreduce:
     break;
 
   case 603:
-
-/* Line 1806 of yacc.c  */
-#line 4057 "gram.y"
+#line 4058 "gram.y"
     {
 					DropUserMappingStmt *n = makeNode(DropUserMappingStmt);
 					n->username = (yyvsp[(7) - (9)].str);
@@ -25322,9 +24289,7 @@ yyreduce:
     break;
 
   case 604:
-
-/* Line 1806 of yacc.c  */
-#line 4074 "gram.y"
+#line 4075 "gram.y"
     {
 					AlterUserMappingStmt *n = makeNode(AlterUserMappingStmt);
 					n->username = (yyvsp[(5) - (8)].str);
@@ -25335,9 +24300,7 @@ yyreduce:
     break;
 
   case 605:
-
-/* Line 1806 of yacc.c  */
-#line 4095 "gram.y"
+#line 4096 "gram.y"
     {
 					CreateTrigStmt *n = makeNode(CreateTrigStmt);
 					n->trigname = (yyvsp[(3) - (15)].str);
@@ -25358,9 +24321,7 @@ yyreduce:
     break;
 
   case 606:
-
-/* Line 1806 of yacc.c  */
-#line 4116 "gram.y"
+#line 4117 "gram.y"
     {
 					CreateTrigStmt *n = makeNode(CreateTrigStmt);
 					n->trigname = (yyvsp[(4) - (20)].str);
@@ -25382,37 +24343,27 @@ yyreduce:
     break;
 
   case 607:
-
-/* Line 1806 of yacc.c  */
-#line 4137 "gram.y"
+#line 4138 "gram.y"
     { (yyval.ival) = TRIGGER_TYPE_BEFORE; }
     break;
 
   case 608:
-
-/* Line 1806 of yacc.c  */
-#line 4138 "gram.y"
+#line 4139 "gram.y"
     { (yyval.ival) = TRIGGER_TYPE_AFTER; }
     break;
 
   case 609:
-
-/* Line 1806 of yacc.c  */
-#line 4139 "gram.y"
+#line 4140 "gram.y"
     { (yyval.ival) = TRIGGER_TYPE_INSTEAD; }
     break;
 
   case 610:
-
-/* Line 1806 of yacc.c  */
-#line 4144 "gram.y"
+#line 4145 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 611:
-
-/* Line 1806 of yacc.c  */
-#line 4146 "gram.y"
+#line 4147 "gram.y"
     {
 					int		events1 = intVal(linitial((yyvsp[(1) - (3)].list)));
 					int		events2 = intVal(linitial((yyvsp[(3) - (3)].list)));
@@ -25434,53 +24385,39 @@ yyreduce:
     break;
 
   case 612:
-
-/* Line 1806 of yacc.c  */
-#line 4168 "gram.y"
+#line 4169 "gram.y"
     { (yyval.list) = list_make2(makeInteger(TRIGGER_TYPE_INSERT), NIL); }
     break;
 
   case 613:
-
-/* Line 1806 of yacc.c  */
-#line 4170 "gram.y"
+#line 4171 "gram.y"
     { (yyval.list) = list_make2(makeInteger(TRIGGER_TYPE_DELETE), NIL); }
     break;
 
   case 614:
-
-/* Line 1806 of yacc.c  */
-#line 4172 "gram.y"
+#line 4173 "gram.y"
     { (yyval.list) = list_make2(makeInteger(TRIGGER_TYPE_UPDATE), NIL); }
     break;
 
   case 615:
-
-/* Line 1806 of yacc.c  */
-#line 4174 "gram.y"
+#line 4175 "gram.y"
     { (yyval.list) = list_make2(makeInteger(TRIGGER_TYPE_UPDATE), (yyvsp[(3) - (3)].list)); }
     break;
 
   case 616:
-
-/* Line 1806 of yacc.c  */
-#line 4176 "gram.y"
+#line 4177 "gram.y"
     { (yyval.list) = list_make2(makeInteger(TRIGGER_TYPE_TRUNCATE), NIL); }
     break;
 
   case 617:
-
-/* Line 1806 of yacc.c  */
-#line 4181 "gram.y"
+#line 4182 "gram.y"
     {
 					(yyval.boolean) = (yyvsp[(3) - (3)].boolean);
 				}
     break;
 
   case 618:
-
-/* Line 1806 of yacc.c  */
-#line 4185 "gram.y"
+#line 4186 "gram.y"
     {
 					/*
 					 * If ROW/STATEMENT not specified, default to
@@ -25491,72 +24428,52 @@ yyreduce:
     break;
 
   case 619:
-
-/* Line 1806 of yacc.c  */
-#line 4195 "gram.y"
+#line 4196 "gram.y"
     {}
     break;
 
   case 620:
-
-/* Line 1806 of yacc.c  */
-#line 4196 "gram.y"
+#line 4197 "gram.y"
     {}
     break;
 
   case 621:
-
-/* Line 1806 of yacc.c  */
-#line 4200 "gram.y"
+#line 4201 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 622:
-
-/* Line 1806 of yacc.c  */
-#line 4201 "gram.y"
+#line 4202 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 623:
-
-/* Line 1806 of yacc.c  */
-#line 4205 "gram.y"
+#line 4206 "gram.y"
     { (yyval.node) = (yyvsp[(3) - (4)].node); }
     break;
 
   case 624:
-
-/* Line 1806 of yacc.c  */
-#line 4206 "gram.y"
+#line 4207 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 625:
-
-/* Line 1806 of yacc.c  */
-#line 4210 "gram.y"
+#line 4211 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].value)); }
     break;
 
   case 626:
-
-/* Line 1806 of yacc.c  */
-#line 4211 "gram.y"
+#line 4212 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].value)); }
     break;
 
   case 627:
-
-/* Line 1806 of yacc.c  */
-#line 4212 "gram.y"
+#line 4213 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 628:
-
-/* Line 1806 of yacc.c  */
-#line 4217 "gram.y"
+#line 4218 "gram.y"
     {
 					char buf[64];
 					snprintf(buf, sizeof(buf), "%d", (yyvsp[(1) - (1)].ival));
@@ -25565,51 +24482,37 @@ yyreduce:
     break;
 
   case 629:
-
-/* Line 1806 of yacc.c  */
-#line 4222 "gram.y"
+#line 4223 "gram.y"
     { (yyval.value) = makeString((yyvsp[(1) - (1)].str)); }
     break;
 
   case 630:
-
-/* Line 1806 of yacc.c  */
-#line 4223 "gram.y"
+#line 4224 "gram.y"
     { (yyval.value) = makeString((yyvsp[(1) - (1)].str)); }
     break;
 
   case 631:
-
-/* Line 1806 of yacc.c  */
-#line 4224 "gram.y"
+#line 4225 "gram.y"
     { (yyval.value) = makeString((yyvsp[(1) - (1)].str)); }
     break;
 
   case 632:
-
-/* Line 1806 of yacc.c  */
-#line 4228 "gram.y"
+#line 4229 "gram.y"
     { (yyval.range) = (yyvsp[(2) - (2)].range); }
     break;
 
   case 633:
-
-/* Line 1806 of yacc.c  */
-#line 4229 "gram.y"
+#line 4230 "gram.y"
     { (yyval.range) = NULL; }
     break;
 
   case 634:
-
-/* Line 1806 of yacc.c  */
-#line 4234 "gram.y"
+#line 4235 "gram.y"
     { (yyval.ival) = 0; }
     break;
 
   case 635:
-
-/* Line 1806 of yacc.c  */
-#line 4236 "gram.y"
+#line 4237 "gram.y"
     {
 					/*
 					 * We must complain about conflicting options.
@@ -25636,51 +24539,37 @@ yyreduce:
     break;
 
   case 636:
-
-/* Line 1806 of yacc.c  */
-#line 4262 "gram.y"
+#line 4263 "gram.y"
     { (yyval.ival) = CAS_NOT_DEFERRABLE; }
     break;
 
   case 637:
-
-/* Line 1806 of yacc.c  */
-#line 4263 "gram.y"
+#line 4264 "gram.y"
     { (yyval.ival) = CAS_DEFERRABLE; }
     break;
 
   case 638:
-
-/* Line 1806 of yacc.c  */
-#line 4264 "gram.y"
+#line 4265 "gram.y"
     { (yyval.ival) = CAS_INITIALLY_IMMEDIATE; }
     break;
 
   case 639:
-
-/* Line 1806 of yacc.c  */
-#line 4265 "gram.y"
+#line 4266 "gram.y"
     { (yyval.ival) = CAS_INITIALLY_DEFERRED; }
     break;
 
   case 640:
-
-/* Line 1806 of yacc.c  */
-#line 4266 "gram.y"
+#line 4267 "gram.y"
     { (yyval.ival) = CAS_NOT_VALID; }
     break;
 
   case 641:
-
-/* Line 1806 of yacc.c  */
-#line 4267 "gram.y"
+#line 4268 "gram.y"
     { (yyval.ival) = CAS_NO_INHERIT; }
     break;
 
   case 642:
-
-/* Line 1806 of yacc.c  */
-#line 4273 "gram.y"
+#line 4274 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_TRIGGER;
@@ -25694,9 +24583,7 @@ yyreduce:
     break;
 
   case 643:
-
-/* Line 1806 of yacc.c  */
-#line 4284 "gram.y"
+#line 4285 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_TRIGGER;
@@ -25710,9 +24597,7 @@ yyreduce:
     break;
 
   case 644:
-
-/* Line 1806 of yacc.c  */
-#line 4308 "gram.y"
+#line 4309 "gram.y"
     {
 					CreateTrigStmt *n = makeNode(CreateTrigStmt);
 					n->trigname = (yyvsp[(3) - (8)].str);
@@ -25731,9 +24616,7 @@ yyreduce:
     break;
 
   case 645:
-
-/* Line 1806 of yacc.c  */
-#line 4327 "gram.y"
+#line 4328 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->objects = NIL;
@@ -25748,9 +24631,7 @@ yyreduce:
     break;
 
   case 646:
-
-/* Line 1806 of yacc.c  */
-#line 4350 "gram.y"
+#line 4351 "gram.y"
     {
 					DefineStmt *n = makeNode(DefineStmt);
 					n->kind = OBJECT_AGGREGATE;
@@ -25763,9 +24644,7 @@ yyreduce:
     break;
 
   case 647:
-
-/* Line 1806 of yacc.c  */
-#line 4360 "gram.y"
+#line 4361 "gram.y"
     {
 					/* old-style (pre-8.2) syntax for CREATE AGGREGATE */
 					DefineStmt *n = makeNode(DefineStmt);
@@ -25779,9 +24658,7 @@ yyreduce:
     break;
 
   case 648:
-
-/* Line 1806 of yacc.c  */
-#line 4371 "gram.y"
+#line 4372 "gram.y"
     {
 					DefineStmt *n = makeNode(DefineStmt);
 					n->kind = OBJECT_OPERATOR;
@@ -25794,9 +24671,7 @@ yyreduce:
     break;
 
   case 649:
-
-/* Line 1806 of yacc.c  */
-#line 4381 "gram.y"
+#line 4382 "gram.y"
     {
 					DefineStmt *n = makeNode(DefineStmt);
 					n->kind = OBJECT_TYPE;
@@ -25809,9 +24684,7 @@ yyreduce:
     break;
 
   case 650:
-
-/* Line 1806 of yacc.c  */
-#line 4391 "gram.y"
+#line 4392 "gram.y"
     {
 					/* Shell type (identified by lack of definition) */
 					DefineStmt *n = makeNode(DefineStmt);
@@ -25825,9 +24698,7 @@ yyreduce:
     break;
 
   case 651:
-
-/* Line 1806 of yacc.c  */
-#line 4402 "gram.y"
+#line 4403 "gram.y"
     {
 					CompositeTypeStmt *n = makeNode(CompositeTypeStmt);
 
@@ -25839,9 +24710,7 @@ yyreduce:
     break;
 
   case 652:
-
-/* Line 1806 of yacc.c  */
-#line 4411 "gram.y"
+#line 4412 "gram.y"
     {
 					CreateEnumStmt *n = makeNode(CreateEnumStmt);
 					n->typeName = (yyvsp[(3) - (8)].list);
@@ -25851,9 +24720,7 @@ yyreduce:
     break;
 
   case 653:
-
-/* Line 1806 of yacc.c  */
-#line 4418 "gram.y"
+#line 4419 "gram.y"
     {
 					CreateRangeStmt *n = makeNode(CreateRangeStmt);
 					n->typeName = (yyvsp[(3) - (6)].list);
@@ -25863,9 +24730,7 @@ yyreduce:
     break;
 
   case 654:
-
-/* Line 1806 of yacc.c  */
-#line 4425 "gram.y"
+#line 4426 "gram.y"
     {
 					DefineStmt *n = makeNode(DefineStmt);
 					n->kind = OBJECT_TSPARSER;
@@ -25877,9 +24742,7 @@ yyreduce:
     break;
 
   case 655:
-
-/* Line 1806 of yacc.c  */
-#line 4434 "gram.y"
+#line 4435 "gram.y"
     {
 					DefineStmt *n = makeNode(DefineStmt);
 					n->kind = OBJECT_TSDICTIONARY;
@@ -25891,9 +24754,7 @@ yyreduce:
     break;
 
   case 656:
-
-/* Line 1806 of yacc.c  */
-#line 4443 "gram.y"
+#line 4444 "gram.y"
     {
 					DefineStmt *n = makeNode(DefineStmt);
 					n->kind = OBJECT_TSTEMPLATE;
@@ -25905,9 +24766,7 @@ yyreduce:
     break;
 
   case 657:
-
-/* Line 1806 of yacc.c  */
-#line 4452 "gram.y"
+#line 4453 "gram.y"
     {
 					DefineStmt *n = makeNode(DefineStmt);
 					n->kind = OBJECT_TSCONFIGURATION;
@@ -25919,9 +24778,7 @@ yyreduce:
     break;
 
   case 658:
-
-/* Line 1806 of yacc.c  */
-#line 4461 "gram.y"
+#line 4462 "gram.y"
     {
 					DefineStmt *n = makeNode(DefineStmt);
 					n->kind = OBJECT_COLLATION;
@@ -25933,9 +24790,7 @@ yyreduce:
     break;
 
   case 659:
-
-/* Line 1806 of yacc.c  */
-#line 4470 "gram.y"
+#line 4471 "gram.y"
     {
 					DefineStmt *n = makeNode(DefineStmt);
 					n->kind = OBJECT_COLLATION;
@@ -25947,155 +24802,113 @@ yyreduce:
     break;
 
   case 660:
-
-/* Line 1806 of yacc.c  */
-#line 4480 "gram.y"
+#line 4481 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (3)].list); }
     break;
 
   case 661:
-
-/* Line 1806 of yacc.c  */
-#line 4483 "gram.y"
+#line 4484 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); }
     break;
 
   case 662:
-
-/* Line 1806 of yacc.c  */
-#line 4484 "gram.y"
+#line 4485 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt)); }
     break;
 
   case 663:
-
-/* Line 1806 of yacc.c  */
-#line 4488 "gram.y"
+#line 4489 "gram.y"
     {
 					(yyval.defelt) = makeDefElem((yyvsp[(1) - (3)].str), (Node *) (yyvsp[(3) - (3)].node));
 				}
     break;
 
   case 664:
-
-/* Line 1806 of yacc.c  */
-#line 4492 "gram.y"
+#line 4493 "gram.y"
     {
 					(yyval.defelt) = makeDefElem((yyvsp[(1) - (1)].str), NULL);
 				}
     break;
 
   case 665:
-
-/* Line 1806 of yacc.c  */
-#line 4498 "gram.y"
+#line 4499 "gram.y"
     { (yyval.node) = (Node *)(yyvsp[(1) - (1)].typnam); }
     break;
 
   case 666:
-
-/* Line 1806 of yacc.c  */
-#line 4499 "gram.y"
+#line 4500 "gram.y"
     { (yyval.node) = (Node *)makeString(pstrdup((yyvsp[(1) - (1)].keyword))); }
     break;
 
   case 667:
-
-/* Line 1806 of yacc.c  */
-#line 4500 "gram.y"
+#line 4501 "gram.y"
     { (yyval.node) = (Node *)(yyvsp[(1) - (1)].list); }
     break;
 
   case 668:
-
-/* Line 1806 of yacc.c  */
-#line 4501 "gram.y"
+#line 4502 "gram.y"
     { (yyval.node) = (Node *)(yyvsp[(1) - (1)].value); }
     break;
 
   case 669:
-
-/* Line 1806 of yacc.c  */
-#line 4502 "gram.y"
+#line 4503 "gram.y"
     { (yyval.node) = (Node *)makeString((yyvsp[(1) - (1)].str)); }
     break;
 
   case 670:
-
-/* Line 1806 of yacc.c  */
-#line 4505 "gram.y"
+#line 4506 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (3)].list); }
     break;
 
   case 671:
-
-/* Line 1806 of yacc.c  */
-#line 4506 "gram.y"
+#line 4507 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 672:
-
-/* Line 1806 of yacc.c  */
-#line 4509 "gram.y"
+#line 4510 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (3)].list); }
     break;
 
   case 673:
-
-/* Line 1806 of yacc.c  */
-#line 4512 "gram.y"
+#line 4513 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); }
     break;
 
   case 674:
-
-/* Line 1806 of yacc.c  */
-#line 4513 "gram.y"
+#line 4514 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt)); }
     break;
 
   case 675:
-
-/* Line 1806 of yacc.c  */
-#line 4522 "gram.y"
+#line 4523 "gram.y"
     {
 					(yyval.defelt) = makeDefElem((yyvsp[(1) - (3)].str), (Node *)(yyvsp[(3) - (3)].node));
 				}
     break;
 
   case 676:
-
-/* Line 1806 of yacc.c  */
-#line 4528 "gram.y"
+#line 4529 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 677:
-
-/* Line 1806 of yacc.c  */
-#line 4529 "gram.y"
+#line 4530 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 678:
-
-/* Line 1806 of yacc.c  */
-#line 4533 "gram.y"
+#line 4534 "gram.y"
     { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); }
     break;
 
   case 679:
-
-/* Line 1806 of yacc.c  */
-#line 4535 "gram.y"
+#line 4536 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeString((yyvsp[(3) - (3)].str))); }
     break;
 
   case 680:
-
-/* Line 1806 of yacc.c  */
-#line 4546 "gram.y"
+#line 4547 "gram.y"
     {
 				AlterEnumStmt *n = makeNode(AlterEnumStmt);
 				n->typeName = (yyvsp[(3) - (6)].list);
@@ -26107,9 +24920,7 @@ yyreduce:
     break;
 
   case 681:
-
-/* Line 1806 of yacc.c  */
-#line 4555 "gram.y"
+#line 4556 "gram.y"
     {
 				AlterEnumStmt *n = makeNode(AlterEnumStmt);
 				n->typeName = (yyvsp[(3) - (8)].list);
@@ -26121,9 +24932,7 @@ yyreduce:
     break;
 
   case 682:
-
-/* Line 1806 of yacc.c  */
-#line 4564 "gram.y"
+#line 4565 "gram.y"
     {
 				AlterEnumStmt *n = makeNode(AlterEnumStmt);
 				n->typeName = (yyvsp[(3) - (8)].list);
@@ -26135,9 +24944,7 @@ yyreduce:
     break;
 
   case 683:
-
-/* Line 1806 of yacc.c  */
-#line 4589 "gram.y"
+#line 4590 "gram.y"
     {
 					CreateOpClassStmt *n = makeNode(CreateOpClassStmt);
 					n->opclassname = (yyvsp[(4) - (13)].list);
@@ -26151,23 +24958,17 @@ yyreduce:
     break;
 
   case 684:
-
-/* Line 1806 of yacc.c  */
-#line 4602 "gram.y"
+#line 4603 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); }
     break;
 
   case 685:
-
-/* Line 1806 of yacc.c  */
-#line 4603 "gram.y"
+#line 4604 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); }
     break;
 
   case 686:
-
-/* Line 1806 of yacc.c  */
-#line 4608 "gram.y"
+#line 4609 "gram.y"
     {
 					CreateOpClassItem *n = makeNode(CreateOpClassItem);
 					n->itemtype = OPCLASS_ITEM_OPERATOR;
@@ -26180,9 +24981,7 @@ yyreduce:
     break;
 
   case 687:
-
-/* Line 1806 of yacc.c  */
-#line 4619 "gram.y"
+#line 4620 "gram.y"
     {
 					CreateOpClassItem *n = makeNode(CreateOpClassItem);
 					n->itemtype = OPCLASS_ITEM_OPERATOR;
@@ -26195,9 +24994,7 @@ yyreduce:
     break;
 
   case 688:
-
-/* Line 1806 of yacc.c  */
-#line 4629 "gram.y"
+#line 4630 "gram.y"
     {
 					CreateOpClassItem *n = makeNode(CreateOpClassItem);
 					n->itemtype = OPCLASS_ITEM_FUNCTION;
@@ -26209,9 +25006,7 @@ yyreduce:
     break;
 
   case 689:
-
-/* Line 1806 of yacc.c  */
-#line 4638 "gram.y"
+#line 4639 "gram.y"
     {
 					CreateOpClassItem *n = makeNode(CreateOpClassItem);
 					n->itemtype = OPCLASS_ITEM_FUNCTION;
@@ -26224,9 +25019,7 @@ yyreduce:
     break;
 
   case 690:
-
-/* Line 1806 of yacc.c  */
-#line 4648 "gram.y"
+#line 4649 "gram.y"
     {
 					CreateOpClassItem *n = makeNode(CreateOpClassItem);
 					n->itemtype = OPCLASS_ITEM_STORAGETYPE;
@@ -26236,58 +25029,42 @@ yyreduce:
     break;
 
   case 691:
-
-/* Line 1806 of yacc.c  */
-#line 4656 "gram.y"
+#line 4657 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 692:
-
-/* Line 1806 of yacc.c  */
-#line 4657 "gram.y"
+#line 4658 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 693:
-
-/* Line 1806 of yacc.c  */
-#line 4660 "gram.y"
+#line 4661 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (2)].list); }
     break;
 
   case 694:
-
-/* Line 1806 of yacc.c  */
-#line 4661 "gram.y"
+#line 4662 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 695:
-
-/* Line 1806 of yacc.c  */
-#line 4664 "gram.y"
+#line 4665 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 696:
-
-/* Line 1806 of yacc.c  */
-#line 4665 "gram.y"
+#line 4666 "gram.y"
     { (yyval.list) = (yyvsp[(4) - (4)].list); }
     break;
 
   case 697:
-
-/* Line 1806 of yacc.c  */
-#line 4666 "gram.y"
+#line 4667 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 698:
-
-/* Line 1806 of yacc.c  */
-#line 4670 "gram.y"
+#line 4671 "gram.y"
     {
 					/*
 					 * RECHECK no longer does anything in opclass definitions,
@@ -26304,16 +25081,12 @@ yyreduce:
     break;
 
   case 699:
-
-/* Line 1806 of yacc.c  */
-#line 4683 "gram.y"
+#line 4684 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 700:
-
-/* Line 1806 of yacc.c  */
-#line 4689 "gram.y"
+#line 4690 "gram.y"
     {
 					CreateOpFamilyStmt *n = makeNode(CreateOpFamilyStmt);
 					n->opfamilyname = (yyvsp[(4) - (6)].list);
@@ -26323,9 +25096,7 @@ yyreduce:
     break;
 
   case 701:
-
-/* Line 1806 of yacc.c  */
-#line 4699 "gram.y"
+#line 4700 "gram.y"
     {
 					AlterOpFamilyStmt *n = makeNode(AlterOpFamilyStmt);
 					n->opfamilyname = (yyvsp[(4) - (8)].list);
@@ -26337,9 +25108,7 @@ yyreduce:
     break;
 
   case 702:
-
-/* Line 1806 of yacc.c  */
-#line 4708 "gram.y"
+#line 4709 "gram.y"
     {
 					AlterOpFamilyStmt *n = makeNode(AlterOpFamilyStmt);
 					n->opfamilyname = (yyvsp[(4) - (8)].list);
@@ -26351,23 +25120,17 @@ yyreduce:
     break;
 
   case 703:
-
-/* Line 1806 of yacc.c  */
-#line 4719 "gram.y"
+#line 4720 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); }
     break;
 
   case 704:
-
-/* Line 1806 of yacc.c  */
-#line 4720 "gram.y"
+#line 4721 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); }
     break;
 
   case 705:
-
-/* Line 1806 of yacc.c  */
-#line 4725 "gram.y"
+#line 4726 "gram.y"
     {
 					CreateOpClassItem *n = makeNode(CreateOpClassItem);
 					n->itemtype = OPCLASS_ITEM_OPERATOR;
@@ -26378,9 +25141,7 @@ yyreduce:
     break;
 
   case 706:
-
-/* Line 1806 of yacc.c  */
-#line 4733 "gram.y"
+#line 4734 "gram.y"
     {
 					CreateOpClassItem *n = makeNode(CreateOpClassItem);
 					n->itemtype = OPCLASS_ITEM_FUNCTION;
@@ -26391,9 +25152,7 @@ yyreduce:
     break;
 
   case 707:
-
-/* Line 1806 of yacc.c  */
-#line 4745 "gram.y"
+#line 4746 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->objects = list_make1((yyvsp[(4) - (7)].list));
@@ -26407,9 +25166,7 @@ yyreduce:
     break;
 
   case 708:
-
-/* Line 1806 of yacc.c  */
-#line 4756 "gram.y"
+#line 4757 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->objects = list_make1((yyvsp[(6) - (9)].list));
@@ -26423,9 +25180,7 @@ yyreduce:
     break;
 
   case 709:
-
-/* Line 1806 of yacc.c  */
-#line 4770 "gram.y"
+#line 4771 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->objects = list_make1((yyvsp[(4) - (7)].list));
@@ -26439,9 +25194,7 @@ yyreduce:
     break;
 
   case 710:
-
-/* Line 1806 of yacc.c  */
-#line 4781 "gram.y"
+#line 4782 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->objects = list_make1((yyvsp[(6) - (9)].list));
@@ -26455,9 +25208,7 @@ yyreduce:
     break;
 
   case 711:
-
-/* Line 1806 of yacc.c  */
-#line 4804 "gram.y"
+#line 4805 "gram.y"
     {
 					DropOwnedStmt *n = makeNode(DropOwnedStmt);
 					n->roles = (yyvsp[(4) - (5)].list);
@@ -26467,9 +25218,7 @@ yyreduce:
     break;
 
   case 712:
-
-/* Line 1806 of yacc.c  */
-#line 4814 "gram.y"
+#line 4815 "gram.y"
     {
 					ReassignOwnedStmt *n = makeNode(ReassignOwnedStmt);
 					n->roles = (yyvsp[(4) - (6)].list);
@@ -26479,9 +25228,7 @@ yyreduce:
     break;
 
   case 713:
-
-/* Line 1806 of yacc.c  */
-#line 4832 "gram.y"
+#line 4833 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = (yyvsp[(2) - (6)].objtype);
@@ -26495,9 +25242,7 @@ yyreduce:
     break;
 
   case 714:
-
-/* Line 1806 of yacc.c  */
-#line 4843 "gram.y"
+#line 4844 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = (yyvsp[(2) - (4)].objtype);
@@ -26511,9 +25256,7 @@ yyreduce:
     break;
 
   case 715:
-
-/* Line 1806 of yacc.c  */
-#line 4854 "gram.y"
+#line 4855 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_INDEX;
@@ -26527,9 +25270,7 @@ yyreduce:
     break;
 
   case 716:
-
-/* Line 1806 of yacc.c  */
-#line 4865 "gram.y"
+#line 4866 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_INDEX;
@@ -26543,156 +25284,112 @@ yyreduce:
     break;
 
   case 717:
-
-/* Line 1806 of yacc.c  */
-#line 4878 "gram.y"
+#line 4879 "gram.y"
     { (yyval.objtype) = OBJECT_TABLE; }
     break;
 
   case 718:
-
-/* Line 1806 of yacc.c  */
-#line 4879 "gram.y"
+#line 4880 "gram.y"
     { (yyval.objtype) = OBJECT_SEQUENCE; }
     break;
 
   case 719:
-
-/* Line 1806 of yacc.c  */
-#line 4880 "gram.y"
+#line 4881 "gram.y"
     { (yyval.objtype) = OBJECT_VIEW; }
     break;
 
   case 720:
-
-/* Line 1806 of yacc.c  */
-#line 4881 "gram.y"
+#line 4882 "gram.y"
     { (yyval.objtype) = OBJECT_INDEX; }
     break;
 
   case 721:
-
-/* Line 1806 of yacc.c  */
-#line 4882 "gram.y"
+#line 4883 "gram.y"
     { (yyval.objtype) = OBJECT_FOREIGN_TABLE; }
     break;
 
   case 722:
-
-/* Line 1806 of yacc.c  */
-#line 4883 "gram.y"
+#line 4884 "gram.y"
     { (yyval.objtype) = OBJECT_TYPE; }
     break;
 
   case 723:
-
-/* Line 1806 of yacc.c  */
-#line 4884 "gram.y"
+#line 4885 "gram.y"
     { (yyval.objtype) = OBJECT_DOMAIN; }
     break;
 
   case 724:
-
-/* Line 1806 of yacc.c  */
-#line 4885 "gram.y"
+#line 4886 "gram.y"
     { (yyval.objtype) = OBJECT_COLLATION; }
     break;
 
   case 725:
-
-/* Line 1806 of yacc.c  */
-#line 4886 "gram.y"
+#line 4887 "gram.y"
     { (yyval.objtype) = OBJECT_CONVERSION; }
     break;
 
   case 726:
-
-/* Line 1806 of yacc.c  */
-#line 4887 "gram.y"
+#line 4888 "gram.y"
     { (yyval.objtype) = OBJECT_SCHEMA; }
     break;
 
   case 727:
-
-/* Line 1806 of yacc.c  */
-#line 4888 "gram.y"
+#line 4889 "gram.y"
     { (yyval.objtype) = OBJECT_EXTENSION; }
     break;
 
   case 728:
-
-/* Line 1806 of yacc.c  */
-#line 4889 "gram.y"
+#line 4890 "gram.y"
     { (yyval.objtype) = OBJECT_TSPARSER; }
     break;
 
   case 729:
-
-/* Line 1806 of yacc.c  */
-#line 4890 "gram.y"
+#line 4891 "gram.y"
     { (yyval.objtype) = OBJECT_TSDICTIONARY; }
     break;
 
   case 730:
-
-/* Line 1806 of yacc.c  */
-#line 4891 "gram.y"
+#line 4892 "gram.y"
     { (yyval.objtype) = OBJECT_TSTEMPLATE; }
     break;
 
   case 731:
-
-/* Line 1806 of yacc.c  */
-#line 4892 "gram.y"
+#line 4893 "gram.y"
     { (yyval.objtype) = OBJECT_TSCONFIGURATION; }
     break;
 
   case 732:
-
-/* Line 1806 of yacc.c  */
-#line 4896 "gram.y"
+#line 4897 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].list)); }
     break;
 
   case 733:
-
-/* Line 1806 of yacc.c  */
-#line 4897 "gram.y"
+#line 4898 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); }
     break;
 
   case 734:
-
-/* Line 1806 of yacc.c  */
-#line 4900 "gram.y"
+#line 4901 "gram.y"
     { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); }
     break;
 
   case 735:
-
-/* Line 1806 of yacc.c  */
-#line 4901 "gram.y"
+#line 4902 "gram.y"
     { (yyval.list) = lcons(makeString((yyvsp[(1) - (2)].str)), (yyvsp[(2) - (2)].list)); }
     break;
 
   case 736:
-
-/* Line 1806 of yacc.c  */
-#line 4905 "gram.y"
+#line 4906 "gram.y"
     { (yyval.list) = list_make1(makeString((yyvsp[(2) - (2)].str))); }
     break;
 
   case 737:
-
-/* Line 1806 of yacc.c  */
-#line 4907 "gram.y"
+#line 4908 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeString((yyvsp[(3) - (3)].str))); }
     break;
 
   case 738:
-
-/* Line 1806 of yacc.c  */
-#line 4920 "gram.y"
+#line 4921 "gram.y"
     {
 					TruncateStmt *n = makeNode(TruncateStmt);
 					n->relations = (yyvsp[(3) - (5)].list);
@@ -26703,30 +25400,22 @@ yyreduce:
     break;
 
   case 739:
-
-/* Line 1806 of yacc.c  */
-#line 4930 "gram.y"
+#line 4931 "gram.y"
     { (yyval.boolean) = false; }
     break;
 
   case 740:
-
-/* Line 1806 of yacc.c  */
-#line 4931 "gram.y"
+#line 4932 "gram.y"
     { (yyval.boolean) = true; }
     break;
 
   case 741:
-
-/* Line 1806 of yacc.c  */
-#line 4932 "gram.y"
+#line 4933 "gram.y"
     { (yyval.boolean) = false; }
     break;
 
   case 742:
-
-/* Line 1806 of yacc.c  */
-#line 4959 "gram.y"
+#line 4960 "gram.y"
     {
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = (yyvsp[(3) - (6)].objtype);
@@ -26738,9 +25427,7 @@ yyreduce:
     break;
 
   case 743:
-
-/* Line 1806 of yacc.c  */
-#line 4968 "gram.y"
+#line 4969 "gram.y"
     {
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = OBJECT_AGGREGATE;
@@ -26752,9 +25439,7 @@ yyreduce:
     break;
 
   case 744:
-
-/* Line 1806 of yacc.c  */
-#line 4977 "gram.y"
+#line 4978 "gram.y"
     {
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = OBJECT_FUNCTION;
@@ -26766,9 +25451,7 @@ yyreduce:
     break;
 
   case 745:
-
-/* Line 1806 of yacc.c  */
-#line 4986 "gram.y"
+#line 4987 "gram.y"
     {
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = OBJECT_OPERATOR;
@@ -26780,9 +25463,7 @@ yyreduce:
     break;
 
   case 746:
-
-/* Line 1806 of yacc.c  */
-#line 4995 "gram.y"
+#line 4996 "gram.y"
     {
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = OBJECT_CONSTRAINT;
@@ -26794,9 +25475,7 @@ yyreduce:
     break;
 
   case 747:
-
-/* Line 1806 of yacc.c  */
-#line 5004 "gram.y"
+#line 5005 "gram.y"
     {
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = OBJECT_RULE;
@@ -26808,9 +25487,7 @@ yyreduce:
     break;
 
   case 748:
-
-/* Line 1806 of yacc.c  */
-#line 5013 "gram.y"
+#line 5014 "gram.y"
     {
 					/* Obsolete syntax supported for awhile for compatibility */
 					CommentStmt *n = makeNode(CommentStmt);
@@ -26823,9 +25500,7 @@ yyreduce:
     break;
 
   case 749:
-
-/* Line 1806 of yacc.c  */
-#line 5023 "gram.y"
+#line 5024 "gram.y"
     {
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = OBJECT_TRIGGER;
@@ -26837,9 +25512,7 @@ yyreduce:
     break;
 
   case 750:
-
-/* Line 1806 of yacc.c  */
-#line 5032 "gram.y"
+#line 5033 "gram.y"
     {
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = OBJECT_OPCLASS;
@@ -26851,9 +25524,7 @@ yyreduce:
     break;
 
   case 751:
-
-/* Line 1806 of yacc.c  */
-#line 5041 "gram.y"
+#line 5042 "gram.y"
     {
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = OBJECT_OPFAMILY;
@@ -26865,9 +25536,7 @@ yyreduce:
     break;
 
   case 752:
-
-/* Line 1806 of yacc.c  */
-#line 5050 "gram.y"
+#line 5051 "gram.y"
     {
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = OBJECT_LARGEOBJECT;
@@ -26879,9 +25548,7 @@ yyreduce:
     break;
 
   case 753:
-
-/* Line 1806 of yacc.c  */
-#line 5059 "gram.y"
+#line 5060 "gram.y"
     {
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = OBJECT_CAST;
@@ -26893,9 +25560,7 @@ yyreduce:
     break;
 
   case 754:
-
-/* Line 1806 of yacc.c  */
-#line 5068 "gram.y"
+#line 5069 "gram.y"
     {
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = OBJECT_LANGUAGE;
@@ -26907,9 +25572,7 @@ yyreduce:
     break;
 
   case 755:
-
-/* Line 1806 of yacc.c  */
-#line 5077 "gram.y"
+#line 5078 "gram.y"
     {
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = OBJECT_TSPARSER;
@@ -26920,9 +25583,7 @@ yyreduce:
     break;
 
   case 756:
-
-/* Line 1806 of yacc.c  */
-#line 5085 "gram.y"
+#line 5086 "gram.y"
     {
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = OBJECT_TSDICTIONARY;
@@ -26933,9 +25594,7 @@ yyreduce:
     break;
 
   case 757:
-
-/* Line 1806 of yacc.c  */
-#line 5093 "gram.y"
+#line 5094 "gram.y"
     {
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = OBJECT_TSTEMPLATE;
@@ -26946,9 +25605,7 @@ yyreduce:
     break;
 
   case 758:
-
-/* Line 1806 of yacc.c  */
-#line 5101 "gram.y"
+#line 5102 "gram.y"
     {
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = OBJECT_TSCONFIGURATION;
@@ -26959,142 +25616,102 @@ yyreduce:
     break;
 
   case 759:
-
-/* Line 1806 of yacc.c  */
-#line 5111 "gram.y"
+#line 5112 "gram.y"
     { (yyval.objtype) = OBJECT_COLUMN; }
     break;
 
   case 760:
-
-/* Line 1806 of yacc.c  */
-#line 5112 "gram.y"
+#line 5113 "gram.y"
     { (yyval.objtype) = OBJECT_DATABASE; }
     break;
 
   case 761:
-
-/* Line 1806 of yacc.c  */
-#line 5113 "gram.y"
+#line 5114 "gram.y"
     { (yyval.objtype) = OBJECT_SCHEMA; }
     break;
 
   case 762:
-
-/* Line 1806 of yacc.c  */
-#line 5114 "gram.y"
+#line 5115 "gram.y"
     { (yyval.objtype) = OBJECT_INDEX; }
     break;
 
   case 763:
-
-/* Line 1806 of yacc.c  */
-#line 5115 "gram.y"
+#line 5116 "gram.y"
     { (yyval.objtype) = OBJECT_SEQUENCE; }
     break;
 
   case 764:
-
-/* Line 1806 of yacc.c  */
-#line 5116 "gram.y"
+#line 5117 "gram.y"
     { (yyval.objtype) = OBJECT_TABLE; }
     break;
 
   case 765:
-
-/* Line 1806 of yacc.c  */
-#line 5117 "gram.y"
+#line 5118 "gram.y"
     { (yyval.objtype) = OBJECT_DOMAIN; }
     break;
 
   case 766:
-
-/* Line 1806 of yacc.c  */
-#line 5118 "gram.y"
+#line 5119 "gram.y"
     { (yyval.objtype) = OBJECT_TYPE; }
     break;
 
   case 767:
-
-/* Line 1806 of yacc.c  */
-#line 5119 "gram.y"
+#line 5120 "gram.y"
     { (yyval.objtype) = OBJECT_VIEW; }
     break;
 
   case 768:
-
-/* Line 1806 of yacc.c  */
-#line 5120 "gram.y"
+#line 5121 "gram.y"
     { (yyval.objtype) = OBJECT_COLLATION; }
     break;
 
   case 769:
-
-/* Line 1806 of yacc.c  */
-#line 5121 "gram.y"
+#line 5122 "gram.y"
     { (yyval.objtype) = OBJECT_CONVERSION; }
     break;
 
   case 770:
-
-/* Line 1806 of yacc.c  */
-#line 5122 "gram.y"
+#line 5123 "gram.y"
     { (yyval.objtype) = OBJECT_TABLESPACE; }
     break;
 
   case 771:
-
-/* Line 1806 of yacc.c  */
-#line 5123 "gram.y"
+#line 5124 "gram.y"
     { (yyval.objtype) = OBJECT_EXTENSION; }
     break;
 
   case 772:
-
-/* Line 1806 of yacc.c  */
-#line 5124 "gram.y"
+#line 5125 "gram.y"
     { (yyval.objtype) = OBJECT_ROLE; }
     break;
 
   case 773:
-
-/* Line 1806 of yacc.c  */
-#line 5125 "gram.y"
+#line 5126 "gram.y"
     { (yyval.objtype) = OBJECT_FOREIGN_TABLE; }
     break;
 
   case 774:
-
-/* Line 1806 of yacc.c  */
-#line 5126 "gram.y"
+#line 5127 "gram.y"
     { (yyval.objtype) = OBJECT_FOREIGN_SERVER; }
     break;
 
   case 775:
-
-/* Line 1806 of yacc.c  */
-#line 5127 "gram.y"
+#line 5128 "gram.y"
     { (yyval.objtype) = OBJECT_FDW; }
     break;
 
   case 776:
-
-/* Line 1806 of yacc.c  */
-#line 5131 "gram.y"
+#line 5132 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 777:
-
-/* Line 1806 of yacc.c  */
-#line 5132 "gram.y"
+#line 5133 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 778:
-
-/* Line 1806 of yacc.c  */
-#line 5148 "gram.y"
+#line 5149 "gram.y"
     {
 					SecLabelStmt *n = makeNode(SecLabelStmt);
 					n->provider = (yyvsp[(3) - (8)].str);
@@ -27107,9 +25724,7 @@ yyreduce:
     break;
 
   case 779:
-
-/* Line 1806 of yacc.c  */
-#line 5159 "gram.y"
+#line 5160 "gram.y"
     {
 					SecLabelStmt *n = makeNode(SecLabelStmt);
 					n->provider = (yyvsp[(3) - (9)].str);
@@ -27122,9 +25737,7 @@ yyreduce:
     break;
 
   case 780:
-
-/* Line 1806 of yacc.c  */
-#line 5170 "gram.y"
+#line 5171 "gram.y"
     {
 					SecLabelStmt *n = makeNode(SecLabelStmt);
 					n->provider = (yyvsp[(3) - (9)].str);
@@ -27137,9 +25750,7 @@ yyreduce:
     break;
 
   case 781:
-
-/* Line 1806 of yacc.c  */
-#line 5181 "gram.y"
+#line 5182 "gram.y"
     {
 					SecLabelStmt *n = makeNode(SecLabelStmt);
 					n->provider = (yyvsp[(3) - (9)].str);
@@ -27152,9 +25763,7 @@ yyreduce:
     break;
 
   case 782:
-
-/* Line 1806 of yacc.c  */
-#line 5192 "gram.y"
+#line 5193 "gram.y"
     {
 					SecLabelStmt *n = makeNode(SecLabelStmt);
 					n->provider = (yyvsp[(3) - (9)].str);
@@ -27167,114 +25776,82 @@ yyreduce:
     break;
 
   case 783:
-
-/* Line 1806 of yacc.c  */
-#line 5203 "gram.y"
+#line 5204 "gram.y"
     { (yyval.str) = (yyvsp[(2) - (2)].str); }
     break;
 
   case 784:
-
-/* Line 1806 of yacc.c  */
-#line 5204 "gram.y"
+#line 5205 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 785:
-
-/* Line 1806 of yacc.c  */
-#line 5208 "gram.y"
+#line 5209 "gram.y"
     { (yyval.objtype) = OBJECT_COLUMN; }
     break;
 
   case 786:
-
-/* Line 1806 of yacc.c  */
-#line 5209 "gram.y"
+#line 5210 "gram.y"
     { (yyval.objtype) = OBJECT_DATABASE; }
     break;
 
   case 787:
-
-/* Line 1806 of yacc.c  */
-#line 5210 "gram.y"
+#line 5211 "gram.y"
     { (yyval.objtype) = OBJECT_FOREIGN_TABLE; }
     break;
 
   case 788:
-
-/* Line 1806 of yacc.c  */
-#line 5211 "gram.y"
+#line 5212 "gram.y"
     { (yyval.objtype) = OBJECT_SCHEMA; }
     break;
 
   case 789:
-
-/* Line 1806 of yacc.c  */
-#line 5212 "gram.y"
+#line 5213 "gram.y"
     { (yyval.objtype) = OBJECT_SEQUENCE; }
     break;
 
   case 790:
-
-/* Line 1806 of yacc.c  */
-#line 5213 "gram.y"
+#line 5214 "gram.y"
     { (yyval.objtype) = OBJECT_TABLE; }
     break;
 
   case 791:
-
-/* Line 1806 of yacc.c  */
-#line 5214 "gram.y"
+#line 5215 "gram.y"
     { (yyval.objtype) = OBJECT_TYPE; }
     break;
 
   case 792:
-
-/* Line 1806 of yacc.c  */
-#line 5215 "gram.y"
+#line 5216 "gram.y"
     { (yyval.objtype) = OBJECT_ROLE; }
     break;
 
   case 793:
-
-/* Line 1806 of yacc.c  */
-#line 5216 "gram.y"
+#line 5217 "gram.y"
     { (yyval.objtype) = OBJECT_TABLESPACE; }
     break;
 
   case 794:
-
-/* Line 1806 of yacc.c  */
-#line 5217 "gram.y"
+#line 5218 "gram.y"
     { (yyval.objtype) = OBJECT_TYPE; }
     break;
 
   case 795:
-
-/* Line 1806 of yacc.c  */
-#line 5218 "gram.y"
+#line 5219 "gram.y"
     { (yyval.objtype) = OBJECT_VIEW; }
     break;
 
   case 796:
-
-/* Line 1806 of yacc.c  */
-#line 5221 "gram.y"
+#line 5222 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 797:
-
-/* Line 1806 of yacc.c  */
-#line 5222 "gram.y"
+#line 5223 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 798:
-
-/* Line 1806 of yacc.c  */
-#line 5233 "gram.y"
+#line 5234 "gram.y"
     {
 					FetchStmt *n = (FetchStmt *) (yyvsp[(2) - (2)].node);
 					n->ismove = FALSE;
@@ -27283,9 +25860,7 @@ yyreduce:
     break;
 
   case 799:
-
-/* Line 1806 of yacc.c  */
-#line 5239 "gram.y"
+#line 5240 "gram.y"
     {
 					FetchStmt *n = (FetchStmt *) (yyvsp[(2) - (2)].node);
 					n->ismove = TRUE;
@@ -27294,9 +25869,7 @@ yyreduce:
     break;
 
   case 800:
-
-/* Line 1806 of yacc.c  */
-#line 5247 "gram.y"
+#line 5248 "gram.y"
     {
 					FetchStmt *n = makeNode(FetchStmt);
 					n->portalname = (yyvsp[(1) - (1)].str);
@@ -27307,9 +25880,7 @@ yyreduce:
     break;
 
   case 801:
-
-/* Line 1806 of yacc.c  */
-#line 5255 "gram.y"
+#line 5256 "gram.y"
     {
 					FetchStmt *n = makeNode(FetchStmt);
 					n->portalname = (yyvsp[(2) - (2)].str);
@@ -27320,9 +25891,7 @@ yyreduce:
     break;
 
   case 802:
-
-/* Line 1806 of yacc.c  */
-#line 5263 "gram.y"
+#line 5264 "gram.y"
     {
 					FetchStmt *n = makeNode(FetchStmt);
 					n->portalname = (yyvsp[(3) - (3)].str);
@@ -27333,9 +25902,7 @@ yyreduce:
     break;
 
   case 803:
-
-/* Line 1806 of yacc.c  */
-#line 5271 "gram.y"
+#line 5272 "gram.y"
     {
 					FetchStmt *n = makeNode(FetchStmt);
 					n->portalname = (yyvsp[(3) - (3)].str);
@@ -27346,9 +25913,7 @@ yyreduce:
     break;
 
   case 804:
-
-/* Line 1806 of yacc.c  */
-#line 5279 "gram.y"
+#line 5280 "gram.y"
     {
 					FetchStmt *n = makeNode(FetchStmt);
 					n->portalname = (yyvsp[(3) - (3)].str);
@@ -27359,9 +25924,7 @@ yyreduce:
     break;
 
   case 805:
-
-/* Line 1806 of yacc.c  */
-#line 5287 "gram.y"
+#line 5288 "gram.y"
     {
 					FetchStmt *n = makeNode(FetchStmt);
 					n->portalname = (yyvsp[(3) - (3)].str);
@@ -27372,9 +25935,7 @@ yyreduce:
     break;
 
   case 806:
-
-/* Line 1806 of yacc.c  */
-#line 5295 "gram.y"
+#line 5296 "gram.y"
     {
 					FetchStmt *n = makeNode(FetchStmt);
 					n->portalname = (yyvsp[(4) - (4)].str);
@@ -27385,9 +25946,7 @@ yyreduce:
     break;
 
   case 807:
-
-/* Line 1806 of yacc.c  */
-#line 5303 "gram.y"
+#line 5304 "gram.y"
     {
 					FetchStmt *n = makeNode(FetchStmt);
 					n->portalname = (yyvsp[(4) - (4)].str);
@@ -27398,9 +25957,7 @@ yyreduce:
     break;
 
   case 808:
-
-/* Line 1806 of yacc.c  */
-#line 5311 "gram.y"
+#line 5312 "gram.y"
     {
 					FetchStmt *n = makeNode(FetchStmt);
 					n->portalname = (yyvsp[(3) - (3)].str);
@@ -27411,9 +25968,7 @@ yyreduce:
     break;
 
   case 809:
-
-/* Line 1806 of yacc.c  */
-#line 5319 "gram.y"
+#line 5320 "gram.y"
     {
 					FetchStmt *n = makeNode(FetchStmt);
 					n->portalname = (yyvsp[(3) - (3)].str);
@@ -27424,9 +25979,7 @@ yyreduce:
     break;
 
   case 810:
-
-/* Line 1806 of yacc.c  */
-#line 5327 "gram.y"
+#line 5328 "gram.y"
     {
 					FetchStmt *n = makeNode(FetchStmt);
 					n->portalname = (yyvsp[(3) - (3)].str);
@@ -27437,9 +25990,7 @@ yyreduce:
     break;
 
   case 811:
-
-/* Line 1806 of yacc.c  */
-#line 5335 "gram.y"
+#line 5336 "gram.y"
     {
 					FetchStmt *n = makeNode(FetchStmt);
 					n->portalname = (yyvsp[(4) - (4)].str);
@@ -27450,9 +26001,7 @@ yyreduce:
     break;
 
   case 812:
-
-/* Line 1806 of yacc.c  */
-#line 5343 "gram.y"
+#line 5344 "gram.y"
     {
 					FetchStmt *n = makeNode(FetchStmt);
 					n->portalname = (yyvsp[(4) - (4)].str);
@@ -27463,9 +26012,7 @@ yyreduce:
     break;
 
   case 813:
-
-/* Line 1806 of yacc.c  */
-#line 5351 "gram.y"
+#line 5352 "gram.y"
     {
 					FetchStmt *n = makeNode(FetchStmt);
 					n->portalname = (yyvsp[(3) - (3)].str);
@@ -27476,9 +26023,7 @@ yyreduce:
     break;
 
   case 814:
-
-/* Line 1806 of yacc.c  */
-#line 5359 "gram.y"
+#line 5360 "gram.y"
     {
 					FetchStmt *n = makeNode(FetchStmt);
 					n->portalname = (yyvsp[(4) - (4)].str);
@@ -27489,9 +26034,7 @@ yyreduce:
     break;
 
   case 815:
-
-/* Line 1806 of yacc.c  */
-#line 5367 "gram.y"
+#line 5368 "gram.y"
     {
 					FetchStmt *n = makeNode(FetchStmt);
 					n->portalname = (yyvsp[(4) - (4)].str);
@@ -27502,37 +26045,27 @@ yyreduce:
     break;
 
   case 816:
-
-/* Line 1806 of yacc.c  */
-#line 5376 "gram.y"
+#line 5377 "gram.y"
     {}
     break;
 
   case 817:
-
-/* Line 1806 of yacc.c  */
-#line 5377 "gram.y"
+#line 5378 "gram.y"
     {}
     break;
 
   case 818:
-
-/* Line 1806 of yacc.c  */
-#line 5380 "gram.y"
+#line 5381 "gram.y"
     {}
     break;
 
   case 819:
-
-/* Line 1806 of yacc.c  */
-#line 5381 "gram.y"
+#line 5382 "gram.y"
     {}
     break;
 
   case 820:
-
-/* Line 1806 of yacc.c  */
-#line 5393 "gram.y"
+#line 5394 "gram.y"
     {
 					GrantStmt *n = makeNode(GrantStmt);
 					n->is_grant = true;
@@ -27547,9 +26080,7 @@ yyreduce:
     break;
 
   case 821:
-
-/* Line 1806 of yacc.c  */
-#line 5409 "gram.y"
+#line 5410 "gram.y"
     {
 					GrantStmt *n = makeNode(GrantStmt);
 					n->is_grant = false;
@@ -27565,9 +26096,7 @@ yyreduce:
     break;
 
   case 822:
-
-/* Line 1806 of yacc.c  */
-#line 5423 "gram.y"
+#line 5424 "gram.y"
     {
 					GrantStmt *n = makeNode(GrantStmt);
 					n->is_grant = false;
@@ -27583,30 +26112,22 @@ yyreduce:
     break;
 
   case 823:
-
-/* Line 1806 of yacc.c  */
-#line 5448 "gram.y"
+#line 5449 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 824:
-
-/* Line 1806 of yacc.c  */
-#line 5450 "gram.y"
+#line 5451 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 825:
-
-/* Line 1806 of yacc.c  */
-#line 5452 "gram.y"
+#line 5453 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 826:
-
-/* Line 1806 of yacc.c  */
-#line 5454 "gram.y"
+#line 5455 "gram.y"
     {
 					AccessPriv *n = makeNode(AccessPriv);
 					n->priv_name = NULL;
@@ -27616,9 +26137,7 @@ yyreduce:
     break;
 
   case 827:
-
-/* Line 1806 of yacc.c  */
-#line 5461 "gram.y"
+#line 5462 "gram.y"
     {
 					AccessPriv *n = makeNode(AccessPriv);
 					n->priv_name = NULL;
@@ -27628,23 +26147,17 @@ yyreduce:
     break;
 
   case 828:
-
-/* Line 1806 of yacc.c  */
-#line 5469 "gram.y"
+#line 5470 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].accesspriv)); }
     break;
 
   case 829:
-
-/* Line 1806 of yacc.c  */
-#line 5470 "gram.y"
+#line 5471 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].accesspriv)); }
     break;
 
   case 830:
-
-/* Line 1806 of yacc.c  */
-#line 5474 "gram.y"
+#line 5475 "gram.y"
     {
 				AccessPriv *n = makeNode(AccessPriv);
 				n->priv_name = pstrdup((yyvsp[(1) - (2)].keyword));
@@ -27654,9 +26167,7 @@ yyreduce:
     break;
 
   case 831:
-
-/* Line 1806 of yacc.c  */
-#line 5481 "gram.y"
+#line 5482 "gram.y"
     {
 				AccessPriv *n = makeNode(AccessPriv);
 				n->priv_name = pstrdup((yyvsp[(1) - (2)].keyword));
@@ -27666,9 +26177,7 @@ yyreduce:
     break;
 
   case 832:
-
-/* Line 1806 of yacc.c  */
-#line 5488 "gram.y"
+#line 5489 "gram.y"
     {
 				AccessPriv *n = makeNode(AccessPriv);
 				n->priv_name = pstrdup((yyvsp[(1) - (2)].keyword));
@@ -27678,9 +26187,7 @@ yyreduce:
     break;
 
   case 833:
-
-/* Line 1806 of yacc.c  */
-#line 5495 "gram.y"
+#line 5496 "gram.y"
     {
 				AccessPriv *n = makeNode(AccessPriv);
 				n->priv_name = (yyvsp[(1) - (2)].str);
@@ -27690,9 +26197,7 @@ yyreduce:
     break;
 
   case 834:
-
-/* Line 1806 of yacc.c  */
-#line 5509 "gram.y"
+#line 5510 "gram.y"
     {
 					PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
 					n->targtype = ACL_TARGET_OBJECT;
@@ -27703,9 +26208,7 @@ yyreduce:
     break;
 
   case 835:
-
-/* Line 1806 of yacc.c  */
-#line 5517 "gram.y"
+#line 5518 "gram.y"
     {
 					PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
 					n->targtype = ACL_TARGET_OBJECT;
@@ -27716,9 +26219,7 @@ yyreduce:
     break;
 
   case 836:
-
-/* Line 1806 of yacc.c  */
-#line 5525 "gram.y"
+#line 5526 "gram.y"
     {
 					PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
 					n->targtype = ACL_TARGET_OBJECT;
@@ -27729,9 +26230,7 @@ yyreduce:
     break;
 
   case 837:
-
-/* Line 1806 of yacc.c  */
-#line 5533 "gram.y"
+#line 5534 "gram.y"
     {
 					PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
 					n->targtype = ACL_TARGET_OBJECT;
@@ -27742,9 +26241,7 @@ yyreduce:
     break;
 
   case 838:
-
-/* Line 1806 of yacc.c  */
-#line 5541 "gram.y"
+#line 5542 "gram.y"
     {
 					PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
 					n->targtype = ACL_TARGET_OBJECT;
@@ -27755,9 +26252,7 @@ yyreduce:
     break;
 
   case 839:
-
-/* Line 1806 of yacc.c  */
-#line 5549 "gram.y"
+#line 5550 "gram.y"
     {
 					PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
 					n->targtype = ACL_TARGET_OBJECT;
@@ -27768,9 +26263,7 @@ yyreduce:
     break;
 
   case 840:
-
-/* Line 1806 of yacc.c  */
-#line 5557 "gram.y"
+#line 5558 "gram.y"
     {
 					PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
 					n->targtype = ACL_TARGET_OBJECT;
@@ -27781,9 +26274,7 @@ yyreduce:
     break;
 
   case 841:
-
-/* Line 1806 of yacc.c  */
-#line 5565 "gram.y"
+#line 5566 "gram.y"
     {
 					PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
 					n->targtype = ACL_TARGET_OBJECT;
@@ -27794,9 +26285,7 @@ yyreduce:
     break;
 
   case 842:
-
-/* Line 1806 of yacc.c  */
-#line 5573 "gram.y"
+#line 5574 "gram.y"
     {
 					PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
 					n->targtype = ACL_TARGET_OBJECT;
@@ -27807,9 +26296,7 @@ yyreduce:
     break;
 
   case 843:
-
-/* Line 1806 of yacc.c  */
-#line 5581 "gram.y"
+#line 5582 "gram.y"
     {
 					PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
 					n->targtype = ACL_TARGET_OBJECT;
@@ -27820,9 +26307,7 @@ yyreduce:
     break;
 
   case 844:
-
-/* Line 1806 of yacc.c  */
-#line 5589 "gram.y"
+#line 5590 "gram.y"
     {
 					PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
 					n->targtype = ACL_TARGET_OBJECT;
@@ -27833,9 +26318,7 @@ yyreduce:
     break;
 
   case 845:
-
-/* Line 1806 of yacc.c  */
-#line 5597 "gram.y"
+#line 5598 "gram.y"
     {
 					PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
 					n->targtype = ACL_TARGET_OBJECT;
@@ -27846,9 +26329,7 @@ yyreduce:
     break;
 
   case 846:
-
-/* Line 1806 of yacc.c  */
-#line 5605 "gram.y"
+#line 5606 "gram.y"
     {
 					PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
 					n->targtype = ACL_TARGET_OBJECT;
@@ -27859,9 +26340,7 @@ yyreduce:
     break;
 
   case 847:
-
-/* Line 1806 of yacc.c  */
-#line 5613 "gram.y"
+#line 5614 "gram.y"
     {
 					PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
 					n->targtype = ACL_TARGET_ALL_IN_SCHEMA;
@@ -27872,9 +26351,7 @@ yyreduce:
     break;
 
   case 848:
-
-/* Line 1806 of yacc.c  */
-#line 5621 "gram.y"
+#line 5622 "gram.y"
     {
 					PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
 					n->targtype = ACL_TARGET_ALL_IN_SCHEMA;
@@ -27885,9 +26362,7 @@ yyreduce:
     break;
 
   case 849:
-
-/* Line 1806 of yacc.c  */
-#line 5629 "gram.y"
+#line 5630 "gram.y"
     {
 					PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
 					n->targtype = ACL_TARGET_ALL_IN_SCHEMA;
@@ -27898,23 +26373,17 @@ yyreduce:
     break;
 
   case 850:
-
-/* Line 1806 of yacc.c  */
-#line 5640 "gram.y"
+#line 5641 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); }
     break;
 
   case 851:
-
-/* Line 1806 of yacc.c  */
-#line 5641 "gram.y"
+#line 5642 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); }
     break;
 
   case 852:
-
-/* Line 1806 of yacc.c  */
-#line 5645 "gram.y"
+#line 5646 "gram.y"
     {
 					PrivGrantee *n = makeNode(PrivGrantee);
 					/* This hack lets us avoid reserving PUBLIC as a keyword*/
@@ -27927,9 +26396,7 @@ yyreduce:
     break;
 
   case 853:
-
-/* Line 1806 of yacc.c  */
-#line 5655 "gram.y"
+#line 5656 "gram.y"
     {
 					PrivGrantee *n = makeNode(PrivGrantee);
 					/* Treat GROUP PUBLIC as a synonym for PUBLIC */
@@ -27942,37 +26409,27 @@ yyreduce:
     break;
 
   case 854:
-
-/* Line 1806 of yacc.c  */
-#line 5668 "gram.y"
+#line 5669 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 855:
-
-/* Line 1806 of yacc.c  */
-#line 5669 "gram.y"
+#line 5670 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 856:
-
-/* Line 1806 of yacc.c  */
-#line 5673 "gram.y"
+#line 5674 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].funwithargs)); }
     break;
 
   case 857:
-
-/* Line 1806 of yacc.c  */
-#line 5675 "gram.y"
+#line 5676 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].funwithargs)); }
     break;
 
   case 858:
-
-/* Line 1806 of yacc.c  */
-#line 5680 "gram.y"
+#line 5681 "gram.y"
     {
 					FuncWithArgs *n = makeNode(FuncWithArgs);
 					n->funcname = (yyvsp[(1) - (2)].list);
@@ -27982,9 +26439,7 @@ yyreduce:
     break;
 
   case 859:
-
-/* Line 1806 of yacc.c  */
-#line 5696 "gram.y"
+#line 5697 "gram.y"
     {
 					GrantRoleStmt *n = makeNode(GrantRoleStmt);
 					n->is_grant = true;
@@ -27997,9 +26452,7 @@ yyreduce:
     break;
 
   case 860:
-
-/* Line 1806 of yacc.c  */
-#line 5709 "gram.y"
+#line 5710 "gram.y"
     {
 					GrantRoleStmt *n = makeNode(GrantRoleStmt);
 					n->is_grant = false;
@@ -28012,9 +26465,7 @@ yyreduce:
     break;
 
   case 861:
-
-/* Line 1806 of yacc.c  */
-#line 5719 "gram.y"
+#line 5720 "gram.y"
     {
 					GrantRoleStmt *n = makeNode(GrantRoleStmt);
 					n->is_grant = false;
@@ -28027,37 +26478,27 @@ yyreduce:
     break;
 
   case 862:
-
-/* Line 1806 of yacc.c  */
-#line 5730 "gram.y"
+#line 5731 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 863:
-
-/* Line 1806 of yacc.c  */
-#line 5731 "gram.y"
+#line 5732 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 864:
-
-/* Line 1806 of yacc.c  */
-#line 5734 "gram.y"
+#line 5735 "gram.y"
     { (yyval.str) = (yyvsp[(3) - (3)].str); }
     break;
 
   case 865:
-
-/* Line 1806 of yacc.c  */
-#line 5735 "gram.y"
+#line 5736 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 866:
-
-/* Line 1806 of yacc.c  */
-#line 5746 "gram.y"
+#line 5747 "gram.y"
     {
 					AlterDefaultPrivilegesStmt *n = makeNode(AlterDefaultPrivilegesStmt);
 					n->options = (yyvsp[(4) - (5)].list);
@@ -28067,50 +26508,38 @@ yyreduce:
     break;
 
   case 867:
-
-/* Line 1806 of yacc.c  */
-#line 5755 "gram.y"
+#line 5756 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); }
     break;
 
   case 868:
-
-/* Line 1806 of yacc.c  */
-#line 5756 "gram.y"
+#line 5757 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 869:
-
-/* Line 1806 of yacc.c  */
-#line 5761 "gram.y"
+#line 5762 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("schemas", (Node *)(yyvsp[(3) - (3)].list));
 				}
     break;
 
   case 870:
-
-/* Line 1806 of yacc.c  */
-#line 5765 "gram.y"
+#line 5766 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("roles", (Node *)(yyvsp[(3) - (3)].list));
 				}
     break;
 
   case 871:
-
-/* Line 1806 of yacc.c  */
-#line 5769 "gram.y"
+#line 5770 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("roles", (Node *)(yyvsp[(3) - (3)].list));
 				}
     break;
 
   case 872:
-
-/* Line 1806 of yacc.c  */
-#line 5781 "gram.y"
+#line 5782 "gram.y"
     {
 					GrantStmt *n = makeNode(GrantStmt);
 					n->is_grant = true;
@@ -28125,9 +26554,7 @@ yyreduce:
     break;
 
   case 873:
-
-/* Line 1806 of yacc.c  */
-#line 5794 "gram.y"
+#line 5795 "gram.y"
     {
 					GrantStmt *n = makeNode(GrantStmt);
 					n->is_grant = false;
@@ -28143,9 +26570,7 @@ yyreduce:
     break;
 
   case 874:
-
-/* Line 1806 of yacc.c  */
-#line 5808 "gram.y"
+#line 5809 "gram.y"
     {
 					GrantStmt *n = makeNode(GrantStmt);
 					n->is_grant = false;
@@ -28161,37 +26586,27 @@ yyreduce:
     break;
 
   case 875:
-
-/* Line 1806 of yacc.c  */
-#line 5823 "gram.y"
+#line 5824 "gram.y"
     { (yyval.ival) = ACL_OBJECT_RELATION; }
     break;
 
   case 876:
-
-/* Line 1806 of yacc.c  */
-#line 5824 "gram.y"
+#line 5825 "gram.y"
     { (yyval.ival) = ACL_OBJECT_FUNCTION; }
     break;
 
   case 877:
-
-/* Line 1806 of yacc.c  */
-#line 5825 "gram.y"
+#line 5826 "gram.y"
     { (yyval.ival) = ACL_OBJECT_SEQUENCE; }
     break;
 
   case 878:
-
-/* Line 1806 of yacc.c  */
-#line 5826 "gram.y"
+#line 5827 "gram.y"
     { (yyval.ival) = ACL_OBJECT_TYPE; }
     break;
 
   case 879:
-
-/* Line 1806 of yacc.c  */
-#line 5841 "gram.y"
+#line 5842 "gram.y"
     {
 					IndexStmt *n = makeNode(IndexStmt);
 					n->unique = (yyvsp[(2) - (14)].boolean);
@@ -28216,79 +26631,57 @@ yyreduce:
     break;
 
   case 880:
-
-/* Line 1806 of yacc.c  */
-#line 5865 "gram.y"
+#line 5866 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 881:
-
-/* Line 1806 of yacc.c  */
-#line 5866 "gram.y"
+#line 5867 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 882:
-
-/* Line 1806 of yacc.c  */
-#line 5870 "gram.y"
+#line 5871 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 883:
-
-/* Line 1806 of yacc.c  */
-#line 5871 "gram.y"
+#line 5872 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 884:
-
-/* Line 1806 of yacc.c  */
-#line 5875 "gram.y"
+#line 5876 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 885:
-
-/* Line 1806 of yacc.c  */
-#line 5876 "gram.y"
+#line 5877 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 886:
-
-/* Line 1806 of yacc.c  */
-#line 5880 "gram.y"
+#line 5881 "gram.y"
     { (yyval.str) = (yyvsp[(2) - (2)].str); }
     break;
 
   case 887:
-
-/* Line 1806 of yacc.c  */
-#line 5881 "gram.y"
+#line 5882 "gram.y"
     { (yyval.str) = DEFAULT_INDEX_TYPE; }
     break;
 
   case 888:
-
-/* Line 1806 of yacc.c  */
-#line 5884 "gram.y"
+#line 5885 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].ielem)); }
     break;
 
   case 889:
-
-/* Line 1806 of yacc.c  */
-#line 5885 "gram.y"
+#line 5886 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].ielem)); }
     break;
 
   case 890:
-
-/* Line 1806 of yacc.c  */
-#line 5894 "gram.y"
+#line 5895 "gram.y"
     {
 					(yyval.ielem) = makeNode(IndexElem);
 					(yyval.ielem)->name = (yyvsp[(1) - (5)].str);
@@ -28302,9 +26695,7 @@ yyreduce:
     break;
 
   case 891:
-
-/* Line 1806 of yacc.c  */
-#line 5905 "gram.y"
+#line 5906 "gram.y"
     {
 					(yyval.ielem) = makeNode(IndexElem);
 					(yyval.ielem)->name = NULL;
@@ -28318,9 +26709,7 @@ yyreduce:
     break;
 
   case 892:
-
-/* Line 1806 of yacc.c  */
-#line 5916 "gram.y"
+#line 5917 "gram.y"
     {
 					(yyval.ielem) = makeNode(IndexElem);
 					(yyval.ielem)->name = NULL;
@@ -28334,86 +26723,62 @@ yyreduce:
     break;
 
   case 893:
-
-/* Line 1806 of yacc.c  */
-#line 5928 "gram.y"
+#line 5929 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (2)].list); }
     break;
 
   case 894:
-
-/* Line 1806 of yacc.c  */
-#line 5929 "gram.y"
+#line 5930 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 895:
-
-/* Line 1806 of yacc.c  */
-#line 5932 "gram.y"
+#line 5933 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 896:
-
-/* Line 1806 of yacc.c  */
-#line 5933 "gram.y"
+#line 5934 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (2)].list); }
     break;
 
   case 897:
-
-/* Line 1806 of yacc.c  */
-#line 5934 "gram.y"
+#line 5935 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 898:
-
-/* Line 1806 of yacc.c  */
-#line 5937 "gram.y"
+#line 5938 "gram.y"
     { (yyval.ival) = SORTBY_ASC; }
     break;
 
   case 899:
-
-/* Line 1806 of yacc.c  */
-#line 5938 "gram.y"
+#line 5939 "gram.y"
     { (yyval.ival) = SORTBY_DESC; }
     break;
 
   case 900:
-
-/* Line 1806 of yacc.c  */
-#line 5939 "gram.y"
+#line 5940 "gram.y"
     { (yyval.ival) = SORTBY_DEFAULT; }
     break;
 
   case 901:
-
-/* Line 1806 of yacc.c  */
-#line 5942 "gram.y"
+#line 5943 "gram.y"
     { (yyval.ival) = SORTBY_NULLS_FIRST; }
     break;
 
   case 902:
-
-/* Line 1806 of yacc.c  */
-#line 5943 "gram.y"
+#line 5944 "gram.y"
     { (yyval.ival) = SORTBY_NULLS_LAST; }
     break;
 
   case 903:
-
-/* Line 1806 of yacc.c  */
-#line 5944 "gram.y"
+#line 5945 "gram.y"
     { (yyval.ival) = SORTBY_NULLS_DEFAULT; }
     break;
 
   case 904:
-
-/* Line 1806 of yacc.c  */
-#line 5962 "gram.y"
+#line 5963 "gram.y"
     {
 					CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
 					n->replace = (yyvsp[(2) - (9)].boolean);
@@ -28427,9 +26792,7 @@ yyreduce:
     break;
 
   case 905:
-
-/* Line 1806 of yacc.c  */
-#line 5974 "gram.y"
+#line 5975 "gram.y"
     {
 					CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
 					n->replace = (yyvsp[(2) - (12)].boolean);
@@ -28444,9 +26807,7 @@ yyreduce:
     break;
 
   case 906:
-
-/* Line 1806 of yacc.c  */
-#line 5987 "gram.y"
+#line 5988 "gram.y"
     {
 					CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
 					n->replace = (yyvsp[(2) - (7)].boolean);
@@ -28460,79 +26821,57 @@ yyreduce:
     break;
 
   case 907:
-
-/* Line 1806 of yacc.c  */
-#line 6000 "gram.y"
+#line 6001 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 908:
-
-/* Line 1806 of yacc.c  */
-#line 6001 "gram.y"
+#line 6002 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 909:
-
-/* Line 1806 of yacc.c  */
-#line 6004 "gram.y"
+#line 6005 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (3)].list); }
     break;
 
   case 910:
-
-/* Line 1806 of yacc.c  */
-#line 6005 "gram.y"
+#line 6006 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 911:
-
-/* Line 1806 of yacc.c  */
-#line 6009 "gram.y"
+#line 6010 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].fun_param)); }
     break;
 
   case 912:
-
-/* Line 1806 of yacc.c  */
-#line 6010 "gram.y"
+#line 6011 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].fun_param)); }
     break;
 
   case 913:
-
-/* Line 1806 of yacc.c  */
-#line 6018 "gram.y"
+#line 6019 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (3)].list); }
     break;
 
   case 914:
-
-/* Line 1806 of yacc.c  */
-#line 6019 "gram.y"
+#line 6020 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 915:
-
-/* Line 1806 of yacc.c  */
-#line 6023 "gram.y"
+#line 6024 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].fun_param)); }
     break;
 
   case 916:
-
-/* Line 1806 of yacc.c  */
-#line 6025 "gram.y"
+#line 6026 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].fun_param)); }
     break;
 
   case 917:
-
-/* Line 1806 of yacc.c  */
-#line 6040 "gram.y"
+#line 6041 "gram.y"
     {
 					FunctionParameter *n = makeNode(FunctionParameter);
 					n->name = (yyvsp[(2) - (3)].str);
@@ -28544,9 +26883,7 @@ yyreduce:
     break;
 
   case 918:
-
-/* Line 1806 of yacc.c  */
-#line 6049 "gram.y"
+#line 6050 "gram.y"
     {
 					FunctionParameter *n = makeNode(FunctionParameter);
 					n->name = (yyvsp[(1) - (3)].str);
@@ -28558,9 +26895,7 @@ yyreduce:
     break;
 
   case 919:
-
-/* Line 1806 of yacc.c  */
-#line 6058 "gram.y"
+#line 6059 "gram.y"
     {
 					FunctionParameter *n = makeNode(FunctionParameter);
 					n->name = (yyvsp[(1) - (2)].str);
@@ -28572,9 +26907,7 @@ yyreduce:
     break;
 
   case 920:
-
-/* Line 1806 of yacc.c  */
-#line 6067 "gram.y"
+#line 6068 "gram.y"
     {
 					FunctionParameter *n = makeNode(FunctionParameter);
 					n->name = NULL;
@@ -28586,9 +26919,7 @@ yyreduce:
     break;
 
   case 921:
-
-/* Line 1806 of yacc.c  */
-#line 6076 "gram.y"
+#line 6077 "gram.y"
     {
 					FunctionParameter *n = makeNode(FunctionParameter);
 					n->name = NULL;
@@ -28600,44 +26931,32 @@ yyreduce:
     break;
 
   case 922:
-
-/* Line 1806 of yacc.c  */
-#line 6087 "gram.y"
+#line 6088 "gram.y"
     { (yyval.fun_param_mode) = FUNC_PARAM_IN; }
     break;
 
   case 923:
-
-/* Line 1806 of yacc.c  */
-#line 6088 "gram.y"
+#line 6089 "gram.y"
     { (yyval.fun_param_mode) = FUNC_PARAM_OUT; }
     break;
 
   case 924:
-
-/* Line 1806 of yacc.c  */
-#line 6089 "gram.y"
+#line 6090 "gram.y"
     { (yyval.fun_param_mode) = FUNC_PARAM_INOUT; }
     break;
 
   case 925:
-
-/* Line 1806 of yacc.c  */
-#line 6090 "gram.y"
+#line 6091 "gram.y"
     { (yyval.fun_param_mode) = FUNC_PARAM_INOUT; }
     break;
 
   case 926:
-
-/* Line 1806 of yacc.c  */
-#line 6091 "gram.y"
+#line 6092 "gram.y"
     { (yyval.fun_param_mode) = FUNC_PARAM_VARIADIC; }
     break;
 
   case 928:
-
-/* Line 1806 of yacc.c  */
-#line 6102 "gram.y"
+#line 6103 "gram.y"
     {
 					/* We can catch over-specified results here if we want to,
 					 * but for now better to silently swallow typmod, etc.
@@ -28648,16 +26967,12 @@ yyreduce:
     break;
 
   case 929:
-
-/* Line 1806 of yacc.c  */
-#line 6116 "gram.y"
+#line 6117 "gram.y"
     { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); }
     break;
 
   case 930:
-
-/* Line 1806 of yacc.c  */
-#line 6118 "gram.y"
+#line 6119 "gram.y"
     {
 					(yyval.typnam) = makeTypeNameFromNameList(lcons(makeString((yyvsp[(1) - (4)].str)), (yyvsp[(2) - (4)].list)));
 					(yyval.typnam)->pct_type = true;
@@ -28666,9 +26981,7 @@ yyreduce:
     break;
 
   case 931:
-
-/* Line 1806 of yacc.c  */
-#line 6124 "gram.y"
+#line 6125 "gram.y"
     {
 					(yyval.typnam) = makeTypeNameFromNameList(lcons(makeString((yyvsp[(2) - (5)].str)), (yyvsp[(3) - (5)].list)));
 					(yyval.typnam)->pct_type = true;
@@ -28678,18 +26991,14 @@ yyreduce:
     break;
 
   case 932:
-
-/* Line 1806 of yacc.c  */
-#line 6134 "gram.y"
+#line 6135 "gram.y"
     {
 					(yyval.fun_param) = (yyvsp[(1) - (1)].fun_param);
 				}
     break;
 
   case 933:
-
-/* Line 1806 of yacc.c  */
-#line 6138 "gram.y"
+#line 6139 "gram.y"
     {
 					(yyval.fun_param) = (yyvsp[(1) - (3)].fun_param);
 					(yyval.fun_param)->defexpr = (yyvsp[(3) - (3)].node);
@@ -28697,9 +27006,7 @@ yyreduce:
     break;
 
   case 934:
-
-/* Line 1806 of yacc.c  */
-#line 6143 "gram.y"
+#line 6144 "gram.y"
     {
 					(yyval.fun_param) = (yyvsp[(1) - (3)].fun_param);
 					(yyval.fun_param)->defexpr = (yyvsp[(3) - (3)].node);
@@ -28707,149 +27014,115 @@ yyreduce:
     break;
 
   case 935:
-
-/* Line 1806 of yacc.c  */
-#line 6152 "gram.y"
+#line 6153 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); }
     break;
 
   case 936:
-
-/* Line 1806 of yacc.c  */
-#line 6153 "gram.y"
+#line 6154 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); }
     break;
 
   case 937:
-
-/* Line 1806 of yacc.c  */
-#line 6161 "gram.y"
+#line 6162 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("strict", (Node *)makeInteger(FALSE));
 				}
     break;
 
   case 938:
-
-/* Line 1806 of yacc.c  */
-#line 6165 "gram.y"
+#line 6166 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("strict", (Node *)makeInteger(TRUE));
 				}
     break;
 
   case 939:
-
-/* Line 1806 of yacc.c  */
-#line 6169 "gram.y"
+#line 6170 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("strict", (Node *)makeInteger(TRUE));
 				}
     break;
 
   case 940:
-
-/* Line 1806 of yacc.c  */
-#line 6173 "gram.y"
+#line 6174 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("volatility", (Node *)makeString("immutable"));
 				}
     break;
 
   case 941:
-
-/* Line 1806 of yacc.c  */
-#line 6177 "gram.y"
+#line 6178 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("volatility", (Node *)makeString("stable"));
 				}
     break;
 
   case 942:
-
-/* Line 1806 of yacc.c  */
-#line 6181 "gram.y"
+#line 6182 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("volatility", (Node *)makeString("volatile"));
 				}
     break;
 
   case 943:
-
-/* Line 1806 of yacc.c  */
-#line 6185 "gram.y"
+#line 6186 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("security", (Node *)makeInteger(TRUE));
 				}
     break;
 
   case 944:
-
-/* Line 1806 of yacc.c  */
-#line 6189 "gram.y"
+#line 6190 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("security", (Node *)makeInteger(FALSE));
 				}
     break;
 
   case 945:
-
-/* Line 1806 of yacc.c  */
-#line 6193 "gram.y"
+#line 6194 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("security", (Node *)makeInteger(TRUE));
 				}
     break;
 
   case 946:
-
-/* Line 1806 of yacc.c  */
-#line 6197 "gram.y"
+#line 6198 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("security", (Node *)makeInteger(FALSE));
 				}
     break;
 
   case 947:
-
-/* Line 1806 of yacc.c  */
-#line 6201 "gram.y"
+#line 6202 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("leakproof", (Node *)makeInteger(TRUE));
 				}
     break;
 
   case 948:
-
-/* Line 1806 of yacc.c  */
-#line 6205 "gram.y"
+#line 6206 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("leakproof", (Node *)makeInteger(FALSE));
 				}
     break;
 
   case 949:
-
-/* Line 1806 of yacc.c  */
-#line 6209 "gram.y"
+#line 6210 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("cost", (Node *)(yyvsp[(2) - (2)].value));
 				}
     break;
 
   case 950:
-
-/* Line 1806 of yacc.c  */
-#line 6213 "gram.y"
+#line 6214 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("rows", (Node *)(yyvsp[(2) - (2)].value));
 				}
     break;
 
   case 951:
-
-/* Line 1806 of yacc.c  */
-#line 6217 "gram.y"
+#line 6218 "gram.y"
     {
 					/* we abuse the normal content of a DefElem here */
 					(yyval.defelt) = makeDefElem("set", (Node *)(yyvsp[(1) - (1)].vsetstmt));
@@ -28857,75 +27130,57 @@ yyreduce:
     break;
 
   case 952:
-
-/* Line 1806 of yacc.c  */
-#line 6225 "gram.y"
+#line 6226 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("as", (Node *)(yyvsp[(2) - (2)].list));
 				}
     break;
 
   case 953:
-
-/* Line 1806 of yacc.c  */
-#line 6229 "gram.y"
+#line 6230 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("language", (Node *)makeString((yyvsp[(2) - (2)].str)));
 				}
     break;
 
   case 954:
-
-/* Line 1806 of yacc.c  */
-#line 6233 "gram.y"
+#line 6234 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("window", (Node *)makeInteger(TRUE));
 				}
     break;
 
   case 955:
-
-/* Line 1806 of yacc.c  */
-#line 6237 "gram.y"
+#line 6238 "gram.y"
     {
 					(yyval.defelt) = (yyvsp[(1) - (1)].defelt);
 				}
     break;
 
   case 956:
-
-/* Line 1806 of yacc.c  */
-#line 6242 "gram.y"
+#line 6243 "gram.y"
     { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); }
     break;
 
   case 957:
-
-/* Line 1806 of yacc.c  */
-#line 6244 "gram.y"
+#line 6245 "gram.y"
     {
 					(yyval.list) = list_make2(makeString((yyvsp[(1) - (3)].str)), makeString((yyvsp[(3) - (3)].str)));
 				}
     break;
 
   case 958:
-
-/* Line 1806 of yacc.c  */
-#line 6250 "gram.y"
+#line 6251 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (2)].list); }
     break;
 
   case 959:
-
-/* Line 1806 of yacc.c  */
-#line 6251 "gram.y"
+#line 6252 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 960:
-
-/* Line 1806 of yacc.c  */
-#line 6255 "gram.y"
+#line 6256 "gram.y"
     {
 					FunctionParameter *n = makeNode(FunctionParameter);
 					n->name = (yyvsp[(1) - (2)].str);
@@ -28937,27 +27192,21 @@ yyreduce:
     break;
 
   case 961:
-
-/* Line 1806 of yacc.c  */
-#line 6267 "gram.y"
+#line 6268 "gram.y"
     {
 					(yyval.list) = list_make1((yyvsp[(1) - (1)].fun_param));
 				}
     break;
 
   case 962:
-
-/* Line 1806 of yacc.c  */
-#line 6271 "gram.y"
+#line 6272 "gram.y"
     {
 					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].fun_param));
 				}
     break;
 
   case 963:
-
-/* Line 1806 of yacc.c  */
-#line 6286 "gram.y"
+#line 6287 "gram.y"
     {
 					AlterFunctionStmt *n = makeNode(AlterFunctionStmt);
 					n->func = (yyvsp[(3) - (5)].funwithargs);
@@ -28967,23 +27216,17 @@ yyreduce:
     break;
 
   case 964:
-
-/* Line 1806 of yacc.c  */
-#line 6296 "gram.y"
+#line 6297 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); }
     break;
 
   case 965:
-
-/* Line 1806 of yacc.c  */
-#line 6297 "gram.y"
+#line 6298 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); }
     break;
 
   case 968:
-
-/* Line 1806 of yacc.c  */
-#line 6319 "gram.y"
+#line 6320 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_FUNCTION;
@@ -28997,9 +27240,7 @@ yyreduce:
     break;
 
   case 969:
-
-/* Line 1806 of yacc.c  */
-#line 6330 "gram.y"
+#line 6331 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_FUNCTION;
@@ -29013,9 +27254,7 @@ yyreduce:
     break;
 
   case 970:
-
-/* Line 1806 of yacc.c  */
-#line 6344 "gram.y"
+#line 6345 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_AGGREGATE;
@@ -29029,9 +27268,7 @@ yyreduce:
     break;
 
   case 971:
-
-/* Line 1806 of yacc.c  */
-#line 6355 "gram.y"
+#line 6356 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_AGGREGATE;
@@ -29045,9 +27282,7 @@ yyreduce:
     break;
 
   case 972:
-
-/* Line 1806 of yacc.c  */
-#line 6369 "gram.y"
+#line 6370 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_OPERATOR;
@@ -29061,9 +27296,7 @@ yyreduce:
     break;
 
   case 973:
-
-/* Line 1806 of yacc.c  */
-#line 6380 "gram.y"
+#line 6381 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_OPERATOR;
@@ -29077,9 +27310,7 @@ yyreduce:
     break;
 
   case 974:
-
-/* Line 1806 of yacc.c  */
-#line 6394 "gram.y"
+#line 6395 "gram.y"
     {
 				   ereport(ERROR,
 						   (errcode(ERRCODE_SYNTAX_ERROR),
@@ -29090,44 +27321,32 @@ yyreduce:
     break;
 
   case 975:
-
-/* Line 1806 of yacc.c  */
-#line 6402 "gram.y"
+#line 6403 "gram.y"
     { (yyval.list) = list_make2((yyvsp[(2) - (5)].typnam), (yyvsp[(4) - (5)].typnam)); }
     break;
 
   case 976:
-
-/* Line 1806 of yacc.c  */
-#line 6404 "gram.y"
+#line 6405 "gram.y"
     { (yyval.list) = list_make2(NULL, (yyvsp[(4) - (5)].typnam)); }
     break;
 
   case 977:
-
-/* Line 1806 of yacc.c  */
-#line 6406 "gram.y"
+#line 6407 "gram.y"
     { (yyval.list) = list_make2((yyvsp[(2) - (5)].typnam), NULL); }
     break;
 
   case 978:
-
-/* Line 1806 of yacc.c  */
-#line 6411 "gram.y"
+#line 6412 "gram.y"
     { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); }
     break;
 
   case 979:
-
-/* Line 1806 of yacc.c  */
-#line 6413 "gram.y"
+#line 6414 "gram.y"
     { (yyval.list) = lcons(makeString((yyvsp[(1) - (3)].str)), (yyvsp[(3) - (3)].list)); }
     break;
 
   case 980:
-
-/* Line 1806 of yacc.c  */
-#line 6426 "gram.y"
+#line 6427 "gram.y"
     {
 					DoStmt *n = makeNode(DoStmt);
 					n->args = (yyvsp[(2) - (2)].list);
@@ -29136,41 +27355,31 @@ yyreduce:
     break;
 
   case 981:
-
-/* Line 1806 of yacc.c  */
-#line 6434 "gram.y"
+#line 6435 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); }
     break;
 
   case 982:
-
-/* Line 1806 of yacc.c  */
-#line 6435 "gram.y"
+#line 6436 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); }
     break;
 
   case 983:
-
-/* Line 1806 of yacc.c  */
-#line 6440 "gram.y"
+#line 6441 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("as", (Node *)makeString((yyvsp[(1) - (1)].str)));
 				}
     break;
 
   case 984:
-
-/* Line 1806 of yacc.c  */
-#line 6444 "gram.y"
+#line 6445 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("language", (Node *)makeString((yyvsp[(2) - (2)].str)));
 				}
     break;
 
   case 985:
-
-/* Line 1806 of yacc.c  */
-#line 6457 "gram.y"
+#line 6458 "gram.y"
     {
 					CreateCastStmt *n = makeNode(CreateCastStmt);
 					n->sourcetype = (yyvsp[(4) - (11)].typnam);
@@ -29183,9 +27392,7 @@ yyreduce:
     break;
 
   case 986:
-
-/* Line 1806 of yacc.c  */
-#line 6468 "gram.y"
+#line 6469 "gram.y"
     {
 					CreateCastStmt *n = makeNode(CreateCastStmt);
 					n->sourcetype = (yyvsp[(4) - (10)].typnam);
@@ -29198,9 +27405,7 @@ yyreduce:
     break;
 
   case 987:
-
-/* Line 1806 of yacc.c  */
-#line 6479 "gram.y"
+#line 6480 "gram.y"
     {
 					CreateCastStmt *n = makeNode(CreateCastStmt);
 					n->sourcetype = (yyvsp[(4) - (10)].typnam);
@@ -29213,30 +27418,22 @@ yyreduce:
     break;
 
   case 988:
-
-/* Line 1806 of yacc.c  */
-#line 6490 "gram.y"
+#line 6491 "gram.y"
     { (yyval.ival) = COERCION_IMPLICIT; }
     break;
 
   case 989:
-
-/* Line 1806 of yacc.c  */
-#line 6491 "gram.y"
+#line 6492 "gram.y"
     { (yyval.ival) = COERCION_ASSIGNMENT; }
     break;
 
   case 990:
-
-/* Line 1806 of yacc.c  */
-#line 6492 "gram.y"
+#line 6493 "gram.y"
     { (yyval.ival) = COERCION_EXPLICIT; }
     break;
 
   case 991:
-
-/* Line 1806 of yacc.c  */
-#line 6497 "gram.y"
+#line 6498 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_CAST;
@@ -29250,23 +27447,17 @@ yyreduce:
     break;
 
   case 992:
-
-/* Line 1806 of yacc.c  */
-#line 6509 "gram.y"
+#line 6510 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 993:
-
-/* Line 1806 of yacc.c  */
-#line 6510 "gram.y"
+#line 6511 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 994:
-
-/* Line 1806 of yacc.c  */
-#line 6525 "gram.y"
+#line 6526 "gram.y"
     {
 					ReindexStmt *n = makeNode(ReindexStmt);
 					n->kind = (yyvsp[(2) - (4)].objtype);
@@ -29277,9 +27468,7 @@ yyreduce:
     break;
 
   case 995:
-
-/* Line 1806 of yacc.c  */
-#line 6533 "gram.y"
+#line 6534 "gram.y"
     {
 					ReindexStmt *n = makeNode(ReindexStmt);
 					n->kind = OBJECT_DATABASE;
@@ -29292,9 +27481,7 @@ yyreduce:
     break;
 
   case 996:
-
-/* Line 1806 of yacc.c  */
-#line 6543 "gram.y"
+#line 6544 "gram.y"
     {
 					ReindexStmt *n = makeNode(ReindexStmt);
 					n->kind = OBJECT_DATABASE;
@@ -29307,37 +27494,27 @@ yyreduce:
     break;
 
   case 997:
-
-/* Line 1806 of yacc.c  */
-#line 6555 "gram.y"
+#line 6556 "gram.y"
     { (yyval.objtype) = OBJECT_INDEX; }
     break;
 
   case 998:
-
-/* Line 1806 of yacc.c  */
-#line 6556 "gram.y"
+#line 6557 "gram.y"
     { (yyval.objtype) = OBJECT_TABLE; }
     break;
 
   case 999:
-
-/* Line 1806 of yacc.c  */
-#line 6559 "gram.y"
+#line 6560 "gram.y"
     {  (yyval.boolean) = TRUE; }
     break;
 
   case 1000:
-
-/* Line 1806 of yacc.c  */
-#line 6560 "gram.y"
+#line 6561 "gram.y"
     {  (yyval.boolean) = FALSE; }
     break;
 
   case 1001:
-
-/* Line 1806 of yacc.c  */
-#line 6571 "gram.y"
+#line 6572 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_AGGREGATE;
@@ -29350,9 +27527,7 @@ yyreduce:
     break;
 
   case 1002:
-
-/* Line 1806 of yacc.c  */
-#line 6581 "gram.y"
+#line 6582 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_COLLATION;
@@ -29364,9 +27539,7 @@ yyreduce:
     break;
 
   case 1003:
-
-/* Line 1806 of yacc.c  */
-#line 6590 "gram.y"
+#line 6591 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_CONVERSION;
@@ -29378,9 +27551,7 @@ yyreduce:
     break;
 
   case 1004:
-
-/* Line 1806 of yacc.c  */
-#line 6599 "gram.y"
+#line 6600 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_DATABASE;
@@ -29392,9 +27563,7 @@ yyreduce:
     break;
 
   case 1005:
-
-/* Line 1806 of yacc.c  */
-#line 6608 "gram.y"
+#line 6609 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_DOMAIN;
@@ -29406,9 +27575,7 @@ yyreduce:
     break;
 
   case 1006:
-
-/* Line 1806 of yacc.c  */
-#line 6617 "gram.y"
+#line 6618 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_CONSTRAINT;
@@ -29421,9 +27588,7 @@ yyreduce:
     break;
 
   case 1007:
-
-/* Line 1806 of yacc.c  */
-#line 6627 "gram.y"
+#line 6628 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_FDW;
@@ -29435,9 +27600,7 @@ yyreduce:
     break;
 
   case 1008:
-
-/* Line 1806 of yacc.c  */
-#line 6636 "gram.y"
+#line 6637 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_FUNCTION;
@@ -29450,9 +27613,7 @@ yyreduce:
     break;
 
   case 1009:
-
-/* Line 1806 of yacc.c  */
-#line 6646 "gram.y"
+#line 6647 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_ROLE;
@@ -29464,9 +27625,7 @@ yyreduce:
     break;
 
   case 1010:
-
-/* Line 1806 of yacc.c  */
-#line 6655 "gram.y"
+#line 6656 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_LANGUAGE;
@@ -29478,9 +27637,7 @@ yyreduce:
     break;
 
   case 1011:
-
-/* Line 1806 of yacc.c  */
-#line 6664 "gram.y"
+#line 6665 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_OPCLASS;
@@ -29493,9 +27650,7 @@ yyreduce:
     break;
 
   case 1012:
-
-/* Line 1806 of yacc.c  */
-#line 6674 "gram.y"
+#line 6675 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_OPFAMILY;
@@ -29508,9 +27663,7 @@ yyreduce:
     break;
 
   case 1013:
-
-/* Line 1806 of yacc.c  */
-#line 6684 "gram.y"
+#line 6685 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_SCHEMA;
@@ -29522,9 +27675,7 @@ yyreduce:
     break;
 
   case 1014:
-
-/* Line 1806 of yacc.c  */
-#line 6693 "gram.y"
+#line 6694 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_FOREIGN_SERVER;
@@ -29536,9 +27687,7 @@ yyreduce:
     break;
 
   case 1015:
-
-/* Line 1806 of yacc.c  */
-#line 6702 "gram.y"
+#line 6703 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_TABLE;
@@ -29551,9 +27700,7 @@ yyreduce:
     break;
 
   case 1016:
-
-/* Line 1806 of yacc.c  */
-#line 6712 "gram.y"
+#line 6713 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_TABLE;
@@ -29566,9 +27713,7 @@ yyreduce:
     break;
 
   case 1017:
-
-/* Line 1806 of yacc.c  */
-#line 6722 "gram.y"
+#line 6723 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_SEQUENCE;
@@ -29581,9 +27726,7 @@ yyreduce:
     break;
 
   case 1018:
-
-/* Line 1806 of yacc.c  */
-#line 6732 "gram.y"
+#line 6733 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_SEQUENCE;
@@ -29596,9 +27739,7 @@ yyreduce:
     break;
 
   case 1019:
-
-/* Line 1806 of yacc.c  */
-#line 6742 "gram.y"
+#line 6743 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_VIEW;
@@ -29611,9 +27752,7 @@ yyreduce:
     break;
 
   case 1020:
-
-/* Line 1806 of yacc.c  */
-#line 6752 "gram.y"
+#line 6753 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_VIEW;
@@ -29626,9 +27765,7 @@ yyreduce:
     break;
 
   case 1021:
-
-/* Line 1806 of yacc.c  */
-#line 6762 "gram.y"
+#line 6763 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_INDEX;
@@ -29641,9 +27778,7 @@ yyreduce:
     break;
 
   case 1022:
-
-/* Line 1806 of yacc.c  */
-#line 6772 "gram.y"
+#line 6773 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_INDEX;
@@ -29656,9 +27791,7 @@ yyreduce:
     break;
 
   case 1023:
-
-/* Line 1806 of yacc.c  */
-#line 6782 "gram.y"
+#line 6783 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_FOREIGN_TABLE;
@@ -29671,9 +27804,7 @@ yyreduce:
     break;
 
   case 1024:
-
-/* Line 1806 of yacc.c  */
-#line 6792 "gram.y"
+#line 6793 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_FOREIGN_TABLE;
@@ -29686,9 +27817,7 @@ yyreduce:
     break;
 
   case 1025:
-
-/* Line 1806 of yacc.c  */
-#line 6802 "gram.y"
+#line 6803 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_COLUMN;
@@ -29702,9 +27831,7 @@ yyreduce:
     break;
 
   case 1026:
-
-/* Line 1806 of yacc.c  */
-#line 6813 "gram.y"
+#line 6814 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_COLUMN;
@@ -29718,9 +27845,7 @@ yyreduce:
     break;
 
   case 1027:
-
-/* Line 1806 of yacc.c  */
-#line 6824 "gram.y"
+#line 6825 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_CONSTRAINT;
@@ -29733,9 +27858,7 @@ yyreduce:
     break;
 
   case 1028:
-
-/* Line 1806 of yacc.c  */
-#line 6834 "gram.y"
+#line 6835 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_COLUMN;
@@ -29749,9 +27872,7 @@ yyreduce:
     break;
 
   case 1029:
-
-/* Line 1806 of yacc.c  */
-#line 6845 "gram.y"
+#line 6846 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_COLUMN;
@@ -29765,9 +27886,7 @@ yyreduce:
     break;
 
   case 1030:
-
-/* Line 1806 of yacc.c  */
-#line 6856 "gram.y"
+#line 6857 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_TRIGGER;
@@ -29780,9 +27899,7 @@ yyreduce:
     break;
 
   case 1031:
-
-/* Line 1806 of yacc.c  */
-#line 6866 "gram.y"
+#line 6867 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_ROLE;
@@ -29794,9 +27911,7 @@ yyreduce:
     break;
 
   case 1032:
-
-/* Line 1806 of yacc.c  */
-#line 6875 "gram.y"
+#line 6876 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_ROLE;
@@ -29808,9 +27923,7 @@ yyreduce:
     break;
 
   case 1033:
-
-/* Line 1806 of yacc.c  */
-#line 6884 "gram.y"
+#line 6885 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_TABLESPACE;
@@ -29822,9 +27935,7 @@ yyreduce:
     break;
 
   case 1034:
-
-/* Line 1806 of yacc.c  */
-#line 6893 "gram.y"
+#line 6894 "gram.y"
     {
 					AlterTableSpaceOptionsStmt *n =
 						makeNode(AlterTableSpaceOptionsStmt);
@@ -29836,9 +27947,7 @@ yyreduce:
     break;
 
   case 1035:
-
-/* Line 1806 of yacc.c  */
-#line 6902 "gram.y"
+#line 6903 "gram.y"
     {
 					AlterTableSpaceOptionsStmt *n =
 						makeNode(AlterTableSpaceOptionsStmt);
@@ -29850,9 +27959,7 @@ yyreduce:
     break;
 
   case 1036:
-
-/* Line 1806 of yacc.c  */
-#line 6911 "gram.y"
+#line 6912 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_TSPARSER;
@@ -29864,9 +27971,7 @@ yyreduce:
     break;
 
   case 1037:
-
-/* Line 1806 of yacc.c  */
-#line 6920 "gram.y"
+#line 6921 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_TSDICTIONARY;
@@ -29878,9 +27983,7 @@ yyreduce:
     break;
 
   case 1038:
-
-/* Line 1806 of yacc.c  */
-#line 6929 "gram.y"
+#line 6930 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_TSTEMPLATE;
@@ -29892,9 +27995,7 @@ yyreduce:
     break;
 
   case 1039:
-
-/* Line 1806 of yacc.c  */
-#line 6938 "gram.y"
+#line 6939 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_TSCONFIGURATION;
@@ -29906,9 +28007,7 @@ yyreduce:
     break;
 
   case 1040:
-
-/* Line 1806 of yacc.c  */
-#line 6947 "gram.y"
+#line 6948 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_TYPE;
@@ -29920,9 +28019,7 @@ yyreduce:
     break;
 
   case 1041:
-
-/* Line 1806 of yacc.c  */
-#line 6956 "gram.y"
+#line 6957 "gram.y"
     {
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_ATTRIBUTE;
@@ -29937,37 +28034,27 @@ yyreduce:
     break;
 
   case 1042:
-
-/* Line 1806 of yacc.c  */
-#line 6969 "gram.y"
+#line 6970 "gram.y"
     { (yyval.ival) = COLUMN; }
     break;
 
   case 1043:
-
-/* Line 1806 of yacc.c  */
-#line 6970 "gram.y"
+#line 6971 "gram.y"
     { (yyval.ival) = 0; }
     break;
 
   case 1044:
-
-/* Line 1806 of yacc.c  */
-#line 6973 "gram.y"
+#line 6974 "gram.y"
     { (yyval.ival) = 1; }
     break;
 
   case 1045:
-
-/* Line 1806 of yacc.c  */
-#line 6974 "gram.y"
+#line 6975 "gram.y"
     { (yyval.ival) = 0; }
     break;
 
   case 1046:
-
-/* Line 1806 of yacc.c  */
-#line 6985 "gram.y"
+#line 6986 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_AGGREGATE;
@@ -29980,9 +28067,7 @@ yyreduce:
     break;
 
   case 1047:
-
-/* Line 1806 of yacc.c  */
-#line 6995 "gram.y"
+#line 6996 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_COLLATION;
@@ -29994,9 +28079,7 @@ yyreduce:
     break;
 
   case 1048:
-
-/* Line 1806 of yacc.c  */
-#line 7004 "gram.y"
+#line 7005 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_CONVERSION;
@@ -30008,9 +28091,7 @@ yyreduce:
     break;
 
   case 1049:
-
-/* Line 1806 of yacc.c  */
-#line 7013 "gram.y"
+#line 7014 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_DOMAIN;
@@ -30022,9 +28103,7 @@ yyreduce:
     break;
 
   case 1050:
-
-/* Line 1806 of yacc.c  */
-#line 7022 "gram.y"
+#line 7023 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_EXTENSION;
@@ -30036,9 +28115,7 @@ yyreduce:
     break;
 
   case 1051:
-
-/* Line 1806 of yacc.c  */
-#line 7031 "gram.y"
+#line 7032 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_FUNCTION;
@@ -30051,9 +28128,7 @@ yyreduce:
     break;
 
   case 1052:
-
-/* Line 1806 of yacc.c  */
-#line 7041 "gram.y"
+#line 7042 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_OPERATOR;
@@ -30066,9 +28141,7 @@ yyreduce:
     break;
 
   case 1053:
-
-/* Line 1806 of yacc.c  */
-#line 7051 "gram.y"
+#line 7052 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_OPCLASS;
@@ -30081,9 +28154,7 @@ yyreduce:
     break;
 
   case 1054:
-
-/* Line 1806 of yacc.c  */
-#line 7061 "gram.y"
+#line 7062 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_OPFAMILY;
@@ -30096,9 +28167,7 @@ yyreduce:
     break;
 
   case 1055:
-
-/* Line 1806 of yacc.c  */
-#line 7071 "gram.y"
+#line 7072 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_TABLE;
@@ -30110,9 +28179,7 @@ yyreduce:
     break;
 
   case 1056:
-
-/* Line 1806 of yacc.c  */
-#line 7080 "gram.y"
+#line 7081 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_TABLE;
@@ -30124,9 +28191,7 @@ yyreduce:
     break;
 
   case 1057:
-
-/* Line 1806 of yacc.c  */
-#line 7089 "gram.y"
+#line 7090 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_TSPARSER;
@@ -30138,9 +28203,7 @@ yyreduce:
     break;
 
   case 1058:
-
-/* Line 1806 of yacc.c  */
-#line 7098 "gram.y"
+#line 7099 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_TSDICTIONARY;
@@ -30152,9 +28215,7 @@ yyreduce:
     break;
 
   case 1059:
-
-/* Line 1806 of yacc.c  */
-#line 7107 "gram.y"
+#line 7108 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_TSTEMPLATE;
@@ -30166,9 +28227,7 @@ yyreduce:
     break;
 
   case 1060:
-
-/* Line 1806 of yacc.c  */
-#line 7116 "gram.y"
+#line 7117 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_TSCONFIGURATION;
@@ -30180,9 +28239,7 @@ yyreduce:
     break;
 
   case 1061:
-
-/* Line 1806 of yacc.c  */
-#line 7125 "gram.y"
+#line 7126 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_SEQUENCE;
@@ -30194,9 +28251,7 @@ yyreduce:
     break;
 
   case 1062:
-
-/* Line 1806 of yacc.c  */
-#line 7134 "gram.y"
+#line 7135 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_SEQUENCE;
@@ -30208,9 +28263,7 @@ yyreduce:
     break;
 
   case 1063:
-
-/* Line 1806 of yacc.c  */
-#line 7143 "gram.y"
+#line 7144 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_VIEW;
@@ -30222,9 +28275,7 @@ yyreduce:
     break;
 
   case 1064:
-
-/* Line 1806 of yacc.c  */
-#line 7152 "gram.y"
+#line 7153 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_VIEW;
@@ -30236,9 +28287,7 @@ yyreduce:
     break;
 
   case 1065:
-
-/* Line 1806 of yacc.c  */
-#line 7161 "gram.y"
+#line 7162 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_FOREIGN_TABLE;
@@ -30250,9 +28299,7 @@ yyreduce:
     break;
 
   case 1066:
-
-/* Line 1806 of yacc.c  */
-#line 7170 "gram.y"
+#line 7171 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_FOREIGN_TABLE;
@@ -30264,9 +28311,7 @@ yyreduce:
     break;
 
   case 1067:
-
-/* Line 1806 of yacc.c  */
-#line 7179 "gram.y"
+#line 7180 "gram.y"
     {
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_TYPE;
@@ -30278,9 +28323,7 @@ yyreduce:
     break;
 
   case 1068:
-
-/* Line 1806 of yacc.c  */
-#line 7196 "gram.y"
+#line 7197 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_AGGREGATE;
@@ -30292,9 +28335,7 @@ yyreduce:
     break;
 
   case 1069:
-
-/* Line 1806 of yacc.c  */
-#line 7205 "gram.y"
+#line 7206 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_COLLATION;
@@ -30305,9 +28346,7 @@ yyreduce:
     break;
 
   case 1070:
-
-/* Line 1806 of yacc.c  */
-#line 7213 "gram.y"
+#line 7214 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_CONVERSION;
@@ -30318,9 +28357,7 @@ yyreduce:
     break;
 
   case 1071:
-
-/* Line 1806 of yacc.c  */
-#line 7221 "gram.y"
+#line 7222 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_DATABASE;
@@ -30331,9 +28368,7 @@ yyreduce:
     break;
 
   case 1072:
-
-/* Line 1806 of yacc.c  */
-#line 7229 "gram.y"
+#line 7230 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_DOMAIN;
@@ -30344,9 +28379,7 @@ yyreduce:
     break;
 
   case 1073:
-
-/* Line 1806 of yacc.c  */
-#line 7237 "gram.y"
+#line 7238 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_FUNCTION;
@@ -30358,9 +28391,7 @@ yyreduce:
     break;
 
   case 1074:
-
-/* Line 1806 of yacc.c  */
-#line 7246 "gram.y"
+#line 7247 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_LANGUAGE;
@@ -30371,9 +28402,7 @@ yyreduce:
     break;
 
   case 1075:
-
-/* Line 1806 of yacc.c  */
-#line 7254 "gram.y"
+#line 7255 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_LARGEOBJECT;
@@ -30384,9 +28413,7 @@ yyreduce:
     break;
 
   case 1076:
-
-/* Line 1806 of yacc.c  */
-#line 7262 "gram.y"
+#line 7263 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_OPERATOR;
@@ -30398,9 +28425,7 @@ yyreduce:
     break;
 
   case 1077:
-
-/* Line 1806 of yacc.c  */
-#line 7271 "gram.y"
+#line 7272 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_OPCLASS;
@@ -30412,9 +28437,7 @@ yyreduce:
     break;
 
   case 1078:
-
-/* Line 1806 of yacc.c  */
-#line 7280 "gram.y"
+#line 7281 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_OPFAMILY;
@@ -30426,9 +28449,7 @@ yyreduce:
     break;
 
   case 1079:
-
-/* Line 1806 of yacc.c  */
-#line 7289 "gram.y"
+#line 7290 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_SCHEMA;
@@ -30439,9 +28460,7 @@ yyreduce:
     break;
 
   case 1080:
-
-/* Line 1806 of yacc.c  */
-#line 7297 "gram.y"
+#line 7298 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_TYPE;
@@ -30452,9 +28471,7 @@ yyreduce:
     break;
 
   case 1081:
-
-/* Line 1806 of yacc.c  */
-#line 7305 "gram.y"
+#line 7306 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_TABLESPACE;
@@ -30465,9 +28482,7 @@ yyreduce:
     break;
 
   case 1082:
-
-/* Line 1806 of yacc.c  */
-#line 7313 "gram.y"
+#line 7314 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_TSDICTIONARY;
@@ -30478,9 +28493,7 @@ yyreduce:
     break;
 
   case 1083:
-
-/* Line 1806 of yacc.c  */
-#line 7321 "gram.y"
+#line 7322 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_TSCONFIGURATION;
@@ -30491,9 +28504,7 @@ yyreduce:
     break;
 
   case 1084:
-
-/* Line 1806 of yacc.c  */
-#line 7329 "gram.y"
+#line 7330 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_FDW;
@@ -30504,9 +28515,7 @@ yyreduce:
     break;
 
   case 1085:
-
-/* Line 1806 of yacc.c  */
-#line 7337 "gram.y"
+#line 7338 "gram.y"
     {
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_FOREIGN_SERVER;
@@ -30517,9 +28526,7 @@ yyreduce:
     break;
 
   case 1086:
-
-/* Line 1806 of yacc.c  */
-#line 7356 "gram.y"
+#line 7357 "gram.y"
     {
 					RuleStmt *n = makeNode(RuleStmt);
 					n->replace = (yyvsp[(2) - (13)].boolean);
@@ -30534,30 +28541,22 @@ yyreduce:
     break;
 
   case 1087:
-
-/* Line 1806 of yacc.c  */
-#line 7370 "gram.y"
+#line 7371 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1088:
-
-/* Line 1806 of yacc.c  */
-#line 7371 "gram.y"
+#line 7372 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); }
     break;
 
   case 1089:
-
-/* Line 1806 of yacc.c  */
-#line 7372 "gram.y"
+#line 7373 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (3)].list); }
     break;
 
   case 1090:
-
-/* Line 1806 of yacc.c  */
-#line 7378 "gram.y"
+#line 7379 "gram.y"
     { if ((yyvsp[(3) - (3)].node) != NULL)
 					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 				  else
@@ -30566,9 +28565,7 @@ yyreduce:
     break;
 
   case 1091:
-
-/* Line 1806 of yacc.c  */
-#line 7384 "gram.y"
+#line 7385 "gram.y"
     { if ((yyvsp[(1) - (1)].node) != NULL)
 					(yyval.list) = list_make1((yyvsp[(1) - (1)].node));
 				  else
@@ -30577,72 +28574,52 @@ yyreduce:
     break;
 
   case 1097:
-
-/* Line 1806 of yacc.c  */
-#line 7400 "gram.y"
+#line 7401 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 1098:
-
-/* Line 1806 of yacc.c  */
-#line 7401 "gram.y"
+#line 7402 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 1099:
-
-/* Line 1806 of yacc.c  */
-#line 7404 "gram.y"
+#line 7405 "gram.y"
     { (yyval.ival) = CMD_SELECT; }
     break;
 
   case 1100:
-
-/* Line 1806 of yacc.c  */
-#line 7405 "gram.y"
+#line 7406 "gram.y"
     { (yyval.ival) = CMD_UPDATE; }
     break;
 
   case 1101:
-
-/* Line 1806 of yacc.c  */
-#line 7406 "gram.y"
+#line 7407 "gram.y"
     { (yyval.ival) = CMD_DELETE; }
     break;
 
   case 1102:
-
-/* Line 1806 of yacc.c  */
-#line 7407 "gram.y"
+#line 7408 "gram.y"
     { (yyval.ival) = CMD_INSERT; }
     break;
 
   case 1103:
-
-/* Line 1806 of yacc.c  */
-#line 7411 "gram.y"
+#line 7412 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 1104:
-
-/* Line 1806 of yacc.c  */
-#line 7412 "gram.y"
+#line 7413 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 1105:
-
-/* Line 1806 of yacc.c  */
-#line 7413 "gram.y"
+#line 7414 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 1106:
-
-/* Line 1806 of yacc.c  */
-#line 7419 "gram.y"
+#line 7420 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_RULE;
@@ -30656,9 +28633,7 @@ yyreduce:
     break;
 
   case 1107:
-
-/* Line 1806 of yacc.c  */
-#line 7430 "gram.y"
+#line 7431 "gram.y"
     {
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_RULE;
@@ -30672,9 +28647,7 @@ yyreduce:
     break;
 
   case 1108:
-
-/* Line 1806 of yacc.c  */
-#line 7452 "gram.y"
+#line 7453 "gram.y"
     {
 					NotifyStmt *n = makeNode(NotifyStmt);
 					n->conditionname = (yyvsp[(2) - (3)].str);
@@ -30684,23 +28657,17 @@ yyreduce:
     break;
 
   case 1109:
-
-/* Line 1806 of yacc.c  */
-#line 7461 "gram.y"
+#line 7462 "gram.y"
     { (yyval.str) = (yyvsp[(2) - (2)].str); }
     break;
 
   case 1110:
-
-/* Line 1806 of yacc.c  */
-#line 7462 "gram.y"
+#line 7463 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 1111:
-
-/* Line 1806 of yacc.c  */
-#line 7466 "gram.y"
+#line 7467 "gram.y"
     {
 					ListenStmt *n = makeNode(ListenStmt);
 					n->conditionname = (yyvsp[(2) - (2)].str);
@@ -30709,9 +28676,7 @@ yyreduce:
     break;
 
   case 1112:
-
-/* Line 1806 of yacc.c  */
-#line 7475 "gram.y"
+#line 7476 "gram.y"
     {
 					UnlistenStmt *n = makeNode(UnlistenStmt);
 					n->conditionname = (yyvsp[(2) - (2)].str);
@@ -30720,9 +28685,7 @@ yyreduce:
     break;
 
   case 1113:
-
-/* Line 1806 of yacc.c  */
-#line 7481 "gram.y"
+#line 7482 "gram.y"
     {
 					UnlistenStmt *n = makeNode(UnlistenStmt);
 					n->conditionname = NULL;
@@ -30731,9 +28694,7 @@ yyreduce:
     break;
 
   case 1114:
-
-/* Line 1806 of yacc.c  */
-#line 7500 "gram.y"
+#line 7501 "gram.y"
     {
 					TransactionStmt *n = makeNode(TransactionStmt);
 					n->kind = TRANS_STMT_ROLLBACK;
@@ -30743,9 +28704,7 @@ yyreduce:
     break;
 
   case 1115:
-
-/* Line 1806 of yacc.c  */
-#line 7507 "gram.y"
+#line 7508 "gram.y"
     {
 					TransactionStmt *n = makeNode(TransactionStmt);
 					n->kind = TRANS_STMT_BEGIN;
@@ -30755,9 +28714,7 @@ yyreduce:
     break;
 
   case 1116:
-
-/* Line 1806 of yacc.c  */
-#line 7514 "gram.y"
+#line 7515 "gram.y"
     {
 					TransactionStmt *n = makeNode(TransactionStmt);
 					n->kind = TRANS_STMT_START;
@@ -30767,9 +28724,7 @@ yyreduce:
     break;
 
   case 1117:
-
-/* Line 1806 of yacc.c  */
-#line 7521 "gram.y"
+#line 7522 "gram.y"
     {
 					TransactionStmt *n = makeNode(TransactionStmt);
 					n->kind = TRANS_STMT_COMMIT;
@@ -30779,9 +28734,7 @@ yyreduce:
     break;
 
   case 1118:
-
-/* Line 1806 of yacc.c  */
-#line 7528 "gram.y"
+#line 7529 "gram.y"
     {
 					TransactionStmt *n = makeNode(TransactionStmt);
 					n->kind = TRANS_STMT_COMMIT;
@@ -30791,9 +28744,7 @@ yyreduce:
     break;
 
   case 1119:
-
-/* Line 1806 of yacc.c  */
-#line 7535 "gram.y"
+#line 7536 "gram.y"
     {
 					TransactionStmt *n = makeNode(TransactionStmt);
 					n->kind = TRANS_STMT_ROLLBACK;
@@ -30803,9 +28754,7 @@ yyreduce:
     break;
 
   case 1120:
-
-/* Line 1806 of yacc.c  */
-#line 7542 "gram.y"
+#line 7543 "gram.y"
     {
 					TransactionStmt *n = makeNode(TransactionStmt);
 					n->kind = TRANS_STMT_SAVEPOINT;
@@ -30816,9 +28765,7 @@ yyreduce:
     break;
 
   case 1121:
-
-/* Line 1806 of yacc.c  */
-#line 7550 "gram.y"
+#line 7551 "gram.y"
     {
 					TransactionStmt *n = makeNode(TransactionStmt);
 					n->kind = TRANS_STMT_RELEASE;
@@ -30829,9 +28776,7 @@ yyreduce:
     break;
 
   case 1122:
-
-/* Line 1806 of yacc.c  */
-#line 7558 "gram.y"
+#line 7559 "gram.y"
     {
 					TransactionStmt *n = makeNode(TransactionStmt);
 					n->kind = TRANS_STMT_RELEASE;
@@ -30842,9 +28787,7 @@ yyreduce:
     break;
 
   case 1123:
-
-/* Line 1806 of yacc.c  */
-#line 7566 "gram.y"
+#line 7567 "gram.y"
     {
 					TransactionStmt *n = makeNode(TransactionStmt);
 					n->kind = TRANS_STMT_ROLLBACK_TO;
@@ -30855,9 +28798,7 @@ yyreduce:
     break;
 
   case 1124:
-
-/* Line 1806 of yacc.c  */
-#line 7574 "gram.y"
+#line 7575 "gram.y"
     {
 					TransactionStmt *n = makeNode(TransactionStmt);
 					n->kind = TRANS_STMT_ROLLBACK_TO;
@@ -30868,9 +28809,7 @@ yyreduce:
     break;
 
   case 1125:
-
-/* Line 1806 of yacc.c  */
-#line 7582 "gram.y"
+#line 7583 "gram.y"
     {
 					TransactionStmt *n = makeNode(TransactionStmt);
 					n->kind = TRANS_STMT_PREPARE;
@@ -30880,9 +28819,7 @@ yyreduce:
     break;
 
   case 1126:
-
-/* Line 1806 of yacc.c  */
-#line 7589 "gram.y"
+#line 7590 "gram.y"
     {
 					TransactionStmt *n = makeNode(TransactionStmt);
 					n->kind = TRANS_STMT_COMMIT_PREPARED;
@@ -30892,9 +28829,7 @@ yyreduce:
     break;
 
   case 1127:
-
-/* Line 1806 of yacc.c  */
-#line 7596 "gram.y"
+#line 7597 "gram.y"
     {
 					TransactionStmt *n = makeNode(TransactionStmt);
 					n->kind = TRANS_STMT_ROLLBACK_PREPARED;
@@ -30904,98 +28839,72 @@ yyreduce:
     break;
 
   case 1128:
-
-/* Line 1806 of yacc.c  */
-#line 7604 "gram.y"
+#line 7605 "gram.y"
     {}
     break;
 
   case 1129:
-
-/* Line 1806 of yacc.c  */
-#line 7605 "gram.y"
+#line 7606 "gram.y"
     {}
     break;
 
   case 1130:
-
-/* Line 1806 of yacc.c  */
-#line 7606 "gram.y"
+#line 7607 "gram.y"
     {}
     break;
 
   case 1131:
-
-/* Line 1806 of yacc.c  */
-#line 7611 "gram.y"
+#line 7612 "gram.y"
     { (yyval.defelt) = makeDefElem("transaction_isolation",
 									   makeStringConst((yyvsp[(3) - (3)].str), (yylsp[(3) - (3)]))); }
     break;
 
   case 1132:
-
-/* Line 1806 of yacc.c  */
-#line 7614 "gram.y"
+#line 7615 "gram.y"
     { (yyval.defelt) = makeDefElem("transaction_read_only",
 									   makeIntConst(TRUE, (yylsp[(1) - (2)]))); }
     break;
 
   case 1133:
-
-/* Line 1806 of yacc.c  */
-#line 7617 "gram.y"
+#line 7618 "gram.y"
     { (yyval.defelt) = makeDefElem("transaction_read_only",
 									   makeIntConst(FALSE, (yylsp[(1) - (2)]))); }
     break;
 
   case 1134:
-
-/* Line 1806 of yacc.c  */
-#line 7620 "gram.y"
+#line 7621 "gram.y"
     { (yyval.defelt) = makeDefElem("transaction_deferrable",
 									   makeIntConst(TRUE, (yylsp[(1) - (1)]))); }
     break;
 
   case 1135:
-
-/* Line 1806 of yacc.c  */
-#line 7623 "gram.y"
+#line 7624 "gram.y"
     { (yyval.defelt) = makeDefElem("transaction_deferrable",
 									   makeIntConst(FALSE, (yylsp[(1) - (2)]))); }
     break;
 
   case 1136:
-
-/* Line 1806 of yacc.c  */
-#line 7630 "gram.y"
+#line 7631 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); }
     break;
 
   case 1137:
-
-/* Line 1806 of yacc.c  */
-#line 7632 "gram.y"
+#line 7633 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt)); }
     break;
 
   case 1138:
-
-/* Line 1806 of yacc.c  */
-#line 7634 "gram.y"
+#line 7635 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); }
     break;
 
   case 1140:
-
-/* Line 1806 of yacc.c  */
-#line 7640 "gram.y"
+#line 7641 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1141:
-
-/* Line 1806 of yacc.c  */
-#line 7654 "gram.y"
+#line 7655 "gram.y"
     {
 					ViewStmt *n = makeNode(ViewStmt);
 					n->view = (yyvsp[(4) - (9)].range);
@@ -31009,9 +28918,7 @@ yyreduce:
     break;
 
   case 1142:
-
-/* Line 1806 of yacc.c  */
-#line 7666 "gram.y"
+#line 7667 "gram.y"
     {
 					ViewStmt *n = makeNode(ViewStmt);
 					n->view = (yyvsp[(6) - (11)].range);
@@ -31025,9 +28932,7 @@ yyreduce:
     break;
 
   case 1143:
-
-/* Line 1806 of yacc.c  */
-#line 7680 "gram.y"
+#line 7681 "gram.y"
     {
 					ereport(ERROR,
 							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -31036,9 +28941,7 @@ yyreduce:
     break;
 
   case 1144:
-
-/* Line 1806 of yacc.c  */
-#line 7686 "gram.y"
+#line 7687 "gram.y"
     {
 					ereport(ERROR,
 							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -31047,9 +28950,7 @@ yyreduce:
     break;
 
   case 1145:
-
-/* Line 1806 of yacc.c  */
-#line 7692 "gram.y"
+#line 7693 "gram.y"
     {
 					ereport(ERROR,
 							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -31058,16 +28959,12 @@ yyreduce:
     break;
 
   case 1146:
-
-/* Line 1806 of yacc.c  */
-#line 7697 "gram.y"
+#line 7698 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1147:
-
-/* Line 1806 of yacc.c  */
-#line 7708 "gram.y"
+#line 7709 "gram.y"
     {
 					LoadStmt *n = makeNode(LoadStmt);
 					n->filename = (yyvsp[(2) - (2)].str);
@@ -31076,9 +28973,7 @@ yyreduce:
     break;
 
   case 1148:
-
-/* Line 1806 of yacc.c  */
-#line 7724 "gram.y"
+#line 7725 "gram.y"
     {
 					CreatedbStmt *n = makeNode(CreatedbStmt);
 					n->dbname = (yyvsp[(3) - (5)].str);
@@ -31088,181 +28983,139 @@ yyreduce:
     break;
 
   case 1149:
-
-/* Line 1806 of yacc.c  */
-#line 7733 "gram.y"
+#line 7734 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); }
     break;
 
   case 1150:
-
-/* Line 1806 of yacc.c  */
-#line 7734 "gram.y"
+#line 7735 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1151:
-
-/* Line 1806 of yacc.c  */
-#line 7739 "gram.y"
+#line 7740 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("tablespace", (Node *)makeString((yyvsp[(3) - (3)].str)));
 				}
     break;
 
   case 1152:
-
-/* Line 1806 of yacc.c  */
-#line 7743 "gram.y"
+#line 7744 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("tablespace", NULL);
 				}
     break;
 
   case 1153:
-
-/* Line 1806 of yacc.c  */
-#line 7747 "gram.y"
+#line 7748 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("location", (Node *)makeString((yyvsp[(3) - (3)].str)));
 				}
     break;
 
   case 1154:
-
-/* Line 1806 of yacc.c  */
-#line 7751 "gram.y"
+#line 7752 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("location", NULL);
 				}
     break;
 
   case 1155:
-
-/* Line 1806 of yacc.c  */
-#line 7755 "gram.y"
+#line 7756 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("template", (Node *)makeString((yyvsp[(3) - (3)].str)));
 				}
     break;
 
   case 1156:
-
-/* Line 1806 of yacc.c  */
-#line 7759 "gram.y"
+#line 7760 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("template", NULL);
 				}
     break;
 
   case 1157:
-
-/* Line 1806 of yacc.c  */
-#line 7763 "gram.y"
+#line 7764 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("encoding", (Node *)makeString((yyvsp[(3) - (3)].str)));
 				}
     break;
 
   case 1158:
-
-/* Line 1806 of yacc.c  */
-#line 7767 "gram.y"
+#line 7768 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("encoding", (Node *)makeInteger((yyvsp[(3) - (3)].ival)));
 				}
     break;
 
   case 1159:
-
-/* Line 1806 of yacc.c  */
-#line 7771 "gram.y"
+#line 7772 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("encoding", NULL);
 				}
     break;
 
   case 1160:
-
-/* Line 1806 of yacc.c  */
-#line 7775 "gram.y"
+#line 7776 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("lc_collate", (Node *)makeString((yyvsp[(3) - (3)].str)));
 				}
     break;
 
   case 1161:
-
-/* Line 1806 of yacc.c  */
-#line 7779 "gram.y"
+#line 7780 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("lc_collate", NULL);
 				}
     break;
 
   case 1162:
-
-/* Line 1806 of yacc.c  */
-#line 7783 "gram.y"
+#line 7784 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("lc_ctype", (Node *)makeString((yyvsp[(3) - (3)].str)));
 				}
     break;
 
   case 1163:
-
-/* Line 1806 of yacc.c  */
-#line 7787 "gram.y"
+#line 7788 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("lc_ctype", NULL);
 				}
     break;
 
   case 1164:
-
-/* Line 1806 of yacc.c  */
-#line 7791 "gram.y"
+#line 7792 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("connectionlimit", (Node *)makeInteger((yyvsp[(4) - (4)].ival)));
 				}
     break;
 
   case 1165:
-
-/* Line 1806 of yacc.c  */
-#line 7795 "gram.y"
+#line 7796 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("owner", (Node *)makeString((yyvsp[(3) - (3)].str)));
 				}
     break;
 
   case 1166:
-
-/* Line 1806 of yacc.c  */
-#line 7799 "gram.y"
+#line 7800 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("owner", NULL);
 				}
     break;
 
   case 1167:
-
-/* Line 1806 of yacc.c  */
-#line 7808 "gram.y"
+#line 7809 "gram.y"
     {}
     break;
 
   case 1168:
-
-/* Line 1806 of yacc.c  */
-#line 7809 "gram.y"
+#line 7810 "gram.y"
     {}
     break;
 
   case 1169:
-
-/* Line 1806 of yacc.c  */
-#line 7821 "gram.y"
+#line 7822 "gram.y"
     {
 					AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt);
 					n->dbname = (yyvsp[(3) - (5)].str);
@@ -31272,9 +29125,7 @@ yyreduce:
     break;
 
   case 1170:
-
-/* Line 1806 of yacc.c  */
-#line 7828 "gram.y"
+#line 7829 "gram.y"
     {
 					AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt);
 					n->dbname = (yyvsp[(3) - (6)].str);
@@ -31285,9 +29136,7 @@ yyreduce:
     break;
 
   case 1171:
-
-/* Line 1806 of yacc.c  */
-#line 7839 "gram.y"
+#line 7840 "gram.y"
     {
 					AlterDatabaseSetStmt *n = makeNode(AlterDatabaseSetStmt);
 					n->dbname = (yyvsp[(3) - (4)].str);
@@ -31297,32 +29146,24 @@ yyreduce:
     break;
 
   case 1172:
-
-/* Line 1806 of yacc.c  */
-#line 7849 "gram.y"
+#line 7850 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); }
     break;
 
   case 1173:
-
-/* Line 1806 of yacc.c  */
-#line 7850 "gram.y"
+#line 7851 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1174:
-
-/* Line 1806 of yacc.c  */
-#line 7855 "gram.y"
+#line 7856 "gram.y"
     {
 					(yyval.defelt) = makeDefElem("connectionlimit", (Node *)makeInteger((yyvsp[(4) - (4)].ival)));
 				}
     break;
 
   case 1175:
-
-/* Line 1806 of yacc.c  */
-#line 7869 "gram.y"
+#line 7870 "gram.y"
     {
 					DropdbStmt *n = makeNode(DropdbStmt);
 					n->dbname = (yyvsp[(3) - (3)].str);
@@ -31332,9 +29173,7 @@ yyreduce:
     break;
 
   case 1176:
-
-/* Line 1806 of yacc.c  */
-#line 7876 "gram.y"
+#line 7877 "gram.y"
     {
 					DropdbStmt *n = makeNode(DropdbStmt);
 					n->dbname = (yyvsp[(5) - (5)].str);
@@ -31344,9 +29183,7 @@ yyreduce:
     break;
 
   case 1177:
-
-/* Line 1806 of yacc.c  */
-#line 7893 "gram.y"
+#line 7894 "gram.y"
     {
 					CreateDomainStmt *n = makeNode(CreateDomainStmt);
 					n->domainname = (yyvsp[(3) - (6)].list);
@@ -31358,9 +29195,7 @@ yyreduce:
     break;
 
   case 1178:
-
-/* Line 1806 of yacc.c  */
-#line 7906 "gram.y"
+#line 7907 "gram.y"
     {
 					AlterDomainStmt *n = makeNode(AlterDomainStmt);
 					n->subtype = 'T';
@@ -31371,9 +29206,7 @@ yyreduce:
     break;
 
   case 1179:
-
-/* Line 1806 of yacc.c  */
-#line 7915 "gram.y"
+#line 7916 "gram.y"
     {
 					AlterDomainStmt *n = makeNode(AlterDomainStmt);
 					n->subtype = 'N';
@@ -31383,9 +29216,7 @@ yyreduce:
     break;
 
   case 1180:
-
-/* Line 1806 of yacc.c  */
-#line 7923 "gram.y"
+#line 7924 "gram.y"
     {
 					AlterDomainStmt *n = makeNode(AlterDomainStmt);
 					n->subtype = 'O';
@@ -31395,9 +29226,7 @@ yyreduce:
     break;
 
   case 1181:
-
-/* Line 1806 of yacc.c  */
-#line 7931 "gram.y"
+#line 7932 "gram.y"
     {
 					AlterDomainStmt *n = makeNode(AlterDomainStmt);
 					n->subtype = 'C';
@@ -31408,9 +29237,7 @@ yyreduce:
     break;
 
   case 1182:
-
-/* Line 1806 of yacc.c  */
-#line 7940 "gram.y"
+#line 7941 "gram.y"
     {
 					AlterDomainStmt *n = makeNode(AlterDomainStmt);
 					n->subtype = 'X';
@@ -31423,9 +29250,7 @@ yyreduce:
     break;
 
   case 1183:
-
-/* Line 1806 of yacc.c  */
-#line 7951 "gram.y"
+#line 7952 "gram.y"
     {
 					AlterDomainStmt *n = makeNode(AlterDomainStmt);
 					n->subtype = 'X';
@@ -31438,9 +29263,7 @@ yyreduce:
     break;
 
   case 1184:
-
-/* Line 1806 of yacc.c  */
-#line 7962 "gram.y"
+#line 7963 "gram.y"
     {
 					AlterDomainStmt *n = makeNode(AlterDomainStmt);
 					n->subtype = 'V';
@@ -31451,23 +29274,17 @@ yyreduce:
     break;
 
   case 1185:
-
-/* Line 1806 of yacc.c  */
-#line 7971 "gram.y"
+#line 7972 "gram.y"
     {}
     break;
 
   case 1186:
-
-/* Line 1806 of yacc.c  */
-#line 7972 "gram.y"
+#line 7973 "gram.y"
     {}
     break;
 
   case 1187:
-
-/* Line 1806 of yacc.c  */
-#line 7984 "gram.y"
+#line 7985 "gram.y"
     {
 					AlterTSDictionaryStmt *n = makeNode(AlterTSDictionaryStmt);
 					n->dictname = (yyvsp[(5) - (6)].list);
@@ -31477,9 +29294,7 @@ yyreduce:
     break;
 
   case 1188:
-
-/* Line 1806 of yacc.c  */
-#line 7994 "gram.y"
+#line 7995 "gram.y"
     {
 					AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
 					n->cfgname = (yyvsp[(5) - (11)].list);
@@ -31492,9 +29307,7 @@ yyreduce:
     break;
 
   case 1189:
-
-/* Line 1806 of yacc.c  */
-#line 8004 "gram.y"
+#line 8005 "gram.y"
     {
 					AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
 					n->cfgname = (yyvsp[(5) - (11)].list);
@@ -31507,9 +29320,7 @@ yyreduce:
     break;
 
   case 1190:
-
-/* Line 1806 of yacc.c  */
-#line 8014 "gram.y"
+#line 8015 "gram.y"
     {
 					AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
 					n->cfgname = (yyvsp[(5) - (11)].list);
@@ -31522,9 +29333,7 @@ yyreduce:
     break;
 
   case 1191:
-
-/* Line 1806 of yacc.c  */
-#line 8024 "gram.y"
+#line 8025 "gram.y"
     {
 					AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
 					n->cfgname = (yyvsp[(5) - (13)].list);
@@ -31537,9 +29346,7 @@ yyreduce:
     break;
 
   case 1192:
-
-/* Line 1806 of yacc.c  */
-#line 8034 "gram.y"
+#line 8035 "gram.y"
     {
 					AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
 					n->cfgname = (yyvsp[(5) - (9)].list);
@@ -31550,9 +29357,7 @@ yyreduce:
     break;
 
   case 1193:
-
-/* Line 1806 of yacc.c  */
-#line 8042 "gram.y"
+#line 8043 "gram.y"
     {
 					AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
 					n->cfgname = (yyvsp[(5) - (11)].list);
@@ -31563,9 +29368,7 @@ yyreduce:
     break;
 
   case 1194:
-
-/* Line 1806 of yacc.c  */
-#line 8064 "gram.y"
+#line 8065 "gram.y"
     {
 				CreateConversionStmt *n = makeNode(CreateConversionStmt);
 				n->conversion_name = (yyvsp[(4) - (10)].list);
@@ -31578,9 +29381,7 @@ yyreduce:
     break;
 
   case 1195:
-
-/* Line 1806 of yacc.c  */
-#line 8086 "gram.y"
+#line 8087 "gram.y"
     {
 					ClusterStmt *n = makeNode(ClusterStmt);
 					n->relation = (yyvsp[(3) - (4)].range);
@@ -31591,9 +29392,7 @@ yyreduce:
     break;
 
   case 1196:
-
-/* Line 1806 of yacc.c  */
-#line 8094 "gram.y"
+#line 8095 "gram.y"
     {
 					ClusterStmt *n = makeNode(ClusterStmt);
 					n->relation = NULL;
@@ -31604,9 +29403,7 @@ yyreduce:
     break;
 
   case 1197:
-
-/* Line 1806 of yacc.c  */
-#line 8103 "gram.y"
+#line 8104 "gram.y"
     {
 					ClusterStmt *n = makeNode(ClusterStmt);
 					n->relation = (yyvsp[(5) - (5)].range);
@@ -31617,23 +29414,17 @@ yyreduce:
     break;
 
   case 1198:
-
-/* Line 1806 of yacc.c  */
-#line 8113 "gram.y"
+#line 8114 "gram.y"
     { (yyval.str) = (yyvsp[(2) - (2)].str); }
     break;
 
   case 1199:
-
-/* Line 1806 of yacc.c  */
-#line 8114 "gram.y"
+#line 8115 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 1200:
-
-/* Line 1806 of yacc.c  */
-#line 8127 "gram.y"
+#line 8128 "gram.y"
     {
 					VacuumStmt *n = makeNode(VacuumStmt);
 					n->options = VACOPT_VACUUM;
@@ -31650,9 +29441,7 @@ yyreduce:
     break;
 
   case 1201:
-
-/* Line 1806 of yacc.c  */
-#line 8141 "gram.y"
+#line 8142 "gram.y"
     {
 					VacuumStmt *n = makeNode(VacuumStmt);
 					n->options = VACOPT_VACUUM;
@@ -31669,9 +29458,7 @@ yyreduce:
     break;
 
   case 1202:
-
-/* Line 1806 of yacc.c  */
-#line 8155 "gram.y"
+#line 8156 "gram.y"
     {
 					VacuumStmt *n = (VacuumStmt *) (yyvsp[(5) - (5)].node);
 					n->options |= VACOPT_VACUUM;
@@ -31686,9 +29473,7 @@ yyreduce:
     break;
 
   case 1203:
-
-/* Line 1806 of yacc.c  */
-#line 8167 "gram.y"
+#line 8168 "gram.y"
     {
 					VacuumStmt *n = makeNode(VacuumStmt);
 					n->options = VACOPT_VACUUM | (yyvsp[(3) - (4)].ival);
@@ -31703,9 +29488,7 @@ yyreduce:
     break;
 
   case 1204:
-
-/* Line 1806 of yacc.c  */
-#line 8179 "gram.y"
+#line 8180 "gram.y"
     {
 					VacuumStmt *n = makeNode(VacuumStmt);
 					n->options = VACOPT_VACUUM | (yyvsp[(3) - (6)].ival);
@@ -31722,51 +29505,37 @@ yyreduce:
     break;
 
   case 1205:
-
-/* Line 1806 of yacc.c  */
-#line 8195 "gram.y"
+#line 8196 "gram.y"
     { (yyval.ival) = (yyvsp[(1) - (1)].ival); }
     break;
 
   case 1206:
-
-/* Line 1806 of yacc.c  */
-#line 8196 "gram.y"
+#line 8197 "gram.y"
     { (yyval.ival) = (yyvsp[(1) - (3)].ival) | (yyvsp[(3) - (3)].ival); }
     break;
 
   case 1207:
-
-/* Line 1806 of yacc.c  */
-#line 8200 "gram.y"
+#line 8201 "gram.y"
     { (yyval.ival) = VACOPT_ANALYZE; }
     break;
 
   case 1208:
-
-/* Line 1806 of yacc.c  */
-#line 8201 "gram.y"
+#line 8202 "gram.y"
     { (yyval.ival) = VACOPT_VERBOSE; }
     break;
 
   case 1209:
-
-/* Line 1806 of yacc.c  */
-#line 8202 "gram.y"
+#line 8203 "gram.y"
     { (yyval.ival) = VACOPT_FREEZE; }
     break;
 
   case 1210:
-
-/* Line 1806 of yacc.c  */
-#line 8203 "gram.y"
+#line 8204 "gram.y"
     { (yyval.ival) = VACOPT_FULL; }
     break;
 
   case 1211:
-
-/* Line 1806 of yacc.c  */
-#line 8208 "gram.y"
+#line 8209 "gram.y"
     {
 					VacuumStmt *n = makeNode(VacuumStmt);
 					n->options = VACOPT_ANALYZE;
@@ -31781,9 +29550,7 @@ yyreduce:
     break;
 
   case 1212:
-
-/* Line 1806 of yacc.c  */
-#line 8220 "gram.y"
+#line 8221 "gram.y"
     {
 					VacuumStmt *n = makeNode(VacuumStmt);
 					n->options = VACOPT_ANALYZE;
@@ -31798,79 +29565,57 @@ yyreduce:
     break;
 
   case 1213:
-
-/* Line 1806 of yacc.c  */
-#line 8234 "gram.y"
+#line 8235 "gram.y"
     {}
     break;
 
   case 1214:
-
-/* Line 1806 of yacc.c  */
-#line 8235 "gram.y"
+#line 8236 "gram.y"
     {}
     break;
 
   case 1215:
-
-/* Line 1806 of yacc.c  */
-#line 8239 "gram.y"
+#line 8240 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 1216:
-
-/* Line 1806 of yacc.c  */
-#line 8240 "gram.y"
+#line 8241 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 1217:
-
-/* Line 1806 of yacc.c  */
-#line 8243 "gram.y"
+#line 8244 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 1218:
-
-/* Line 1806 of yacc.c  */
-#line 8244 "gram.y"
+#line 8245 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 1219:
-
-/* Line 1806 of yacc.c  */
-#line 8247 "gram.y"
+#line 8248 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 1220:
-
-/* Line 1806 of yacc.c  */
-#line 8248 "gram.y"
+#line 8249 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 1221:
-
-/* Line 1806 of yacc.c  */
-#line 8252 "gram.y"
+#line 8253 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (3)].list); }
     break;
 
   case 1222:
-
-/* Line 1806 of yacc.c  */
-#line 8253 "gram.y"
+#line 8254 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1223:
-
-/* Line 1806 of yacc.c  */
-#line 8267 "gram.y"
+#line 8268 "gram.y"
     {
 					ExplainStmt *n = makeNode(ExplainStmt);
 					n->query = (yyvsp[(2) - (2)].node);
@@ -31880,9 +29625,7 @@ yyreduce:
     break;
 
   case 1224:
-
-/* Line 1806 of yacc.c  */
-#line 8274 "gram.y"
+#line 8275 "gram.y"
     {
 					ExplainStmt *n = makeNode(ExplainStmt);
 					n->query = (yyvsp[(4) - (4)].node);
@@ -31895,9 +29638,7 @@ yyreduce:
     break;
 
   case 1225:
-
-/* Line 1806 of yacc.c  */
-#line 8284 "gram.y"
+#line 8285 "gram.y"
     {
 					ExplainStmt *n = makeNode(ExplainStmt);
 					n->query = (yyvsp[(3) - (3)].node);
@@ -31907,9 +29648,7 @@ yyreduce:
     break;
 
   case 1226:
-
-/* Line 1806 of yacc.c  */
-#line 8291 "gram.y"
+#line 8292 "gram.y"
     {
 					ExplainStmt *n = makeNode(ExplainStmt);
 					n->query = (yyvsp[(5) - (5)].node);
@@ -31919,78 +29658,58 @@ yyreduce:
     break;
 
   case 1234:
-
-/* Line 1806 of yacc.c  */
-#line 8311 "gram.y"
+#line 8312 "gram.y"
     {
 					(yyval.list) = list_make1((yyvsp[(1) - (1)].defelt));
 				}
     break;
 
   case 1235:
-
-/* Line 1806 of yacc.c  */
-#line 8315 "gram.y"
+#line 8316 "gram.y"
     {
 					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt));
 				}
     break;
 
   case 1236:
-
-/* Line 1806 of yacc.c  */
-#line 8322 "gram.y"
+#line 8323 "gram.y"
     {
 					(yyval.defelt) = makeDefElem((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].node));
 				}
     break;
 
   case 1237:
-
-/* Line 1806 of yacc.c  */
-#line 8328 "gram.y"
+#line 8329 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1238:
-
-/* Line 1806 of yacc.c  */
-#line 8329 "gram.y"
+#line 8330 "gram.y"
     { (yyval.str) = "analyze"; }
     break;
 
   case 1239:
-
-/* Line 1806 of yacc.c  */
-#line 8330 "gram.y"
+#line 8331 "gram.y"
     { (yyval.str) = "verbose"; }
     break;
 
   case 1240:
-
-/* Line 1806 of yacc.c  */
-#line 8334 "gram.y"
+#line 8335 "gram.y"
     { (yyval.node) = (Node *) makeString((yyvsp[(1) - (1)].str)); }
     break;
 
   case 1241:
-
-/* Line 1806 of yacc.c  */
-#line 8335 "gram.y"
+#line 8336 "gram.y"
     { (yyval.node) = (Node *) (yyvsp[(1) - (1)].value); }
     break;
 
   case 1242:
-
-/* Line 1806 of yacc.c  */
-#line 8336 "gram.y"
+#line 8337 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 1243:
-
-/* Line 1806 of yacc.c  */
-#line 8347 "gram.y"
+#line 8348 "gram.y"
     {
 					PrepareStmt *n = makeNode(PrepareStmt);
 					n->name = (yyvsp[(2) - (5)].str);
@@ -32001,23 +29720,17 @@ yyreduce:
     break;
 
   case 1244:
-
-/* Line 1806 of yacc.c  */
-#line 8356 "gram.y"
+#line 8357 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (3)].list); }
     break;
 
   case 1245:
-
-/* Line 1806 of yacc.c  */
-#line 8357 "gram.y"
+#line 8358 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1250:
-
-/* Line 1806 of yacc.c  */
-#line 8375 "gram.y"
+#line 8376 "gram.y"
     {
 					ExecuteStmt *n = makeNode(ExecuteStmt);
 					n->name = (yyvsp[(2) - (3)].str);
@@ -32027,9 +29740,7 @@ yyreduce:
     break;
 
   case 1251:
-
-/* Line 1806 of yacc.c  */
-#line 8383 "gram.y"
+#line 8384 "gram.y"
     {
 					CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt);
 					ExecuteStmt *n = makeNode(ExecuteStmt);
@@ -32046,23 +29757,17 @@ yyreduce:
     break;
 
   case 1252:
-
-/* Line 1806 of yacc.c  */
-#line 8398 "gram.y"
+#line 8399 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (3)].list); }
     break;
 
   case 1253:
-
-/* Line 1806 of yacc.c  */
-#line 8399 "gram.y"
+#line 8400 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1254:
-
-/* Line 1806 of yacc.c  */
-#line 8410 "gram.y"
+#line 8411 "gram.y"
     {
 						DeallocateStmt *n = makeNode(DeallocateStmt);
 						n->name = (yyvsp[(2) - (2)].str);
@@ -32071,9 +29776,7 @@ yyreduce:
     break;
 
   case 1255:
-
-/* Line 1806 of yacc.c  */
-#line 8416 "gram.y"
+#line 8417 "gram.y"
     {
 						DeallocateStmt *n = makeNode(DeallocateStmt);
 						n->name = (yyvsp[(3) - (3)].str);
@@ -32082,9 +29785,7 @@ yyreduce:
     break;
 
   case 1256:
-
-/* Line 1806 of yacc.c  */
-#line 8422 "gram.y"
+#line 8423 "gram.y"
     {
 						DeallocateStmt *n = makeNode(DeallocateStmt);
 						n->name = NULL;
@@ -32093,9 +29794,7 @@ yyreduce:
     break;
 
   case 1257:
-
-/* Line 1806 of yacc.c  */
-#line 8428 "gram.y"
+#line 8429 "gram.y"
     {
 						DeallocateStmt *n = makeNode(DeallocateStmt);
 						n->name = NULL;
@@ -32104,9 +29803,7 @@ yyreduce:
     break;
 
   case 1258:
-
-/* Line 1806 of yacc.c  */
-#line 8444 "gram.y"
+#line 8445 "gram.y"
     {
 					(yyvsp[(5) - (6)].istmt)->relation = (yyvsp[(4) - (6)].range);
 					(yyvsp[(5) - (6)].istmt)->returningList = (yyvsp[(6) - (6)].list);
@@ -32116,9 +29813,7 @@ yyreduce:
     break;
 
   case 1259:
-
-/* Line 1806 of yacc.c  */
-#line 8454 "gram.y"
+#line 8455 "gram.y"
     {
 					(yyval.istmt) = makeNode(InsertStmt);
 					(yyval.istmt)->cols = NIL;
@@ -32127,9 +29822,7 @@ yyreduce:
     break;
 
   case 1260:
-
-/* Line 1806 of yacc.c  */
-#line 8460 "gram.y"
+#line 8461 "gram.y"
     {
 					(yyval.istmt) = makeNode(InsertStmt);
 					(yyval.istmt)->cols = (yyvsp[(2) - (4)].list);
@@ -32138,9 +29831,7 @@ yyreduce:
     break;
 
   case 1261:
-
-/* Line 1806 of yacc.c  */
-#line 8466 "gram.y"
+#line 8467 "gram.y"
     {
 					(yyval.istmt) = makeNode(InsertStmt);
 					(yyval.istmt)->cols = NIL;
@@ -32149,23 +29840,17 @@ yyreduce:
     break;
 
   case 1262:
-
-/* Line 1806 of yacc.c  */
-#line 8475 "gram.y"
+#line 8476 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].target)); }
     break;
 
   case 1263:
-
-/* Line 1806 of yacc.c  */
-#line 8477 "gram.y"
+#line 8478 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].target)); }
     break;
 
   case 1264:
-
-/* Line 1806 of yacc.c  */
-#line 8482 "gram.y"
+#line 8483 "gram.y"
     {
 					(yyval.target) = makeNode(ResTarget);
 					(yyval.target)->name = (yyvsp[(1) - (2)].str);
@@ -32176,23 +29861,17 @@ yyreduce:
     break;
 
   case 1265:
-
-/* Line 1806 of yacc.c  */
-#line 8492 "gram.y"
+#line 8493 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (2)].list); }
     break;
 
   case 1266:
-
-/* Line 1806 of yacc.c  */
-#line 8493 "gram.y"
+#line 8494 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1267:
-
-/* Line 1806 of yacc.c  */
-#line 8506 "gram.y"
+#line 8507 "gram.y"
     {
 					DeleteStmt *n = makeNode(DeleteStmt);
 					n->relation = (yyvsp[(4) - (7)].range);
@@ -32205,23 +29884,17 @@ yyreduce:
     break;
 
   case 1268:
-
-/* Line 1806 of yacc.c  */
-#line 8518 "gram.y"
+#line 8519 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (2)].list); }
     break;
 
   case 1269:
-
-/* Line 1806 of yacc.c  */
-#line 8519 "gram.y"
+#line 8520 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1270:
-
-/* Line 1806 of yacc.c  */
-#line 8531 "gram.y"
+#line 8532 "gram.y"
     {
 					LockStmt *n = makeNode(LockStmt);
 
@@ -32233,93 +29906,67 @@ yyreduce:
     break;
 
   case 1271:
-
-/* Line 1806 of yacc.c  */
-#line 8541 "gram.y"
+#line 8542 "gram.y"
     { (yyval.ival) = (yyvsp[(2) - (3)].ival); }
     break;
 
   case 1272:
-
-/* Line 1806 of yacc.c  */
-#line 8542 "gram.y"
+#line 8543 "gram.y"
     { (yyval.ival) = AccessExclusiveLock; }
     break;
 
   case 1273:
-
-/* Line 1806 of yacc.c  */
-#line 8545 "gram.y"
+#line 8546 "gram.y"
     { (yyval.ival) = AccessShareLock; }
     break;
 
   case 1274:
-
-/* Line 1806 of yacc.c  */
-#line 8546 "gram.y"
+#line 8547 "gram.y"
     { (yyval.ival) = RowShareLock; }
     break;
 
   case 1275:
-
-/* Line 1806 of yacc.c  */
-#line 8547 "gram.y"
+#line 8548 "gram.y"
     { (yyval.ival) = RowExclusiveLock; }
     break;
 
   case 1276:
-
-/* Line 1806 of yacc.c  */
-#line 8548 "gram.y"
+#line 8549 "gram.y"
     { (yyval.ival) = ShareUpdateExclusiveLock; }
     break;
 
   case 1277:
-
-/* Line 1806 of yacc.c  */
-#line 8549 "gram.y"
+#line 8550 "gram.y"
     { (yyval.ival) = ShareLock; }
     break;
 
   case 1278:
-
-/* Line 1806 of yacc.c  */
-#line 8550 "gram.y"
+#line 8551 "gram.y"
     { (yyval.ival) = ShareRowExclusiveLock; }
     break;
 
   case 1279:
-
-/* Line 1806 of yacc.c  */
-#line 8551 "gram.y"
+#line 8552 "gram.y"
     { (yyval.ival) = ExclusiveLock; }
     break;
 
   case 1280:
-
-/* Line 1806 of yacc.c  */
-#line 8552 "gram.y"
+#line 8553 "gram.y"
     { (yyval.ival) = AccessExclusiveLock; }
     break;
 
   case 1281:
-
-/* Line 1806 of yacc.c  */
-#line 8555 "gram.y"
+#line 8556 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 1282:
-
-/* Line 1806 of yacc.c  */
-#line 8556 "gram.y"
+#line 8557 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 1283:
-
-/* Line 1806 of yacc.c  */
-#line 8572 "gram.y"
+#line 8573 "gram.y"
     {
 					UpdateStmt *n = makeNode(UpdateStmt);
 					n->relation = (yyvsp[(3) - (8)].range);
@@ -32333,37 +29980,27 @@ yyreduce:
     break;
 
   case 1284:
-
-/* Line 1806 of yacc.c  */
-#line 8585 "gram.y"
+#line 8586 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 1285:
-
-/* Line 1806 of yacc.c  */
-#line 8586 "gram.y"
+#line 8587 "gram.y"
     { (yyval.list) = list_concat((yyvsp[(1) - (3)].list),(yyvsp[(3) - (3)].list)); }
     break;
 
   case 1286:
-
-/* Line 1806 of yacc.c  */
-#line 8590 "gram.y"
+#line 8591 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].target)); }
     break;
 
   case 1287:
-
-/* Line 1806 of yacc.c  */
-#line 8591 "gram.y"
+#line 8592 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 1288:
-
-/* Line 1806 of yacc.c  */
-#line 8596 "gram.y"
+#line 8597 "gram.y"
     {
 					(yyval.target) = (yyvsp[(1) - (3)].target);
 					(yyval.target)->val = (Node *) (yyvsp[(3) - (3)].node);
@@ -32371,9 +30008,7 @@ yyreduce:
     break;
 
   case 1289:
-
-/* Line 1806 of yacc.c  */
-#line 8604 "gram.y"
+#line 8605 "gram.y"
     {
 					ListCell *col_cell;
 					ListCell *val_cell;
@@ -32401,9 +30036,7 @@ yyreduce:
     break;
 
   case 1290:
-
-/* Line 1806 of yacc.c  */
-#line 8632 "gram.y"
+#line 8633 "gram.y"
     {
 					(yyval.target) = makeNode(ResTarget);
 					(yyval.target)->name = (yyvsp[(1) - (2)].str);
@@ -32414,23 +30047,17 @@ yyreduce:
     break;
 
   case 1291:
-
-/* Line 1806 of yacc.c  */
-#line 8642 "gram.y"
+#line 8643 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].target)); }
     break;
 
   case 1292:
-
-/* Line 1806 of yacc.c  */
-#line 8643 "gram.y"
+#line 8644 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list),(yyvsp[(3) - (3)].target)); }
     break;
 
   case 1293:
-
-/* Line 1806 of yacc.c  */
-#line 8654 "gram.y"
+#line 8655 "gram.y"
     {
 					DeclareCursorStmt *n = makeNode(DeclareCursorStmt);
 					n->portalname = (yyvsp[(2) - (7)].str);
@@ -32442,93 +30069,67 @@ yyreduce:
     break;
 
   case 1294:
-
-/* Line 1806 of yacc.c  */
-#line 8664 "gram.y"
+#line 8665 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1295:
-
-/* Line 1806 of yacc.c  */
-#line 8667 "gram.y"
+#line 8668 "gram.y"
     { (yyval.ival) = 0; }
     break;
 
   case 1296:
-
-/* Line 1806 of yacc.c  */
-#line 8668 "gram.y"
+#line 8669 "gram.y"
     { (yyval.ival) = (yyvsp[(1) - (3)].ival) | CURSOR_OPT_NO_SCROLL; }
     break;
 
   case 1297:
-
-/* Line 1806 of yacc.c  */
-#line 8669 "gram.y"
+#line 8670 "gram.y"
     { (yyval.ival) = (yyvsp[(1) - (2)].ival) | CURSOR_OPT_SCROLL; }
     break;
 
   case 1298:
-
-/* Line 1806 of yacc.c  */
-#line 8670 "gram.y"
+#line 8671 "gram.y"
     { (yyval.ival) = (yyvsp[(1) - (2)].ival) | CURSOR_OPT_BINARY; }
     break;
 
   case 1299:
-
-/* Line 1806 of yacc.c  */
-#line 8671 "gram.y"
+#line 8672 "gram.y"
     { (yyval.ival) = (yyvsp[(1) - (2)].ival) | CURSOR_OPT_INSENSITIVE; }
     break;
 
   case 1300:
-
-/* Line 1806 of yacc.c  */
-#line 8674 "gram.y"
+#line 8675 "gram.y"
     { (yyval.ival) = 0; }
     break;
 
   case 1301:
-
-/* Line 1806 of yacc.c  */
-#line 8675 "gram.y"
+#line 8676 "gram.y"
     { (yyval.ival) = CURSOR_OPT_HOLD; }
     break;
 
   case 1302:
-
-/* Line 1806 of yacc.c  */
-#line 8676 "gram.y"
+#line 8677 "gram.y"
     { (yyval.ival) = 0; }
     break;
 
   case 1305:
-
-/* Line 1806 of yacc.c  */
-#line 8729 "gram.y"
+#line 8730 "gram.y"
     { (yyval.node) = (yyvsp[(2) - (3)].node); }
     break;
 
   case 1306:
-
-/* Line 1806 of yacc.c  */
-#line 8730 "gram.y"
+#line 8731 "gram.y"
     { (yyval.node) = (yyvsp[(2) - (3)].node); }
     break;
 
   case 1307:
-
-/* Line 1806 of yacc.c  */
-#line 8744 "gram.y"
+#line 8745 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 1308:
-
-/* Line 1806 of yacc.c  */
-#line 8746 "gram.y"
+#line 8747 "gram.y"
     {
 					insertSelectOptions((SelectStmt *) (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].list), NIL,
 										NULL, NULL, NULL,
@@ -32538,9 +30139,7 @@ yyreduce:
     break;
 
   case 1309:
-
-/* Line 1806 of yacc.c  */
-#line 8753 "gram.y"
+#line 8754 "gram.y"
     {
 					insertSelectOptions((SelectStmt *) (yyvsp[(1) - (4)].node), (yyvsp[(2) - (4)].list), (yyvsp[(3) - (4)].list),
 										list_nth((yyvsp[(4) - (4)].list), 0), list_nth((yyvsp[(4) - (4)].list), 1),
@@ -32551,9 +30150,7 @@ yyreduce:
     break;
 
   case 1310:
-
-/* Line 1806 of yacc.c  */
-#line 8761 "gram.y"
+#line 8762 "gram.y"
     {
 					insertSelectOptions((SelectStmt *) (yyvsp[(1) - (4)].node), (yyvsp[(2) - (4)].list), (yyvsp[(4) - (4)].list),
 										list_nth((yyvsp[(3) - (4)].list), 0), list_nth((yyvsp[(3) - (4)].list), 1),
@@ -32564,9 +30161,7 @@ yyreduce:
     break;
 
   case 1311:
-
-/* Line 1806 of yacc.c  */
-#line 8769 "gram.y"
+#line 8770 "gram.y"
     {
 					insertSelectOptions((SelectStmt *) (yyvsp[(2) - (2)].node), NULL, NIL,
 										NULL, NULL,
@@ -32577,9 +30172,7 @@ yyreduce:
     break;
 
   case 1312:
-
-/* Line 1806 of yacc.c  */
-#line 8777 "gram.y"
+#line 8778 "gram.y"
     {
 					insertSelectOptions((SelectStmt *) (yyvsp[(2) - (3)].node), (yyvsp[(3) - (3)].list), NIL,
 										NULL, NULL,
@@ -32590,9 +30183,7 @@ yyreduce:
     break;
 
   case 1313:
-
-/* Line 1806 of yacc.c  */
-#line 8785 "gram.y"
+#line 8786 "gram.y"
     {
 					insertSelectOptions((SelectStmt *) (yyvsp[(2) - (5)].node), (yyvsp[(3) - (5)].list), (yyvsp[(4) - (5)].list),
 										list_nth((yyvsp[(5) - (5)].list), 0), list_nth((yyvsp[(5) - (5)].list), 1),
@@ -32603,9 +30194,7 @@ yyreduce:
     break;
 
   case 1314:
-
-/* Line 1806 of yacc.c  */
-#line 8793 "gram.y"
+#line 8794 "gram.y"
     {
 					insertSelectOptions((SelectStmt *) (yyvsp[(2) - (5)].node), (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list),
 										list_nth((yyvsp[(4) - (5)].list), 0), list_nth((yyvsp[(4) - (5)].list), 1),
@@ -32616,23 +30205,17 @@ yyreduce:
     break;
 
   case 1315:
-
-/* Line 1806 of yacc.c  */
-#line 8803 "gram.y"
+#line 8804 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 1316:
-
-/* Line 1806 of yacc.c  */
-#line 8804 "gram.y"
+#line 8805 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 1317:
-
-/* Line 1806 of yacc.c  */
-#line 8834 "gram.y"
+#line 8835 "gram.y"
     {
 					SelectStmt *n = makeNode(SelectStmt);
 					n->distinctClause = (yyvsp[(2) - (9)].list);
@@ -32648,16 +30231,12 @@ yyreduce:
     break;
 
   case 1318:
-
-/* Line 1806 of yacc.c  */
-#line 8846 "gram.y"
+#line 8847 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 1319:
-
-/* Line 1806 of yacc.c  */
-#line 8848 "gram.y"
+#line 8849 "gram.y"
     {
 					/* same as SELECT * FROM relation_expr */
 					ColumnRef *cr = makeNode(ColumnRef);
@@ -32679,36 +30258,28 @@ yyreduce:
     break;
 
   case 1320:
-
-/* Line 1806 of yacc.c  */
-#line 8867 "gram.y"
+#line 8868 "gram.y"
     {
 					(yyval.node) = makeSetOp(SETOP_UNION, (yyvsp[(3) - (4)].boolean), (yyvsp[(1) - (4)].node), (yyvsp[(4) - (4)].node));
 				}
     break;
 
   case 1321:
-
-/* Line 1806 of yacc.c  */
-#line 8871 "gram.y"
+#line 8872 "gram.y"
     {
 					(yyval.node) = makeSetOp(SETOP_INTERSECT, (yyvsp[(3) - (4)].boolean), (yyvsp[(1) - (4)].node), (yyvsp[(4) - (4)].node));
 				}
     break;
 
   case 1322:
-
-/* Line 1806 of yacc.c  */
-#line 8875 "gram.y"
+#line 8876 "gram.y"
     {
 					(yyval.node) = makeSetOp(SETOP_EXCEPT, (yyvsp[(3) - (4)].boolean), (yyvsp[(1) - (4)].node), (yyvsp[(4) - (4)].node));
 				}
     break;
 
   case 1323:
-
-/* Line 1806 of yacc.c  */
-#line 8890 "gram.y"
+#line 8891 "gram.y"
     {
 				(yyval.with) = makeNode(WithClause);
 				(yyval.with)->ctes = (yyvsp[(2) - (2)].list);
@@ -32718,9 +30289,7 @@ yyreduce:
     break;
 
   case 1324:
-
-/* Line 1806 of yacc.c  */
-#line 8897 "gram.y"
+#line 8898 "gram.y"
     {
 				(yyval.with) = makeNode(WithClause);
 				(yyval.with)->ctes = (yyvsp[(3) - (3)].list);
@@ -32730,23 +30299,17 @@ yyreduce:
     break;
 
   case 1325:
-
-/* Line 1806 of yacc.c  */
-#line 8906 "gram.y"
+#line 8907 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); }
     break;
 
   case 1326:
-
-/* Line 1806 of yacc.c  */
-#line 8907 "gram.y"
+#line 8908 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); }
     break;
 
   case 1327:
-
-/* Line 1806 of yacc.c  */
-#line 8911 "gram.y"
+#line 8912 "gram.y"
     {
 				CommonTableExpr *n = makeNode(CommonTableExpr);
 				n->ctename = (yyvsp[(1) - (6)].str);
@@ -32758,23 +30321,17 @@ yyreduce:
     break;
 
   case 1328:
-
-/* Line 1806 of yacc.c  */
-#line 8922 "gram.y"
+#line 8923 "gram.y"
     { (yyval.with) = (yyvsp[(1) - (1)].with); }
     break;
 
   case 1329:
-
-/* Line 1806 of yacc.c  */
-#line 8923 "gram.y"
+#line 8924 "gram.y"
     { (yyval.with) = NULL; }
     break;
 
   case 1330:
-
-/* Line 1806 of yacc.c  */
-#line 8928 "gram.y"
+#line 8929 "gram.y"
     {
 					(yyval.into) = makeNode(IntoClause);
 					(yyval.into)->rel = (yyvsp[(2) - (2)].range);
@@ -32787,16 +30344,12 @@ yyreduce:
     break;
 
   case 1331:
-
-/* Line 1806 of yacc.c  */
-#line 8938 "gram.y"
+#line 8939 "gram.y"
     { (yyval.into) = NULL; }
     break;
 
   case 1332:
-
-/* Line 1806 of yacc.c  */
-#line 8947 "gram.y"
+#line 8948 "gram.y"
     {
 					(yyval.range) = (yyvsp[(3) - (3)].range);
 					(yyval.range)->relpersistence = RELPERSISTENCE_TEMP;
@@ -32804,9 +30357,7 @@ yyreduce:
     break;
 
   case 1333:
-
-/* Line 1806 of yacc.c  */
-#line 8952 "gram.y"
+#line 8953 "gram.y"
     {
 					(yyval.range) = (yyvsp[(3) - (3)].range);
 					(yyval.range)->relpersistence = RELPERSISTENCE_TEMP;
@@ -32814,9 +30365,7 @@ yyreduce:
     break;
 
   case 1334:
-
-/* Line 1806 of yacc.c  */
-#line 8957 "gram.y"
+#line 8958 "gram.y"
     {
 					(yyval.range) = (yyvsp[(4) - (4)].range);
 					(yyval.range)->relpersistence = RELPERSISTENCE_TEMP;
@@ -32824,9 +30373,7 @@ yyreduce:
     break;
 
   case 1335:
-
-/* Line 1806 of yacc.c  */
-#line 8962 "gram.y"
+#line 8963 "gram.y"
     {
 					(yyval.range) = (yyvsp[(4) - (4)].range);
 					(yyval.range)->relpersistence = RELPERSISTENCE_TEMP;
@@ -32834,9 +30381,7 @@ yyreduce:
     break;
 
   case 1336:
-
-/* Line 1806 of yacc.c  */
-#line 8967 "gram.y"
+#line 8968 "gram.y"
     {
 					ereport(WARNING,
 							(errmsg("GLOBAL is deprecated in temporary table creation"),
@@ -32847,9 +30392,7 @@ yyreduce:
     break;
 
   case 1337:
-
-/* Line 1806 of yacc.c  */
-#line 8975 "gram.y"
+#line 8976 "gram.y"
     {
 					ereport(WARNING,
 							(errmsg("GLOBAL is deprecated in temporary table creation"),
@@ -32860,9 +30403,7 @@ yyreduce:
     break;
 
   case 1338:
-
-/* Line 1806 of yacc.c  */
-#line 8983 "gram.y"
+#line 8984 "gram.y"
     {
 					(yyval.range) = (yyvsp[(3) - (3)].range);
 					(yyval.range)->relpersistence = RELPERSISTENCE_UNLOGGED;
@@ -32870,9 +30411,7 @@ yyreduce:
     break;
 
   case 1339:
-
-/* Line 1806 of yacc.c  */
-#line 8988 "gram.y"
+#line 8989 "gram.y"
     {
 					(yyval.range) = (yyvsp[(2) - (2)].range);
 					(yyval.range)->relpersistence = RELPERSISTENCE_PERMANENT;
@@ -32880,9 +30419,7 @@ yyreduce:
     break;
 
   case 1340:
-
-/* Line 1806 of yacc.c  */
-#line 8993 "gram.y"
+#line 8994 "gram.y"
     {
 					(yyval.range) = (yyvsp[(1) - (1)].range);
 					(yyval.range)->relpersistence = RELPERSISTENCE_PERMANENT;
@@ -32890,107 +30427,77 @@ yyreduce:
     break;
 
   case 1341:
-
-/* Line 1806 of yacc.c  */
-#line 8999 "gram.y"
+#line 9000 "gram.y"
     {}
     break;
 
   case 1342:
-
-/* Line 1806 of yacc.c  */
-#line 9000 "gram.y"
+#line 9001 "gram.y"
     {}
     break;
 
   case 1343:
-
-/* Line 1806 of yacc.c  */
-#line 9003 "gram.y"
+#line 9004 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 1344:
-
-/* Line 1806 of yacc.c  */
-#line 9004 "gram.y"
+#line 9005 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 1345:
-
-/* Line 1806 of yacc.c  */
-#line 9005 "gram.y"
+#line 9006 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 1346:
-
-/* Line 1806 of yacc.c  */
-#line 9012 "gram.y"
+#line 9013 "gram.y"
     { (yyval.list) = list_make1(NIL); }
     break;
 
   case 1347:
-
-/* Line 1806 of yacc.c  */
-#line 9013 "gram.y"
+#line 9014 "gram.y"
     { (yyval.list) = (yyvsp[(4) - (5)].list); }
     break;
 
   case 1348:
-
-/* Line 1806 of yacc.c  */
-#line 9014 "gram.y"
+#line 9015 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1349:
-
-/* Line 1806 of yacc.c  */
-#line 9015 "gram.y"
+#line 9016 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1350:
-
-/* Line 1806 of yacc.c  */
-#line 9019 "gram.y"
+#line 9020 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list);}
     break;
 
   case 1351:
-
-/* Line 1806 of yacc.c  */
-#line 9020 "gram.y"
+#line 9021 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1352:
-
-/* Line 1806 of yacc.c  */
-#line 9024 "gram.y"
+#line 9025 "gram.y"
     { (yyval.list) = (yyvsp[(3) - (3)].list); }
     break;
 
   case 1353:
-
-/* Line 1806 of yacc.c  */
-#line 9028 "gram.y"
+#line 9029 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].sortby)); }
     break;
 
   case 1354:
-
-/* Line 1806 of yacc.c  */
-#line 9029 "gram.y"
+#line 9030 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].sortby)); }
     break;
 
   case 1355:
-
-/* Line 1806 of yacc.c  */
-#line 9033 "gram.y"
+#line 9034 "gram.y"
     {
 					(yyval.sortby) = makeNode(SortBy);
 					(yyval.sortby)->node = (yyvsp[(1) - (4)].node);
@@ -33002,9 +30509,7 @@ yyreduce:
     break;
 
   case 1356:
-
-/* Line 1806 of yacc.c  */
-#line 9042 "gram.y"
+#line 9043 "gram.y"
     {
 					(yyval.sortby) = makeNode(SortBy);
 					(yyval.sortby)->node = (yyvsp[(1) - (3)].node);
@@ -33016,58 +30521,42 @@ yyreduce:
     break;
 
   case 1357:
-
-/* Line 1806 of yacc.c  */
-#line 9054 "gram.y"
+#line 9055 "gram.y"
     { (yyval.list) = list_make2((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].node)); }
     break;
 
   case 1358:
-
-/* Line 1806 of yacc.c  */
-#line 9055 "gram.y"
+#line 9056 "gram.y"
     { (yyval.list) = list_make2((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node)); }
     break;
 
   case 1359:
-
-/* Line 1806 of yacc.c  */
-#line 9056 "gram.y"
+#line 9057 "gram.y"
     { (yyval.list) = list_make2(NULL, (yyvsp[(1) - (1)].node)); }
     break;
 
   case 1360:
-
-/* Line 1806 of yacc.c  */
-#line 9057 "gram.y"
+#line 9058 "gram.y"
     { (yyval.list) = list_make2((yyvsp[(1) - (1)].node), NULL); }
     break;
 
   case 1361:
-
-/* Line 1806 of yacc.c  */
-#line 9061 "gram.y"
+#line 9062 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 1362:
-
-/* Line 1806 of yacc.c  */
-#line 9062 "gram.y"
+#line 9063 "gram.y"
     { (yyval.list) = list_make2(NULL,NULL); }
     break;
 
   case 1363:
-
-/* Line 1806 of yacc.c  */
-#line 9067 "gram.y"
+#line 9068 "gram.y"
     { (yyval.node) = (yyvsp[(2) - (2)].node); }
     break;
 
   case 1364:
-
-/* Line 1806 of yacc.c  */
-#line 9069 "gram.y"
+#line 9070 "gram.y"
     {
 					/* Disabled because it was too confusing, bjm 2002-02-18 */
 					ereport(ERROR,
@@ -33079,37 +30568,27 @@ yyreduce:
     break;
 
   case 1365:
-
-/* Line 1806 of yacc.c  */
-#line 9079 "gram.y"
+#line 9080 "gram.y"
     { (yyval.node) = (yyvsp[(3) - (5)].node); }
     break;
 
   case 1366:
-
-/* Line 1806 of yacc.c  */
-#line 9084 "gram.y"
+#line 9085 "gram.y"
     { (yyval.node) = (yyvsp[(2) - (2)].node); }
     break;
 
   case 1367:
-
-/* Line 1806 of yacc.c  */
-#line 9087 "gram.y"
+#line 9088 "gram.y"
     { (yyval.node) = (yyvsp[(2) - (3)].node); }
     break;
 
   case 1368:
-
-/* Line 1806 of yacc.c  */
-#line 9091 "gram.y"
+#line 9092 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 1369:
-
-/* Line 1806 of yacc.c  */
-#line 9093 "gram.y"
+#line 9094 "gram.y"
     {
 					/* LIMIT ALL is represented as a NULL constant */
 					(yyval.node) = makeNullAConst((yylsp[(1) - (1)]));
@@ -33117,142 +30596,102 @@ yyreduce:
     break;
 
   case 1370:
-
-/* Line 1806 of yacc.c  */
-#line 9100 "gram.y"
+#line 9101 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 1371:
-
-/* Line 1806 of yacc.c  */
-#line 9110 "gram.y"
+#line 9111 "gram.y"
     { (yyval.node) = makeIntConst((yyvsp[(1) - (1)].ival), (yylsp[(1) - (1)])); }
     break;
 
   case 1372:
-
-/* Line 1806 of yacc.c  */
-#line 9111 "gram.y"
+#line 9112 "gram.y"
     { (yyval.node) = (yyvsp[(2) - (3)].node); }
     break;
 
   case 1373:
-
-/* Line 1806 of yacc.c  */
-#line 9112 "gram.y"
+#line 9113 "gram.y"
     { (yyval.node) = makeIntConst(1, -1); }
     break;
 
   case 1374:
-
-/* Line 1806 of yacc.c  */
-#line 9120 "gram.y"
+#line 9121 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 1375:
-
-/* Line 1806 of yacc.c  */
-#line 9124 "gram.y"
+#line 9125 "gram.y"
     { (yyval.ival) = 0; }
     break;
 
   case 1376:
-
-/* Line 1806 of yacc.c  */
-#line 9125 "gram.y"
+#line 9126 "gram.y"
     { (yyval.ival) = 0; }
     break;
 
   case 1377:
-
-/* Line 1806 of yacc.c  */
-#line 9128 "gram.y"
+#line 9129 "gram.y"
     { (yyval.ival) = 0; }
     break;
 
   case 1378:
-
-/* Line 1806 of yacc.c  */
-#line 9129 "gram.y"
+#line 9130 "gram.y"
     { (yyval.ival) = 0; }
     break;
 
   case 1379:
-
-/* Line 1806 of yacc.c  */
-#line 9134 "gram.y"
+#line 9135 "gram.y"
     { (yyval.list) = (yyvsp[(3) - (3)].list); }
     break;
 
   case 1380:
-
-/* Line 1806 of yacc.c  */
-#line 9135 "gram.y"
+#line 9136 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1381:
-
-/* Line 1806 of yacc.c  */
-#line 9139 "gram.y"
+#line 9140 "gram.y"
     { (yyval.node) = (yyvsp[(2) - (2)].node); }
     break;
 
   case 1382:
-
-/* Line 1806 of yacc.c  */
-#line 9140 "gram.y"
+#line 9141 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 1383:
-
-/* Line 1806 of yacc.c  */
-#line 9144 "gram.y"
+#line 9145 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 1384:
-
-/* Line 1806 of yacc.c  */
-#line 9145 "gram.y"
+#line 9146 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1385:
-
-/* Line 1806 of yacc.c  */
-#line 9149 "gram.y"
+#line 9150 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 1386:
-
-/* Line 1806 of yacc.c  */
-#line 9150 "gram.y"
+#line 9151 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1387:
-
-/* Line 1806 of yacc.c  */
-#line 9154 "gram.y"
+#line 9155 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); }
     break;
 
   case 1388:
-
-/* Line 1806 of yacc.c  */
-#line 9155 "gram.y"
+#line 9156 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); }
     break;
 
   case 1389:
-
-/* Line 1806 of yacc.c  */
-#line 9160 "gram.y"
+#line 9161 "gram.y"
     {
 					LockingClause *n = makeNode(LockingClause);
 					n->lockedRels = (yyvsp[(3) - (4)].list);
@@ -33263,9 +30702,7 @@ yyreduce:
     break;
 
   case 1390:
-
-/* Line 1806 of yacc.c  */
-#line 9168 "gram.y"
+#line 9169 "gram.y"
     {
 					LockingClause *n = makeNode(LockingClause);
 					n->lockedRels = (yyvsp[(3) - (4)].list);
@@ -33276,23 +30713,17 @@ yyreduce:
     break;
 
   case 1391:
-
-/* Line 1806 of yacc.c  */
-#line 9178 "gram.y"
+#line 9179 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (2)].list); }
     break;
 
   case 1392:
-
-/* Line 1806 of yacc.c  */
-#line 9179 "gram.y"
+#line 9180 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1393:
-
-/* Line 1806 of yacc.c  */
-#line 9185 "gram.y"
+#line 9186 "gram.y"
     {
 					SelectStmt *n = makeNode(SelectStmt);
 					n->valuesLists = list_make1((yyvsp[(2) - (2)].list));
@@ -33301,9 +30732,7 @@ yyreduce:
     break;
 
   case 1394:
-
-/* Line 1806 of yacc.c  */
-#line 9191 "gram.y"
+#line 9192 "gram.y"
     {
 					SelectStmt *n = (SelectStmt *) (yyvsp[(1) - (3)].node);
 					n->valuesLists = lappend(n->valuesLists, (yyvsp[(3) - (3)].list));
@@ -33312,46 +30741,34 @@ yyreduce:
     break;
 
   case 1395:
-
-/* Line 1806 of yacc.c  */
-#line 9208 "gram.y"
+#line 9209 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (2)].list); }
     break;
 
   case 1396:
-
-/* Line 1806 of yacc.c  */
-#line 9209 "gram.y"
+#line 9210 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1397:
-
-/* Line 1806 of yacc.c  */
-#line 9213 "gram.y"
+#line 9214 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); }
     break;
 
   case 1398:
-
-/* Line 1806 of yacc.c  */
-#line 9214 "gram.y"
+#line 9215 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); }
     break;
 
   case 1399:
-
-/* Line 1806 of yacc.c  */
-#line 9225 "gram.y"
+#line 9226 "gram.y"
     {
 					(yyval.node) = (Node *) (yyvsp[(1) - (1)].range);
 				}
     break;
 
   case 1400:
-
-/* Line 1806 of yacc.c  */
-#line 9229 "gram.y"
+#line 9230 "gram.y"
     {
 					(yyvsp[(1) - (2)].range)->alias = (yyvsp[(2) - (2)].alias);
 					(yyval.node) = (Node *) (yyvsp[(1) - (2)].range);
@@ -33359,9 +30776,7 @@ yyreduce:
     break;
 
   case 1401:
-
-/* Line 1806 of yacc.c  */
-#line 9234 "gram.y"
+#line 9235 "gram.y"
     {
 					RangeFunction *n = makeNode(RangeFunction);
 					n->funccallnode = (yyvsp[(1) - (1)].node);
@@ -33371,9 +30786,7 @@ yyreduce:
     break;
 
   case 1402:
-
-/* Line 1806 of yacc.c  */
-#line 9241 "gram.y"
+#line 9242 "gram.y"
     {
 					RangeFunction *n = makeNode(RangeFunction);
 					n->funccallnode = (yyvsp[(1) - (2)].node);
@@ -33384,9 +30797,7 @@ yyreduce:
     break;
 
   case 1403:
-
-/* Line 1806 of yacc.c  */
-#line 9249 "gram.y"
+#line 9250 "gram.y"
     {
 					RangeFunction *n = makeNode(RangeFunction);
 					n->funccallnode = (yyvsp[(1) - (5)].node);
@@ -33396,9 +30807,7 @@ yyreduce:
     break;
 
   case 1404:
-
-/* Line 1806 of yacc.c  */
-#line 9256 "gram.y"
+#line 9257 "gram.y"
     {
 					RangeFunction *n = makeNode(RangeFunction);
 					Alias *a = makeNode(Alias);
@@ -33411,9 +30820,7 @@ yyreduce:
     break;
 
   case 1405:
-
-/* Line 1806 of yacc.c  */
-#line 9266 "gram.y"
+#line 9267 "gram.y"
     {
 					RangeFunction *n = makeNode(RangeFunction);
 					Alias *a = makeNode(Alias);
@@ -33426,9 +30833,7 @@ yyreduce:
     break;
 
   case 1406:
-
-/* Line 1806 of yacc.c  */
-#line 9276 "gram.y"
+#line 9277 "gram.y"
     {
 					/*
 					 * The SQL spec does not permit a subselect
@@ -33459,9 +30864,7 @@ yyreduce:
     break;
 
   case 1407:
-
-/* Line 1806 of yacc.c  */
-#line 9304 "gram.y"
+#line 9305 "gram.y"
     {
 					RangeSubselect *n = makeNode(RangeSubselect);
 					n->subquery = (yyvsp[(1) - (2)].node);
@@ -33471,18 +30874,14 @@ yyreduce:
     break;
 
   case 1408:
-
-/* Line 1806 of yacc.c  */
-#line 9311 "gram.y"
+#line 9312 "gram.y"
     {
 					(yyval.node) = (Node *) (yyvsp[(1) - (1)].jexpr);
 				}
     break;
 
   case 1409:
-
-/* Line 1806 of yacc.c  */
-#line 9315 "gram.y"
+#line 9316 "gram.y"
     {
 					(yyvsp[(2) - (4)].jexpr)->alias = (yyvsp[(4) - (4)].alias);
 					(yyval.node) = (Node *) (yyvsp[(2) - (4)].jexpr);
@@ -33490,18 +30889,14 @@ yyreduce:
     break;
 
   case 1410:
-
-/* Line 1806 of yacc.c  */
-#line 9341 "gram.y"
+#line 9342 "gram.y"
     {
 					(yyval.jexpr) = (yyvsp[(2) - (3)].jexpr);
 				}
     break;
 
   case 1411:
-
-/* Line 1806 of yacc.c  */
-#line 9345 "gram.y"
+#line 9346 "gram.y"
     {
 					/* CROSS JOIN is same as unqualified inner join */
 					JoinExpr *n = makeNode(JoinExpr);
@@ -33516,9 +30911,7 @@ yyreduce:
     break;
 
   case 1412:
-
-/* Line 1806 of yacc.c  */
-#line 9357 "gram.y"
+#line 9358 "gram.y"
     {
 					JoinExpr *n = makeNode(JoinExpr);
 					n->jointype = (yyvsp[(2) - (5)].jtype);
@@ -33534,9 +30927,7 @@ yyreduce:
     break;
 
   case 1413:
-
-/* Line 1806 of yacc.c  */
-#line 9370 "gram.y"
+#line 9371 "gram.y"
     {
 					/* letting join_type reduce to empty doesn't work */
 					JoinExpr *n = makeNode(JoinExpr);
@@ -33553,9 +30944,7 @@ yyreduce:
     break;
 
   case 1414:
-
-/* Line 1806 of yacc.c  */
-#line 9384 "gram.y"
+#line 9385 "gram.y"
     {
 					JoinExpr *n = makeNode(JoinExpr);
 					n->jointype = (yyvsp[(3) - (5)].jtype);
@@ -33569,9 +30958,7 @@ yyreduce:
     break;
 
   case 1415:
-
-/* Line 1806 of yacc.c  */
-#line 9395 "gram.y"
+#line 9396 "gram.y"
     {
 					/* letting join_type reduce to empty doesn't work */
 					JoinExpr *n = makeNode(JoinExpr);
@@ -33586,9 +30973,7 @@ yyreduce:
     break;
 
   case 1416:
-
-/* Line 1806 of yacc.c  */
-#line 9410 "gram.y"
+#line 9411 "gram.y"
     {
 					(yyval.alias) = makeNode(Alias);
 					(yyval.alias)->aliasname = (yyvsp[(2) - (5)].str);
@@ -33597,9 +30982,7 @@ yyreduce:
     break;
 
   case 1417:
-
-/* Line 1806 of yacc.c  */
-#line 9416 "gram.y"
+#line 9417 "gram.y"
     {
 					(yyval.alias) = makeNode(Alias);
 					(yyval.alias)->aliasname = (yyvsp[(2) - (2)].str);
@@ -33607,9 +30990,7 @@ yyreduce:
     break;
 
   case 1418:
-
-/* Line 1806 of yacc.c  */
-#line 9421 "gram.y"
+#line 9422 "gram.y"
     {
 					(yyval.alias) = makeNode(Alias);
 					(yyval.alias)->aliasname = (yyvsp[(1) - (4)].str);
@@ -33618,9 +30999,7 @@ yyreduce:
     break;
 
   case 1419:
-
-/* Line 1806 of yacc.c  */
-#line 9427 "gram.y"
+#line 9428 "gram.y"
     {
 					(yyval.alias) = makeNode(Alias);
 					(yyval.alias)->aliasname = (yyvsp[(1) - (1)].str);
@@ -33628,65 +31007,47 @@ yyreduce:
     break;
 
   case 1420:
-
-/* Line 1806 of yacc.c  */
-#line 9433 "gram.y"
+#line 9434 "gram.y"
     { (yyval.jtype) = JOIN_FULL; }
     break;
 
   case 1421:
-
-/* Line 1806 of yacc.c  */
-#line 9434 "gram.y"
+#line 9435 "gram.y"
     { (yyval.jtype) = JOIN_LEFT; }
     break;
 
   case 1422:
-
-/* Line 1806 of yacc.c  */
-#line 9435 "gram.y"
+#line 9436 "gram.y"
     { (yyval.jtype) = JOIN_RIGHT; }
     break;
 
   case 1423:
-
-/* Line 1806 of yacc.c  */
-#line 9436 "gram.y"
+#line 9437 "gram.y"
     { (yyval.jtype) = JOIN_INNER; }
     break;
 
   case 1424:
-
-/* Line 1806 of yacc.c  */
-#line 9440 "gram.y"
+#line 9441 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 1425:
-
-/* Line 1806 of yacc.c  */
-#line 9441 "gram.y"
+#line 9442 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 1426:
-
-/* Line 1806 of yacc.c  */
-#line 9453 "gram.y"
+#line 9454 "gram.y"
     { (yyval.node) = (Node *) (yyvsp[(3) - (4)].list); }
     break;
 
   case 1427:
-
-/* Line 1806 of yacc.c  */
-#line 9454 "gram.y"
+#line 9455 "gram.y"
     { (yyval.node) = (yyvsp[(2) - (2)].node); }
     break;
 
   case 1428:
-
-/* Line 1806 of yacc.c  */
-#line 9460 "gram.y"
+#line 9461 "gram.y"
     {
 					/* default inheritance */
 					(yyval.range) = (yyvsp[(1) - (1)].range);
@@ -33696,9 +31057,7 @@ yyreduce:
     break;
 
   case 1429:
-
-/* Line 1806 of yacc.c  */
-#line 9467 "gram.y"
+#line 9468 "gram.y"
     {
 					/* inheritance query */
 					(yyval.range) = (yyvsp[(1) - (2)].range);
@@ -33708,9 +31067,7 @@ yyreduce:
     break;
 
   case 1430:
-
-/* Line 1806 of yacc.c  */
-#line 9474 "gram.y"
+#line 9475 "gram.y"
     {
 					/* no inheritance */
 					(yyval.range) = (yyvsp[(2) - (2)].range);
@@ -33720,9 +31077,7 @@ yyreduce:
     break;
 
   case 1431:
-
-/* Line 1806 of yacc.c  */
-#line 9481 "gram.y"
+#line 9482 "gram.y"
     {
 					/* no inheritance, SQL99-style syntax */
 					(yyval.range) = (yyvsp[(3) - (4)].range);
@@ -33732,32 +31087,24 @@ yyreduce:
     break;
 
   case 1432:
-
-/* Line 1806 of yacc.c  */
-#line 9491 "gram.y"
+#line 9492 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].range)); }
     break;
 
   case 1433:
-
-/* Line 1806 of yacc.c  */
-#line 9492 "gram.y"
+#line 9493 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].range)); }
     break;
 
   case 1434:
-
-/* Line 1806 of yacc.c  */
-#line 9506 "gram.y"
+#line 9507 "gram.y"
     {
 					(yyval.range) = (yyvsp[(1) - (1)].range);
 				}
     break;
 
   case 1435:
-
-/* Line 1806 of yacc.c  */
-#line 9510 "gram.y"
+#line 9511 "gram.y"
     {
 					Alias *alias = makeNode(Alias);
 					alias->aliasname = (yyvsp[(2) - (2)].str);
@@ -33767,9 +31114,7 @@ yyreduce:
     break;
 
   case 1436:
-
-/* Line 1806 of yacc.c  */
-#line 9517 "gram.y"
+#line 9518 "gram.y"
     {
 					Alias *alias = makeNode(Alias);
 					alias->aliasname = (yyvsp[(3) - (3)].str);
@@ -33779,37 +31124,27 @@ yyreduce:
     break;
 
   case 1437:
-
-/* Line 1806 of yacc.c  */
-#line 9526 "gram.y"
+#line 9527 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 1438:
-
-/* Line 1806 of yacc.c  */
-#line 9531 "gram.y"
+#line 9532 "gram.y"
     { (yyval.node) = (yyvsp[(2) - (2)].node); }
     break;
 
   case 1439:
-
-/* Line 1806 of yacc.c  */
-#line 9532 "gram.y"
+#line 9533 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 1440:
-
-/* Line 1806 of yacc.c  */
-#line 9537 "gram.y"
+#line 9538 "gram.y"
     { (yyval.node) = (yyvsp[(2) - (2)].node); }
     break;
 
   case 1441:
-
-/* Line 1806 of yacc.c  */
-#line 9539 "gram.y"
+#line 9540 "gram.y"
     {
 					CurrentOfExpr *n = makeNode(CurrentOfExpr);
 					/* cvarno is filled in by parse analysis */
@@ -33820,48 +31155,36 @@ yyreduce:
     break;
 
   case 1442:
-
-/* Line 1806 of yacc.c  */
-#line 9546 "gram.y"
+#line 9547 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 1443:
-
-/* Line 1806 of yacc.c  */
-#line 9551 "gram.y"
+#line 9552 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 1444:
-
-/* Line 1806 of yacc.c  */
-#line 9552 "gram.y"
+#line 9553 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1445:
-
-/* Line 1806 of yacc.c  */
-#line 9557 "gram.y"
+#line 9558 "gram.y"
     {
 					(yyval.list) = list_make1((yyvsp[(1) - (1)].node));
 				}
     break;
 
   case 1446:
-
-/* Line 1806 of yacc.c  */
-#line 9561 "gram.y"
+#line 9562 "gram.y"
     {
 					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 				}
     break;
 
   case 1447:
-
-/* Line 1806 of yacc.c  */
-#line 9567 "gram.y"
+#line 9568 "gram.y"
     {
 					ColumnDef *n = makeNode(ColumnDef);
 					n->colname = (yyvsp[(1) - (3)].str);
@@ -33881,9 +31204,7 @@ yyreduce:
     break;
 
   case 1448:
-
-/* Line 1806 of yacc.c  */
-#line 9596 "gram.y"
+#line 9597 "gram.y"
     {
 					(yyval.typnam) = (yyvsp[(1) - (2)].typnam);
 					(yyval.typnam)->arrayBounds = (yyvsp[(2) - (2)].list);
@@ -33891,9 +31212,7 @@ yyreduce:
     break;
 
   case 1449:
-
-/* Line 1806 of yacc.c  */
-#line 9601 "gram.y"
+#line 9602 "gram.y"
     {
 					(yyval.typnam) = (yyvsp[(2) - (3)].typnam);
 					(yyval.typnam)->arrayBounds = (yyvsp[(3) - (3)].list);
@@ -33902,9 +31221,7 @@ yyreduce:
     break;
 
   case 1450:
-
-/* Line 1806 of yacc.c  */
-#line 9608 "gram.y"
+#line 9609 "gram.y"
     {
 					(yyval.typnam) = (yyvsp[(1) - (5)].typnam);
 					(yyval.typnam)->arrayBounds = list_make1(makeInteger((yyvsp[(4) - (5)].ival)));
@@ -33912,9 +31229,7 @@ yyreduce:
     break;
 
   case 1451:
-
-/* Line 1806 of yacc.c  */
-#line 9613 "gram.y"
+#line 9614 "gram.y"
     {
 					(yyval.typnam) = (yyvsp[(2) - (6)].typnam);
 					(yyval.typnam)->arrayBounds = list_make1(makeInteger((yyvsp[(5) - (6)].ival)));
@@ -33923,9 +31238,7 @@ yyreduce:
     break;
 
   case 1452:
-
-/* Line 1806 of yacc.c  */
-#line 9619 "gram.y"
+#line 9620 "gram.y"
     {
 					(yyval.typnam) = (yyvsp[(1) - (2)].typnam);
 					(yyval.typnam)->arrayBounds = list_make1(makeInteger(-1));
@@ -33933,9 +31246,7 @@ yyreduce:
     break;
 
   case 1453:
-
-/* Line 1806 of yacc.c  */
-#line 9624 "gram.y"
+#line 9625 "gram.y"
     {
 					(yyval.typnam) = (yyvsp[(2) - (3)].typnam);
 					(yyval.typnam)->arrayBounds = list_make1(makeInteger(-1));
@@ -33944,65 +31255,47 @@ yyreduce:
     break;
 
   case 1454:
-
-/* Line 1806 of yacc.c  */
-#line 9633 "gram.y"
+#line 9634 "gram.y"
     {  (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeInteger(-1)); }
     break;
 
   case 1455:
-
-/* Line 1806 of yacc.c  */
-#line 9635 "gram.y"
+#line 9636 "gram.y"
     {  (yyval.list) = lappend((yyvsp[(1) - (4)].list), makeInteger((yyvsp[(3) - (4)].ival))); }
     break;
 
   case 1456:
-
-/* Line 1806 of yacc.c  */
-#line 9637 "gram.y"
+#line 9638 "gram.y"
     {  (yyval.list) = NIL; }
     break;
 
   case 1457:
-
-/* Line 1806 of yacc.c  */
-#line 9641 "gram.y"
+#line 9642 "gram.y"
     { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); }
     break;
 
   case 1458:
-
-/* Line 1806 of yacc.c  */
-#line 9642 "gram.y"
+#line 9643 "gram.y"
     { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); }
     break;
 
   case 1459:
-
-/* Line 1806 of yacc.c  */
-#line 9643 "gram.y"
+#line 9644 "gram.y"
     { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); }
     break;
 
   case 1460:
-
-/* Line 1806 of yacc.c  */
-#line 9644 "gram.y"
+#line 9645 "gram.y"
     { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); }
     break;
 
   case 1461:
-
-/* Line 1806 of yacc.c  */
-#line 9645 "gram.y"
+#line 9646 "gram.y"
     { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); }
     break;
 
   case 1462:
-
-/* Line 1806 of yacc.c  */
-#line 9647 "gram.y"
+#line 9648 "gram.y"
     {
 					(yyval.typnam) = (yyvsp[(1) - (2)].typnam);
 					(yyval.typnam)->typmods = (yyvsp[(2) - (2)].list);
@@ -34010,9 +31303,7 @@ yyreduce:
     break;
 
   case 1463:
-
-/* Line 1806 of yacc.c  */
-#line 9652 "gram.y"
+#line 9653 "gram.y"
     {
 					(yyval.typnam) = (yyvsp[(1) - (5)].typnam);
 					if ((yyvsp[(5) - (5)].list) != NIL)
@@ -34031,37 +31322,27 @@ yyreduce:
     break;
 
   case 1464:
-
-/* Line 1806 of yacc.c  */
-#line 9681 "gram.y"
+#line 9682 "gram.y"
     { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); }
     break;
 
   case 1465:
-
-/* Line 1806 of yacc.c  */
-#line 9682 "gram.y"
+#line 9683 "gram.y"
     { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); }
     break;
 
   case 1466:
-
-/* Line 1806 of yacc.c  */
-#line 9683 "gram.y"
+#line 9684 "gram.y"
     { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); }
     break;
 
   case 1467:
-
-/* Line 1806 of yacc.c  */
-#line 9684 "gram.y"
+#line 9685 "gram.y"
     { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); }
     break;
 
   case 1468:
-
-/* Line 1806 of yacc.c  */
-#line 9696 "gram.y"
+#line 9697 "gram.y"
     {
 					(yyval.typnam) = makeTypeName((yyvsp[(1) - (2)].str));
 					(yyval.typnam)->typmods = (yyvsp[(2) - (2)].list);
@@ -34070,9 +31351,7 @@ yyreduce:
     break;
 
   case 1469:
-
-/* Line 1806 of yacc.c  */
-#line 9702 "gram.y"
+#line 9703 "gram.y"
     {
 					(yyval.typnam) = makeTypeNameFromNameList(lcons(makeString((yyvsp[(1) - (3)].str)), (yyvsp[(2) - (3)].list)));
 					(yyval.typnam)->typmods = (yyvsp[(3) - (3)].list);
@@ -34081,23 +31360,17 @@ yyreduce:
     break;
 
   case 1470:
-
-/* Line 1806 of yacc.c  */
-#line 9709 "gram.y"
+#line 9710 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (3)].list); }
     break;
 
   case 1471:
-
-/* Line 1806 of yacc.c  */
-#line 9710 "gram.y"
+#line 9711 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1472:
-
-/* Line 1806 of yacc.c  */
-#line 9717 "gram.y"
+#line 9718 "gram.y"
     {
 					(yyval.typnam) = SystemTypeName("int4");
 					(yyval.typnam)->location = (yylsp[(1) - (1)]);
@@ -34105,9 +31378,7 @@ yyreduce:
     break;
 
   case 1473:
-
-/* Line 1806 of yacc.c  */
-#line 9722 "gram.y"
+#line 9723 "gram.y"
     {
 					(yyval.typnam) = SystemTypeName("int4");
 					(yyval.typnam)->location = (yylsp[(1) - (1)]);
@@ -34115,9 +31386,7 @@ yyreduce:
     break;
 
   case 1474:
-
-/* Line 1806 of yacc.c  */
-#line 9727 "gram.y"
+#line 9728 "gram.y"
     {
 					(yyval.typnam) = SystemTypeName("int2");
 					(yyval.typnam)->location = (yylsp[(1) - (1)]);
@@ -34125,9 +31394,7 @@ yyreduce:
     break;
 
   case 1475:
-
-/* Line 1806 of yacc.c  */
-#line 9732 "gram.y"
+#line 9733 "gram.y"
     {
 					(yyval.typnam) = SystemTypeName("int8");
 					(yyval.typnam)->location = (yylsp[(1) - (1)]);
@@ -34135,9 +31402,7 @@ yyreduce:
     break;
 
   case 1476:
-
-/* Line 1806 of yacc.c  */
-#line 9737 "gram.y"
+#line 9738 "gram.y"
     {
 					(yyval.typnam) = SystemTypeName("float4");
 					(yyval.typnam)->location = (yylsp[(1) - (1)]);
@@ -34145,9 +31410,7 @@ yyreduce:
     break;
 
   case 1477:
-
-/* Line 1806 of yacc.c  */
-#line 9742 "gram.y"
+#line 9743 "gram.y"
     {
 					(yyval.typnam) = (yyvsp[(2) - (2)].typnam);
 					(yyval.typnam)->location = (yylsp[(1) - (2)]);
@@ -34155,9 +31418,7 @@ yyreduce:
     break;
 
   case 1478:
-
-/* Line 1806 of yacc.c  */
-#line 9747 "gram.y"
+#line 9748 "gram.y"
     {
 					(yyval.typnam) = SystemTypeName("float8");
 					(yyval.typnam)->location = (yylsp[(1) - (2)]);
@@ -34165,9 +31426,7 @@ yyreduce:
     break;
 
   case 1479:
-
-/* Line 1806 of yacc.c  */
-#line 9752 "gram.y"
+#line 9753 "gram.y"
     {
 					(yyval.typnam) = SystemTypeName("numeric");
 					(yyval.typnam)->typmods = (yyvsp[(2) - (2)].list);
@@ -34176,9 +31435,7 @@ yyreduce:
     break;
 
   case 1480:
-
-/* Line 1806 of yacc.c  */
-#line 9758 "gram.y"
+#line 9759 "gram.y"
     {
 					(yyval.typnam) = SystemTypeName("numeric");
 					(yyval.typnam)->typmods = (yyvsp[(2) - (2)].list);
@@ -34187,9 +31444,7 @@ yyreduce:
     break;
 
   case 1481:
-
-/* Line 1806 of yacc.c  */
-#line 9764 "gram.y"
+#line 9765 "gram.y"
     {
 					(yyval.typnam) = SystemTypeName("numeric");
 					(yyval.typnam)->typmods = (yyvsp[(2) - (2)].list);
@@ -34198,9 +31453,7 @@ yyreduce:
     break;
 
   case 1482:
-
-/* Line 1806 of yacc.c  */
-#line 9770 "gram.y"
+#line 9771 "gram.y"
     {
 					(yyval.typnam) = SystemTypeName("bool");
 					(yyval.typnam)->location = (yylsp[(1) - (1)]);
@@ -34208,9 +31461,7 @@ yyreduce:
     break;
 
   case 1483:
-
-/* Line 1806 of yacc.c  */
-#line 9777 "gram.y"
+#line 9778 "gram.y"
     {
 					/*
 					 * Check FLOAT() precision limits assuming IEEE floating
@@ -34234,45 +31485,35 @@ yyreduce:
     break;
 
   case 1484:
-
-/* Line 1806 of yacc.c  */
-#line 9798 "gram.y"
+#line 9799 "gram.y"
     {
 					(yyval.typnam) = SystemTypeName("float8");
 				}
     break;
 
   case 1485:
-
-/* Line 1806 of yacc.c  */
-#line 9808 "gram.y"
+#line 9809 "gram.y"
     {
 					(yyval.typnam) = (yyvsp[(1) - (1)].typnam);
 				}
     break;
 
   case 1486:
-
-/* Line 1806 of yacc.c  */
-#line 9812 "gram.y"
+#line 9813 "gram.y"
     {
 					(yyval.typnam) = (yyvsp[(1) - (1)].typnam);
 				}
     break;
 
   case 1487:
-
-/* Line 1806 of yacc.c  */
-#line 9820 "gram.y"
+#line 9821 "gram.y"
     {
 					(yyval.typnam) = (yyvsp[(1) - (1)].typnam);
 				}
     break;
 
   case 1488:
-
-/* Line 1806 of yacc.c  */
-#line 9824 "gram.y"
+#line 9825 "gram.y"
     {
 					(yyval.typnam) = (yyvsp[(1) - (1)].typnam);
 					(yyval.typnam)->typmods = NIL;
@@ -34280,9 +31521,7 @@ yyreduce:
     break;
 
   case 1489:
-
-/* Line 1806 of yacc.c  */
-#line 9832 "gram.y"
+#line 9833 "gram.y"
     {
 					char *typname;
 
@@ -34294,9 +31533,7 @@ yyreduce:
     break;
 
   case 1490:
-
-/* Line 1806 of yacc.c  */
-#line 9844 "gram.y"
+#line 9845 "gram.y"
     {
 					/* bit defaults to bit(1), varbit to no limit */
 					if ((yyvsp[(2) - (2)].boolean))
@@ -34313,36 +31550,28 @@ yyreduce:
     break;
 
   case 1491:
-
-/* Line 1806 of yacc.c  */
-#line 9865 "gram.y"
+#line 9866 "gram.y"
     {
 					(yyval.typnam) = (yyvsp[(1) - (1)].typnam);
 				}
     break;
 
   case 1492:
-
-/* Line 1806 of yacc.c  */
-#line 9869 "gram.y"
+#line 9870 "gram.y"
     {
 					(yyval.typnam) = (yyvsp[(1) - (1)].typnam);
 				}
     break;
 
   case 1493:
-
-/* Line 1806 of yacc.c  */
-#line 9875 "gram.y"
+#line 9876 "gram.y"
     {
 					(yyval.typnam) = (yyvsp[(1) - (1)].typnam);
 				}
     break;
 
   case 1494:
-
-/* Line 1806 of yacc.c  */
-#line 9879 "gram.y"
+#line 9880 "gram.y"
     {
 					/* Length was not specified so allow to be unrestricted.
 					 * This handles problems with fixed-length (char) strings
@@ -34356,9 +31585,7 @@ yyreduce:
     break;
 
   case 1495:
-
-/* Line 1806 of yacc.c  */
-#line 9892 "gram.y"
+#line 9893 "gram.y"
     {
 					if (((yyvsp[(5) - (5)].str) != NULL) && (strcmp((yyvsp[(5) - (5)].str), "sql_text") != 0))
 					{
@@ -34378,9 +31605,7 @@ yyreduce:
     break;
 
   case 1496:
-
-/* Line 1806 of yacc.c  */
-#line 9911 "gram.y"
+#line 9912 "gram.y"
     {
 					if (((yyvsp[(2) - (2)].str) != NULL) && (strcmp((yyvsp[(2) - (2)].str), "sql_text") != 0))
 					{
@@ -34404,79 +31629,57 @@ yyreduce:
     break;
 
   case 1497:
-
-/* Line 1806 of yacc.c  */
-#line 9934 "gram.y"
+#line 9935 "gram.y"
     { (yyval.str) = (yyvsp[(2) - (2)].boolean) ? "varchar": "char"; }
     break;
 
   case 1498:
-
-/* Line 1806 of yacc.c  */
-#line 9936 "gram.y"
+#line 9937 "gram.y"
     { (yyval.str) = (yyvsp[(2) - (2)].boolean) ? "varchar": "char"; }
     break;
 
   case 1499:
-
-/* Line 1806 of yacc.c  */
-#line 9938 "gram.y"
+#line 9939 "gram.y"
     { (yyval.str) = "varchar"; }
     break;
 
   case 1500:
-
-/* Line 1806 of yacc.c  */
-#line 9940 "gram.y"
+#line 9941 "gram.y"
     { (yyval.str) = (yyvsp[(3) - (3)].boolean) ? "varchar": "char"; }
     break;
 
   case 1501:
-
-/* Line 1806 of yacc.c  */
-#line 9942 "gram.y"
+#line 9943 "gram.y"
     { (yyval.str) = (yyvsp[(3) - (3)].boolean) ? "varchar": "char"; }
     break;
 
   case 1502:
-
-/* Line 1806 of yacc.c  */
-#line 9944 "gram.y"
+#line 9945 "gram.y"
     { (yyval.str) = (yyvsp[(2) - (2)].boolean) ? "varchar": "char"; }
     break;
 
   case 1503:
-
-/* Line 1806 of yacc.c  */
-#line 9948 "gram.y"
+#line 9949 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 1504:
-
-/* Line 1806 of yacc.c  */
-#line 9949 "gram.y"
+#line 9950 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 1505:
-
-/* Line 1806 of yacc.c  */
-#line 9953 "gram.y"
+#line 9954 "gram.y"
     { (yyval.str) = (yyvsp[(3) - (3)].str); }
     break;
 
   case 1506:
-
-/* Line 1806 of yacc.c  */
-#line 9954 "gram.y"
+#line 9955 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 1507:
-
-/* Line 1806 of yacc.c  */
-#line 9962 "gram.y"
+#line 9963 "gram.y"
     {
 					if ((yyvsp[(5) - (5)].boolean))
 						(yyval.typnam) = SystemTypeName("timestamptz");
@@ -34488,9 +31691,7 @@ yyreduce:
     break;
 
   case 1508:
-
-/* Line 1806 of yacc.c  */
-#line 9971 "gram.y"
+#line 9972 "gram.y"
     {
 					if ((yyvsp[(2) - (2)].boolean))
 						(yyval.typnam) = SystemTypeName("timestamptz");
@@ -34501,9 +31702,7 @@ yyreduce:
     break;
 
   case 1509:
-
-/* Line 1806 of yacc.c  */
-#line 9979 "gram.y"
+#line 9980 "gram.y"
     {
 					if ((yyvsp[(5) - (5)].boolean))
 						(yyval.typnam) = SystemTypeName("timetz");
@@ -34515,9 +31714,7 @@ yyreduce:
     break;
 
   case 1510:
-
-/* Line 1806 of yacc.c  */
-#line 9988 "gram.y"
+#line 9989 "gram.y"
     {
 					if ((yyvsp[(2) - (2)].boolean))
 						(yyval.typnam) = SystemTypeName("timetz");
@@ -34528,9 +31725,7 @@ yyreduce:
     break;
 
   case 1511:
-
-/* Line 1806 of yacc.c  */
-#line 9999 "gram.y"
+#line 10000 "gram.y"
     {
 					(yyval.typnam) = SystemTypeName("interval");
 					(yyval.typnam)->location = (yylsp[(1) - (1)]);
@@ -34538,72 +31733,52 @@ yyreduce:
     break;
 
   case 1512:
-
-/* Line 1806 of yacc.c  */
-#line 10006 "gram.y"
+#line 10007 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 1513:
-
-/* Line 1806 of yacc.c  */
-#line 10007 "gram.y"
+#line 10008 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 1514:
-
-/* Line 1806 of yacc.c  */
-#line 10008 "gram.y"
+#line 10009 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 1515:
-
-/* Line 1806 of yacc.c  */
-#line 10013 "gram.y"
+#line 10014 "gram.y"
     { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(YEAR), (yylsp[(1) - (1)]))); }
     break;
 
   case 1516:
-
-/* Line 1806 of yacc.c  */
-#line 10015 "gram.y"
+#line 10016 "gram.y"
     { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MONTH), (yylsp[(1) - (1)]))); }
     break;
 
   case 1517:
-
-/* Line 1806 of yacc.c  */
-#line 10017 "gram.y"
+#line 10018 "gram.y"
     { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY), (yylsp[(1) - (1)]))); }
     break;
 
   case 1518:
-
-/* Line 1806 of yacc.c  */
-#line 10019 "gram.y"
+#line 10020 "gram.y"
     { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(HOUR), (yylsp[(1) - (1)]))); }
     break;
 
   case 1519:
-
-/* Line 1806 of yacc.c  */
-#line 10021 "gram.y"
+#line 10022 "gram.y"
     { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MINUTE), (yylsp[(1) - (1)]))); }
     break;
 
   case 1520:
-
-/* Line 1806 of yacc.c  */
-#line 10023 "gram.y"
+#line 10024 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 1521:
-
-/* Line 1806 of yacc.c  */
-#line 10025 "gram.y"
+#line 10026 "gram.y"
     {
 					(yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(YEAR) |
 												 INTERVAL_MASK(MONTH), (yylsp[(1) - (3)])));
@@ -34611,9 +31786,7 @@ yyreduce:
     break;
 
   case 1522:
-
-/* Line 1806 of yacc.c  */
-#line 10030 "gram.y"
+#line 10031 "gram.y"
     {
 					(yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY) |
 												 INTERVAL_MASK(HOUR), (yylsp[(1) - (3)])));
@@ -34621,9 +31794,7 @@ yyreduce:
     break;
 
   case 1523:
-
-/* Line 1806 of yacc.c  */
-#line 10035 "gram.y"
+#line 10036 "gram.y"
     {
 					(yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY) |
 												 INTERVAL_MASK(HOUR) |
@@ -34632,9 +31803,7 @@ yyreduce:
     break;
 
   case 1524:
-
-/* Line 1806 of yacc.c  */
-#line 10041 "gram.y"
+#line 10042 "gram.y"
     {
 					(yyval.list) = (yyvsp[(3) - (3)].list);
 					linitial((yyval.list)) = makeIntConst(INTERVAL_MASK(DAY) |
@@ -34645,9 +31814,7 @@ yyreduce:
     break;
 
   case 1525:
-
-/* Line 1806 of yacc.c  */
-#line 10049 "gram.y"
+#line 10050 "gram.y"
     {
 					(yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(HOUR) |
 												 INTERVAL_MASK(MINUTE), (yylsp[(1) - (3)])));
@@ -34655,9 +31822,7 @@ yyreduce:
     break;
 
   case 1526:
-
-/* Line 1806 of yacc.c  */
-#line 10054 "gram.y"
+#line 10055 "gram.y"
     {
 					(yyval.list) = (yyvsp[(3) - (3)].list);
 					linitial((yyval.list)) = makeIntConst(INTERVAL_MASK(HOUR) |
@@ -34667,9 +31832,7 @@ yyreduce:
     break;
 
   case 1527:
-
-/* Line 1806 of yacc.c  */
-#line 10061 "gram.y"
+#line 10062 "gram.y"
     {
 					(yyval.list) = (yyvsp[(3) - (3)].list);
 					linitial((yyval.list)) = makeIntConst(INTERVAL_MASK(MINUTE) |
@@ -34678,25 +31841,19 @@ yyreduce:
     break;
 
   case 1528:
-
-/* Line 1806 of yacc.c  */
-#line 10067 "gram.y"
+#line 10068 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1529:
-
-/* Line 1806 of yacc.c  */
-#line 10072 "gram.y"
+#line 10073 "gram.y"
     {
 					(yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(SECOND), (yylsp[(1) - (1)])));
 				}
     break;
 
   case 1530:
-
-/* Line 1806 of yacc.c  */
-#line 10076 "gram.y"
+#line 10077 "gram.y"
     {
 					(yyval.list) = list_make2(makeIntConst(INTERVAL_MASK(SECOND), (yylsp[(1) - (4)])),
 									makeIntConst((yyvsp[(3) - (4)].ival), (yylsp[(3) - (4)])));
@@ -34704,23 +31861,17 @@ yyreduce:
     break;
 
   case 1531:
-
-/* Line 1806 of yacc.c  */
-#line 10105 "gram.y"
+#line 10106 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 1532:
-
-/* Line 1806 of yacc.c  */
-#line 10107 "gram.y"
+#line 10108 "gram.y"
     { (yyval.node) = makeTypeCast((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].typnam), (yylsp[(2) - (3)])); }
     break;
 
   case 1533:
-
-/* Line 1806 of yacc.c  */
-#line 10109 "gram.y"
+#line 10110 "gram.y"
     {
 					CollateClause *n = makeNode(CollateClause);
 					n->arg = (yyvsp[(1) - (3)].node);
@@ -34731,9 +31882,7 @@ yyreduce:
     break;
 
   case 1534:
-
-/* Line 1806 of yacc.c  */
-#line 10117 "gram.y"
+#line 10118 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("timezone");
@@ -34749,135 +31898,97 @@ yyreduce:
     break;
 
   case 1535:
-
-/* Line 1806 of yacc.c  */
-#line 10139 "gram.y"
+#line 10140 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); }
     break;
 
   case 1536:
-
-/* Line 1806 of yacc.c  */
-#line 10141 "gram.y"
+#line 10142 "gram.y"
     { (yyval.node) = doNegate((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); }
     break;
 
   case 1537:
-
-/* Line 1806 of yacc.c  */
-#line 10143 "gram.y"
+#line 10144 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1538:
-
-/* Line 1806 of yacc.c  */
-#line 10145 "gram.y"
+#line 10146 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1539:
-
-/* Line 1806 of yacc.c  */
-#line 10147 "gram.y"
+#line 10148 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1540:
-
-/* Line 1806 of yacc.c  */
-#line 10149 "gram.y"
+#line 10150 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1541:
-
-/* Line 1806 of yacc.c  */
-#line 10151 "gram.y"
+#line 10152 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1542:
-
-/* Line 1806 of yacc.c  */
-#line 10153 "gram.y"
+#line 10154 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1543:
-
-/* Line 1806 of yacc.c  */
-#line 10155 "gram.y"
+#line 10156 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1544:
-
-/* Line 1806 of yacc.c  */
-#line 10157 "gram.y"
+#line 10158 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1545:
-
-/* Line 1806 of yacc.c  */
-#line 10159 "gram.y"
+#line 10160 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1546:
-
-/* Line 1806 of yacc.c  */
-#line 10162 "gram.y"
+#line 10163 "gram.y"
     { (yyval.node) = (Node *) makeA_Expr(AEXPR_OP, (yyvsp[(2) - (3)].list), (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1547:
-
-/* Line 1806 of yacc.c  */
-#line 10164 "gram.y"
+#line 10165 "gram.y"
     { (yyval.node) = (Node *) makeA_Expr(AEXPR_OP, (yyvsp[(1) - (2)].list), NULL, (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); }
     break;
 
   case 1548:
-
-/* Line 1806 of yacc.c  */
-#line 10166 "gram.y"
+#line 10167 "gram.y"
     { (yyval.node) = (Node *) makeA_Expr(AEXPR_OP, (yyvsp[(2) - (2)].list), (yyvsp[(1) - (2)].node), NULL, (yylsp[(2) - (2)])); }
     break;
 
   case 1549:
-
-/* Line 1806 of yacc.c  */
-#line 10169 "gram.y"
+#line 10170 "gram.y"
     { (yyval.node) = (Node *) makeA_Expr(AEXPR_AND, NIL, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1550:
-
-/* Line 1806 of yacc.c  */
-#line 10171 "gram.y"
+#line 10172 "gram.y"
     { (yyval.node) = (Node *) makeA_Expr(AEXPR_OR, NIL, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1551:
-
-/* Line 1806 of yacc.c  */
-#line 10173 "gram.y"
+#line 10174 "gram.y"
     { (yyval.node) = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL, (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); }
     break;
 
   case 1552:
-
-/* Line 1806 of yacc.c  */
-#line 10176 "gram.y"
+#line 10177 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1553:
-
-/* Line 1806 of yacc.c  */
-#line 10178 "gram.y"
+#line 10179 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("like_escape");
@@ -34893,16 +32004,12 @@ yyreduce:
     break;
 
   case 1554:
-
-/* Line 1806 of yacc.c  */
-#line 10191 "gram.y"
+#line 10192 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~", (yyvsp[(1) - (4)].node), (yyvsp[(4) - (4)].node), (yylsp[(2) - (4)])); }
     break;
 
   case 1555:
-
-/* Line 1806 of yacc.c  */
-#line 10193 "gram.y"
+#line 10194 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("like_escape");
@@ -34918,16 +32025,12 @@ yyreduce:
     break;
 
   case 1556:
-
-/* Line 1806 of yacc.c  */
-#line 10206 "gram.y"
+#line 10207 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~*", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1557:
-
-/* Line 1806 of yacc.c  */
-#line 10208 "gram.y"
+#line 10209 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("like_escape");
@@ -34943,16 +32046,12 @@ yyreduce:
     break;
 
   case 1558:
-
-/* Line 1806 of yacc.c  */
-#line 10221 "gram.y"
+#line 10222 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~*", (yyvsp[(1) - (4)].node), (yyvsp[(4) - (4)].node), (yylsp[(2) - (4)])); }
     break;
 
   case 1559:
-
-/* Line 1806 of yacc.c  */
-#line 10223 "gram.y"
+#line 10224 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("like_escape");
@@ -34968,9 +32067,7 @@ yyreduce:
     break;
 
   case 1560:
-
-/* Line 1806 of yacc.c  */
-#line 10237 "gram.y"
+#line 10238 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("similar_escape");
@@ -34986,9 +32083,7 @@ yyreduce:
     break;
 
   case 1561:
-
-/* Line 1806 of yacc.c  */
-#line 10250 "gram.y"
+#line 10251 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("similar_escape");
@@ -35004,9 +32099,7 @@ yyreduce:
     break;
 
   case 1562:
-
-/* Line 1806 of yacc.c  */
-#line 10263 "gram.y"
+#line 10264 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("similar_escape");
@@ -35022,9 +32115,7 @@ yyreduce:
     break;
 
   case 1563:
-
-/* Line 1806 of yacc.c  */
-#line 10276 "gram.y"
+#line 10277 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("similar_escape");
@@ -35040,9 +32131,7 @@ yyreduce:
     break;
 
   case 1564:
-
-/* Line 1806 of yacc.c  */
-#line 10299 "gram.y"
+#line 10300 "gram.y"
     {
 					NullTest *n = makeNode(NullTest);
 					n->arg = (Expr *) (yyvsp[(1) - (3)].node);
@@ -35052,9 +32141,7 @@ yyreduce:
     break;
 
   case 1565:
-
-/* Line 1806 of yacc.c  */
-#line 10306 "gram.y"
+#line 10307 "gram.y"
     {
 					NullTest *n = makeNode(NullTest);
 					n->arg = (Expr *) (yyvsp[(1) - (2)].node);
@@ -35064,9 +32151,7 @@ yyreduce:
     break;
 
   case 1566:
-
-/* Line 1806 of yacc.c  */
-#line 10313 "gram.y"
+#line 10314 "gram.y"
     {
 					NullTest *n = makeNode(NullTest);
 					n->arg = (Expr *) (yyvsp[(1) - (4)].node);
@@ -35076,9 +32161,7 @@ yyreduce:
     break;
 
   case 1567:
-
-/* Line 1806 of yacc.c  */
-#line 10320 "gram.y"
+#line 10321 "gram.y"
     {
 					NullTest *n = makeNode(NullTest);
 					n->arg = (Expr *) (yyvsp[(1) - (2)].node);
@@ -35088,18 +32171,14 @@ yyreduce:
     break;
 
   case 1568:
-
-/* Line 1806 of yacc.c  */
-#line 10327 "gram.y"
+#line 10328 "gram.y"
     {
 					(yyval.node) = (Node *)makeOverlaps((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list), (yylsp[(2) - (3)]), yyscanner);
 				}
     break;
 
   case 1569:
-
-/* Line 1806 of yacc.c  */
-#line 10331 "gram.y"
+#line 10332 "gram.y"
     {
 					BooleanTest *b = makeNode(BooleanTest);
 					b->arg = (Expr *) (yyvsp[(1) - (3)].node);
@@ -35109,9 +32188,7 @@ yyreduce:
     break;
 
   case 1570:
-
-/* Line 1806 of yacc.c  */
-#line 10338 "gram.y"
+#line 10339 "gram.y"
     {
 					BooleanTest *b = makeNode(BooleanTest);
 					b->arg = (Expr *) (yyvsp[(1) - (4)].node);
@@ -35121,9 +32198,7 @@ yyreduce:
     break;
 
   case 1571:
-
-/* Line 1806 of yacc.c  */
-#line 10345 "gram.y"
+#line 10346 "gram.y"
     {
 					BooleanTest *b = makeNode(BooleanTest);
 					b->arg = (Expr *) (yyvsp[(1) - (3)].node);
@@ -35133,9 +32208,7 @@ yyreduce:
     break;
 
   case 1572:
-
-/* Line 1806 of yacc.c  */
-#line 10352 "gram.y"
+#line 10353 "gram.y"
     {
 					BooleanTest *b = makeNode(BooleanTest);
 					b->arg = (Expr *) (yyvsp[(1) - (4)].node);
@@ -35145,9 +32218,7 @@ yyreduce:
     break;
 
   case 1573:
-
-/* Line 1806 of yacc.c  */
-#line 10359 "gram.y"
+#line 10360 "gram.y"
     {
 					BooleanTest *b = makeNode(BooleanTest);
 					b->arg = (Expr *) (yyvsp[(1) - (3)].node);
@@ -35157,9 +32228,7 @@ yyreduce:
     break;
 
   case 1574:
-
-/* Line 1806 of yacc.c  */
-#line 10366 "gram.y"
+#line 10367 "gram.y"
     {
 					BooleanTest *b = makeNode(BooleanTest);
 					b->arg = (Expr *) (yyvsp[(1) - (4)].node);
@@ -35169,18 +32238,14 @@ yyreduce:
     break;
 
   case 1575:
-
-/* Line 1806 of yacc.c  */
-#line 10373 "gram.y"
+#line 10374 "gram.y"
     {
 					(yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", (yyvsp[(1) - (5)].node), (yyvsp[(5) - (5)].node), (yylsp[(2) - (5)]));
 				}
     break;
 
   case 1576:
-
-/* Line 1806 of yacc.c  */
-#line 10377 "gram.y"
+#line 10378 "gram.y"
     {
 					(yyval.node) = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL,
 									(Node *) makeSimpleA_Expr(AEXPR_DISTINCT,
@@ -35191,27 +32256,21 @@ yyreduce:
     break;
 
   case 1577:
-
-/* Line 1806 of yacc.c  */
-#line 10385 "gram.y"
+#line 10386 "gram.y"
     {
 					(yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", (yyvsp[(1) - (6)].node), (Node *) (yyvsp[(5) - (6)].list), (yylsp[(2) - (6)]));
 				}
     break;
 
   case 1578:
-
-/* Line 1806 of yacc.c  */
-#line 10389 "gram.y"
+#line 10390 "gram.y"
     {
 					(yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", (yyvsp[(1) - (7)].node), (Node *) (yyvsp[(6) - (7)].list), (yylsp[(2) - (7)]));
 				}
     break;
 
   case 1579:
-
-/* Line 1806 of yacc.c  */
-#line 10399 "gram.y"
+#line 10400 "gram.y"
     {
 					(yyval.node) = (Node *) makeA_Expr(AEXPR_AND, NIL,
 						(Node *) makeSimpleA_Expr(AEXPR_OP, ">=", (yyvsp[(1) - (6)].node), (yyvsp[(4) - (6)].node), (yylsp[(2) - (6)])),
@@ -35221,9 +32280,7 @@ yyreduce:
     break;
 
   case 1580:
-
-/* Line 1806 of yacc.c  */
-#line 10406 "gram.y"
+#line 10407 "gram.y"
     {
 					(yyval.node) = (Node *) makeA_Expr(AEXPR_OR, NIL,
 						(Node *) makeSimpleA_Expr(AEXPR_OP, "<", (yyvsp[(1) - (7)].node), (yyvsp[(5) - (7)].node), (yylsp[(2) - (7)])),
@@ -35233,9 +32290,7 @@ yyreduce:
     break;
 
   case 1581:
-
-/* Line 1806 of yacc.c  */
-#line 10413 "gram.y"
+#line 10414 "gram.y"
     {
 					(yyval.node) = (Node *) makeA_Expr(AEXPR_OR, NIL,
 						(Node *) makeA_Expr(AEXPR_AND, NIL,
@@ -35251,9 +32306,7 @@ yyreduce:
     break;
 
   case 1582:
-
-/* Line 1806 of yacc.c  */
-#line 10426 "gram.y"
+#line 10427 "gram.y"
     {
 					(yyval.node) = (Node *) makeA_Expr(AEXPR_AND, NIL,
 						(Node *) makeA_Expr(AEXPR_OR, NIL,
@@ -35269,9 +32322,7 @@ yyreduce:
     break;
 
   case 1583:
-
-/* Line 1806 of yacc.c  */
-#line 10439 "gram.y"
+#line 10440 "gram.y"
     {
 					/* in_expr returns a SubLink or a list of a_exprs */
 					if (IsA((yyvsp[(3) - (3)].node), SubLink))
@@ -35293,9 +32344,7 @@ yyreduce:
     break;
 
   case 1584:
-
-/* Line 1806 of yacc.c  */
-#line 10458 "gram.y"
+#line 10459 "gram.y"
     {
 					/* in_expr returns a SubLink or a list of a_exprs */
 					if (IsA((yyvsp[(4) - (4)].node), SubLink))
@@ -35319,9 +32368,7 @@ yyreduce:
     break;
 
   case 1585:
-
-/* Line 1806 of yacc.c  */
-#line 10479 "gram.y"
+#line 10480 "gram.y"
     {
 					SubLink *n = makeNode(SubLink);
 					n->subLinkType = (yyvsp[(3) - (4)].ival);
@@ -35334,9 +32381,7 @@ yyreduce:
     break;
 
   case 1586:
-
-/* Line 1806 of yacc.c  */
-#line 10489 "gram.y"
+#line 10490 "gram.y"
     {
 					if ((yyvsp[(3) - (6)].ival) == ANY_SUBLINK)
 						(yyval.node) = (Node *) makeA_Expr(AEXPR_OP_ANY, (yyvsp[(2) - (6)].list), (yyvsp[(1) - (6)].node), (yyvsp[(5) - (6)].node), (yylsp[(2) - (6)]));
@@ -35346,9 +32391,7 @@ yyreduce:
     break;
 
   case 1587:
-
-/* Line 1806 of yacc.c  */
-#line 10496 "gram.y"
+#line 10497 "gram.y"
     {
 					/* Not sure how to get rid of the parentheses
 					 * but there are lots of shift/reduce errors without them.
@@ -35367,9 +32410,7 @@ yyreduce:
     break;
 
   case 1588:
-
-/* Line 1806 of yacc.c  */
-#line 10512 "gram.y"
+#line 10513 "gram.y"
     {
 					(yyval.node) = makeXmlExpr(IS_DOCUMENT, NULL, NIL,
 									 list_make1((yyvsp[(1) - (3)].node)), (yylsp[(2) - (3)]));
@@ -35377,9 +32418,7 @@ yyreduce:
     break;
 
   case 1589:
-
-/* Line 1806 of yacc.c  */
-#line 10517 "gram.y"
+#line 10518 "gram.y"
     {
 					(yyval.node) = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL,
 											 makeXmlExpr(IS_DOCUMENT, NULL, NIL,
@@ -35389,130 +32428,94 @@ yyreduce:
     break;
 
   case 1590:
-
-/* Line 1806 of yacc.c  */
-#line 10535 "gram.y"
+#line 10536 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 1591:
-
-/* Line 1806 of yacc.c  */
-#line 10537 "gram.y"
+#line 10538 "gram.y"
     { (yyval.node) = makeTypeCast((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].typnam), (yylsp[(2) - (3)])); }
     break;
 
   case 1592:
-
-/* Line 1806 of yacc.c  */
-#line 10539 "gram.y"
+#line 10540 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); }
     break;
 
   case 1593:
-
-/* Line 1806 of yacc.c  */
-#line 10541 "gram.y"
+#line 10542 "gram.y"
     { (yyval.node) = doNegate((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); }
     break;
 
   case 1594:
-
-/* Line 1806 of yacc.c  */
-#line 10543 "gram.y"
+#line 10544 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1595:
-
-/* Line 1806 of yacc.c  */
-#line 10545 "gram.y"
+#line 10546 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1596:
-
-/* Line 1806 of yacc.c  */
-#line 10547 "gram.y"
+#line 10548 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1597:
-
-/* Line 1806 of yacc.c  */
-#line 10549 "gram.y"
+#line 10550 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1598:
-
-/* Line 1806 of yacc.c  */
-#line 10551 "gram.y"
+#line 10552 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1599:
-
-/* Line 1806 of yacc.c  */
-#line 10553 "gram.y"
+#line 10554 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1600:
-
-/* Line 1806 of yacc.c  */
-#line 10555 "gram.y"
+#line 10556 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1601:
-
-/* Line 1806 of yacc.c  */
-#line 10557 "gram.y"
+#line 10558 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1602:
-
-/* Line 1806 of yacc.c  */
-#line 10559 "gram.y"
+#line 10560 "gram.y"
     { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1603:
-
-/* Line 1806 of yacc.c  */
-#line 10561 "gram.y"
+#line 10562 "gram.y"
     { (yyval.node) = (Node *) makeA_Expr(AEXPR_OP, (yyvsp[(2) - (3)].list), (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); }
     break;
 
   case 1604:
-
-/* Line 1806 of yacc.c  */
-#line 10563 "gram.y"
+#line 10564 "gram.y"
     { (yyval.node) = (Node *) makeA_Expr(AEXPR_OP, (yyvsp[(1) - (2)].list), NULL, (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); }
     break;
 
   case 1605:
-
-/* Line 1806 of yacc.c  */
-#line 10565 "gram.y"
+#line 10566 "gram.y"
     { (yyval.node) = (Node *) makeA_Expr(AEXPR_OP, (yyvsp[(2) - (2)].list), (yyvsp[(1) - (2)].node), NULL, (yylsp[(2) - (2)])); }
     break;
 
   case 1606:
-
-/* Line 1806 of yacc.c  */
-#line 10567 "gram.y"
+#line 10568 "gram.y"
     {
 					(yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", (yyvsp[(1) - (5)].node), (yyvsp[(5) - (5)].node), (yylsp[(2) - (5)]));
 				}
     break;
 
   case 1607:
-
-/* Line 1806 of yacc.c  */
-#line 10571 "gram.y"
+#line 10572 "gram.y"
     {
 					(yyval.node) = (Node *) makeA_Expr(AEXPR_NOT, NIL,
 						NULL, (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", (yyvsp[(1) - (6)].node), (yyvsp[(6) - (6)].node), (yylsp[(2) - (6)])), (yylsp[(2) - (6)]));
@@ -35520,27 +32523,21 @@ yyreduce:
     break;
 
   case 1608:
-
-/* Line 1806 of yacc.c  */
-#line 10576 "gram.y"
+#line 10577 "gram.y"
     {
 					(yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", (yyvsp[(1) - (6)].node), (Node *) (yyvsp[(5) - (6)].list), (yylsp[(2) - (6)]));
 				}
     break;
 
   case 1609:
-
-/* Line 1806 of yacc.c  */
-#line 10580 "gram.y"
+#line 10581 "gram.y"
     {
 					(yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", (yyvsp[(1) - (7)].node), (Node *) (yyvsp[(6) - (7)].list), (yylsp[(2) - (7)]));
 				}
     break;
 
   case 1610:
-
-/* Line 1806 of yacc.c  */
-#line 10584 "gram.y"
+#line 10585 "gram.y"
     {
 					(yyval.node) = makeXmlExpr(IS_DOCUMENT, NULL, NIL,
 									 list_make1((yyvsp[(1) - (3)].node)), (yylsp[(2) - (3)]));
@@ -35548,9 +32545,7 @@ yyreduce:
     break;
 
   case 1611:
-
-/* Line 1806 of yacc.c  */
-#line 10589 "gram.y"
+#line 10590 "gram.y"
     {
 					(yyval.node) = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL,
 											 makeXmlExpr(IS_DOCUMENT, NULL, NIL,
@@ -35560,23 +32555,17 @@ yyreduce:
     break;
 
   case 1612:
-
-/* Line 1806 of yacc.c  */
-#line 10605 "gram.y"
+#line 10606 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 1613:
-
-/* Line 1806 of yacc.c  */
-#line 10606 "gram.y"
+#line 10607 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 1614:
-
-/* Line 1806 of yacc.c  */
-#line 10608 "gram.y"
+#line 10609 "gram.y"
     {
 					ParamRef *p = makeNode(ParamRef);
 					p->number = (yyvsp[(1) - (2)].ival);
@@ -35594,9 +32583,7 @@ yyreduce:
     break;
 
   case 1615:
-
-/* Line 1806 of yacc.c  */
-#line 10623 "gram.y"
+#line 10624 "gram.y"
     {
 					if ((yyvsp[(4) - (4)].list))
 					{
@@ -35611,23 +32598,17 @@ yyreduce:
     break;
 
   case 1616:
-
-/* Line 1806 of yacc.c  */
-#line 10635 "gram.y"
+#line 10636 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 1617:
-
-/* Line 1806 of yacc.c  */
-#line 10637 "gram.y"
+#line 10638 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 1618:
-
-/* Line 1806 of yacc.c  */
-#line 10639 "gram.y"
+#line 10640 "gram.y"
     {
 					SubLink *n = makeNode(SubLink);
 					n->subLinkType = EXPR_SUBLINK;
@@ -35640,9 +32621,7 @@ yyreduce:
     break;
 
   case 1619:
-
-/* Line 1806 of yacc.c  */
-#line 10649 "gram.y"
+#line 10650 "gram.y"
     {
 					/*
 					 * Because the select_with_parens nonterminal is designed
@@ -35668,9 +32647,7 @@ yyreduce:
     break;
 
   case 1620:
-
-/* Line 1806 of yacc.c  */
-#line 10672 "gram.y"
+#line 10673 "gram.y"
     {
 					SubLink *n = makeNode(SubLink);
 					n->subLinkType = EXISTS_SUBLINK;
@@ -35683,9 +32660,7 @@ yyreduce:
     break;
 
   case 1621:
-
-/* Line 1806 of yacc.c  */
-#line 10682 "gram.y"
+#line 10683 "gram.y"
     {
 					SubLink *n = makeNode(SubLink);
 					n->subLinkType = ARRAY_SUBLINK;
@@ -35698,9 +32673,7 @@ yyreduce:
     break;
 
   case 1622:
-
-/* Line 1806 of yacc.c  */
-#line 10692 "gram.y"
+#line 10693 "gram.y"
     {
 					A_ArrayExpr *n = (A_ArrayExpr *) (yyvsp[(2) - (2)].node);
 					Assert(IsA(n, A_ArrayExpr));
@@ -35711,9 +32684,7 @@ yyreduce:
     break;
 
   case 1623:
-
-/* Line 1806 of yacc.c  */
-#line 10700 "gram.y"
+#line 10701 "gram.y"
     {
 					RowExpr *r = makeNode(RowExpr);
 					r->args = (yyvsp[(1) - (1)].list);
@@ -35725,9 +32696,7 @@ yyreduce:
     break;
 
   case 1624:
-
-/* Line 1806 of yacc.c  */
-#line 10719 "gram.y"
+#line 10720 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = (yyvsp[(1) - (4)].list);
@@ -35743,9 +32712,7 @@ yyreduce:
     break;
 
   case 1625:
-
-/* Line 1806 of yacc.c  */
-#line 10732 "gram.y"
+#line 10733 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = (yyvsp[(1) - (5)].list);
@@ -35761,9 +32728,7 @@ yyreduce:
     break;
 
   case 1626:
-
-/* Line 1806 of yacc.c  */
-#line 10745 "gram.y"
+#line 10746 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = (yyvsp[(1) - (6)].list);
@@ -35779,9 +32744,7 @@ yyreduce:
     break;
 
   case 1627:
-
-/* Line 1806 of yacc.c  */
-#line 10758 "gram.y"
+#line 10759 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = (yyvsp[(1) - (8)].list);
@@ -35797,9 +32760,7 @@ yyreduce:
     break;
 
   case 1628:
-
-/* Line 1806 of yacc.c  */
-#line 10771 "gram.y"
+#line 10772 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = (yyvsp[(1) - (6)].list);
@@ -35815,9 +32776,7 @@ yyreduce:
     break;
 
   case 1629:
-
-/* Line 1806 of yacc.c  */
-#line 10784 "gram.y"
+#line 10785 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = (yyvsp[(1) - (7)].list);
@@ -35837,9 +32796,7 @@ yyreduce:
     break;
 
   case 1630:
-
-/* Line 1806 of yacc.c  */
-#line 10801 "gram.y"
+#line 10802 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = (yyvsp[(1) - (7)].list);
@@ -35855,9 +32812,7 @@ yyreduce:
     break;
 
   case 1631:
-
-/* Line 1806 of yacc.c  */
-#line 10814 "gram.y"
+#line 10815 "gram.y"
     {
 					/*
 					 * We consider AGGREGATE(*) to invoke a parameterless
@@ -35883,9 +32838,7 @@ yyreduce:
     break;
 
   case 1632:
-
-/* Line 1806 of yacc.c  */
-#line 10837 "gram.y"
+#line 10838 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("pg_collation_for");
@@ -35901,9 +32854,7 @@ yyreduce:
     break;
 
   case 1633:
-
-/* Line 1806 of yacc.c  */
-#line 10850 "gram.y"
+#line 10851 "gram.y"
     {
 					/*
 					 * Translate as "'now'::text::date".
@@ -35927,9 +32878,7 @@ yyreduce:
     break;
 
   case 1634:
-
-/* Line 1806 of yacc.c  */
-#line 10871 "gram.y"
+#line 10872 "gram.y"
     {
 					/*
 					 * Translate as "'now'::text::timetz".
@@ -35942,9 +32891,7 @@ yyreduce:
     break;
 
   case 1635:
-
-/* Line 1806 of yacc.c  */
-#line 10881 "gram.y"
+#line 10882 "gram.y"
     {
 					/*
 					 * Translate as "'now'::text::timetz(n)".
@@ -35960,9 +32907,7 @@ yyreduce:
     break;
 
   case 1636:
-
-/* Line 1806 of yacc.c  */
-#line 10894 "gram.y"
+#line 10895 "gram.y"
     {
 					/*
 					 * Translate as "now()", since we have a function that
@@ -35982,9 +32927,7 @@ yyreduce:
     break;
 
   case 1637:
-
-/* Line 1806 of yacc.c  */
-#line 10911 "gram.y"
+#line 10912 "gram.y"
     {
 					/*
 					 * Translate as "'now'::text::timestamptz(n)".
@@ -36000,9 +32943,7 @@ yyreduce:
     break;
 
   case 1638:
-
-/* Line 1806 of yacc.c  */
-#line 10924 "gram.y"
+#line 10925 "gram.y"
     {
 					/*
 					 * Translate as "'now'::text::time".
@@ -36015,9 +32956,7 @@ yyreduce:
     break;
 
   case 1639:
-
-/* Line 1806 of yacc.c  */
-#line 10934 "gram.y"
+#line 10935 "gram.y"
     {
 					/*
 					 * Translate as "'now'::text::time(n)".
@@ -36033,9 +32972,7 @@ yyreduce:
     break;
 
   case 1640:
-
-/* Line 1806 of yacc.c  */
-#line 10947 "gram.y"
+#line 10948 "gram.y"
     {
 					/*
 					 * Translate as "'now'::text::timestamp".
@@ -36048,9 +32985,7 @@ yyreduce:
     break;
 
   case 1641:
-
-/* Line 1806 of yacc.c  */
-#line 10957 "gram.y"
+#line 10958 "gram.y"
     {
 					/*
 					 * Translate as "'now'::text::timestamp(n)".
@@ -36066,9 +33001,7 @@ yyreduce:
     break;
 
   case 1642:
-
-/* Line 1806 of yacc.c  */
-#line 10970 "gram.y"
+#line 10971 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("current_user");
@@ -36084,9 +33017,7 @@ yyreduce:
     break;
 
   case 1643:
-
-/* Line 1806 of yacc.c  */
-#line 10983 "gram.y"
+#line 10984 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("current_user");
@@ -36102,9 +33033,7 @@ yyreduce:
     break;
 
   case 1644:
-
-/* Line 1806 of yacc.c  */
-#line 10996 "gram.y"
+#line 10997 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("session_user");
@@ -36120,9 +33049,7 @@ yyreduce:
     break;
 
   case 1645:
-
-/* Line 1806 of yacc.c  */
-#line 11009 "gram.y"
+#line 11010 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("current_user");
@@ -36138,9 +33065,7 @@ yyreduce:
     break;
 
   case 1646:
-
-/* Line 1806 of yacc.c  */
-#line 11022 "gram.y"
+#line 11023 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("current_database");
@@ -36156,9 +33081,7 @@ yyreduce:
     break;
 
   case 1647:
-
-/* Line 1806 of yacc.c  */
-#line 11035 "gram.y"
+#line 11036 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("current_schema");
@@ -36174,16 +33097,12 @@ yyreduce:
     break;
 
   case 1648:
-
-/* Line 1806 of yacc.c  */
-#line 11048 "gram.y"
+#line 11049 "gram.y"
     { (yyval.node) = makeTypeCast((yyvsp[(3) - (6)].node), (yyvsp[(5) - (6)].typnam), (yylsp[(1) - (6)])); }
     break;
 
   case 1649:
-
-/* Line 1806 of yacc.c  */
-#line 11050 "gram.y"
+#line 11051 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("date_part");
@@ -36199,9 +33118,7 @@ yyreduce:
     break;
 
   case 1650:
-
-/* Line 1806 of yacc.c  */
-#line 11063 "gram.y"
+#line 11064 "gram.y"
     {
 					/* overlay(A PLACING B FROM C FOR D) is converted to
 					 * overlay(A, B, C, D)
@@ -36222,9 +33139,7 @@ yyreduce:
     break;
 
   case 1651:
-
-/* Line 1806 of yacc.c  */
-#line 11081 "gram.y"
+#line 11082 "gram.y"
     {
 					/* position(A in B) is converted to position(B, A) */
 					FuncCall *n = makeNode(FuncCall);
@@ -36241,9 +33156,7 @@ yyreduce:
     break;
 
   case 1652:
-
-/* Line 1806 of yacc.c  */
-#line 11095 "gram.y"
+#line 11096 "gram.y"
     {
 					/* substring(A from B for C) is converted to
 					 * substring(A, B, C) - thomas 2000-11-28
@@ -36262,9 +33175,7 @@ yyreduce:
     break;
 
   case 1653:
-
-/* Line 1806 of yacc.c  */
-#line 11111 "gram.y"
+#line 11112 "gram.y"
     {
 					/* TREAT(expr AS target) converts expr of a particular type to target,
 					 * which is defined to be a subtype of the original expression.
@@ -36289,9 +33200,7 @@ yyreduce:
     break;
 
   case 1654:
-
-/* Line 1806 of yacc.c  */
-#line 11133 "gram.y"
+#line 11134 "gram.y"
     {
 					/* various trim expressions are defined in SQL92
 					 * - thomas 1997-07-19
@@ -36310,9 +33219,7 @@ yyreduce:
     break;
 
   case 1655:
-
-/* Line 1806 of yacc.c  */
-#line 11149 "gram.y"
+#line 11150 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("ltrim");
@@ -36328,9 +33235,7 @@ yyreduce:
     break;
 
   case 1656:
-
-/* Line 1806 of yacc.c  */
-#line 11162 "gram.y"
+#line 11163 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("rtrim");
@@ -36346,9 +33251,7 @@ yyreduce:
     break;
 
   case 1657:
-
-/* Line 1806 of yacc.c  */
-#line 11175 "gram.y"
+#line 11176 "gram.y"
     {
 					FuncCall *n = makeNode(FuncCall);
 					n->funcname = SystemFuncName("btrim");
@@ -36364,18 +33267,14 @@ yyreduce:
     break;
 
   case 1658:
-
-/* Line 1806 of yacc.c  */
-#line 11188 "gram.y"
+#line 11189 "gram.y"
     {
 					(yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_NULLIF, "=", (yyvsp[(3) - (6)].node), (yyvsp[(5) - (6)].node), (yylsp[(1) - (6)]));
 				}
     break;
 
   case 1659:
-
-/* Line 1806 of yacc.c  */
-#line 11192 "gram.y"
+#line 11193 "gram.y"
     {
 					CoalesceExpr *c = makeNode(CoalesceExpr);
 					c->args = (yyvsp[(3) - (4)].list);
@@ -36385,9 +33284,7 @@ yyreduce:
     break;
 
   case 1660:
-
-/* Line 1806 of yacc.c  */
-#line 11199 "gram.y"
+#line 11200 "gram.y"
     {
 					MinMaxExpr *v = makeNode(MinMaxExpr);
 					v->args = (yyvsp[(3) - (4)].list);
@@ -36398,9 +33295,7 @@ yyreduce:
     break;
 
   case 1661:
-
-/* Line 1806 of yacc.c  */
-#line 11207 "gram.y"
+#line 11208 "gram.y"
     {
 					MinMaxExpr *v = makeNode(MinMaxExpr);
 					v->args = (yyvsp[(3) - (4)].list);
@@ -36411,54 +33306,42 @@ yyreduce:
     break;
 
   case 1662:
-
-/* Line 1806 of yacc.c  */
-#line 11215 "gram.y"
+#line 11216 "gram.y"
     {
 					(yyval.node) = makeXmlExpr(IS_XMLCONCAT, NULL, NIL, (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)]));
 				}
     break;
 
   case 1663:
-
-/* Line 1806 of yacc.c  */
-#line 11219 "gram.y"
+#line 11220 "gram.y"
     {
 					(yyval.node) = makeXmlExpr(IS_XMLELEMENT, (yyvsp[(4) - (5)].str), NIL, NIL, (yylsp[(1) - (5)]));
 				}
     break;
 
   case 1664:
-
-/* Line 1806 of yacc.c  */
-#line 11223 "gram.y"
+#line 11224 "gram.y"
     {
 					(yyval.node) = makeXmlExpr(IS_XMLELEMENT, (yyvsp[(4) - (7)].str), (yyvsp[(6) - (7)].list), NIL, (yylsp[(1) - (7)]));
 				}
     break;
 
   case 1665:
-
-/* Line 1806 of yacc.c  */
-#line 11227 "gram.y"
+#line 11228 "gram.y"
     {
 					(yyval.node) = makeXmlExpr(IS_XMLELEMENT, (yyvsp[(4) - (7)].str), NIL, (yyvsp[(6) - (7)].list), (yylsp[(1) - (7)]));
 				}
     break;
 
   case 1666:
-
-/* Line 1806 of yacc.c  */
-#line 11231 "gram.y"
+#line 11232 "gram.y"
     {
 					(yyval.node) = makeXmlExpr(IS_XMLELEMENT, (yyvsp[(4) - (9)].str), (yyvsp[(6) - (9)].list), (yyvsp[(8) - (9)].list), (yylsp[(1) - (9)]));
 				}
     break;
 
   case 1667:
-
-/* Line 1806 of yacc.c  */
-#line 11235 "gram.y"
+#line 11236 "gram.y"
     {
 					/* xmlexists(A PASSING [BY REF] B [BY REF]) is
 					 * converted to xmlexists(A, B)*/
@@ -36476,18 +33359,14 @@ yyreduce:
     break;
 
   case 1668:
-
-/* Line 1806 of yacc.c  */
-#line 11250 "gram.y"
+#line 11251 "gram.y"
     {
 					(yyval.node) = makeXmlExpr(IS_XMLFOREST, NULL, (yyvsp[(3) - (4)].list), NIL, (yylsp[(1) - (4)]));
 				}
     break;
 
   case 1669:
-
-/* Line 1806 of yacc.c  */
-#line 11254 "gram.y"
+#line 11255 "gram.y"
     {
 					XmlExpr *x = (XmlExpr *)
 						makeXmlExpr(IS_XMLPARSE, NULL, NIL,
@@ -36499,27 +33378,21 @@ yyreduce:
     break;
 
   case 1670:
-
-/* Line 1806 of yacc.c  */
-#line 11263 "gram.y"
+#line 11264 "gram.y"
     {
 					(yyval.node) = makeXmlExpr(IS_XMLPI, (yyvsp[(4) - (5)].str), NULL, NIL, (yylsp[(1) - (5)]));
 				}
     break;
 
   case 1671:
-
-/* Line 1806 of yacc.c  */
-#line 11267 "gram.y"
+#line 11268 "gram.y"
     {
 					(yyval.node) = makeXmlExpr(IS_XMLPI, (yyvsp[(4) - (7)].str), NULL, list_make1((yyvsp[(6) - (7)].node)), (yylsp[(1) - (7)]));
 				}
     break;
 
   case 1672:
-
-/* Line 1806 of yacc.c  */
-#line 11271 "gram.y"
+#line 11272 "gram.y"
     {
 					(yyval.node) = makeXmlExpr(IS_XMLROOT, NULL, NIL,
 									 list_make3((yyvsp[(3) - (7)].node), (yyvsp[(5) - (7)].node), (yyvsp[(6) - (7)].node)), (yylsp[(1) - (7)]));
@@ -36527,9 +33400,7 @@ yyreduce:
     break;
 
   case 1673:
-
-/* Line 1806 of yacc.c  */
-#line 11276 "gram.y"
+#line 11277 "gram.y"
     {
 					XmlSerialize *n = makeNode(XmlSerialize);
 					n->xmloption = (yyvsp[(3) - (7)].ival);
@@ -36541,72 +33412,52 @@ yyreduce:
     break;
 
   case 1674:
-
-/* Line 1806 of yacc.c  */
-#line 11290 "gram.y"
+#line 11291 "gram.y"
     { (yyval.node) = (yyvsp[(2) - (2)].node); }
     break;
 
   case 1675:
-
-/* Line 1806 of yacc.c  */
-#line 11292 "gram.y"
+#line 11293 "gram.y"
     { (yyval.node) = makeNullAConst(-1); }
     break;
 
   case 1676:
-
-/* Line 1806 of yacc.c  */
-#line 11296 "gram.y"
+#line 11297 "gram.y"
     { (yyval.node) = makeIntConst(XML_STANDALONE_YES, -1); }
     break;
 
   case 1677:
-
-/* Line 1806 of yacc.c  */
-#line 11298 "gram.y"
+#line 11299 "gram.y"
     { (yyval.node) = makeIntConst(XML_STANDALONE_NO, -1); }
     break;
 
   case 1678:
-
-/* Line 1806 of yacc.c  */
-#line 11300 "gram.y"
+#line 11301 "gram.y"
     { (yyval.node) = makeIntConst(XML_STANDALONE_NO_VALUE, -1); }
     break;
 
   case 1679:
-
-/* Line 1806 of yacc.c  */
-#line 11302 "gram.y"
+#line 11303 "gram.y"
     { (yyval.node) = makeIntConst(XML_STANDALONE_OMITTED, -1); }
     break;
 
   case 1680:
-
-/* Line 1806 of yacc.c  */
-#line 11305 "gram.y"
+#line 11306 "gram.y"
     { (yyval.list) = (yyvsp[(3) - (4)].list); }
     break;
 
   case 1681:
-
-/* Line 1806 of yacc.c  */
-#line 11308 "gram.y"
+#line 11309 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].target)); }
     break;
 
   case 1682:
-
-/* Line 1806 of yacc.c  */
-#line 11309 "gram.y"
+#line 11310 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].target)); }
     break;
 
   case 1683:
-
-/* Line 1806 of yacc.c  */
-#line 11313 "gram.y"
+#line 11314 "gram.y"
     {
 					(yyval.target) = makeNode(ResTarget);
 					(yyval.target)->name = (yyvsp[(3) - (3)].str);
@@ -36617,9 +33468,7 @@ yyreduce:
     break;
 
   case 1684:
-
-/* Line 1806 of yacc.c  */
-#line 11321 "gram.y"
+#line 11322 "gram.y"
     {
 					(yyval.target) = makeNode(ResTarget);
 					(yyval.target)->name = NULL;
@@ -36630,108 +33479,80 @@ yyreduce:
     break;
 
   case 1685:
-
-/* Line 1806 of yacc.c  */
-#line 11330 "gram.y"
+#line 11331 "gram.y"
     { (yyval.ival) = XMLOPTION_DOCUMENT; }
     break;
 
   case 1686:
-
-/* Line 1806 of yacc.c  */
-#line 11331 "gram.y"
+#line 11332 "gram.y"
     { (yyval.ival) = XMLOPTION_CONTENT; }
     break;
 
   case 1687:
-
-/* Line 1806 of yacc.c  */
-#line 11334 "gram.y"
+#line 11335 "gram.y"
     { (yyval.boolean) = TRUE; }
     break;
 
   case 1688:
-
-/* Line 1806 of yacc.c  */
-#line 11335 "gram.y"
+#line 11336 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 1689:
-
-/* Line 1806 of yacc.c  */
-#line 11336 "gram.y"
+#line 11337 "gram.y"
     { (yyval.boolean) = FALSE; }
     break;
 
   case 1690:
-
-/* Line 1806 of yacc.c  */
-#line 11342 "gram.y"
+#line 11343 "gram.y"
     {
 					(yyval.node) = (yyvsp[(2) - (2)].node);
 				}
     break;
 
   case 1691:
-
-/* Line 1806 of yacc.c  */
-#line 11346 "gram.y"
+#line 11347 "gram.y"
     {
 					(yyval.node) = (yyvsp[(2) - (4)].node);
 				}
     break;
 
   case 1692:
-
-/* Line 1806 of yacc.c  */
-#line 11350 "gram.y"
+#line 11351 "gram.y"
     {
 					(yyval.node) = (yyvsp[(4) - (4)].node);
 				}
     break;
 
   case 1693:
-
-/* Line 1806 of yacc.c  */
-#line 11354 "gram.y"
+#line 11355 "gram.y"
     {
 					(yyval.node) = (yyvsp[(4) - (6)].node);
 				}
     break;
 
   case 1694:
-
-/* Line 1806 of yacc.c  */
-#line 11364 "gram.y"
+#line 11365 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (2)].list); }
     break;
 
   case 1695:
-
-/* Line 1806 of yacc.c  */
-#line 11365 "gram.y"
+#line 11366 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1696:
-
-/* Line 1806 of yacc.c  */
-#line 11369 "gram.y"
+#line 11370 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].windef)); }
     break;
 
   case 1697:
-
-/* Line 1806 of yacc.c  */
-#line 11371 "gram.y"
+#line 11372 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].windef)); }
     break;
 
   case 1698:
-
-/* Line 1806 of yacc.c  */
-#line 11376 "gram.y"
+#line 11377 "gram.y"
     {
 					WindowDef *n = (yyvsp[(3) - (3)].windef);
 					n->name = (yyvsp[(1) - (3)].str);
@@ -36740,16 +33561,12 @@ yyreduce:
     break;
 
   case 1699:
-
-/* Line 1806 of yacc.c  */
-#line 11384 "gram.y"
+#line 11385 "gram.y"
     { (yyval.windef) = (yyvsp[(2) - (2)].windef); }
     break;
 
   case 1700:
-
-/* Line 1806 of yacc.c  */
-#line 11386 "gram.y"
+#line 11387 "gram.y"
     {
 					WindowDef *n = makeNode(WindowDef);
 					n->name = (yyvsp[(2) - (2)].str);
@@ -36765,16 +33582,12 @@ yyreduce:
     break;
 
   case 1701:
-
-/* Line 1806 of yacc.c  */
-#line 11399 "gram.y"
+#line 11400 "gram.y"
     { (yyval.windef) = NULL; }
     break;
 
   case 1702:
-
-/* Line 1806 of yacc.c  */
-#line 11404 "gram.y"
+#line 11405 "gram.y"
     {
 					WindowDef *n = makeNode(WindowDef);
 					n->name = NULL;
@@ -36791,37 +33604,27 @@ yyreduce:
     break;
 
   case 1703:
-
-/* Line 1806 of yacc.c  */
-#line 11429 "gram.y"
+#line 11430 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1704:
-
-/* Line 1806 of yacc.c  */
-#line 11430 "gram.y"
+#line 11431 "gram.y"
     { (yyval.str) = NULL; }
     break;
 
   case 1705:
-
-/* Line 1806 of yacc.c  */
-#line 11433 "gram.y"
+#line 11434 "gram.y"
     { (yyval.list) = (yyvsp[(3) - (3)].list); }
     break;
 
   case 1706:
-
-/* Line 1806 of yacc.c  */
-#line 11434 "gram.y"
+#line 11435 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1707:
-
-/* Line 1806 of yacc.c  */
-#line 11446 "gram.y"
+#line 11447 "gram.y"
     {
 					WindowDef *n = (yyvsp[(2) - (2)].windef);
 					n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_RANGE;
@@ -36842,9 +33645,7 @@ yyreduce:
     break;
 
   case 1708:
-
-/* Line 1806 of yacc.c  */
-#line 11464 "gram.y"
+#line 11465 "gram.y"
     {
 					WindowDef *n = (yyvsp[(2) - (2)].windef);
 					n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_ROWS;
@@ -36853,9 +33654,7 @@ yyreduce:
     break;
 
   case 1709:
-
-/* Line 1806 of yacc.c  */
-#line 11470 "gram.y"
+#line 11471 "gram.y"
     {
 					WindowDef *n = makeNode(WindowDef);
 					n->frameOptions = FRAMEOPTION_DEFAULTS;
@@ -36866,9 +33665,7 @@ yyreduce:
     break;
 
   case 1710:
-
-/* Line 1806 of yacc.c  */
-#line 11480 "gram.y"
+#line 11481 "gram.y"
     {
 					WindowDef *n = (yyvsp[(1) - (1)].windef);
 					/* reject invalid cases */
@@ -36888,9 +33685,7 @@ yyreduce:
     break;
 
   case 1711:
-
-/* Line 1806 of yacc.c  */
-#line 11497 "gram.y"
+#line 11498 "gram.y"
     {
 					WindowDef *n1 = (yyvsp[(2) - (4)].windef);
 					WindowDef *n2 = (yyvsp[(4) - (4)].windef);
@@ -36930,9 +33725,7 @@ yyreduce:
     break;
 
   case 1712:
-
-/* Line 1806 of yacc.c  */
-#line 11542 "gram.y"
+#line 11543 "gram.y"
     {
 					WindowDef *n = makeNode(WindowDef);
 					n->frameOptions = FRAMEOPTION_START_UNBOUNDED_PRECEDING;
@@ -36943,9 +33736,7 @@ yyreduce:
     break;
 
   case 1713:
-
-/* Line 1806 of yacc.c  */
-#line 11550 "gram.y"
+#line 11551 "gram.y"
     {
 					WindowDef *n = makeNode(WindowDef);
 					n->frameOptions = FRAMEOPTION_START_UNBOUNDED_FOLLOWING;
@@ -36956,9 +33747,7 @@ yyreduce:
     break;
 
   case 1714:
-
-/* Line 1806 of yacc.c  */
-#line 11558 "gram.y"
+#line 11559 "gram.y"
     {
 					WindowDef *n = makeNode(WindowDef);
 					n->frameOptions = FRAMEOPTION_START_CURRENT_ROW;
@@ -36969,9 +33758,7 @@ yyreduce:
     break;
 
   case 1715:
-
-/* Line 1806 of yacc.c  */
-#line 11566 "gram.y"
+#line 11567 "gram.y"
     {
 					WindowDef *n = makeNode(WindowDef);
 					n->frameOptions = FRAMEOPTION_START_VALUE_PRECEDING;
@@ -36982,9 +33769,7 @@ yyreduce:
     break;
 
   case 1716:
-
-/* Line 1806 of yacc.c  */
-#line 11574 "gram.y"
+#line 11575 "gram.y"
     {
 					WindowDef *n = makeNode(WindowDef);
 					n->frameOptions = FRAMEOPTION_START_VALUE_FOLLOWING;
@@ -36995,243 +33780,177 @@ yyreduce:
     break;
 
   case 1717:
-
-/* Line 1806 of yacc.c  */
-#line 11594 "gram.y"
+#line 11595 "gram.y"
     { (yyval.list) = (yyvsp[(3) - (4)].list); }
     break;
 
   case 1718:
-
-/* Line 1806 of yacc.c  */
-#line 11595 "gram.y"
+#line 11596 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1719:
-
-/* Line 1806 of yacc.c  */
-#line 11596 "gram.y"
+#line 11597 "gram.y"
     { (yyval.list) = lappend((yyvsp[(2) - (5)].list), (yyvsp[(4) - (5)].node)); }
     break;
 
   case 1720:
-
-/* Line 1806 of yacc.c  */
-#line 11599 "gram.y"
+#line 11600 "gram.y"
     { (yyval.ival) = ANY_SUBLINK; }
     break;
 
   case 1721:
-
-/* Line 1806 of yacc.c  */
-#line 11600 "gram.y"
+#line 11601 "gram.y"
     { (yyval.ival) = ANY_SUBLINK; }
     break;
 
   case 1722:
-
-/* Line 1806 of yacc.c  */
-#line 11601 "gram.y"
+#line 11602 "gram.y"
     { (yyval.ival) = ALL_SUBLINK; }
     break;
 
   case 1723:
-
-/* Line 1806 of yacc.c  */
-#line 11604 "gram.y"
+#line 11605 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1724:
-
-/* Line 1806 of yacc.c  */
-#line 11605 "gram.y"
+#line 11606 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1725:
-
-/* Line 1806 of yacc.c  */
-#line 11608 "gram.y"
+#line 11609 "gram.y"
     { (yyval.str) = "+"; }
     break;
 
   case 1726:
-
-/* Line 1806 of yacc.c  */
-#line 11609 "gram.y"
+#line 11610 "gram.y"
     { (yyval.str) = "-"; }
     break;
 
   case 1727:
-
-/* Line 1806 of yacc.c  */
-#line 11610 "gram.y"
+#line 11611 "gram.y"
     { (yyval.str) = "*"; }
     break;
 
   case 1728:
-
-/* Line 1806 of yacc.c  */
-#line 11611 "gram.y"
+#line 11612 "gram.y"
     { (yyval.str) = "/"; }
     break;
 
   case 1729:
-
-/* Line 1806 of yacc.c  */
-#line 11612 "gram.y"
+#line 11613 "gram.y"
     { (yyval.str) = "%"; }
     break;
 
   case 1730:
-
-/* Line 1806 of yacc.c  */
-#line 11613 "gram.y"
+#line 11614 "gram.y"
     { (yyval.str) = "^"; }
     break;
 
   case 1731:
-
-/* Line 1806 of yacc.c  */
-#line 11614 "gram.y"
+#line 11615 "gram.y"
     { (yyval.str) = "<"; }
     break;
 
   case 1732:
-
-/* Line 1806 of yacc.c  */
-#line 11615 "gram.y"
+#line 11616 "gram.y"
     { (yyval.str) = ">"; }
     break;
 
   case 1733:
-
-/* Line 1806 of yacc.c  */
-#line 11616 "gram.y"
+#line 11617 "gram.y"
     { (yyval.str) = "="; }
     break;
 
   case 1734:
-
-/* Line 1806 of yacc.c  */
-#line 11620 "gram.y"
+#line 11621 "gram.y"
     { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); }
     break;
 
   case 1735:
-
-/* Line 1806 of yacc.c  */
-#line 11622 "gram.y"
+#line 11623 "gram.y"
     { (yyval.list) = (yyvsp[(3) - (4)].list); }
     break;
 
   case 1736:
-
-/* Line 1806 of yacc.c  */
-#line 11627 "gram.y"
+#line 11628 "gram.y"
     { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); }
     break;
 
   case 1737:
-
-/* Line 1806 of yacc.c  */
-#line 11629 "gram.y"
+#line 11630 "gram.y"
     { (yyval.list) = (yyvsp[(3) - (4)].list); }
     break;
 
   case 1738:
-
-/* Line 1806 of yacc.c  */
-#line 11634 "gram.y"
+#line 11635 "gram.y"
     { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); }
     break;
 
   case 1739:
-
-/* Line 1806 of yacc.c  */
-#line 11636 "gram.y"
+#line 11637 "gram.y"
     { (yyval.list) = (yyvsp[(3) - (4)].list); }
     break;
 
   case 1740:
-
-/* Line 1806 of yacc.c  */
-#line 11638 "gram.y"
+#line 11639 "gram.y"
     { (yyval.list) = list_make1(makeString("~~")); }
     break;
 
   case 1741:
-
-/* Line 1806 of yacc.c  */
-#line 11640 "gram.y"
+#line 11641 "gram.y"
     { (yyval.list) = list_make1(makeString("!~~")); }
     break;
 
   case 1742:
-
-/* Line 1806 of yacc.c  */
-#line 11642 "gram.y"
+#line 11643 "gram.y"
     { (yyval.list) = list_make1(makeString("~~*")); }
     break;
 
   case 1743:
-
-/* Line 1806 of yacc.c  */
-#line 11644 "gram.y"
+#line 11645 "gram.y"
     { (yyval.list) = list_make1(makeString("!~~*")); }
     break;
 
   case 1744:
-
-/* Line 1806 of yacc.c  */
-#line 11656 "gram.y"
+#line 11657 "gram.y"
     {
 					(yyval.list) = list_make1((yyvsp[(1) - (1)].node));
 				}
     break;
 
   case 1745:
-
-/* Line 1806 of yacc.c  */
-#line 11660 "gram.y"
+#line 11661 "gram.y"
     {
 					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 				}
     break;
 
   case 1746:
-
-/* Line 1806 of yacc.c  */
-#line 11667 "gram.y"
+#line 11668 "gram.y"
     {
 					(yyval.list) = list_make1((yyvsp[(1) - (1)].node));
 				}
     break;
 
   case 1747:
-
-/* Line 1806 of yacc.c  */
-#line 11671 "gram.y"
+#line 11672 "gram.y"
     {
 					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 				}
     break;
 
   case 1748:
-
-/* Line 1806 of yacc.c  */
-#line 11677 "gram.y"
+#line 11678 "gram.y"
     {
 					(yyval.node) = (yyvsp[(1) - (1)].node);
 				}
     break;
 
   case 1749:
-
-/* Line 1806 of yacc.c  */
-#line 11681 "gram.y"
+#line 11682 "gram.y"
     {
 					NamedArgExpr *na = makeNode(NamedArgExpr);
 					na->name = (yyvsp[(1) - (3)].str);
@@ -37243,184 +33962,136 @@ yyreduce:
     break;
 
   case 1750:
-
-/* Line 1806 of yacc.c  */
-#line 11691 "gram.y"
+#line 11692 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].typnam)); }
     break;
 
   case 1751:
-
-/* Line 1806 of yacc.c  */
-#line 11692 "gram.y"
+#line 11693 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].typnam)); }
     break;
 
   case 1752:
-
-/* Line 1806 of yacc.c  */
-#line 11696 "gram.y"
+#line 11697 "gram.y"
     {
 					(yyval.node) = makeAArrayExpr((yyvsp[(2) - (3)].list), (yylsp[(1) - (3)]));
 				}
     break;
 
   case 1753:
-
-/* Line 1806 of yacc.c  */
-#line 11700 "gram.y"
+#line 11701 "gram.y"
     {
 					(yyval.node) = makeAArrayExpr((yyvsp[(2) - (3)].list), (yylsp[(1) - (3)]));
 				}
     break;
 
   case 1754:
-
-/* Line 1806 of yacc.c  */
-#line 11704 "gram.y"
+#line 11705 "gram.y"
     {
 					(yyval.node) = makeAArrayExpr(NIL, (yylsp[(1) - (2)]));
 				}
     break;
 
   case 1755:
-
-/* Line 1806 of yacc.c  */
-#line 11709 "gram.y"
+#line 11710 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); }
     break;
 
   case 1756:
-
-/* Line 1806 of yacc.c  */
-#line 11710 "gram.y"
+#line 11711 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); }
     break;
 
   case 1757:
-
-/* Line 1806 of yacc.c  */
-#line 11716 "gram.y"
+#line 11717 "gram.y"
     {
 					(yyval.list) = list_make2(makeStringConst((yyvsp[(1) - (3)].str), (yylsp[(1) - (3)])), (yyvsp[(3) - (3)].node));
 				}
     break;
 
   case 1758:
-
-/* Line 1806 of yacc.c  */
-#line 11719 "gram.y"
+#line 11720 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1759:
-
-/* Line 1806 of yacc.c  */
-#line 11726 "gram.y"
+#line 11727 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1760:
-
-/* Line 1806 of yacc.c  */
-#line 11727 "gram.y"
+#line 11728 "gram.y"
     { (yyval.str) = "year"; }
     break;
 
   case 1761:
-
-/* Line 1806 of yacc.c  */
-#line 11728 "gram.y"
+#line 11729 "gram.y"
     { (yyval.str) = "month"; }
     break;
 
   case 1762:
-
-/* Line 1806 of yacc.c  */
-#line 11729 "gram.y"
+#line 11730 "gram.y"
     { (yyval.str) = "day"; }
     break;
 
   case 1763:
-
-/* Line 1806 of yacc.c  */
-#line 11730 "gram.y"
+#line 11731 "gram.y"
     { (yyval.str) = "hour"; }
     break;
 
   case 1764:
-
-/* Line 1806 of yacc.c  */
-#line 11731 "gram.y"
+#line 11732 "gram.y"
     { (yyval.str) = "minute"; }
     break;
 
   case 1765:
-
-/* Line 1806 of yacc.c  */
-#line 11732 "gram.y"
+#line 11733 "gram.y"
     { (yyval.str) = "second"; }
     break;
 
   case 1766:
-
-/* Line 1806 of yacc.c  */
-#line 11733 "gram.y"
+#line 11734 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1767:
-
-/* Line 1806 of yacc.c  */
-#line 11744 "gram.y"
+#line 11745 "gram.y"
     {
 					(yyval.list) = list_make4((yyvsp[(1) - (4)].node), (yyvsp[(2) - (4)].node), (yyvsp[(3) - (4)].node), (yyvsp[(4) - (4)].node));
 				}
     break;
 
   case 1768:
-
-/* Line 1806 of yacc.c  */
-#line 11748 "gram.y"
+#line 11749 "gram.y"
     {
 					(yyval.list) = list_make3((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].node), (yyvsp[(3) - (3)].node));
 				}
     break;
 
   case 1769:
-
-/* Line 1806 of yacc.c  */
-#line 11755 "gram.y"
+#line 11756 "gram.y"
     { (yyval.node) = (yyvsp[(2) - (2)].node); }
     break;
 
   case 1770:
-
-/* Line 1806 of yacc.c  */
-#line 11761 "gram.y"
+#line 11762 "gram.y"
     { (yyval.list) = list_make2((yyvsp[(3) - (3)].node), (yyvsp[(1) - (3)].node)); }
     break;
 
   case 1771:
-
-/* Line 1806 of yacc.c  */
-#line 11762 "gram.y"
+#line 11763 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1772:
-
-/* Line 1806 of yacc.c  */
-#line 11779 "gram.y"
+#line 11780 "gram.y"
     {
 					(yyval.list) = list_make3((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].node), (yyvsp[(3) - (3)].node));
 				}
     break;
 
   case 1773:
-
-/* Line 1806 of yacc.c  */
-#line 11783 "gram.y"
+#line 11784 "gram.y"
     {
 					/* not legal per SQL99, but might as well allow it */
 					(yyval.list) = list_make3((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yyvsp[(2) - (3)].node));
@@ -37428,18 +34099,14 @@ yyreduce:
     break;
 
   case 1774:
-
-/* Line 1806 of yacc.c  */
-#line 11788 "gram.y"
+#line 11789 "gram.y"
     {
 					(yyval.list) = list_make2((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
 				}
     break;
 
   case 1775:
-
-/* Line 1806 of yacc.c  */
-#line 11792 "gram.y"
+#line 11793 "gram.y"
     {
 					/*
 					 * Since there are no cases where this syntax allows
@@ -37457,60 +34124,44 @@ yyreduce:
     break;
 
   case 1776:
-
-/* Line 1806 of yacc.c  */
-#line 11807 "gram.y"
+#line 11808 "gram.y"
     {
 					(yyval.list) = (yyvsp[(1) - (1)].list);
 				}
     break;
 
   case 1777:
-
-/* Line 1806 of yacc.c  */
-#line 11811 "gram.y"
+#line 11812 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1778:
-
-/* Line 1806 of yacc.c  */
-#line 11815 "gram.y"
+#line 11816 "gram.y"
     { (yyval.node) = (yyvsp[(2) - (2)].node); }
     break;
 
   case 1779:
-
-/* Line 1806 of yacc.c  */
-#line 11818 "gram.y"
+#line 11819 "gram.y"
     { (yyval.node) = (yyvsp[(2) - (2)].node); }
     break;
 
   case 1780:
-
-/* Line 1806 of yacc.c  */
-#line 11821 "gram.y"
+#line 11822 "gram.y"
     { (yyval.list) = lappend((yyvsp[(3) - (3)].list), (yyvsp[(1) - (3)].node)); }
     break;
 
   case 1781:
-
-/* Line 1806 of yacc.c  */
-#line 11822 "gram.y"
+#line 11823 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (2)].list); }
     break;
 
   case 1782:
-
-/* Line 1806 of yacc.c  */
-#line 11823 "gram.y"
+#line 11824 "gram.y"
     { (yyval.list) = (yyvsp[(1) - (1)].list); }
     break;
 
   case 1783:
-
-/* Line 1806 of yacc.c  */
-#line 11827 "gram.y"
+#line 11828 "gram.y"
     {
 					SubLink *n = makeNode(SubLink);
 					n->subselect = (yyvsp[(1) - (1)].node);
@@ -37520,16 +34171,12 @@ yyreduce:
     break;
 
   case 1784:
-
-/* Line 1806 of yacc.c  */
-#line 11833 "gram.y"
+#line 11834 "gram.y"
     { (yyval.node) = (Node *)(yyvsp[(2) - (3)].list); }
     break;
 
   case 1785:
-
-/* Line 1806 of yacc.c  */
-#line 11844 "gram.y"
+#line 11845 "gram.y"
     {
 					CaseExpr *c = makeNode(CaseExpr);
 					c->casetype = InvalidOid; /* not analyzed yet */
@@ -37542,23 +34189,17 @@ yyreduce:
     break;
 
   case 1786:
-
-/* Line 1806 of yacc.c  */
-#line 11857 "gram.y"
+#line 11858 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); }
     break;
 
   case 1787:
-
-/* Line 1806 of yacc.c  */
-#line 11858 "gram.y"
+#line 11859 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); }
     break;
 
   case 1788:
-
-/* Line 1806 of yacc.c  */
-#line 11863 "gram.y"
+#line 11864 "gram.y"
     {
 					CaseWhen *w = makeNode(CaseWhen);
 					w->expr = (Expr *) (yyvsp[(2) - (4)].node);
@@ -37569,73 +34210,55 @@ yyreduce:
     break;
 
   case 1789:
-
-/* Line 1806 of yacc.c  */
-#line 11873 "gram.y"
+#line 11874 "gram.y"
     { (yyval.node) = (yyvsp[(2) - (2)].node); }
     break;
 
   case 1790:
-
-/* Line 1806 of yacc.c  */
-#line 11874 "gram.y"
+#line 11875 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 1791:
-
-/* Line 1806 of yacc.c  */
-#line 11877 "gram.y"
+#line 11878 "gram.y"
     { (yyval.node) = (yyvsp[(1) - (1)].node); }
     break;
 
   case 1792:
-
-/* Line 1806 of yacc.c  */
-#line 11878 "gram.y"
+#line 11879 "gram.y"
     { (yyval.node) = NULL; }
     break;
 
   case 1793:
-
-/* Line 1806 of yacc.c  */
-#line 11882 "gram.y"
+#line 11883 "gram.y"
     {
 					(yyval.node) = makeColumnRef((yyvsp[(1) - (1)].str), NIL, (yylsp[(1) - (1)]), yyscanner);
 				}
     break;
 
   case 1794:
-
-/* Line 1806 of yacc.c  */
-#line 11886 "gram.y"
+#line 11887 "gram.y"
     {
 					(yyval.node) = makeColumnRef((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].list), (yylsp[(1) - (2)]), yyscanner);
 				}
     break;
 
   case 1795:
-
-/* Line 1806 of yacc.c  */
-#line 11893 "gram.y"
+#line 11894 "gram.y"
     {
 					(yyval.node) = (Node *) makeString((yyvsp[(2) - (2)].str));
 				}
     break;
 
   case 1796:
-
-/* Line 1806 of yacc.c  */
-#line 11897 "gram.y"
+#line 11898 "gram.y"
     {
 					(yyval.node) = (Node *) makeNode(A_Star);
 				}
     break;
 
   case 1797:
-
-/* Line 1806 of yacc.c  */
-#line 11901 "gram.y"
+#line 11902 "gram.y"
     {
 					A_Indices *ai = makeNode(A_Indices);
 					ai->lidx = NULL;
@@ -37645,9 +34268,7 @@ yyreduce:
     break;
 
   case 1798:
-
-/* Line 1806 of yacc.c  */
-#line 11908 "gram.y"
+#line 11909 "gram.y"
     {
 					A_Indices *ai = makeNode(A_Indices);
 					ai->lidx = (yyvsp[(2) - (5)].node);
@@ -37657,44 +34278,32 @@ yyreduce:
     break;
 
   case 1799:
-
-/* Line 1806 of yacc.c  */
-#line 11917 "gram.y"
+#line 11918 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); }
     break;
 
   case 1800:
-
-/* Line 1806 of yacc.c  */
-#line 11918 "gram.y"
+#line 11919 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); }
     break;
 
   case 1801:
-
-/* Line 1806 of yacc.c  */
-#line 11922 "gram.y"
+#line 11923 "gram.y"
     { (yyval.list) = NIL; }
     break;
 
   case 1802:
-
-/* Line 1806 of yacc.c  */
-#line 11923 "gram.y"
+#line 11924 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); }
     break;
 
   case 1805:
-
-/* Line 1806 of yacc.c  */
-#line 11938 "gram.y"
+#line 11939 "gram.y"
     { (yyval.node) = (Node *) (yyvsp[(1) - (1)].node); }
     break;
 
   case 1806:
-
-/* Line 1806 of yacc.c  */
-#line 11940 "gram.y"
+#line 11941 "gram.y"
     {
 					SetToDefault *n = makeNode(SetToDefault);
 					n->location = (yylsp[(1) - (1)]);
@@ -37703,44 +34312,32 @@ yyreduce:
     break;
 
   case 1807:
-
-/* Line 1806 of yacc.c  */
-#line 11948 "gram.y"
+#line 11949 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); }
     break;
 
   case 1808:
-
-/* Line 1806 of yacc.c  */
-#line 11949 "gram.y"
+#line 11950 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); }
     break;
 
   case 1809:
-
-/* Line 1806 of yacc.c  */
-#line 11957 "gram.y"
+#line 11958 "gram.y"
     { (yyval.list) = (yyvsp[(2) - (3)].list); }
     break;
 
   case 1810:
-
-/* Line 1806 of yacc.c  */
-#line 11968 "gram.y"
+#line 11969 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].target)); }
     break;
 
   case 1811:
-
-/* Line 1806 of yacc.c  */
-#line 11969 "gram.y"
+#line 11970 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].target)); }
     break;
 
   case 1812:
-
-/* Line 1806 of yacc.c  */
-#line 11973 "gram.y"
+#line 11974 "gram.y"
     {
 					(yyval.target) = makeNode(ResTarget);
 					(yyval.target)->name = (yyvsp[(3) - (3)].str);
@@ -37751,9 +34348,7 @@ yyreduce:
     break;
 
   case 1813:
-
-/* Line 1806 of yacc.c  */
-#line 11989 "gram.y"
+#line 11990 "gram.y"
     {
 					(yyval.target) = makeNode(ResTarget);
 					(yyval.target)->name = (yyvsp[(2) - (2)].str);
@@ -37764,9 +34359,7 @@ yyreduce:
     break;
 
   case 1814:
-
-/* Line 1806 of yacc.c  */
-#line 11997 "gram.y"
+#line 11998 "gram.y"
     {
 					(yyval.target) = makeNode(ResTarget);
 					(yyval.target)->name = NULL;
@@ -37777,9 +34370,7 @@ yyreduce:
     break;
 
   case 1815:
-
-/* Line 1806 of yacc.c  */
-#line 12005 "gram.y"
+#line 12006 "gram.y"
     {
 					ColumnRef *n = makeNode(ColumnRef);
 					n->fields = list_make1(makeNode(A_Star));
@@ -37794,32 +34385,24 @@ yyreduce:
     break;
 
   case 1816:
-
-/* Line 1806 of yacc.c  */
-#line 12026 "gram.y"
+#line 12027 "gram.y"
     { (yyval.list) = list_make1((yyvsp[(1) - (1)].range)); }
     break;
 
   case 1817:
-
-/* Line 1806 of yacc.c  */
-#line 12027 "gram.y"
+#line 12028 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].range)); }
     break;
 
   case 1818:
-
-/* Line 1806 of yacc.c  */
-#line 12039 "gram.y"
+#line 12040 "gram.y"
     {
 					(yyval.range) = makeRangeVar(NULL, (yyvsp[(1) - (1)].str), (yylsp[(1) - (1)]));
 				}
     break;
 
   case 1819:
-
-/* Line 1806 of yacc.c  */
-#line 12043 "gram.y"
+#line 12044 "gram.y"
     {
 					check_qualified_name((yyvsp[(2) - (2)].list), yyscanner);
 					(yyval.range) = makeRangeVar(NULL, NULL, (yylsp[(1) - (2)]));
@@ -37847,72 +34430,52 @@ yyreduce:
     break;
 
   case 1820:
-
-/* Line 1806 of yacc.c  */
-#line 12070 "gram.y"
+#line 12071 "gram.y"
     { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); }
     break;
 
   case 1821:
-
-/* Line 1806 of yacc.c  */
-#line 12072 "gram.y"
+#line 12073 "gram.y"
     { (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeString((yyvsp[(3) - (3)].str))); }
     break;
 
   case 1822:
-
-/* Line 1806 of yacc.c  */
-#line 12076 "gram.y"
+#line 12077 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1823:
-
-/* Line 1806 of yacc.c  */
-#line 12079 "gram.y"
+#line 12080 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1824:
-
-/* Line 1806 of yacc.c  */
-#line 12082 "gram.y"
+#line 12083 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1825:
-
-/* Line 1806 of yacc.c  */
-#line 12084 "gram.y"
+#line 12085 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1826:
-
-/* Line 1806 of yacc.c  */
-#line 12086 "gram.y"
+#line 12087 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1827:
-
-/* Line 1806 of yacc.c  */
-#line 12088 "gram.y"
+#line 12089 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1828:
-
-/* Line 1806 of yacc.c  */
-#line 12099 "gram.y"
+#line 12100 "gram.y"
     { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); }
     break;
 
   case 1829:
-
-/* Line 1806 of yacc.c  */
-#line 12101 "gram.y"
+#line 12102 "gram.y"
     {
 						(yyval.list) = check_func_name(lcons(makeString((yyvsp[(1) - (2)].str)), (yyvsp[(2) - (2)].list)),
 											 yyscanner);
@@ -37920,45 +34483,35 @@ yyreduce:
     break;
 
   case 1830:
-
-/* Line 1806 of yacc.c  */
-#line 12112 "gram.y"
+#line 12113 "gram.y"
     {
 					(yyval.node) = makeIntConst((yyvsp[(1) - (1)].ival), (yylsp[(1) - (1)]));
 				}
     break;
 
   case 1831:
-
-/* Line 1806 of yacc.c  */
-#line 12116 "gram.y"
+#line 12117 "gram.y"
     {
 					(yyval.node) = makeFloatConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)]));
 				}
     break;
 
   case 1832:
-
-/* Line 1806 of yacc.c  */
-#line 12120 "gram.y"
+#line 12121 "gram.y"
     {
 					(yyval.node) = makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)]));
 				}
     break;
 
   case 1833:
-
-/* Line 1806 of yacc.c  */
-#line 12124 "gram.y"
+#line 12125 "gram.y"
     {
 					(yyval.node) = makeBitStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)]));
 				}
     break;
 
   case 1834:
-
-/* Line 1806 of yacc.c  */
-#line 12128 "gram.y"
+#line 12129 "gram.y"
     {
 					/* This is a bit constant per SQL99:
 					 * Without Feature F511, "BIT data type",
@@ -37970,9 +34523,7 @@ yyreduce:
     break;
 
   case 1835:
-
-/* Line 1806 of yacc.c  */
-#line 12137 "gram.y"
+#line 12138 "gram.y"
     {
 					/* generic type 'literal' syntax */
 					TypeName *t = makeTypeNameFromNameList((yyvsp[(1) - (2)].list));
@@ -37982,9 +34533,7 @@ yyreduce:
     break;
 
   case 1836:
-
-/* Line 1806 of yacc.c  */
-#line 12144 "gram.y"
+#line 12145 "gram.y"
     {
 					/* generic syntax with a type modifier */
 					TypeName *t = makeTypeNameFromNameList((yyvsp[(1) - (5)].list));
@@ -38012,18 +34561,14 @@ yyreduce:
     break;
 
   case 1837:
-
-/* Line 1806 of yacc.c  */
-#line 12169 "gram.y"
+#line 12170 "gram.y"
     {
 					(yyval.node) = makeStringConstCast((yyvsp[(2) - (2)].str), (yylsp[(2) - (2)]), (yyvsp[(1) - (2)].typnam));
 				}
     break;
 
   case 1838:
-
-/* Line 1806 of yacc.c  */
-#line 12173 "gram.y"
+#line 12174 "gram.y"
     {
 					TypeName *t = (yyvsp[(1) - (3)].typnam);
 					t->typmods = (yyvsp[(3) - (3)].list);
@@ -38032,9 +34577,7 @@ yyreduce:
     break;
 
   case 1839:
-
-/* Line 1806 of yacc.c  */
-#line 12179 "gram.y"
+#line 12180 "gram.y"
     {
 					TypeName *t = (yyvsp[(1) - (6)].typnam);
 					if ((yyvsp[(6) - (6)].list) != NIL)
@@ -38054,168 +34597,116 @@ yyreduce:
     break;
 
   case 1840:
-
-/* Line 1806 of yacc.c  */
-#line 12196 "gram.y"
+#line 12197 "gram.y"
     {
 					(yyval.node) = makeBoolAConst(TRUE, (yylsp[(1) - (1)]));
 				}
     break;
 
   case 1841:
-
-/* Line 1806 of yacc.c  */
-#line 12200 "gram.y"
+#line 12201 "gram.y"
     {
 					(yyval.node) = makeBoolAConst(FALSE, (yylsp[(1) - (1)]));
 				}
     break;
 
   case 1842:
-
-/* Line 1806 of yacc.c  */
-#line 12204 "gram.y"
+#line 12205 "gram.y"
     {
 					(yyval.node) = makeNullAConst((yylsp[(1) - (1)]));
 				}
     break;
 
   case 1843:
-
-/* Line 1806 of yacc.c  */
-#line 12209 "gram.y"
+#line 12210 "gram.y"
     { (yyval.ival) = (yyvsp[(1) - (1)].ival); }
     break;
 
   case 1844:
-
-/* Line 1806 of yacc.c  */
-#line 12210 "gram.y"
+#line 12211 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1845:
-
-/* Line 1806 of yacc.c  */
-#line 12211 "gram.y"
+#line 12212 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1846:
-
-/* Line 1806 of yacc.c  */
-#line 12213 "gram.y"
+#line 12214 "gram.y"
     { (yyval.ival) = (yyvsp[(1) - (1)].ival); }
     break;
 
   case 1847:
-
-/* Line 1806 of yacc.c  */
-#line 12214 "gram.y"
+#line 12215 "gram.y"
     { (yyval.ival) = + (yyvsp[(2) - (2)].ival); }
     break;
 
   case 1848:
-
-/* Line 1806 of yacc.c  */
-#line 12215 "gram.y"
+#line 12216 "gram.y"
     { (yyval.ival) = - (yyvsp[(2) - (2)].ival); }
     break;
 
   case 1849:
-
-/* Line 1806 of yacc.c  */
-#line 12231 "gram.y"
+#line 12232 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1850:
-
-/* Line 1806 of yacc.c  */
-#line 12232 "gram.y"
+#line 12233 "gram.y"
     { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); }
     break;
 
   case 1851:
-
-/* Line 1806 of yacc.c  */
-#line 12233 "gram.y"
+#line 12234 "gram.y"
     { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); }
     break;
 
   case 1852:
-
-/* Line 1806 of yacc.c  */
-#line 12238 "gram.y"
+#line 12239 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1853:
-
-/* Line 1806 of yacc.c  */
-#line 12239 "gram.y"
+#line 12240 "gram.y"
     { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); }
     break;
 
   case 1854:
-
-/* Line 1806 of yacc.c  */
-#line 12240 "gram.y"
+#line 12241 "gram.y"
     { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); }
     break;
 
   case 1855:
-
-/* Line 1806 of yacc.c  */
-#line 12246 "gram.y"
+#line 12247 "gram.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
   case 1856:
-
-/* Line 1806 of yacc.c  */
-#line 12247 "gram.y"
+#line 12248 "gram.y"
     { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); }
     break;
 
   case 1857:
-
-/* Line 1806 of yacc.c  */
-#line 12248 "gram.y"
+#line 12249 "gram.y"
     { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); }
     break;
 
   case 1858:
-
-/* Line 1806 of yacc.c  */
-#line 12249 "gram.y"
+#line 12250 "gram.y"
     { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); }
     break;
 
   case 1859:
-
-/* Line 1806 of yacc.c  */
-#line 12250 "gram.y"
+#line 12251 "gram.y"
     { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); }
     break;
 
 
-
-/* Line 1806 of yacc.c  */
-#line 38206 "gram.c"
+/* Line 1267 of yacc.c.  */
+#line 34708 "gram.c"
       default: break;
     }
-  /* User semantic actions sometimes alter yychar, and that requires
-     that yytoken be updated with the new translation.  We take the
-     approach of translating immediately before every use of yytoken.
-     One alternative is translating here after every semantic action,
-     but that translation would be missed if the semantic action invokes
-     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
-     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
-     incorrect destructor might then be invoked immediately.  In the
-     case of YYERROR or YYBACKUP, subsequent parser actions might lead
-     to an incorrect destructor call or verbose syntax error message
-     before the lookahead is translated.  */
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
 
   YYPOPSTACK (yylen);
@@ -38244,10 +34735,6 @@ yyreduce:
 | yyerrlab -- here on detecting error |
 `------------------------------------*/
 yyerrlab:
-  /* Make sure we have latest lookahead translation.  See comments at
-     user semantic actions for why this is necessary.  */
-  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
-
   /* If not already recovering from an error, report this error.  */
   if (!yyerrstatus)
     {
@@ -38255,44 +34742,45 @@ yyerrlab:
 #if ! YYERROR_VERBOSE
       yyerror (&yylloc, yyscanner, YY_("syntax error"));
 #else
-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
-                                        yyssp, yytoken)
       {
-        char const *yymsgp = YY_("syntax error");
-        int yysyntax_error_status;
-        yysyntax_error_status = YYSYNTAX_ERROR;
-        if (yysyntax_error_status == 0)
-          yymsgp = yymsg;
-        else if (yysyntax_error_status == 1)
-          {
-            if (yymsg != yymsgbuf)
-              YYSTACK_FREE (yymsg);
-            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
-            if (!yymsg)
-              {
-                yymsg = yymsgbuf;
-                yymsg_alloc = sizeof yymsgbuf;
-                yysyntax_error_status = 2;
-              }
-            else
-              {
-                yysyntax_error_status = YYSYNTAX_ERROR;
-                yymsgp = yymsg;
-              }
-          }
-        yyerror (&yylloc, yyscanner, yymsgp);
-        if (yysyntax_error_status == 2)
-          goto yyexhaustedlab;
+	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+	  {
+	    YYSIZE_T yyalloc = 2 * yysize;
+	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
+	    if (yymsg != yymsgbuf)
+	      YYSTACK_FREE (yymsg);
+	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+	    if (yymsg)
+	      yymsg_alloc = yyalloc;
+	    else
+	      {
+		yymsg = yymsgbuf;
+		yymsg_alloc = sizeof yymsgbuf;
+	      }
+	  }
+
+	if (0 < yysize && yysize <= yymsg_alloc)
+	  {
+	    (void) yysyntax_error (yymsg, yystate, yychar);
+	    yyerror (&yylloc, yyscanner, yymsg);
+	  }
+	else
+	  {
+	    yyerror (&yylloc, yyscanner, YY_("syntax error"));
+	    if (yysize != 0)
+	      goto yyexhaustedlab;
+	  }
       }
-# undef YYSYNTAX_ERROR
 #endif
     }
 
-  yyerror_range[1] = yylloc;
+  yyerror_range[0] = yylloc;
 
   if (yyerrstatus == 3)
     {
-      /* If just tried and failed to reuse lookahead token after an
+      /* If just tried and failed to reuse look-ahead token after an
 	 error, discard it.  */
 
       if (yychar <= YYEOF)
@@ -38309,7 +34797,7 @@ yyerrlab:
 	}
     }
 
-  /* Else will try to reuse lookahead token after shifting the error
+  /* Else will try to reuse look-ahead token after shifting the error
      token.  */
   goto yyerrlab1;
 
@@ -38325,7 +34813,7 @@ yyerrorlab:
   if (/*CONSTCOND*/ 0)
      goto yyerrorlab;
 
-  yyerror_range[1] = yylsp[1-yylen];
+  yyerror_range[0] = yylsp[1-yylen];
   /* Do not reclaim the symbols of the rule which action triggered
      this YYERROR.  */
   YYPOPSTACK (yylen);
@@ -38344,7 +34832,7 @@ yyerrlab1:
   for (;;)
     {
       yyn = yypact[yystate];
-      if (!yypact_value_is_default (yyn))
+      if (yyn != YYPACT_NINF)
 	{
 	  yyn += YYTERROR;
 	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@@ -38359,7 +34847,7 @@ yyerrlab1:
       if (yyssp == yyss)
 	YYABORT;
 
-      yyerror_range[1] = *yylsp;
+      yyerror_range[0] = *yylsp;
       yydestruct ("Error: popping",
 		  yystos[yystate], yyvsp, yylsp, yyscanner);
       YYPOPSTACK (1);
@@ -38367,12 +34855,15 @@ yyerrlab1:
       YY_STACK_PRINT (yyss, yyssp);
     }
 
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
   *++yyvsp = yylval;
 
-  yyerror_range[2] = yylloc;
+  yyerror_range[1] = yylloc;
   /* Using YYLLOC is tempting, but would change the location of
-     the lookahead.  YYLOC is available though.  */
-  YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
+     the look-ahead.  YYLOC is available though.  */
+  YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
   *++yylsp = yyloc;
 
   /* Shift the error token.  */
@@ -38396,7 +34887,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#ifndef yyoverflow
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
 `-------------------------------------------------*/
@@ -38407,14 +34898,9 @@ yyexhaustedlab:
 #endif
 
 yyreturn:
-  if (yychar != YYEMPTY)
-    {
-      /* Make sure we have latest lookahead translation.  See comments at
-         user semantic actions for why this is necessary.  */
-      yytoken = YYTRANSLATE (yychar);
-      yydestruct ("Cleanup: discarding lookahead",
-                  yytoken, &yylval, &yylloc, yyscanner);
-    }
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval, &yylloc, yyscanner);
   /* Do not reclaim the symbols of the rule which action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
@@ -38438,9 +34924,7 @@ yyreturn:
 }
 
 
-
-/* Line 2067 of yacc.c  */
-#line 12703 "gram.y"
+#line 12704 "gram.y"
 
 
 /*
diff --git a/src/parser/gram.y b/src/parser/gram.y
index a6ca07d..e72ee72 100644
--- a/src/parser/gram.y
+++ b/src/parser/gram.y
@@ -48,7 +48,8 @@
  *-------------------------------------------------------------------------
  */
 #include "pool_parser.h"
-
+#include "utils/elog.h"
+#include "utils/palloc.h"
 #include <ctype.h>
 #include <limits.h>
 #include <stdio.h>
@@ -57,7 +58,7 @@
 
 #include "nodes.h"
 #include "keywords.h"
-#include "pool_memory.h"
+//#include "pool_memory.h"
 #include "gramparse.h"
 #include "makefuncs.h"
 #include "pool_string.h"
diff --git a/src/parser/list.c b/src/parser/list.c
index 2221d1a..7818e47 100644
--- a/src/parser/list.c
+++ b/src/parser/list.c
@@ -15,9 +15,9 @@
  *-------------------------------------------------------------------------
  */
 /*#include "postgres.h"*/
-
+#include "utils/elog.h"
 #include <stdlib.h>
-#include "pool_memory.h"
+#include "utils/palloc.h"
 #include "pg_list.h"
 
 
diff --git a/src/parser/makefuncs.c b/src/parser/makefuncs.c
index 13e7e89..69ff203 100644
--- a/src/parser/makefuncs.c
+++ b/src/parser/makefuncs.c
@@ -17,7 +17,7 @@
 #include "pool_parser.h"
 
 #include "makefuncs.h"
-#include "pool_memory.h"
+#include "utils/palloc.h"
 #include "pg_class.h"
 #include <stdlib.h>
 #include <string.h>
diff --git a/src/parser/outfuncs.c b/src/parser/outfuncs.c
index 219ec79..2064733 100644
--- a/src/parser/outfuncs.c
+++ b/src/parser/outfuncs.c
@@ -22,8 +22,8 @@
  */
 #include <string.h>
 #include <limits.h>
-
-#include "pool_memory.h"
+#include "pool_type.h"
+#include "utils/palloc.h"
 #include "parser.h"
 #include "pool_string.h"
 #include "pg_list.h"
@@ -196,7 +196,7 @@ static void _outCurrentOfExpr(String *str, CurrentOfExpr *node);
  * In most scenarios the list elements should always be Value strings,
  * but we also allow A_Star for the convenience of ColumnRef processing.
  */
-static String *NameListToString(List *names)
+String *NameListToString(List *names)
 {
 	String *str;
 	ListCell   *l;
diff --git a/src/parser/parser.c b/src/parser/parser.c
index 44a4c29..2528933 100644
--- a/src/parser/parser.c
+++ b/src/parser/parser.c
@@ -22,15 +22,14 @@
 
 #include <string.h>
 #include "pool_parser.h"
-#include "pool_memory.h"
+#include "utils/palloc.h"
 #include "gramparse.h"	/* required before parser/gram.h! */
 #include "gram.h"
 #include "parser.h"
 #include "pg_wchar.h"
-
+#include "utils/elog.h"
 
 List	   *parsetree;			/* result of parsing is left here */
-jmp_buf    jmpbuffer;
 int			server_version_num = 0;
 
 static pg_enc		server_encoding = PG_SQL_ASCII;
@@ -52,8 +51,9 @@ raw_parser(const char *str)
 	base_yy_extra_type yyextra;
 	int			yyresult;
 
-	if (pool_memory == NULL)
-		pool_memory = pool_memory_create(PARSER_BLOCK_SIZE);
+//	Do we need a seperate memory context here?
+//	if (pool_memory == NULL)
+//		pool_memory = pool_memory_create(PARSER_BLOCK_SIZE);
 
 	parsetree = NIL;			/* in case grammar forgets to set it */
 
@@ -66,30 +66,29 @@ raw_parser(const char *str)
 
 	/* initialize the bison parser */
 	parser_init(&yyextra);
-
 	in_parser_context = true;
-	if (setjmp(jmpbuffer) != 0)
+	PG_TRY();
 	{
+		yyresult = base_yyparse(yyscanner);
 		scanner_finish(yyscanner);
 		in_parser_context = false;
-		return NIL; /* error */
+		if (yyresult)				/* error */
+			return NIL;
+		return yyextra.parsetree;
 	}
-	else
+	PG_CATCH();
 	{
-		yyresult = base_yyparse(yyscanner);
-
 		scanner_finish(yyscanner);
-
 		in_parser_context = false;
-		if (yyresult)				/* error */
-			return NIL;
+		return NIL; /* error */
 	}
+	PG_END_TRY();
 	return yyextra.parsetree;
 }
 
 void free_parser(void)
 {
-	pool_memory_delete(pool_memory, 1);
+	//pool_memory_delete(pool_memory, 1);
 }
 
 /*
@@ -195,18 +194,6 @@ base_yylex(YYSTYPE *lvalp, YYLTYPE *llocp, core_yyscan_t yyscanner)
 }
 
 
-void
-pool_parser_error(int level, const char *file, int line)
-{
-#ifdef PARSER_DEBUG
-	fprintf(stderr, "error: %d %s %d\n", level, file, line);
-#endif
-	if (level < ERROR)
-		return;
-	if (in_parser_context)
-		longjmp(jmpbuffer, 1);
-}
-
 static int
 parse_version(const char *versionString)
 {
diff --git a/src/parser/pool_memory.c b/src/parser/pool_memory.c
deleted file mode 100644
index ab59f6b..0000000
--- a/src/parser/pool_memory.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/* -*-pgsql-c-*- */
-/*
- * $Header$
- *
- * pgpool: a language independent connection pool server for PostgreSQL 
- * written by Tatsuo Ishii
- *
- * Copyright (c) 2003-2012	PgPool Global Development Group
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of the
- * author not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. The author makes no representations about the
- * suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * pool_memory.c: Memory pooling module for SQL parser.
- *
- */
-
-#undef POOL_MEMORY_DEBUG
-
-#include "pool.h"
-#include "pool_memory.h"
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define ALIGN 3
-#define POOL_HEADER_SIZE (sizeof (POOL_CHUNK_HEADER))
-
-POOL_MEMORY_POOL *pool_memory = NULL;
-
-static int get_free_index(unsigned int size);
-
-static int get_free_index(unsigned int size)
-{
-	int idx = 0;
-
-	if (size > 0)
-	{
-		size = (size - 1) >> ALIGN;
-		while (size)
-		{
-			size >>= 1;
-			idx++;
-		}
-	}
-	return idx;
-}
-
-/*
- * pool_memory_alloc:
- *     Returns pointer to allocated memory of given size.
- */
-void *pool_memory_alloc(POOL_MEMORY_POOL *pool, unsigned int size)
-{
-	POOL_BLOCK *block;
-	POOL_CHUNK *chunk;
-
-#ifdef POOL_MEMORY_DEBUG
-	pool_log("pool_memory_alloc: pool:%p size:%d", pool, size);
-#endif
-
-	if ((size + POOL_HEADER_SIZE) > pool->blocksize)
-	{
-		block = malloc(sizeof(POOL_BLOCK));
-		if (block == NULL)
-		{
-			pool_error("pool_memory_alloc: malloc failed: %s", strerror(errno));
-			child_exit(1);
-		}
-		block->allocsize = block->size = size + POOL_HEADER_SIZE;
-		block->block = malloc(size + POOL_HEADER_SIZE);
-		if (block->block == NULL)
-		{
-			pool_error("pool_memory_alloc: malloc failed: %s", strerror(errno));
-			child_exit(1);
-		}
-		block->freepoint = block + (size + POOL_HEADER_SIZE);
-		chunk = block->block;
-		chunk->header.size = size + POOL_HEADER_SIZE;
-		block->next = pool->largeblocks;
-		pool->largeblocks = block;
-	}
-	else
-	{
-		int fidx = get_free_index(size + POOL_HEADER_SIZE);
-		int allocsize = 1 << (fidx + ALIGN);
-
-		/* pick up from freelist */
-		if (pool->freelist[fidx] != NULL)
-		{
-			chunk = pool->freelist[fidx];
-			pool->freelist[fidx] = chunk->header.next;
-			chunk->header.size = allocsize;
-			return chunk->data;
-		}
-		
-		block = pool->blocks;
-		if (block == NULL ||
-			block->freepoint + allocsize > block->block + block->size)
-		{
-			block = malloc(sizeof(POOL_BLOCK));
-			if (block == NULL)
-			{
-				pool_error("pool_memory_alloc: malloc failed: %s", strerror(errno));
-				child_exit(1);
-			}
-			block->size = pool->blocksize;
-			block->allocsize = 0;
-			block->block = malloc(pool->blocksize);
-			if (block->block == NULL)
-			{
-				pool_error("pool_memory_alloc: malloc failed: %s", strerror(errno));
-				child_exit(1);
-			}
-			block->freepoint = block->block;
-			block->next = pool->blocks;
-			pool->blocks = block;
-		}
-
-		block = pool->blocks;
-		chunk = block->freepoint;
-		block->freepoint += allocsize;
-		block->allocsize += allocsize;
-		chunk->header.size = allocsize;
-	}
-	return chunk->data;
-}
-
-
-/*
- * pool_memory_alloc_zero:
- *     Returns pointer to allocated memory of given size.
- *     The allocated memory is cleared.
- */
-void *pool_memory_alloc_zero(POOL_MEMORY_POOL *pool, unsigned int size)
-{
-	void *ptr = pool_memory_alloc(pool, size);
-	memset(ptr, 0, size);
-	return ptr;
-}
-
-/*
- * pool_memory_free:
- *    Frees allocated memory into memory pool.
- */
-void pool_memory_free(POOL_MEMORY_POOL *pool, void *ptr)
-{
-	POOL_CHUNK *chunk = ptr - POOL_HEADER_SIZE;
-	int fidx;
-
-#ifdef POOL_MEMORY_DEBUG
-	pool_log("pool_memory_free: pool:%p ptr:%p", pool, ptr);
-#endif
-
-	if (ptr == NULL)
-		return;
-
-	if (chunk->header.size > pool->blocksize)
-	{
-		POOL_BLOCK *block, *ptr = NULL;
-
-		for (block = pool->largeblocks; block; ptr = block, block = block->next)
-		{
-			if (block->block == chunk)
-				break;
-		}
-
-		if (block == NULL)
-		{
-			pool_log("An address \"%p\" does not exist in memory pool.", chunk);
-			return;
-		}
-
-		if (ptr == NULL)
-		{
-			pool->largeblocks = block->next;
-		}
-		else
-		{
-			ptr->next = block->next;
-		}
-		free(block->block);
-		free(block);
-	}
-	else
-	{
-		fidx = get_free_index(chunk->header.size);
-		chunk->header.next = pool->freelist[fidx];
-		pool->freelist[fidx] = chunk;
-	}
-}
-
-/*
- * pool_memory_realloc:
- *     Returns new pointer to allocated memory of given size.
- *     The new memory is copied from the old memory, and the old
- *     memory is freed.
- */
-void *pool_memory_realloc(POOL_MEMORY_POOL *pool, void *ptr, unsigned int size)
-{
-	int fidx;
-	void *p;
-	POOL_CHUNK *chunk = ptr - POOL_HEADER_SIZE;
-
-	if (size <= chunk->header.size - POOL_HEADER_SIZE)
-		return ptr;
-
-	fidx = get_free_index(size + POOL_HEADER_SIZE);
-	if (size + POOL_HEADER_SIZE <= pool->blocksize &&
-		chunk->header.size <= pool->blocksize &&
-		fidx == get_free_index(chunk->header.size))
-	{
-		return ptr;
-	}
-
-	p = pool_memory_alloc(pool, size);
-	memmove(p, ptr, chunk->header.size - POOL_HEADER_SIZE);
-	pool_memory_free(pool, ptr);
-
-	return p;
-}
-
-/*
- * pool_memory_create:
- *     Create a new memory pool.
- */
-POOL_MEMORY_POOL *pool_memory_create(int blocksize)
-{
-	POOL_MEMORY_POOL *pool;
-	int i;
-
-	pool = malloc(sizeof(POOL_MEMORY_POOL));
-	if (pool == NULL)
-	{
-		pool_error("pool_memory_create: malloc failed: %s", strerror(errno));
-		child_exit(1);
-	}
-
-#ifdef POOL_MEMORY_DEBUG
-	pool_log("pool_memory_create: blocksize: %d pool:%p", blocksize, pool);
-#endif
-
-	pool->blocks = NULL;
-	pool->largeblocks = NULL;
-	pool->blocksize = blocksize;
-	
-	for (i = 0; i < SLOT_NUM; i++)
-	{
-		pool->freelist[i] = NULL;
-	}
-
-	return pool;
-}
-
-/*
- * pool_memory_delete:
- *     Frees all memory which is allocated in the memory pool.
- */
-void pool_memory_delete(POOL_MEMORY_POOL *pool_memory, int reuse)
-{
-	POOL_BLOCK *block, *ptr;
-
-#ifdef POOL_MEMORY_DEBUG
-	pool_log("pool_memory_delete: pool:%p reuse:%d", pool_memory, reuse);
-#endif
-
-	/* Reuse the first memory block */
-	if (reuse && pool_memory->blocks)
-		block = pool_memory->blocks->next;
-	else
-		block = pool_memory->blocks;
-
-	while (block)
-	{
-		ptr = block->next;
-		free(block->block);
-		free(block);
-		block = ptr;
-	}
-
-	for (block = pool_memory->largeblocks; block;)
-	{
-		ptr = block->next;
-		free(block->block);
-		free(block);
-		block = ptr;
-	}
-
-	if (reuse)
-	{
-		int i;
-
-		if (pool_memory->blocks)
-		{
-			pool_memory->blocks->next = NULL;
-			pool_memory->blocks->allocsize = 0;
-			pool_memory->blocks->freepoint = pool_memory->blocks->block;
-		}
-		pool_memory->largeblocks = NULL;
-		for (i = 0; i < SLOT_NUM; i++)
-		{
-			pool_memory->freelist[i] = NULL;
-		}
-	}
-	else
-	{
-		free(pool_memory);
-		pool_memory = NULL;
-	}
-}
-
-/*
- * pool_memory_strdup:
- *     Creates the new string which is copied the given string.
- */
-char *pool_memory_strdup(POOL_MEMORY_POOL *pool_memory, const char *string)
-{
-	int len = strlen(string);
-	char *str = pool_memory_alloc(pool_memory, len + 1);
-
-	memmove(str, string, len);
-	str[len] = '\0';
-	return str;
-}
-
-/*
- * Switch memory context from pool_memory to pm
- */
-POOL_MEMORY_POOL *pool_memory_context_switch_to(POOL_MEMORY_POOL *pm)
-{
-	POOL_MEMORY_POOL *old = pool_memory;
-	pool_memory = pm;
-	return old;
-}
-
diff --git a/src/parser/pool_string.c b/src/parser/pool_string.c
index 1979e6e..a275fdb 100644
--- a/src/parser/pool_string.c
+++ b/src/parser/pool_string.c
@@ -22,7 +22,7 @@
 #include <string.h>
 #include <stdlib.h>
 
-#include "pool_memory.h"
+#include "utils/palloc.h"
 #include "pool_string.h"
 #include "value.h"
 
diff --git a/src/parser/scan.c b/src/parser/scan.c
index 4f87b0f..bd73091 100644
--- a/src/parser/scan.c
+++ b/src/parser/scan.c
@@ -47,6 +47,7 @@ typedef int16_t flex_int16_t;
 typedef uint16_t flex_uint16_t;
 typedef int32_t flex_int32_t;
 typedef uint32_t flex_uint32_t;
+typedef uint64_t flex_uint64_t;
 #else
 typedef signed char flex_int8_t;
 typedef short int flex_int16_t;
@@ -54,6 +55,7 @@ typedef int flex_int32_t;
 typedef unsigned char flex_uint8_t; 
 typedef unsigned short int flex_uint16_t;
 typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
 
 /* Limits of integral types. */
 #ifndef INT8_MIN
@@ -84,8 +86,6 @@ typedef unsigned int flex_uint32_t;
 #define UINT32_MAX             (4294967295U)
 #endif
 
-#endif /* ! C99 */
-
 #endif /* ! FLEXINT_H */
 
 #ifdef __cplusplus
@@ -159,15 +159,7 @@ typedef void* yyscan_t;
 
 /* Size of default input buffer. */
 #ifndef YY_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k.
- * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
- * Ditto for the __ia64__ case accordingly.
- */
-#define YY_BUF_SIZE 32768
-#else
 #define YY_BUF_SIZE 16384
-#endif /* __ia64__ */
 #endif
 
 /* The state buf must be large enough to hold one state per character in the main buffer.
@@ -179,6 +171,11 @@ typedef void* yyscan_t;
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
 #endif
 
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
 #define EOB_ACT_CONTINUE_SCAN 0
 #define EOB_ACT_END_OF_FILE 1
 #define EOB_ACT_LAST_MATCH 2
@@ -201,11 +198,6 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE;
 
 #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
 
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
@@ -223,7 +215,7 @@ struct yy_buffer_state
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 */
-	int yy_n_chars;
+	yy_size_t yy_n_chars;
 
 	/* Whether we "own" the buffer - i.e., we know we created it,
 	 * and can realloc() it to grow it, and should free() it to
@@ -302,7 +294,7 @@ static void core_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanne
 
 YY_BUFFER_STATE core_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
 YY_BUFFER_STATE core_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE core_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+YY_BUFFER_STATE core_yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );
 
 void *core_yyalloc (yy_size_t ,yyscan_t yyscanner );
 void *core_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
@@ -353,7 +345,7 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
  */
 #define YY_DO_BEFORE_ACTION \
 	yyg->yytext_ptr = yy_bp; \
-	yyleng = (size_t) (yy_cp - yy_bp); \
+	yyleng = (yy_size_t) (yy_cp - yy_bp); \
 	yyg->yy_hold_char = *yy_cp; \
 	*yy_cp = '\0'; \
 	yyg->yy_c_buf_p = yy_cp;
@@ -1078,16 +1070,16 @@ static yyconst flex_int16_t yy_chk[2067] =
 #include "scanner.h"
 #include "scansup.h"
 
-#include "pool_memory.h"
+#include "utils/palloc.h"
 #include "pg_wchar.h"
 
 
 
-
+#ifdef nouse
 /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
 #undef fprintf
 #define fprintf(file, fmt, msg)  ereport(ERROR, (errmsg_internal("%s", msg)))
-
+#endif
 /*
  * GUC variables.  This is a DIRECT violation of the warning given at the
  * head of gram.y, ie flex/bison code must not depend on any GUC variables;
@@ -1298,7 +1290,7 @@ extern void core_yyset_column(int column_no, yyscan_t yyscanner);
  * Note that xcstart must appear before operator, as explained above!
  *  Also whitespace (comment) must appear before operator.
  */
-#line 1302 "scan.c"
+#line 1294 "scan.c"
 
 #define INITIAL 0
 #define xb 1
@@ -1337,8 +1329,8 @@ struct yyguts_t
     size_t yy_buffer_stack_max; /**< capacity of stack. */
     YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
     char yy_hold_char;
-    int yy_n_chars;
-    int yyleng_r;
+    yy_size_t yy_n_chars;
+    yy_size_t yyleng_r;
     char *yy_c_buf_p;
     int yy_init;
     int yy_start;
@@ -1395,7 +1387,7 @@ FILE *core_yyget_out (yyscan_t yyscanner );
 
 void core_yyset_out  (FILE * out_str ,yyscan_t yyscanner );
 
-int core_yyget_leng (yyscan_t yyscanner );
+yy_size_t core_yyget_leng (yyscan_t yyscanner );
 
 char *core_yyget_text (yyscan_t yyscanner );
 
@@ -1443,12 +1435,7 @@ static int input (yyscan_t yyscanner );
 
 /* Amount of stuff to slurp up with each read. */
 #ifndef YY_READ_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k */
-#define YY_READ_BUF_SIZE 16384
-#else
 #define YY_READ_BUF_SIZE 8192
-#endif /* __ia64__ */
 #endif
 
 /* Copy whatever the last rule matched to the standard output. */
@@ -1456,7 +1443,7 @@ static int input (yyscan_t yyscanner );
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -1467,7 +1454,7 @@ static int input (yyscan_t yyscanner );
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
 		{ \
 		int c = '*'; \
-		size_t n; \
+		yy_size_t n; \
 		for ( n = 0; n < max_size && \
 			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
 			buf[n] = (char) c; \
@@ -1555,7 +1542,7 @@ YY_DECL
 #line 381 "scan.l"
 
 
-#line 1559 "scan.c"
+#line 1546 "scan.c"
 
     yylval = yylval_param;
 
@@ -2471,7 +2458,7 @@ YY_RULE_SETUP
 #line 938 "scan.l"
 YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 2475 "scan.c"
+#line 2462 "scan.c"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -2657,7 +2644,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 
 	else
 		{
-			int num_to_read =
+			yy_size_t num_to_read =
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 
 		while ( num_to_read <= 0 )
@@ -2671,7 +2658,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 
 			if ( b->yy_is_our_buffer )
 				{
-				int new_size = b->yy_buf_size * 2;
+				yy_size_t new_size = b->yy_buf_size * 2;
 
 				if ( new_size <= 0 )
 					b->yy_buf_size += b->yy_buf_size / 8;
@@ -2702,7 +2689,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 
 		/* Read in more data. */
 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			yyg->yy_n_chars, (size_t) num_to_read );
+			yyg->yy_n_chars, num_to_read );
 
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
 		}
@@ -2827,7 +2814,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 
 		else
 			{ /* need more input */
-			int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+			yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
 			++yyg->yy_c_buf_p;
 
 			switch ( yy_get_next_buffer( yyscanner ) )
@@ -2851,7 +2838,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 				case EOB_ACT_END_OF_FILE:
 					{
 					if ( core_yywrap(yyscanner ) )
-						return EOF;
+						return 0;
 
 					if ( ! yyg->yy_did_buffer_switch_on_eof )
 						YY_NEW_FILE;
@@ -3107,7 +3094,7 @@ void core_yypop_buffer_state (yyscan_t yyscanner)
  */
 static void core_yyensure_buffer_stack (yyscan_t yyscanner)
 {
-	int num_to_alloc;
+	yy_size_t num_to_alloc;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
 	if (!yyg->yy_buffer_stack) {
@@ -3200,17 +3187,16 @@ YY_BUFFER_STATE core_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
 
 /** Setup the input buffer state to scan the given bytes. The next call to core_yylex() will
  * scan from a @e copy of @a bytes.
- * @param yybytes the byte buffer to scan
- * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
  * @param yyscanner The scanner object.
  * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE core_yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len , yyscan_t yyscanner)
+YY_BUFFER_STATE core_yy_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len , yyscan_t yyscanner)
 {
 	YY_BUFFER_STATE b;
 	char *buf;
-	yy_size_t n;
-	int i;
+	yy_size_t n, i;
     
 	/* Get memory for full buffer, including space for trailing EOB's. */
 	n = _yybytes_len + 2;
@@ -3320,7 +3306,7 @@ FILE *core_yyget_out  (yyscan_t yyscanner)
 /** Get the length of the current token.
  * @param yyscanner The scanner object.
  */
-int core_yyget_leng  (yyscan_t yyscanner)
+yy_size_t core_yyget_leng  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
     return yyleng;
diff --git a/src/parser/scan.l b/src/parser/scan.l
index acae7ff..3495542 100644
--- a/src/parser/scan.l
+++ b/src/parser/scan.l
@@ -43,16 +43,16 @@
 #include "scanner.h"
 #include "scansup.h"
 
-#include "pool_memory.h"
+#include "utils/palloc.h"
 #include "pg_wchar.h"
 
 
 
-
+#ifdef nouse
 /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
 #undef fprintf
 #define fprintf(file, fmt, msg)  ereport(ERROR, (errmsg_internal("%s", msg)))
-
+#endif
 /*
  * GUC variables.  This is a DIRECT violation of the warning given at the
  * head of gram.y, ie flex/bison code must not depend on any GUC variables;
diff --git a/src/parser/scansup.c b/src/parser/scansup.c
index 837a8e9..a82eef0 100644
--- a/src/parser/scansup.c
+++ b/src/parser/scansup.c
@@ -15,7 +15,7 @@
  *-------------------------------------------------------------------------
  */
 #include "pool_parser.h"
-#include "pool_memory.h"
+#include "utils/palloc.h"
 
 #include <ctype.h>
 #include <string.h>
diff --git a/src/parser/snprintf.c b/src/parser/snprintf.c
index ff657f6..62f48a3 100644
--- a/src/parser/snprintf.c
+++ b/src/parser/snprintf.c
@@ -51,9 +51,9 @@
 #include <string.h>
 #include <ctype.h>
 #include <errno.h>
-#include "pool_memory.h"
 #include "pool_parser.h"
 #include "stringinfo.h"
+#include "utils/palloc.h"
 
 /* --------------------------------------------------------------------- */
 /* c.h                                                                   */
diff --git a/src/parser/stringinfo.c b/src/parser/stringinfo.c
index 3528397..58ae2cc 100644
--- a/src/parser/stringinfo.c
+++ b/src/parser/stringinfo.c
@@ -18,7 +18,7 @@
 #include <stdarg.h>
 #include "pool_type.h"
 #include "stringinfo.h"
-#include "pool_memory.h"
+#include "utils/palloc.h"
 
 /*
  * makeStringInfo
diff --git a/src/parser/value.c b/src/parser/value.c
index d2fd1a6..70c75bb 100644
--- a/src/parser/value.c
+++ b/src/parser/value.c
@@ -16,8 +16,8 @@
 /*#include "postgres.h"*/
 
 #include <stdlib.h>
-#include "pool_memory.h"
 #include "parsenodes.h"
+#include "utils/palloc.h"
 
 /*
  *	makeInteger
diff --git a/src/parser/wchar.c b/src/parser/wchar.c
index dccce4f..634c10e 100644
--- a/src/parser/wchar.c
+++ b/src/parser/wchar.c
@@ -6,10 +6,114 @@
  */
 /* can be used in either frontend or backend */
 #include "pool_parser.h"
+#include "utils/elog.h"
 #include <stdio.h>
 #include <string.h>
 #include "pg_wchar.h"
 
+#ifndef WIN32
+#define DEF_ENC2NAME(name, codepage) { #name, PG_##name }
+#else
+#define DEF_ENC2NAME(name, codepage) { #name, PG_##name, codepage }
+#endif
+
+pg_enc2name pg_enc2name_tbl[] =
+{
+	DEF_ENC2NAME(SQL_ASCII, 0),
+	DEF_ENC2NAME(EUC_JP, 20932),
+	DEF_ENC2NAME(EUC_CN, 20936),
+	DEF_ENC2NAME(EUC_KR, 51949),
+	DEF_ENC2NAME(EUC_TW, 0),
+	DEF_ENC2NAME(EUC_JIS_2004, 20932),
+	DEF_ENC2NAME(UTF8, 65001),
+	DEF_ENC2NAME(MULE_INTERNAL, 0),
+	DEF_ENC2NAME(LATIN1, 28591),
+	DEF_ENC2NAME(LATIN2, 28592),
+	DEF_ENC2NAME(LATIN3, 28593),
+	DEF_ENC2NAME(LATIN4, 28594),
+	DEF_ENC2NAME(LATIN5, 28599),
+	DEF_ENC2NAME(LATIN6, 0),
+	DEF_ENC2NAME(LATIN7, 0),
+	DEF_ENC2NAME(LATIN8, 0),
+	DEF_ENC2NAME(LATIN9, 28605),
+	DEF_ENC2NAME(LATIN10, 0),
+	DEF_ENC2NAME(WIN1256, 1256),
+	DEF_ENC2NAME(WIN1258, 1258),
+	DEF_ENC2NAME(WIN866, 866),
+	DEF_ENC2NAME(WIN874, 874),
+	DEF_ENC2NAME(KOI8R, 20866),
+	DEF_ENC2NAME(WIN1251, 1251),
+	DEF_ENC2NAME(WIN1252, 1252),
+	DEF_ENC2NAME(ISO_8859_5, 28595),
+	DEF_ENC2NAME(ISO_8859_6, 28596),
+	DEF_ENC2NAME(ISO_8859_7, 28597),
+	DEF_ENC2NAME(ISO_8859_8, 28598),
+	DEF_ENC2NAME(WIN1250, 1250),
+	DEF_ENC2NAME(WIN1253, 1253),
+	DEF_ENC2NAME(WIN1254, 1254),
+	DEF_ENC2NAME(WIN1255, 1255),
+	DEF_ENC2NAME(WIN1257, 1257),
+	DEF_ENC2NAME(KOI8U, 21866),
+	DEF_ENC2NAME(SJIS, 932),
+	DEF_ENC2NAME(BIG5, 950),
+	DEF_ENC2NAME(GBK, 936),
+	DEF_ENC2NAME(UHC, 0),
+	DEF_ENC2NAME(GB18030, 54936),
+	DEF_ENC2NAME(JOHAB, 0),
+	DEF_ENC2NAME(SHIFT_JIS_2004, 932)
+};
+
+/* ----------
+ * These are encoding names for gettext.
+ *
+ * This covers all encodings except MULE_INTERNAL, which is alien to gettext.
+ * ----------
+ */
+pg_enc2gettext pg_enc2gettext_tbl[] =
+{
+	{PG_SQL_ASCII, "US-ASCII"},
+	{PG_UTF8, "UTF-8"},
+	{PG_LATIN1, "LATIN1"},
+	{PG_LATIN2, "LATIN2"},
+	{PG_LATIN3, "LATIN3"},
+	{PG_LATIN4, "LATIN4"},
+	{PG_ISO_8859_5, "ISO-8859-5"},
+	{PG_ISO_8859_6, "ISO_8859-6"},
+	{PG_ISO_8859_7, "ISO-8859-7"},
+	{PG_ISO_8859_8, "ISO-8859-8"},
+	{PG_LATIN5, "LATIN5"},
+	{PG_LATIN6, "LATIN6"},
+	{PG_LATIN7, "LATIN7"},
+	{PG_LATIN8, "LATIN8"},
+	{PG_LATIN9, "LATIN-9"},
+	{PG_LATIN10, "LATIN10"},
+	{PG_KOI8R, "KOI8-R"},
+	{PG_KOI8U, "KOI8-U"},
+	{PG_WIN1250, "CP1250"},
+	{PG_WIN1251, "CP1251"},
+	{PG_WIN1252, "CP1252"},
+	{PG_WIN1253, "CP1253"},
+	{PG_WIN1254, "CP1254"},
+	{PG_WIN1255, "CP1255"},
+	{PG_WIN1256, "CP1256"},
+	{PG_WIN1257, "CP1257"},
+	{PG_WIN1258, "CP1258"},
+	{PG_WIN866, "CP866"},
+	{PG_WIN874, "CP874"},
+	{PG_EUC_CN, "EUC-CN"},
+	{PG_EUC_JP, "EUC-JP"},
+	{PG_EUC_KR, "EUC-KR"},
+	{PG_EUC_TW, "EUC-TW"},
+	{PG_EUC_JIS_2004, "EUC-JP"},
+	{PG_SJIS, "SHIFT-JIS"},
+	{PG_BIG5, "BIG5"},
+	{PG_GBK, "GBK"},
+	{PG_UHC, "UHC"},
+	{PG_GB18030, "GB18030"},
+	{PG_JOHAB, "JOHAB"},
+	{PG_SHIFT_JIS_2004, "SHIFT_JISX0213"},
+	{0, NULL}
+};
 
 /*
  * conversion to pg_wchar is done by "table driven."
diff --git a/src/pcp_con/pcp_child.c b/src/pcp_con/pcp_child.c
index 1d61fb4..8f9d6a8 100644
--- a/src/pcp_con/pcp_child.c
+++ b/src/pcp_con/pcp_child.c
@@ -22,6 +22,9 @@
  *
  */
 #include "config.h"
+#include "pool.h"
+#include "utils/palloc.h"
+#include "utils/memutils.h"
 
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -57,6 +60,7 @@
 #include "context/pool_process_context.h"
 #include "utils/pool_process_reporting.h"
 #include "watchdog/wd_ext.h"
+#include "utils/elog.h"
 
 #define MAX_FILE_LINE_LEN    512
 #define MAX_USER_PASSWD_LEN  128
@@ -81,6 +85,26 @@ static volatile sig_atomic_t pcp_got_sighup = 0;
 volatile sig_atomic_t pcp_wakeup_request = 0;
 static volatile sig_atomic_t pcp_restart_request = 0;
 
+static void  do_pcp_flush(PCP_CONNECTION *frontend);
+
+static void inform_process_count(PCP_CONNECTION *frontend);
+static void inform_process_info(PCP_CONNECTION *frontend, char *buf);
+static void inform_systemDB_info(PCP_CONNECTION *frontend);
+static void inform_watchdog_info(PCP_CONNECTION *frontend, char *buf);
+static void inform_node_info(PCP_CONNECTION *frontend, char *buf);
+static void inform_node_count(PCP_CONNECTION *frontend);
+static void process_detach_node(PCP_CONNECTION *frontend,char *buf,char tos);
+static void process_attach_node(PCP_CONNECTION *frontend,char *buf);
+static void process_recovery_request(PCP_CONNECTION *frontend,char *buf);
+static void process_status_request(PCP_CONNECTION *frontend);
+static void process_promote_node(PCP_CONNECTION *frontend,char *buf, char tos);
+static void process_shutown_request(char mode);
+
+static void process_authentication(PCP_CONNECTION *frontend, char *buf, char *pcp_conf_file,
+				char* salt, int *random_salt, int *authenticated);
+static void send_md5salt(PCP_CONNECTION *frontend, char* salt);
+
+
 #define CHECK_RESTART_REQUEST \
 	do { \
 		if (pcp_restart_request) \
@@ -97,12 +121,14 @@ static volatile sig_atomic_t pcp_restart_request = 0;
 void
 pcp_do_child(int unix_fd, int inet_fd, char *pcp_conf_file)
 {
+	sigjmp_buf	local_sigjmp_buf;
+	MemoryContext PCPMemoryContext;
+
 	PCP_CONNECTION *frontend = NULL;
 	int authenticated = 0;
 	struct timeval uptime;
 	char salt[4];
 	int random_salt = 0;
-	int i;
 	char tos;
 	int rsize;
 	char *buf = NULL;
@@ -128,6 +154,14 @@ pcp_do_child(int unix_fd, int inet_fd, char *pcp_conf_file)
 	signal(SIGUSR2, wakeup_handler);
 	signal(SIGPIPE, SIG_IGN);
 	signal(SIGALRM, SIG_IGN);
+	/* Create per loop iteration memory context */
+	PCPMemoryContext = AllocSetContextCreate(TopMemoryContext,
+											  "PCP_main_loop",
+											  ALLOCSET_DEFAULT_MINSIZE,
+											  ALLOCSET_DEFAULT_INITSIZE,
+											  ALLOCSET_DEFAULT_MAXSIZE);
+
+	MemoryContextSwitchTo(TopMemoryContext);
 
 	/* Initialize my backend status */
 	pool_initialize_private_backend_status();
@@ -135,8 +169,26 @@ pcp_do_child(int unix_fd, int inet_fd, char *pcp_conf_file)
 	/* Initialize process context */
 	pool_init_process_context();
 
+	if (sigsetjmp(local_sigjmp_buf, 1) != 0)
+	{
+		pool_signal(SIGALRM, SIG_IGN);
+		if(frontend)
+			pcp_close(frontend);
+		frontend = NULL;
+		authenticated = 0;
+		error_context_stack = NULL;
+		EmitErrorReport();
+		MemoryContextSwitchTo(TopMemoryContext);
+		FlushErrorState();
+	}
+	/* We can now handle ereport(ERROR) */
+	PG_exception_stack = &local_sigjmp_buf;
+
 	for(;;)
 	{
+		MemoryContextSwitchTo(PCPMemoryContext);
+		MemoryContextResetAndDeleteChildren(PCPMemoryContext);
+
 		errno = 0;
 
 		CHECK_RESTART_REQUEST;
@@ -155,63 +207,51 @@ pcp_do_child(int unix_fd, int inet_fd, char *pcp_conf_file)
 		{
 			if (errorcode == TIMEOUTERR)
 			{
-				pool_debug("pcp_child: pcp_read() has timed out");
-				authenticated = 0;
-				pcp_close(frontend); frontend = NULL;
-				free(buf); buf = NULL;
-				continue;
+				ereport(ERROR,
+					(errmsg("unable to read from client"),
+						errdetail("pcp_read time out")));
 			}
-			pool_error("pcp_child: pcp_read() failed. reason: %s", strerror(errno));
-			exit(1);
+			ereport(FATAL,
+				(errmsg("unable to read from client"),
+					errdetail("pcp_read failed with error : \"%s\"",strerror(errno))));
+
 		}
 		if (pcp_read(frontend, &rsize, sizeof(int)))
 		{
 			if (errorcode == TIMEOUTERR)
 			{
-				pool_debug("pcp_child: pcp_read() has timed out");
-				authenticated = 0;
-				pcp_close(frontend); frontend = NULL;
-				free(buf); buf = NULL;
-				continue;
+				ereport(ERROR,
+					(errmsg("unable to read from client"),
+						errdetail("pcp_read time out")));
 			}
-			pool_error("pcp_child: pcp_read() failed. reason: %s", strerror(errno));
-			exit(1);
+			ereport(FATAL,
+				(errmsg("unable to read from client"),
+					errdetail("pcp_read failed with error : \"%s\"",strerror(errno))));
 		}
 
 		rsize = ntohl(rsize);
 		if ((rsize - sizeof(int)) > 0)
 		{
-			buf = (char *)malloc(rsize - sizeof(int));
-			if (buf == NULL)
-			{
-				pool_error("pcp_child: malloc() failed. reason: %s", strerror(errno));
-				exit(1);
-			}
+			buf = (char *)palloc(rsize - sizeof(int));
 			if (pcp_read(frontend, buf, rsize - sizeof(int)))
 			{
 				if (errorcode == TIMEOUTERR)
 				{
-					pool_debug("pcp_child: pcp_read() has timed out");
-					authenticated = 0;
-					pcp_close(frontend); frontend = NULL;
-					free(buf); buf = NULL;
-					continue;
+					ereport(ERROR,
+						(errmsg("unable to read from client"),
+							errdetail("pcp_read time out")));
 				}
-				pool_error("pcp_child: pcp_read() failed. reason: %s", strerror(errno));
-				exit(1);
+				ereport(FATAL,
+					(errmsg("unable to read from client"),
+						errdetail("pcp_read failed with error : \"%s\"",strerror(errno))));
 			}
 		}
 
 		/* is this connection authenticated? if not disconnect immediately*/
 		if ((! authenticated) && (tos != 'R' && tos != 'M'))
 		{
-			pool_debug("pcp_child: connection not authorized");
-			free(buf);
-			buf = NULL;
-			pcp_close(frontend);
-			frontend = NULL;
-			pool_signal(SIGALRM, SIG_IGN);
-			continue;
+			ereport(ERROR,
+				(errmsg("connection not authorized")));
 		}
 
 		/* process a request */
@@ -248,874 +288,56 @@ pcp_do_child(int unix_fd, int inet_fd, char *pcp_conf_file)
 		switch (tos)
 		{
 			case 'R':			/* authentication */
-			{
-				int wsize;
-
-				if (random_salt)
-				{
-					authenticated = user_authenticate(buf, pcp_conf_file, salt, 4);
-				}
-				if (!random_salt || !authenticated)
-				{
-					char code[] = "AuthenticationFailed";
-					char mesg[] = "username and/or password do not match";
-					pcp_write(frontend, "r", 1);
-					wsize = htonl(sizeof(code) + sizeof(mesg) + sizeof(int));
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, code, sizeof(code));
-					pcp_write(frontend, mesg, sizeof(mesg));
-					if (pcp_flush(frontend) < 0)
-					{
-						pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-						exit(1);
-					}
-
-					pool_error("pcp_child: authentication failed");
-					pcp_close(frontend);
-					frontend = NULL;
-					random_salt = 0;
-				}
-				else
-				{
-					char code[] = "AuthenticationOK";
-					pcp_write(frontend, "r", 1);
-					wsize = htonl(sizeof(code) + sizeof(int));
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, code, sizeof(code));
-					if (pcp_flush(frontend) < 0)
-					{
-						pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-						exit(1);
-					}
-					random_salt = 0;
-
-					pool_debug("pcp_child: authentication OK");
-				}
+				process_authentication(frontend, buf, pcp_conf_file,
+					salt, &random_salt, &authenticated);
 				break;
-			}
 
 			case 'M':			/* md5 salt */
-			{
-				int wsize;
-
-				pool_random_salt(salt);
+				send_md5salt(frontend, salt);
 				random_salt = 1;
-
-				pcp_write(frontend, "m", 1);
-				wsize = htonl(sizeof(int) + 4);
-				pcp_write(frontend, &wsize, sizeof(int));
-				pcp_write(frontend, salt, 4);
-				if (pcp_flush(frontend) < 0)
-				{
-					pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-					exit(1);
-				}
-
-				pool_debug("pcp_child: salt sent to the client");
 				break;
-			}
 
 			case 'L':			/* node count */
-			{
-				int wsize;
-				int node_count = pool_get_node_count();
-
-				char code[] = "CommandComplete";
-				char mesg[16];
-
-				snprintf(mesg, sizeof(mesg), "%d", node_count);
-
-				pcp_write(frontend, "l", 1);
-				wsize = htonl(sizeof(code) +
-							  strlen(mesg)+1 +
-							  sizeof(int));
-				pcp_write(frontend, &wsize, sizeof(int));
-				pcp_write(frontend, code, sizeof(code));
-				pcp_write(frontend, mesg, strlen(mesg)+1);
-				if (pcp_flush(frontend) < 0)
-				{
-					pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-					exit(1);
-				}
-
-				pool_debug("pcp_child: %d node(s) found", node_count);
+				inform_node_count(frontend);
 				break;
-			}
 			case 'I':			/* node info */
-			{
-				int node_id;
-				int wsize;
-
-				BackendInfo *bi = NULL;
-
-				node_id = atoi(buf);
-				bi = pool_get_node_info(node_id);
-
-				if (bi == NULL) {
-					char code[] = "Invalid Node ID";
-
-					pcp_write(frontend, "e", 1);
-					wsize = htonl(sizeof(code) + sizeof(int));
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, code, sizeof(code));
-					if (pcp_flush(frontend) < 0)
-					{
-						pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-						exit(1);
-					}
-
-					pool_debug("pcp_child: invalid node ID");
-				}
-				else
-				{
-					char code[] = "CommandComplete";
-					char port_str[6];
-					char status[2];
-					char weight_str[20];
-
-					snprintf(port_str, sizeof(port_str), "%d", bi->backend_port);
-					snprintf(status, sizeof(status), "%d", bi->backend_status);
-					snprintf(weight_str, sizeof(weight_str), "%f", bi->backend_weight);
-
-					pcp_write(frontend, "i", 1);
-					wsize = htonl(sizeof(code) +
-								  strlen(bi->backend_hostname)+1 +
-								  strlen(port_str)+1 +
-								  strlen(status)+1 +
-								  strlen(weight_str)+1 +
-								  sizeof(int));
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, code, sizeof(code));
-					pcp_write(frontend, bi->backend_hostname, strlen(bi->backend_hostname)+1);
-					pcp_write(frontend, port_str, strlen(port_str)+1);
-					pcp_write(frontend, status, strlen(status)+1);
-					pcp_write(frontend, weight_str, strlen(weight_str)+1);
-					if (pcp_flush(frontend) < 0)
-					{
-						pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-						exit(1);
-					}
-
-					pool_debug("pcp_child: retrieved node information from shared memory");
-				}
+				inform_node_info(frontend, buf);
 				break;
-			}
-
 			case 'N':			/* process count */
-			{
-				int wsize;
-				int process_count;
-				char process_count_str[16];
-				int *process_list = NULL;
-				char code[] = "CommandComplete";
-				char *mesg = NULL;
-				int i;
-				int total_port_len = 0;
-
-				process_list = pool_get_process_list(&process_count);
-
-				mesg = (char *)malloc(6*process_count);	/* port# is at most 5 characters long (MAX:65535) */
-				if (mesg == NULL)
-				{
-					pool_error("pcp_child: malloc() failed. reason: %s", strerror(errno));
-					exit(1);
-				}
-
-				snprintf(process_count_str, sizeof(process_count_str), "%d", process_count);
-
-				for (i = 0; i < process_count; i++)
-				{
-					char port[6];
-					snprintf(port, sizeof(port), "%d", process_list[i]);
-					snprintf(mesg+total_port_len, strlen(port)+1, "%s", port);
-					total_port_len += strlen(port)+1;
-				}
-
-				pcp_write(frontend, "n", 1);
-				wsize = htonl(sizeof(code) +
-							  strlen(process_count_str)+1 +
-							  total_port_len +
-							  sizeof(int));
-				pcp_write(frontend, &wsize, sizeof(int));
-				pcp_write(frontend, code, sizeof(code));
-				pcp_write(frontend, process_count_str, strlen(process_count_str)+1);
-				pcp_write(frontend, mesg, total_port_len);
-				if (pcp_flush(frontend) < 0)
-				{
-					pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-					exit(1);
-				}
-
-				free(process_list);
-				free(mesg);
-
-				pool_debug("pcp_child: %d process(es) found", process_count);
+				inform_process_count(frontend);
 				break;
-			}
-
 			case 'P':			/* process info */
-			{
-				int proc_id;
-				int wsize;
-				int num_proc = pool_config->num_init_children;
-				int i;
-
-				proc_id = atoi(buf);
-
-				if ((proc_id != 0) && (pool_get_process_info(proc_id) == NULL))
-				{
-					char code[] = "InvalidProcessID";
-
-					pcp_write(frontend, "e", 1);
-					wsize = htonl(sizeof(code) + sizeof(int));
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, code, sizeof(code));
-					if (pcp_flush(frontend) < 0)
-					{
-						pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-						exit(1);
-					}
-
-					pool_debug("pcp_child: invalid process ID");
-				}
-				else
-				{
-					/* First, send array size of connection_info */
-					char arr_code[] = "ArraySize";
-					char con_info_size[16];
-					/* Finally, indicate that all data is sent */
-					char fin_code[] = "CommandComplete";
-
-					POOL_REPORT_POOLS *pools = get_pools(&num_proc);
-
-					if (proc_id == 0)
-					{
-						snprintf(con_info_size, sizeof(con_info_size), "%d", num_proc);
-					}
-					else
-					{
-						snprintf(con_info_size, sizeof(con_info_size), "%d", pool_config->max_pool * NUM_BACKENDS);
-					}
-
-					pcp_write(frontend, "p", 1);
-					wsize = htonl(sizeof(arr_code) +
-								  strlen(con_info_size)+1 +
-								  sizeof(int));
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, arr_code, sizeof(arr_code));
-					pcp_write(frontend, con_info_size, strlen(con_info_size)+1);
-					if (pcp_flush(frontend) < 0)
-					{
-						pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-						free(pools);
-						exit(1);
-					}
-
-					/* Second, send process information for all connection_info */
-					for (i=0; i<num_proc; i++)
-					{
-						char code[] = "ProcessInfo";
-						char proc_pid[16];
-						char proc_start_time[20];
-						char proc_create_time[20];
-						char majorversion[5];
-						char minorversion[5];
-						char pool_counter[16];
-						char backend_id[16];
-						char backend_pid[16];
-						char connected[2];
-
-						if (proc_id != 0 && proc_id != pools[i].pool_pid) continue;
-
-						snprintf(proc_pid, sizeof(proc_pid), "%d", pools[i].pool_pid);
-						snprintf(proc_start_time, sizeof(proc_start_time), "%ld", pools[i].start_time);
-						snprintf(proc_create_time, sizeof(proc_create_time), "%ld", pools[i].create_time);
-						snprintf(majorversion, sizeof(majorversion), "%d", pools[i].pool_majorversion);
-						snprintf(minorversion, sizeof(minorversion), "%d", pools[i].pool_minorversion);
-						snprintf(pool_counter, sizeof(pool_counter), "%d", pools[i].pool_counter);
-						snprintf(backend_id, sizeof(backend_pid), "%d", pools[i].backend_id);
-						snprintf(backend_pid, sizeof(backend_pid), "%d", pools[i].pool_backendpid);
-						snprintf(connected, sizeof(connected), "%d", pools[i].pool_connected);
-
-						pcp_write(frontend, "p", 1);
-						wsize = htonl(	sizeof(code) +
-										strlen(proc_pid)+1 +
-										strlen(pools[i].database)+1 +
-										strlen(pools[i].username)+1 +
-										strlen(proc_start_time)+1 +
-										strlen(proc_create_time)+1 +
-										strlen(majorversion)+1 +
-										strlen(minorversion)+1 +
-										strlen(pool_counter)+1 +
-										strlen(backend_id)+1 +
-										strlen(backend_pid)+1 +
-										strlen(connected)+1 +
-										sizeof(int));
-						pcp_write(frontend, &wsize, sizeof(int));
-						pcp_write(frontend, code, sizeof(code));
-						pcp_write(frontend, proc_pid, strlen(proc_pid)+1);
-						pcp_write(frontend, pools[i].database, strlen(pools[i].database)+1);
-						pcp_write(frontend, pools[i].username, strlen(pools[i].username)+1);
-						pcp_write(frontend, proc_start_time, strlen(proc_start_time)+1);
-						pcp_write(frontend, proc_create_time, strlen(proc_create_time)+1);
-						pcp_write(frontend, majorversion, strlen(majorversion)+1);
-						pcp_write(frontend, minorversion, strlen(minorversion)+1);
-						pcp_write(frontend, pool_counter, strlen(pool_counter)+1);
-						pcp_write(frontend, backend_id, strlen(backend_id)+1);
-						pcp_write(frontend, backend_pid, strlen(backend_pid)+1);
-						pcp_write(frontend, connected, strlen(connected)+1);
-						if (pcp_flush(frontend) < 0)
-						{
-							pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-							free(pools);
-							exit(1);
-						}
-					}
-
-					pcp_write(frontend, "p", 1);
-					wsize = htonl(sizeof(fin_code) +
-								  sizeof(int));
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, fin_code, sizeof(fin_code));
-					if (pcp_flush(frontend) < 0)
-					{
-						pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-						free(pools);
-						exit(1);
-					}
-
-					pool_debug("pcp_child: retrieved process information from shared memory");
-					free(pools);
-				}
+				inform_process_info(frontend, buf);
 				break;
-			}
-
 			case 'S':			/* SystemDB info */
-			{
-				int wsize;
-
-				SystemDBInfo *si = NULL;
-				si = pool_get_system_db_info();
-
-				if (si == NULL)
-				{
-					char code[] = "SystemDBNotDefined";
-
-					pcp_write(frontend, "e", 1);
-					wsize = htonl(sizeof(code) + sizeof(int));
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, code, sizeof(code));
-					if (pcp_flush(frontend) < 0)
-					{
-						pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-						exit(1);
-					}
-				}
-				else
-				{
-					/* first, send systemDB information */
-					char code[] = "SystemDBInfo";
-					char port[6];
-					char status[2];
-					char dist_def_num[16];
-					/* finally, indicate that all data is sent */
-					char fin_code[] = "CommandComplete";
-
-					/* since PCP clients can only see SystemDBInfo, set system_db_status from the shared memory */
-					si->system_db_status = SYSDB_STATUS;
-
-					snprintf(port, sizeof(port), "%d", si->port);
-					snprintf(status, sizeof(status), "%d", si->system_db_status);
-					snprintf(dist_def_num, sizeof(dist_def_num), "%d", si->dist_def_num);
-
-					pcp_write(frontend, "s", 1);
-					wsize = htonl(sizeof(code) +
-								  strlen(si->hostname)+1 +
-								  strlen(port)+1 +
-								  strlen(si->user)+1 +
-								  strlen(si->password)+1 +
-								  strlen(si->schema_name)+1 +
-								  strlen(si->database_name)+1 +
-								  strlen(dist_def_num)+1 +
-								  strlen(status)+1 +
-								  sizeof(int));
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, code, sizeof(code));
-					pcp_write(frontend, si->hostname, strlen(si->hostname)+1);
-					pcp_write(frontend, port, strlen(port)+1);
-					pcp_write(frontend, si->user, strlen(si->user)+1);
-					pcp_write(frontend, si->password, strlen(si->password)+1);
-					pcp_write(frontend, si->schema_name, strlen(si->schema_name)+1);
-					pcp_write(frontend, si->database_name, strlen(si->database_name)+1);
-					pcp_write(frontend, dist_def_num, strlen(dist_def_num)+1);
-					pcp_write(frontend, status, strlen(status)+1);
-					if (pcp_flush(frontend) < 0)
-					{
-						pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-						exit(1);
-					}
-
-					/* second, send DistDefInfo if any */
-					if (si->dist_def_num > 0)
-					{
-						char dist_code[] = "DistDefInfo";
-						char col_num[16];
-						int col_list_total_len;
-						int type_list_total_len;
-						char *col_list = NULL;
-						char *type_list = NULL;
-						int col_list_offset;
-						int type_list_offset;
-						DistDefInfo *ddi;
-						int i, j;
-
-						for (i = 0; i < si->dist_def_num; i++)
-						{
-							ddi = &si->dist_def_slot[i];
-							snprintf(col_num, sizeof(col_num), "%d", ddi->col_num);
-
-							col_list_total_len = type_list_total_len = 0;
-							for (j = 0; j < ddi->col_num; j++)
-							{
-								col_list_total_len += strlen(ddi->col_list[j]) + 1;
-								type_list_total_len += strlen(ddi->type_list[j]) + 1;
-							}
-
-							col_list = (char *)malloc(col_list_total_len);
-							type_list = (char *)malloc(type_list_total_len);
-							if (col_list == NULL || type_list == NULL)
-							{
-								pool_error("pcp_child: malloc() failed. reason: %s", strerror(errno));
-								exit(1);
-							}
-
-							col_list_offset = type_list_offset = 0;
-							for (j = 0; j < ddi->col_num; j++)
-							{
-								snprintf(col_list + col_list_offset, strlen(ddi->col_list[j])+1,
-										 "%s", ddi->col_list[j]);
-								snprintf(type_list + type_list_offset, strlen(ddi->type_list[j])+1,
-										 "%s", ddi->type_list[j]);
-								col_list_offset += strlen(ddi->col_list[j]) + 1;
-								type_list_offset += strlen(ddi->type_list[j]) + 1;
-							}
-
-							pcp_write(frontend, "s", 1);
-							wsize = htonl(sizeof(dist_code) +
-										  strlen(ddi->dbname)+1 +
-										  strlen(ddi->schema_name)+1 +
-										  strlen(ddi->table_name)+1 +
-										  strlen(ddi->dist_key_col_name)+1 +
-										  strlen(col_num)+1 +
-										  col_list_total_len +
-										  type_list_total_len +
-										  strlen(ddi->dist_def_func)+1 +
-										  sizeof(int));
-							pcp_write(frontend, &wsize, sizeof(int));
-							pcp_write(frontend, dist_code, sizeof(dist_code));
-							pcp_write(frontend, ddi->dbname, strlen(ddi->dbname)+1);
-							pcp_write(frontend, ddi->schema_name, strlen(ddi->schema_name)+1);
-							pcp_write(frontend, ddi->table_name, strlen(ddi->table_name)+1);
-							pcp_write(frontend, ddi->dist_key_col_name, strlen(ddi->dist_key_col_name)+1);
-							pcp_write(frontend, col_num, strlen(col_num)+1);
-							pcp_write(frontend, col_list, col_list_total_len);
-							pcp_write(frontend, type_list, type_list_total_len);
-							pcp_write(frontend, ddi->dist_def_func, strlen(ddi->dist_def_func)+1);
-							if (pcp_flush(frontend) < 0)
-							{
-								pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-								exit(1);
-							}
-
-							free(col_list);
-							free(type_list);
-						}
-					}
-
-					pcp_write(frontend, "s", 1);
-					wsize = htonl(sizeof(fin_code) +
-								  sizeof(int));
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, fin_code, sizeof(fin_code));
-					if (pcp_flush(frontend) < 0)
-					{
-						pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-						exit(1);
-					}
-
-					pool_debug("pcp_child: retrieved SystemDB information from shared memory");
-				}
+				inform_systemDB_info(frontend);
 				break;
-			}
-
 			case 'W':			/* watchdog info */
-			{
-				int wd_index;
-				int wsize;
-
-				WdInfo *wi = NULL;
-
-				if (!pool_config->use_watchdog)
-				{
-					char code[] = "watchdog not enabled";
-
-					pcp_write(frontend, "e", 1);
-					wsize = htonl(sizeof(code) + sizeof(int));
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, code, sizeof(code));
-					if (pcp_flush(frontend) < 0)
-					{
-						pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-						exit(1);
-					}
-
-					pool_debug("pcp_child: watcdhog not enabled");
-					break;
-				}
-
-				wd_index = atoi(buf);
-				wi = wd_get_watchdog_info(wd_index);
-
-				if (wi == NULL) {
-					char code[] = "Invalid watchdog index";
-
-					pcp_write(frontend, "e", 1);
-					wsize = htonl(sizeof(code) + sizeof(int));
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, code, sizeof(code));
-					if (pcp_flush(frontend) < 0)
-					{
-						pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-						exit(1);
-					}
-
-					pool_debug("pcp_child: invalid watchdog index");
-				}
-				else
-				{
-					char code[] = "CommandComplete";
-					char pgpool_port_str[6];
-					char wd_port_str[6];
-					char status[2];
-
-					snprintf(pgpool_port_str, sizeof(pgpool_port_str), "%d", wi->pgpool_port);
-					snprintf(wd_port_str, sizeof(wd_port_str), "%d", wi->wd_port);
-					snprintf(status, sizeof(status), "%d", wi->status);
-
-					pcp_write(frontend, "w", 1);
-					wsize = htonl(sizeof(code) +
-								  strlen(wi->hostname)+1 +
-								  strlen(pgpool_port_str)+1 +
-								  strlen(wd_port_str)+1 +
-								  strlen(status)+1 +
-								  sizeof(int));
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, code, sizeof(code));
-
-					pcp_write(frontend, wi->hostname, strlen(wi->hostname)+1);
-					pcp_write(frontend, pgpool_port_str, strlen(pgpool_port_str)+1);
-					pcp_write(frontend, wd_port_str, strlen(wd_port_str)+1);
-					pcp_write(frontend, status, strlen(status)+1);
-					if (pcp_flush(frontend) < 0)
-					{
-						pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-						exit(1);
-					}
-
-					pool_debug("pcp_child: retrieved node information from shared memory");
-				}
+				inform_watchdog_info(frontend, buf);
 				break;
-			}
-
 			case 'D':			/* detach node */
 			case 'd':			/* detach node gracefully */
-			{
-				int node_id;
-				int wsize;
-				char code[] = "CommandComplete";
-				bool gracefully;
-
-				if (tos == 'D')
-					gracefully = false;
-				else
-					gracefully = true;
-
-				node_id = atoi(buf);
-				pool_debug("pcp_child: detaching Node ID %d", node_id);
-				pool_detach_node(node_id, gracefully);
-
-				pcp_write(frontend, "d", 1);
-				wsize = htonl(sizeof(code) + sizeof(int));
-				pcp_write(frontend, &wsize, sizeof(int));
-				pcp_write(frontend, code, sizeof(code));
-				if (pcp_flush(frontend) < 0)
-				{
-					pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-					exit(1);
-				}
+				process_detach_node(frontend, buf, tos);
 				break;
-			}
-
 			case 'C':			/* attach node */
-			{
-				int node_id;
-				int wsize;
-				char code[] = "CommandComplete";
-
-				node_id = atoi(buf);
-				pool_debug("pcp_child: attaching Node ID %d", node_id);
-				send_failback_request(node_id);
-
-				pcp_write(frontend, "c", 1);
-				wsize = htonl(sizeof(code) + sizeof(int));
-				pcp_write(frontend, &wsize, sizeof(int));
-				pcp_write(frontend, code, sizeof(code));
-				if (pcp_flush(frontend) < 0)
-				{
-					pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-					exit(1);
-				}
+				process_attach_node(frontend, buf);
 				break;
-			}
-
 			case 'T':
-			{
-				char mode = buf[0];
-				pid_t ppid = getppid();
-
-				if (mode == 's')
-				{
-					pool_debug("pcp_child: sending SIGTERM to the parent process(%d)", ppid);
-					kill(ppid, SIGTERM);
-				}
-				else if (mode == 'f')
-				{
-					pool_debug("pcp_child: sending SIGINT to the parent process(%d)", ppid);
-					kill(ppid, SIGINT);
-				}
-				else if (mode == 'i')
-				{
-					pool_debug("pcp_child: sending SIGQUIT to the parent process(%d)", ppid);
-					kill(ppid, SIGQUIT);
-				}
-				else
-				{
-					pool_debug("pcp_child: invalid shutdown mode %c", mode);
-				}
-
+				process_shutown_request(buf[0]);
 				break;
-			}
 
 			case 'O': /* recovery request */
-			{
-				int node_id;
-				int wsize;
-				char code[] = "CommandComplete";
-				int r;
-
-				node_id = atoi(buf);
-
-				if ( (node_id < 0) || (node_id >= pool_config->backend_desc->num_backends) )
-				{
-					char code[] = "NodeIdOutOfRange";
-					pool_error("pcp_child: node id %d is not valid", node_id);
-					pcp_write(frontend, "e", 1);
-					wsize = htonl(sizeof(code) + sizeof(int));
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, code, sizeof(code));
-					if (pcp_flush(frontend) < 0)
-					{
-						pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-						exit(1);
-					}
-					exit(1);
-				}
-
-				if ((!REPLICATION &&
-					 !(MASTER_SLAVE &&
-					   !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))) ||
-					(MASTER_SLAVE &&
-					 !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP) &&
-					 node_id == PRIMARY_NODE_ID))
-				{
-					int len;
-					char *msg;
-
-					if (MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
-						msg = "primary server cannot be recovered by online recovery.";
-					else
-						msg = "recovery request is accepted only in replication mode or stereaming replication mode. ";
-
-					len = strlen(msg)+1;
-					pcp_write(frontend, "e", 1);
-					wsize = htonl(sizeof(int) + len);
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, msg, len);
-				}
-				else
-				{
-					pool_debug("pcp_child: start online recovery");
-
-					r = start_recovery(node_id);
-					finish_recovery();
-
-					if (r == 0) /* success */
-					{
-						pcp_write(frontend, "c", 1);
-						wsize = htonl(sizeof(code) + sizeof(int));
-						pcp_write(frontend, &wsize, sizeof(int));
-						pcp_write(frontend, code, sizeof(code));
-					}
-					else
-					{
-						int len = strlen("recovery failed") + 1;
-						pcp_write(frontend, "e", 1);
-						wsize = htonl(sizeof(int) + len);
-						pcp_write(frontend, &wsize, sizeof(int));
-						pcp_write(frontend, "recovery failed", len);
-					}
-				}
-				if (pcp_flush(frontend) < 0)
-				{
-					pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-					exit(1);
-				}
-			}
+				process_recovery_request(frontend, buf);
 				break;
 
 			case 'B': /* status request*/
-			{
-				int nrows = 0;
-				POOL_REPORT_CONFIG *status = get_config(&nrows);
-				int len = 0;
-				/* First, send array size of connection_info */
-				char arr_code[] = "ArraySize";
-				char code[] = "ProcessConfig";
-				/* Finally, indicate that all data is sent */
-				char fin_code[] = "CommandComplete";
-
-				pcp_write(frontend, "b", 1);
-				len = htonl(sizeof(arr_code) + sizeof(int) + sizeof(int));
-				pcp_write(frontend, &len, sizeof(int));
-				pcp_write(frontend, arr_code, sizeof(arr_code));
-				len = htonl(nrows);
-				pcp_write(frontend, &len, sizeof(int));
-
-				if (pcp_flush(frontend) < 0)
-				{
-					pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-					exit(1);
-				}
-
-				for (i = 0; i < nrows; i++)
-				{
-					pcp_write(frontend, "b", 1);
-					len = htonl(sizeof(int)
-						+ sizeof(code)
-						+ strlen(status[i].name) + 1
-						+ strlen(status[i].value) + 1
-						+ strlen(status[i].desc) + 1
-					);
-
-					pcp_write(frontend, &len, sizeof(int));
-					pcp_write(frontend, code, sizeof(code));
-					pcp_write(frontend, status[i].name, strlen(status[i].name)+1);
-					pcp_write(frontend, status[i].value, strlen(status[i].value)+1);
-					pcp_write(frontend, status[i].desc, strlen(status[i].desc)+1);
-				}
-
-				pcp_write(frontend, "b", 1);
-				len = htonl(sizeof(fin_code) + sizeof(int));
-				pcp_write(frontend, &len, sizeof(int));
-				pcp_write(frontend, fin_code, sizeof(fin_code));
-				if (pcp_flush(frontend) < 0)
-				{
-					pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-					exit(1);
-				}
-
-				free(status);
-
-				pool_debug("pcp_child: retrieved status information");
+				process_status_request(frontend);
 				break;
-			}
 
 			case 'J':			/* promote node */
 			case 'j':			/* promote node gracefully */
-			{
-				int node_id;
-				int wsize;
-				char code[] = "CommandComplete";
-				bool gracefully;
-
-				if (tos == 'J')
-					gracefully = false;
-				else
-					gracefully = true;
-
-				node_id = atoi(buf);
-				if ( (node_id < 0) || (node_id >= pool_config->backend_desc->num_backends) )
-				{
-					char code[] = "NodeIdOutOfRange";
-					pool_error("pcp_child: node id %d is not valid", node_id);
-					pcp_write(frontend, "e", 1);
-					wsize = htonl(sizeof(code) + sizeof(int));
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, code, sizeof(code));
-					if (pcp_flush(frontend) < 0)
-					{
-						pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-						exit(1);
-					}
-					exit(1);
-				}
-				/* promoting node is reserved to Streaming Replication */
-				if (!MASTER_SLAVE || (strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP) != 0))
-				{
-					char code[] = "NotInStreamingReplication";
-					pool_error("pcp_child: not in streaming replication mode, can't promote node id %d", node_id);
-					pcp_write(frontend, "e", 1);
-					wsize = htonl(sizeof(code) + sizeof(int));
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, code, sizeof(code));
-					if (pcp_flush(frontend) < 0)
-					{
-						pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-						exit(1);
-					}
-					exit(1);
-				}
-
-				if (node_id == PRIMARY_NODE_ID)
-				{
-					char code[] = "NodeIdAlreadyPrimary";
-					pool_error("pcp_child: specified node is already primary node, can't promote node id %d", node_id);
-					pcp_write(frontend, "e", 1);
-					wsize = htonl(sizeof(code) + sizeof(int));
-					pcp_write(frontend, &wsize, sizeof(int));
-					pcp_write(frontend, code, sizeof(code));
-					if (pcp_flush(frontend) < 0)
-					{
-						pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-						exit(1);
-					}
-					exit(1);
-				}
-
-				pool_debug("pcp_child: promoting Node ID %d", node_id);
-				pool_promote_node(node_id, gracefully);
-
-				pcp_write(frontend, "d", 1);
-				wsize = htonl(sizeof(code) + sizeof(int));
-				pcp_write(frontend, &wsize, sizeof(int));
-				pcp_write(frontend, code, sizeof(code));
-				if (pcp_flush(frontend) < 0)
-				{
-					pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
-					exit(1);
-				}
+				process_promote_node(frontend,buf,tos);
 				break;
-			}
 
 			case 'F':
 				pool_debug("pcp_child: stop online recovery");
@@ -1129,13 +351,10 @@ pcp_do_child(int unix_fd, int inet_fd, char *pcp_conf_file)
 				break;
 
 			default:
-				pool_error("pcp_child: unknown packet type %c received", tos);
-				exit(1);
+				ereport(FATAL,
+					(errmsg("invalid pcp packet"),
+						errdetail("unknown pcp packet type \"%c\"",tos)));
 		}
-
-		free(buf);
-		buf = NULL;
-
 		/* seems ok. cancel idle check timer */
 		pool_signal(SIGALRM, SIG_IGN);
 	}
@@ -1205,9 +424,9 @@ pcp_do_accept(int unix_fd, int inet_fd)
 	{
 		if (errno == EAGAIN || errno == EINTR)
 			return NULL;
-
-		pool_error("pcp_child: select() failed. reason: %s", strerror(errno));
-		return NULL;
+		ereport(ERROR,
+			(errmsg("unable to accept new pcp connection"),
+				errdetail("select system call failed with error : \"%s\"",strerror(errno))));
 	}
 
 	if (FD_ISSET(unix_fd, &readmask))
@@ -1231,8 +450,9 @@ pcp_do_accept(int unix_fd, int inet_fd)
 		 * can be silently ignored.
 		 */
 		if (errno != EAGAIN && errno != EWOULDBLOCK)
-			pool_error("pcp_child: accept() failed. reason: %s", strerror(errno));
-		return NULL;
+			ereport(ERROR,
+				(errmsg("unable to accept new pcp connection"),
+					errdetail("socket accept system call failed with error : \"%s\"",strerror(errno))));
 	}
 
 	if (pcp_got_sighup)
@@ -1251,25 +471,24 @@ pcp_do_accept(int unix_fd, int inet_fd)
 					   (char *) &on,
 					   sizeof(on)) < 0)
 		{
-			pool_error("pcp_child: setsockopt() failed: %s", strerror(errno));
 			close(afd);
-			return NULL;
+			ereport(ERROR,
+				(errmsg("unable to accept new pcp connection"),
+					errdetail("setsockopt system call failed with error : \"%s\"",strerror(errno))));
 		}
 		if (setsockopt(afd, SOL_SOCKET, SO_KEEPALIVE,
 					   (char *) &on,
 					   sizeof(on)) < 0)
 		{
-			pool_error("pcp_child: setsockopt() failed: %s", strerror(errno));
 			close(afd);
-			return NULL;
+			ereport(ERROR,
+				(errmsg("unable to accept new pcp connection"),
+					errdetail("setsockopt system call failed with error : \"%s\"",strerror(errno))));
 		}
 	}
 
 	if ((pc = pcp_open(afd)) == NULL)
-	{
 		close(afd);
-		return NULL;
-	}
 	return pc;
 }
 
@@ -1285,13 +504,16 @@ unset_nonblock(int fd)
 	var = fcntl(fd, F_GETFL, 0);
 	if (var == -1)
 	{
-		pool_error("pcp_child: fcntl failed. %s", strerror(errno));
-		exit(1);
+		ereport(FATAL,
+			(errmsg("unable to connect"),
+				errdetail("fcntl system call failed with error : \"%s\"",strerror(errno))));
+
 	}
 	if (fcntl(fd, F_SETFL, var & ~O_NONBLOCK) == -1)
 	{
-		pool_error("pcp_child: fcntl failed. %s", strerror(errno));
-		exit(1);
+		ereport(FATAL,
+			(errmsg("unable to connect"),
+				errdetail("fcntl system call failed with error : \"%s\"",strerror(errno))));
 	}
 }
 
@@ -1491,3 +713,764 @@ static int pool_promote_node(int node_id, bool gracefully)
 
 	return 0;
 }
+
+static void 
+inform_process_count(PCP_CONNECTION *frontend)
+{
+	int wsize;
+	int process_count;
+	char process_count_str[16];
+	int *process_list = NULL;
+	char code[] = "CommandComplete";
+	char *mesg = NULL;
+	int i;
+	int total_port_len = 0;
+
+	process_list = pool_get_process_list(&process_count);
+
+	mesg = (char *)palloc(6*process_count);	/* port# is at most 5 characters long (MAX:65535) */
+
+	snprintf(process_count_str, sizeof(process_count_str), "%d", process_count);
+
+	for (i = 0; i < process_count; i++)
+	{
+		char port[6];
+		snprintf(port, sizeof(port), "%d", process_list[i]);
+		snprintf(mesg+total_port_len, strlen(port)+1, "%s", port);
+		total_port_len += strlen(port)+1;
+	}
+
+	pcp_write(frontend, "n", 1);
+	wsize = htonl(sizeof(code) +
+				  strlen(process_count_str)+1 +
+				  total_port_len +
+				  sizeof(int));
+	pcp_write(frontend, &wsize, sizeof(int));
+	pcp_write(frontend, code, sizeof(code));
+	pcp_write(frontend, process_count_str, strlen(process_count_str)+1);
+	pcp_write(frontend, mesg, total_port_len);
+	do_pcp_flush(frontend);
+
+	pfree(process_list);
+	pfree(mesg);
+
+	pool_debug("pcp_child: %d process(es) found", process_count);
+}
+
+static void
+inform_process_info(PCP_CONNECTION *frontend,char *buf)
+{
+	int proc_id;
+	int wsize;
+	int num_proc = pool_config->num_init_children;
+	int i;
+
+	proc_id = atoi(buf);
+
+	if ((proc_id != 0) && (pool_get_process_info(proc_id) == NULL))
+	{
+		char code[] = "InvalidProcessID";
+
+		pcp_write(frontend, "e", 1);
+		wsize = htonl(sizeof(code) + sizeof(int));
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, code, sizeof(code));
+		do_pcp_flush(frontend);
+
+		pool_debug("pcp_child: invalid process ID");
+	}
+	else
+	{
+		/* First, send array size of connection_info */
+		char arr_code[] = "ArraySize";
+		char con_info_size[16];
+		/* Finally, indicate that all data is sent */
+		char fin_code[] = "CommandComplete";
+
+		POOL_REPORT_POOLS *pools = get_pools(&num_proc);
+
+		if (proc_id == 0)
+		{
+			snprintf(con_info_size, sizeof(con_info_size), "%d", num_proc);
+		}
+		else
+		{
+			snprintf(con_info_size, sizeof(con_info_size), "%d", pool_config->max_pool * NUM_BACKENDS);
+		}
+
+		pcp_write(frontend, "p", 1);
+		wsize = htonl(sizeof(arr_code) +
+					  strlen(con_info_size)+1 +
+					  sizeof(int));
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, arr_code, sizeof(arr_code));
+		pcp_write(frontend, con_info_size, strlen(con_info_size)+1);
+		do_pcp_flush(frontend);
+
+		/* Second, send process information for all connection_info */
+		for (i=0; i<num_proc; i++)
+		{
+			char code[] = "ProcessInfo";
+			char proc_pid[16];
+			char proc_start_time[20];
+			char proc_create_time[20];
+			char majorversion[5];
+			char minorversion[5];
+			char pool_counter[16];
+			char backend_id[16];
+			char backend_pid[16];
+			char connected[2];
+
+			if (proc_id != 0 && proc_id != pools[i].pool_pid) continue;
+
+			snprintf(proc_pid, sizeof(proc_pid), "%d", pools[i].pool_pid);
+			snprintf(proc_start_time, sizeof(proc_start_time), "%ld", pools[i].start_time);
+			snprintf(proc_create_time, sizeof(proc_create_time), "%ld", pools[i].create_time);
+			snprintf(majorversion, sizeof(majorversion), "%d", pools[i].pool_majorversion);
+			snprintf(minorversion, sizeof(minorversion), "%d", pools[i].pool_minorversion);
+			snprintf(pool_counter, sizeof(pool_counter), "%d", pools[i].pool_counter);
+			snprintf(backend_id, sizeof(backend_pid), "%d", pools[i].backend_id);
+			snprintf(backend_pid, sizeof(backend_pid), "%d", pools[i].pool_backendpid);
+			snprintf(connected, sizeof(connected), "%d", pools[i].pool_connected);
+
+			pcp_write(frontend, "p", 1);
+			wsize = htonl(	sizeof(code) +
+							strlen(proc_pid)+1 +
+							strlen(pools[i].database)+1 +
+							strlen(pools[i].username)+1 +
+							strlen(proc_start_time)+1 +
+							strlen(proc_create_time)+1 +
+							strlen(majorversion)+1 +
+							strlen(minorversion)+1 +
+							strlen(pool_counter)+1 +
+							strlen(backend_id)+1 +
+							strlen(backend_pid)+1 +
+							strlen(connected)+1 +
+							sizeof(int));
+			pcp_write(frontend, &wsize, sizeof(int));
+			pcp_write(frontend, code, sizeof(code));
+			pcp_write(frontend, proc_pid, strlen(proc_pid)+1);
+			pcp_write(frontend, pools[i].database, strlen(pools[i].database)+1);
+			pcp_write(frontend, pools[i].username, strlen(pools[i].username)+1);
+			pcp_write(frontend, proc_start_time, strlen(proc_start_time)+1);
+			pcp_write(frontend, proc_create_time, strlen(proc_create_time)+1);
+			pcp_write(frontend, majorversion, strlen(majorversion)+1);
+			pcp_write(frontend, minorversion, strlen(minorversion)+1);
+			pcp_write(frontend, pool_counter, strlen(pool_counter)+1);
+			pcp_write(frontend, backend_id, strlen(backend_id)+1);
+			pcp_write(frontend, backend_pid, strlen(backend_pid)+1);
+			pcp_write(frontend, connected, strlen(connected)+1);
+			do_pcp_flush(frontend);
+		}
+
+		pcp_write(frontend, "p", 1);
+		wsize = htonl(sizeof(fin_code) +
+					  sizeof(int));
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, fin_code, sizeof(fin_code));
+		do_pcp_flush(frontend);
+		pool_debug("pcp_child: retrieved process information from shared memory");
+		pfree(pools);
+	}
+}
+
+static void
+inform_systemDB_info(PCP_CONNECTION *frontend)
+{
+	int wsize;
+
+	SystemDBInfo *si = NULL;
+	si = pool_get_system_db_info();
+
+	if (si == NULL)
+	{
+		char code[] = "SystemDBNotDefined";
+
+		pcp_write(frontend, "e", 1);
+		wsize = htonl(sizeof(code) + sizeof(int));
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, code, sizeof(code));
+		do_pcp_flush(frontend);
+	}
+	else
+	{
+		/* first, send systemDB information */
+		char code[] = "SystemDBInfo";
+		char port[6];
+		char status[2];
+		char dist_def_num[16];
+		/* finally, indicate that all data is sent */
+		char fin_code[] = "CommandComplete";
+
+		/* since PCP clients can only see SystemDBInfo, set system_db_status from the shared memory */
+		si->system_db_status = SYSDB_STATUS;
+
+		snprintf(port, sizeof(port), "%d", si->port);
+		snprintf(status, sizeof(status), "%d", si->system_db_status);
+		snprintf(dist_def_num, sizeof(dist_def_num), "%d", si->dist_def_num);
+
+		pcp_write(frontend, "s", 1);
+		wsize = htonl(sizeof(code) +
+					  strlen(si->hostname)+1 +
+					  strlen(port)+1 +
+					  strlen(si->user)+1 +
+					  strlen(si->password)+1 +
+					  strlen(si->schema_name)+1 +
+					  strlen(si->database_name)+1 +
+					  strlen(dist_def_num)+1 +
+					  strlen(status)+1 +
+					  sizeof(int));
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, code, sizeof(code));
+		pcp_write(frontend, si->hostname, strlen(si->hostname)+1);
+		pcp_write(frontend, port, strlen(port)+1);
+		pcp_write(frontend, si->user, strlen(si->user)+1);
+		pcp_write(frontend, si->password, strlen(si->password)+1);
+		pcp_write(frontend, si->schema_name, strlen(si->schema_name)+1);
+		pcp_write(frontend, si->database_name, strlen(si->database_name)+1);
+		pcp_write(frontend, dist_def_num, strlen(dist_def_num)+1);
+		pcp_write(frontend, status, strlen(status)+1);
+		do_pcp_flush(frontend);
+		/* second, send DistDefInfo if any */
+		if (si->dist_def_num > 0)
+		{
+			char dist_code[] = "DistDefInfo";
+			char col_num[16];
+			int col_list_total_len;
+			int type_list_total_len;
+			char *col_list = NULL;
+			char *type_list = NULL;
+			int col_list_offset;
+			int type_list_offset;
+			DistDefInfo *ddi;
+			int i, j;
+
+			for (i = 0; i < si->dist_def_num; i++)
+			{
+				ddi = &si->dist_def_slot[i];
+				snprintf(col_num, sizeof(col_num), "%d", ddi->col_num);
+
+				col_list_total_len = type_list_total_len = 0;
+				for (j = 0; j < ddi->col_num; j++)
+				{
+					col_list_total_len += strlen(ddi->col_list[j]) + 1;
+					type_list_total_len += strlen(ddi->type_list[j]) + 1;
+				}
+
+				col_list = (char *)palloc(col_list_total_len);
+				type_list = (char *)palloc(type_list_total_len);
+
+				col_list_offset = type_list_offset = 0;
+				for (j = 0; j < ddi->col_num; j++)
+				{
+					snprintf(col_list + col_list_offset, strlen(ddi->col_list[j])+1,
+							 "%s", ddi->col_list[j]);
+					snprintf(type_list + type_list_offset, strlen(ddi->type_list[j])+1,
+							 "%s", ddi->type_list[j]);
+					col_list_offset += strlen(ddi->col_list[j]) + 1;
+					type_list_offset += strlen(ddi->type_list[j]) + 1;
+				}
+
+				pcp_write(frontend, "s", 1);
+				wsize = htonl(sizeof(dist_code) +
+							  strlen(ddi->dbname)+1 +
+							  strlen(ddi->schema_name)+1 +
+							  strlen(ddi->table_name)+1 +
+							  strlen(ddi->dist_key_col_name)+1 +
+							  strlen(col_num)+1 +
+							  col_list_total_len +
+							  type_list_total_len +
+							  strlen(ddi->dist_def_func)+1 +
+							  sizeof(int));
+				pcp_write(frontend, &wsize, sizeof(int));
+				pcp_write(frontend, dist_code, sizeof(dist_code));
+				pcp_write(frontend, ddi->dbname, strlen(ddi->dbname)+1);
+				pcp_write(frontend, ddi->schema_name, strlen(ddi->schema_name)+1);
+				pcp_write(frontend, ddi->table_name, strlen(ddi->table_name)+1);
+				pcp_write(frontend, ddi->dist_key_col_name, strlen(ddi->dist_key_col_name)+1);
+				pcp_write(frontend, col_num, strlen(col_num)+1);
+				pcp_write(frontend, col_list, col_list_total_len);
+				pcp_write(frontend, type_list, type_list_total_len);
+				pcp_write(frontend, ddi->dist_def_func, strlen(ddi->dist_def_func)+1);
+				do_pcp_flush(frontend);
+
+				pfree(col_list);
+				pfree(type_list);
+			}
+		}
+
+		pcp_write(frontend, "s", 1);
+		wsize = htonl(sizeof(fin_code) +
+					  sizeof(int));
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, fin_code, sizeof(fin_code));
+		do_pcp_flush(frontend);
+
+		pool_debug("pcp_child: retrieved SystemDB information from shared memory");
+	}
+}
+
+static void
+inform_watchdog_info(PCP_CONNECTION *frontend,char *buf)
+{
+	int wd_index;
+	int wsize;
+
+	WdInfo *wi = NULL;
+
+	if (!pool_config->use_watchdog)
+	{
+		char code[] = "watchdog not enabled";
+
+		pcp_write(frontend, "e", 1);
+		wsize = htonl(sizeof(code) + sizeof(int));
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, code, sizeof(code));
+		do_pcp_flush(frontend);
+
+		pool_debug("pcp_child: watcdhog not enabled");
+		return;
+	}
+
+	wd_index = atoi(buf);
+	wi = wd_get_watchdog_info(wd_index);
+
+	if (wi == NULL) {
+		char code[] = "Invalid watchdog index";
+
+		pcp_write(frontend, "e", 1);
+		wsize = htonl(sizeof(code) + sizeof(int));
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, code, sizeof(code));
+		do_pcp_flush(frontend);
+
+		pool_debug("pcp_child: invalid watchdog index");
+	}
+	else
+	{
+		char code[] = "CommandComplete";
+		char pgpool_port_str[6];
+		char wd_port_str[6];
+		char status[2];
+
+		snprintf(pgpool_port_str, sizeof(pgpool_port_str), "%d", wi->pgpool_port);
+		snprintf(wd_port_str, sizeof(wd_port_str), "%d", wi->wd_port);
+		snprintf(status, sizeof(status), "%d", wi->status);
+
+		pcp_write(frontend, "w", 1);
+		wsize = htonl(sizeof(code) +
+					  strlen(wi->hostname)+1 +
+					  strlen(pgpool_port_str)+1 +
+					  strlen(wd_port_str)+1 +
+					  strlen(status)+1 +
+					  sizeof(int));
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, code, sizeof(code));
+
+		pcp_write(frontend, wi->hostname, strlen(wi->hostname)+1);
+		pcp_write(frontend, pgpool_port_str, strlen(pgpool_port_str)+1);
+		pcp_write(frontend, wd_port_str, strlen(wd_port_str)+1);
+		pcp_write(frontend, status, strlen(status)+1);
+		do_pcp_flush(frontend);
+
+		pool_debug("pcp_child: retrieved node information from shared memory");
+	}
+}
+
+static void
+inform_node_info(PCP_CONNECTION *frontend,char *buf)
+{
+	int node_id;
+	int wsize;
+
+	BackendInfo *bi = NULL;
+
+	node_id = atoi(buf);
+	bi = pool_get_node_info(node_id);
+
+	if (bi == NULL) {
+		char code[] = "Invalid Node ID";
+
+		pcp_write(frontend, "e", 1);
+		wsize = htonl(sizeof(code) + sizeof(int));
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, code, sizeof(code));
+		do_pcp_flush(frontend);
+
+		pool_debug("pcp_child: invalid node ID");
+	}
+	else
+	{
+		char code[] = "CommandComplete";
+		char port_str[6];
+		char status[2];
+		char weight_str[20];
+
+		snprintf(port_str, sizeof(port_str), "%d", bi->backend_port);
+		snprintf(status, sizeof(status), "%d", bi->backend_status);
+		snprintf(weight_str, sizeof(weight_str), "%f", bi->backend_weight);
+
+		pcp_write(frontend, "i", 1);
+		wsize = htonl(sizeof(code) +
+					  strlen(bi->backend_hostname)+1 +
+					  strlen(port_str)+1 +
+					  strlen(status)+1 +
+					  strlen(weight_str)+1 +
+					  sizeof(int));
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, code, sizeof(code));
+		pcp_write(frontend, bi->backend_hostname, strlen(bi->backend_hostname)+1);
+		pcp_write(frontend, port_str, strlen(port_str)+1);
+		pcp_write(frontend, status, strlen(status)+1);
+		pcp_write(frontend, weight_str, strlen(weight_str)+1);
+		do_pcp_flush(frontend);
+
+		pool_debug("pcp_child: retrieved node information from shared memory");
+	}
+}
+
+static void
+inform_node_count(PCP_CONNECTION *frontend)
+{
+	int wsize;
+	int node_count = pool_get_node_count();
+
+	char code[] = "CommandComplete";
+	char mesg[16];
+
+	snprintf(mesg, sizeof(mesg), "%d", node_count);
+
+	pcp_write(frontend, "l", 1);
+	wsize = htonl(sizeof(code) +
+				  strlen(mesg)+1 +
+				  sizeof(int));
+	pcp_write(frontend, &wsize, sizeof(int));
+	pcp_write(frontend, code, sizeof(code));
+	pcp_write(frontend, mesg, strlen(mesg)+1);
+	do_pcp_flush(frontend);
+
+	pool_debug("pcp_child: %d node(s) found", node_count);
+}
+
+static void 
+process_detach_node(PCP_CONNECTION *frontend,char *buf, char tos)
+{
+	int node_id;
+	int wsize;
+	char code[] = "CommandComplete";
+	bool gracefully;
+
+	if (tos == 'D')
+		gracefully = false;
+	else
+		gracefully = true;
+
+	node_id = atoi(buf);
+	pool_debug("pcp_child: detaching Node ID %d", node_id);
+	pool_detach_node(node_id, gracefully);
+
+	pcp_write(frontend, "d", 1);
+	wsize = htonl(sizeof(code) + sizeof(int));
+	pcp_write(frontend, &wsize, sizeof(int));
+	pcp_write(frontend, code, sizeof(code));
+	do_pcp_flush(frontend);
+}
+
+static void 
+process_attach_node(PCP_CONNECTION *frontend,char *buf)
+{
+	int node_id;
+	int wsize;
+	char code[] = "CommandComplete";
+
+	node_id = atoi(buf);
+	pool_debug("pcp_child: attaching Node ID %d", node_id);
+	send_failback_request(node_id);
+
+	pcp_write(frontend, "c", 1);
+	wsize = htonl(sizeof(code) + sizeof(int));
+	pcp_write(frontend, &wsize, sizeof(int));
+	pcp_write(frontend, code, sizeof(code));
+	do_pcp_flush(frontend);
+}
+
+
+static void
+process_recovery_request(PCP_CONNECTION *frontend,char *buf)
+{
+	int node_id;
+	int wsize;
+	char code[] = "CommandComplete";
+	int r;
+
+	node_id = atoi(buf);
+
+	if ( (node_id < 0) || (node_id >= pool_config->backend_desc->num_backends) )
+	{
+		char code[] = "NodeIdOutOfRange";
+		pcp_write(frontend, "e", 1);
+		wsize = htonl(sizeof(code) + sizeof(int));
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, code, sizeof(code));
+		do_pcp_flush(frontend);
+		ereport(FATAL,
+			(errmsg("could not process recovery request"),
+				errdetail("node id %d is not valid", node_id)));
+	}
+
+	if ((!REPLICATION &&
+		 !(MASTER_SLAVE &&
+		   !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))) ||
+		(MASTER_SLAVE &&
+		 !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP) &&
+		 node_id == PRIMARY_NODE_ID))
+	{
+		int len;
+		char *msg;
+
+		if (MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
+			msg = "primary server cannot be recovered by online recovery.";
+		else
+			msg = "recovery request is accepted only in replication mode or stereaming replication mode. ";
+
+		len = strlen(msg)+1;
+		pcp_write(frontend, "e", 1);
+		wsize = htonl(sizeof(int) + len);
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, msg, len);
+	}
+	else
+	{
+		pool_debug("pcp_child: start online recovery");
+
+		r = start_recovery(node_id);
+		finish_recovery();
+
+		if (r == 0) /* success */
+		{
+			pcp_write(frontend, "c", 1);
+			wsize = htonl(sizeof(code) + sizeof(int));
+			pcp_write(frontend, &wsize, sizeof(int));
+			pcp_write(frontend, code, sizeof(code));
+		}
+		else
+		{
+			int len = strlen("recovery failed") + 1;
+			pcp_write(frontend, "e", 1);
+			wsize = htonl(sizeof(int) + len);
+			pcp_write(frontend, &wsize, sizeof(int));
+			pcp_write(frontend, "recovery failed", len);
+		}
+	}
+	do_pcp_flush(frontend);
+}
+
+static void
+process_status_request(PCP_CONNECTION *frontend)
+{
+	int nrows = 0;
+	int i;
+	POOL_REPORT_CONFIG *status = get_config(&nrows);
+	int len = 0;
+	/* First, send array size of connection_info */
+	char arr_code[] = "ArraySize";
+	char code[] = "ProcessConfig";
+	/* Finally, indicate that all data is sent */
+	char fin_code[] = "CommandComplete";
+
+	pcp_write(frontend, "b", 1);
+	len = htonl(sizeof(arr_code) + sizeof(int) + sizeof(int));
+	pcp_write(frontend, &len, sizeof(int));
+	pcp_write(frontend, arr_code, sizeof(arr_code));
+	len = htonl(nrows);
+	pcp_write(frontend, &len, sizeof(int));
+
+	do_pcp_flush(frontend);
+
+	for (i = 0; i < nrows; i++)
+	{
+		pcp_write(frontend, "b", 1);
+		len = htonl(sizeof(int)
+			+ sizeof(code)
+			+ strlen(status[i].name) + 1
+			+ strlen(status[i].value) + 1
+			+ strlen(status[i].desc) + 1
+		);
+
+		pcp_write(frontend, &len, sizeof(int));
+		pcp_write(frontend, code, sizeof(code));
+		pcp_write(frontend, status[i].name, strlen(status[i].name)+1);
+		pcp_write(frontend, status[i].value, strlen(status[i].value)+1);
+		pcp_write(frontend, status[i].desc, strlen(status[i].desc)+1);
+	}
+
+	pcp_write(frontend, "b", 1);
+	len = htonl(sizeof(fin_code) + sizeof(int));
+	pcp_write(frontend, &len, sizeof(int));
+	pcp_write(frontend, fin_code, sizeof(fin_code));
+	do_pcp_flush(frontend);
+
+	pfree(status);
+
+	pool_debug("pcp_child: retrieved status information");
+}
+
+static void
+process_promote_node(PCP_CONNECTION *frontend, char *buf, char tos)
+{
+	int node_id;
+	int wsize;
+	char code[] = "CommandComplete";
+	bool gracefully;
+
+	if (tos == 'J')
+		gracefully = false;
+	else
+		gracefully = true;
+
+	node_id = atoi(buf);
+	if ( (node_id < 0) || (node_id >= pool_config->backend_desc->num_backends) )
+	{
+		char code[] = "NodeIdOutOfRange";
+		pcp_write(frontend, "e", 1);
+		wsize = htonl(sizeof(code) + sizeof(int));
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, code, sizeof(code));
+		do_pcp_flush(frontend);
+		ereport(FATAL,
+			(errmsg("could not process recovery request"),
+				errdetail("node id %d is not valid", node_id)));
+	}
+	/* promoting node is reserved to Streaming Replication */
+	if (!MASTER_SLAVE || (strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP) != 0))
+	{
+		char code[] = "NotInStreamingReplication";
+		pcp_write(frontend, "e", 1);
+		wsize = htonl(sizeof(code) + sizeof(int));
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, code, sizeof(code));
+		do_pcp_flush(frontend);
+		ereport(FATAL,
+			(errmsg("invalid pgpool mode for the command"),
+				errdetail("not in streaming replication mode, can't promote node id %d", node_id)));
+
+	}
+
+	if (node_id == PRIMARY_NODE_ID)
+	{
+		char code[] = "NodeIdAlreadyPrimary";
+		pcp_write(frontend, "e", 1);
+		wsize = htonl(sizeof(code) + sizeof(int));
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, code, sizeof(code));
+		do_pcp_flush(frontend);
+		ereport(FATAL,
+			(errmsg("invalid pgpool mode for the command"),
+				errdetail("specified node is already primary node, can't promote node id %d", node_id)));
+
+	}
+
+	pool_debug("pcp_child: promoting Node ID %d", node_id);
+	pool_promote_node(node_id, gracefully);
+
+	pcp_write(frontend, "d", 1);
+	wsize = htonl(sizeof(code) + sizeof(int));
+	pcp_write(frontend, &wsize, sizeof(int));
+	pcp_write(frontend, code, sizeof(code));
+	do_pcp_flush(frontend);
+}
+
+static void
+process_authentication(PCP_CONNECTION *frontend, char *buf, char *pcp_conf_file,
+				char* salt, int *random_salt, int *authenticated)
+{
+	int wsize;
+
+	if (*random_salt)
+	{
+		*authenticated = user_authenticate(buf, pcp_conf_file, salt, 4);
+	}
+	if (!*random_salt || !*authenticated)
+	{
+		char code[] = "AuthenticationFailed";
+		char mesg[] = "username and/or password do not match";
+		pcp_write(frontend, "r", 1);
+		wsize = htonl(sizeof(code) + sizeof(mesg) + sizeof(int));
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, code, sizeof(code));
+		pcp_write(frontend, mesg, sizeof(mesg));
+		do_pcp_flush(frontend);
+
+		*random_salt = 0;
+		ereport(ERROR,
+			(errmsg("authentication failed"),
+				errdetail("username and/or password do not match")));
+	}
+	else
+	{
+		char code[] = "AuthenticationOK";
+		pcp_write(frontend, "r", 1);
+		wsize = htonl(sizeof(code) + sizeof(int));
+		pcp_write(frontend, &wsize, sizeof(int));
+		pcp_write(frontend, code, sizeof(code));
+		do_pcp_flush(frontend);
+		*random_salt = 0;
+
+		pool_debug("pcp_child: authentication OK");
+	}
+}
+
+static void
+send_md5salt(PCP_CONNECTION *frontend, char* salt)
+{
+	int wsize;
+
+	pool_random_salt(salt);
+//	random_salt = 1;
+
+	pcp_write(frontend, "m", 1);
+	wsize = htonl(sizeof(int) + 4);
+	pcp_write(frontend, &wsize, sizeof(int));
+	pcp_write(frontend, salt, 4);
+	do_pcp_flush(frontend);
+
+	pool_debug("pcp_child: salt sent to the client");
+}
+
+static void 
+process_shutown_request(char mode)
+{
+	pid_t ppid = getppid();
+
+	if (mode == 's')
+	{
+		pool_debug("pcp_child: sending SIGTERM to the parent process(%d)", ppid);
+		kill(ppid, SIGTERM);
+	}
+	else if (mode == 'f')
+	{
+		pool_debug("pcp_child: sending SIGINT to the parent process(%d)", ppid);
+		kill(ppid, SIGINT);
+	}
+	else if (mode == 'i')
+	{
+		pool_debug("pcp_child: sending SIGQUIT to the parent process(%d)", ppid);
+		kill(ppid, SIGQUIT);
+	}
+	else
+	{
+		pool_debug("pcp_child: invalid shutdown mode %c", mode);
+	}
+}
+
+/* 
+ * Wrapper around pcp_flush which throws FATAL error when pcp_flush fails
+ */
+static void 
+do_pcp_flush(PCP_CONNECTION *frontend)
+{
+	if (pcp_flush(frontend) < 0)
+		ereport(FATAL,
+			(errmsg("failed to flush data to client"),
+				errdetail("pcp_flush failed with error : \"%s\"",strerror(errno))));
+}
diff --git a/src/protocol/child.c b/src/protocol/child.c
index 5767b25..3ef1c5b 100644
--- a/src/protocol/child.c
+++ b/src/protocol/child.c
@@ -37,7 +37,6 @@
 #endif
 
 #include <signal.h>
-
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
@@ -50,11 +49,14 @@
 #endif
 
 #include "pool.h"
+#include "utils/palloc.h"
+#include "utils/memutils.h"
 #include "context/pool_process_context.h"
 #include "context/pool_session_context.h"
 #include "pool_config.h"
 #include "utils/pool_ip.h"
 #include "utils/pool_stream.h"
+#include "utils/elog.h"
 #include "auth/md5.h"
 #include "auth/pool_passwd.h"
 
@@ -75,10 +77,25 @@ static void init_system_db_connection(void);
 static bool connect_using_existing_connection(POOL_CONNECTION *frontend,
 											  POOL_CONNECTION_POOL *backend,
 											  StartupPacket *sp);
+static void check_restart_request();
+static void enable_authentication_timeout();
+static void disable_authentication_timeout();
+static int wait_for_new_connections(int unix_fd, int inet_fd, struct timeval *timeout, SockAddr *saddr);
+static void check_config_reload();
+static void get_backends_status(unsigned int *valid_backends, unsigned int *down_backends);
+static void validate_backend_connectivity(int front_end_fd);
+static POOL_CONNECTION *get_connection(int front_end_fd, SockAddr *saddr);
+static POOL_CONNECTION_POOL *get_backend_connection(POOL_CONNECTION *frontend);
+static StartupPacket *StartupPacketCopy(StartupPacket *sp);
+static void print_process_status(char *remote_host,char* remote_port);
+
+
 /*
  * non 0 means SIGTERM(smart shutdown) or SIGINT(fast shutdown) has arrived
  */
 volatile sig_atomic_t exit_request = 0;
+static volatile sig_atomic_t alarm_enabled = false;
+
 
 static int idle;		/* non 0 means this child is in idle state */
 static int accepted = 0;
@@ -98,14 +115,17 @@ char remote_port[NI_MAXSERV];	/* client port */
 */
 void do_child(int unix_fd, int inet_fd)
 {
-	POOL_CONNECTION *frontend;
+	sigjmp_buf	local_sigjmp_buf;
+	MemoryContext ChildLoopMemoryContext;
+	MemoryContext QueryProcessMemoryContext;
+
+	POOL_CONNECTION *frontend = NULL;
 	POOL_CONNECTION_POOL *backend;
 	struct timeval now;
 	struct timezone tz;
 	struct timeval timeout;
 	static int connected;		/* non 0 if has been accepted connections from frontend */
 	int connections_count = 0;	/* used if child_max_connections > 0 */
-	int found;
 	char psbuf[NI_MAXHOST + 128];
 
 	pool_debug("I am %d", getpid());
@@ -115,11 +135,11 @@ void do_child(int unix_fd, int inet_fd)
 
 	/* set up signal handlers */
 	signal(SIGALRM, SIG_DFL);
+	signal(SIGCHLD, SIG_DFL);
 	signal(SIGTERM, die);
-	signal(SIGINT, die);
-	signal(SIGHUP, reload_config_handler);
+	signal(SIGINT,  die);
 	signal(SIGQUIT, die);
-	signal(SIGCHLD, SIG_DFL);
+	signal(SIGHUP, reload_config_handler);
 	signal(SIGUSR1, close_idle_connection);
 	signal(SIGUSR2, wakeup_handler);
 	signal(SIGPIPE, SIG_IGN);
@@ -133,6 +153,15 @@ void do_child(int unix_fd, int inet_fd)
 	}
 #endif
 
+	/* Create per loop iteration memory context */
+	ChildLoopMemoryContext = AllocSetContextCreate(TopMemoryContext,
+											  "pgpool_child_main_loop",
+											  ALLOCSET_DEFAULT_MINSIZE,
+											  ALLOCSET_DEFAULT_INITSIZE,
+											  ALLOCSET_DEFAULT_MAXSIZE);
+
+	MemoryContextSwitchTo(TopMemoryContext);
+
 	/* Initialize my backend status */
 	pool_initialize_private_backend_status();
 
@@ -141,6 +170,7 @@ void do_child(int unix_fd, int inet_fd)
 
 	/* initialize random seed */
 	gettimeofday(&now, &tz);
+
 #if defined(sun) || defined(__sun)
 	srand((unsigned int) now.tv_usec);
 #else
@@ -168,47 +198,67 @@ void do_child(int unix_fd, int inet_fd)
 	timeout.tv_sec = pool_config->child_life_time;
 	timeout.tv_usec = 0;
 
+	if (sigsetjmp(local_sigjmp_buf, 1) != 0)
+	{
+		disable_authentication_timeout();
+		/* Since not using PG_TRY, must reset error stack by hand */
+		if (accepted)
+			connection_count_down();
+
+		if(frontend)
+		{
+			pool_close(frontend);
+			frontend = NULL;
+		}
+		error_context_stack = NULL;
+		EmitErrorReport();
+		MemoryContextSwitchTo(TopMemoryContext);
+		FlushErrorState();
+	}
+	/* We can now handle ereport(ERROR) */
+	PG_exception_stack = &local_sigjmp_buf;
+
 	for (;;)
 	{
 		StartupPacket *sp;
+		int front_end_fd;
+		SockAddr saddr;
+		connected = 0;
+		/* rest per iteration memory context */
+		MemoryContextSwitchTo(ChildLoopMemoryContext);
+		MemoryContextResetAndDeleteChildren(ChildLoopMemoryContext);
 
 		idle = 1;
 
 		/* pgpool stop request already sent? */
 		check_stop_request();
-
-		/* Check if restart request is set because of failback event
-		 * happend.  If so, exit myself with exit code 1 to be
-		 * restarted by pgpool parent.
-		 */
-		if (pool_get_my_process_info()->need_to_restart)
-		{
-			pool_log("do_child: failback event found. restart myself.");
-			pool_get_my_process_info()->need_to_restart = 0;
-			child_exit(1);
-		}
-
+		check_restart_request();
 		accepted = 0;
+		/* Destroy session context for just in case... */
+		pool_session_context_destroy();
 
-		/* perform accept() */
-		frontend = do_accept(unix_fd, inet_fd, &timeout);
-
-		if (frontend == NULL)	/* connection request from frontend timed out */
+		front_end_fd = wait_for_new_connections(unix_fd, inet_fd, &timeout, &saddr);
+		if(front_end_fd == OPERATION_TIMEOUT)
 		{
-			/* check select() timeout */
-			if (connected && pool_config->child_life_time > 0 &&
-				timeout.tv_sec == 0 && timeout.tv_usec == 0)
+			if(pool_config->child_life_time > 0 && connected)
 			{
-				pool_debug("child life %d seconds expired", pool_config->child_life_time);
-				/*
-				 * Doesn't need to call this. child_exit() calls it.
-				 * send_frontend_exits();
-				 */
+				ereport(DEBUG1,
+					(errmsg("child life %d seconds expired", pool_config->child_life_time)));
 				child_exit(2);
 			}
 			continue;
 		}
 
+		if(front_end_fd == RETRY)
+			continue;
+
+		connection_count_up();
+		accepted = 1;
+
+		check_config_reload();
+		validate_backend_connectivity(front_end_fd);
+		frontend = get_connection(front_end_fd,&saddr);
+
 		/* set frontend fd to blocking */
 		pool_unset_nonblock(frontend->fd);
 
@@ -222,138 +272,21 @@ void do_child(int unix_fd, int inet_fd)
 			backend_timer_expired = 0;
 		}
 
-		/* read the startup packet */
-	retry_startup:
-		sp = read_startup_packet(frontend);
-		if (sp == NULL)
-		{
-			/* failed to read the startup packet. return to the accept() loop */
-			pool_close(frontend);
-			connection_count_down();
-			continue;
-		}
-
-		/* cancel request? */
-		if (sp->major == 1234 && sp->minor == 5678)
+		backend = get_backend_connection(frontend);
+		if(!backend)
 		{
-			cancel_request((CancelPacket *)sp->startup_packet);
-
 			pool_close(frontend);
-			pool_free_startup_packet(sp);
-			connection_count_down();
+			frontend = NULL;
 			continue;
 		}
-
-		/* SSL? */
-		if (sp->major == 1234 && sp->minor == 5679 && !frontend->ssl_active)
-		{
-			pool_debug("SSLRequest from client");
-			pool_ssl_negotiate_serverclient(frontend);
-			pool_free_startup_packet(sp);
-			goto retry_startup;
-		}
-
-		if (pool_config->enable_pool_hba)
-		{
-			/*
-			 * do client authentication.
-			 * Note that ClientAuthentication does not return if frontend
-			 * was rejected; it simply terminates this process.
-			 */
-			frontend->protoVersion = sp->major;
-			frontend->database = strdup(sp->database);
-			if (frontend->database == NULL)
-			{
-				pool_error("do_child: strdup failed: %s\n", strerror(errno));
-				child_exit(1);
-			}
-			frontend->username = strdup(sp->user);
-			if (frontend->username == NULL)
-			{
-				pool_error("do_child: strdup failed: %s\n", strerror(errno));
-				child_exit(1);
-			}
-			ClientAuthentication(frontend);
-		}
-
-		/*
-		 * Ok, negotiation with frontend has been done. Let's go to the
-		 * next step.  Connect to backend if there's no existing
-		 * connection which can be reused by this frontend.
-		 * Authentication is also done in this step.
-		 */
-
-		/* Check if restart request is set because of failback event
-		 * happend.  If so, close idle connections to backend and make
-		 * a new copy of backend status.
-		 */
-		if (pool_get_my_process_info()->need_to_restart)
-		{
-			pool_log("do_child: failback event found. discard existing connections");
-			pool_get_my_process_info()->need_to_restart = 0;
-			close_idle_connection(0);
-			pool_initialize_private_backend_status();
-		}
-
+		connected = 1;
+	
 		/*
-		 * if there's no connection associated with user and database,
-		 * we need to connect to the backend and send the startup packet.
+		 * show ps status 
 		 */
-
-		/* look for existing connection */
-		found = 0;
-		backend = pool_get_cp(sp->user, sp->database, sp->major, 1);
-
-		if (backend != NULL)
-		{
-			found = 1;
-
-			/* existing connection associated with same user/database/major found.
-			 * however we should make sure that the startup packet contents are identical.
-			 * OPTION data and others might be different.
-			 */
-			if (sp->len != MASTER_CONNECTION(backend)->sp->len)
-			{
-				pool_debug("do_child: connection exists but startup packet length is not identical");
-				found = 0;
-			}
-			else if(memcmp(sp->startup_packet, MASTER_CONNECTION(backend)->sp->startup_packet, sp->len) != 0)
-			{
-				pool_debug("do_child: connection exists but startup packet contents is not identical");
-				found = 0;
-			}
-
-			if (found == 0)
-			{
-				/* we need to discard existing connection since startup packet is different */
-				pool_discard_cp(sp->user, sp->database, sp->major);
-				backend = NULL;
-			}
-		}
-
-		if (backend == NULL)
-		{
-			/* create a new connection to backend */
-			if ((backend = connect_backend(sp, frontend)) == NULL)
-			{
-				connection_count_down();
-				continue;
-			}
-		}
-
-		else
-		{
-			/* reuse existing connection */
-			if (!connect_using_existing_connection(frontend, backend, sp))
-				continue;
-		}
-
-		connected = 1;
-
- 		/* show ps status */
 		sp = MASTER_CONNECTION(backend)->sp;
 		snprintf(psbuf, sizeof(psbuf), "%s %s %s idle",
-				 sp->user, sp->database, remote_ps_data);
+								sp->user, sp->database, remote_ps_data);
 		set_ps_display(psbuf, false);
 
 		/*
@@ -361,13 +294,24 @@ void do_child(int unix_fd, int inet_fd)
 		 */
 		pool_init_session_context(frontend, backend);
 
-		/* Mark this connection pool is connected from frontend */
+		/*
+		 * Mark this connection pool is connected from frontend 
+		 */
 		pool_coninfo_set_frontend_connected(pool_get_process_context()->proc_id, pool_pool_index());
+		/* create memory context for query processing */
+		QueryProcessMemoryContext = AllocSetContextCreate(ChildLoopMemoryContext,
+										  "query_child_query_process",
+										  ALLOCSET_DEFAULT_MINSIZE,
+										  ALLOCSET_DEFAULT_INITSIZE,
+										  ALLOCSET_DEFAULT_MAXSIZE);
 
 		/* query process loop */
 		for (;;)
 		{
 			POOL_STATUS status;
+			/* Reset the query process memory context */
+			MemoryContextSwitchTo(QueryProcessMemoryContext);
+			MemoryContextResetAndDeleteChildren(QueryProcessMemoryContext);
 
 			status = pool_process_query(frontend, backend, 0);
 
@@ -390,6 +334,7 @@ void do_child(int unix_fd, int inet_fd)
 					{
 						reset_connection();
 						pool_close(frontend);
+						frontend = NULL;
 						pool_send_frontend_exits(backend);
 						pool_discard_cp(sp->user, sp->database, sp->major);
 					}
@@ -400,6 +345,7 @@ void do_child(int unix_fd, int inet_fd)
 						/* send reset request to backend */
 						status1 = pool_process_query(frontend, backend, 1);
 						pool_close(frontend);
+						frontend = NULL;
 
 						/* if we detect errors on resetting connection, we need to discard
 						 * this connection since it might be in unknown status
@@ -462,9 +408,11 @@ void do_child(int unix_fd, int inet_fd)
 		if ( ( pool_config->child_max_connections > 0 ) &&
 			( connections_count >= pool_config->child_max_connections ) )
 		{
-			pool_log("child exiting, %d connections reached", pool_config->child_max_connections);
-			send_frontend_exits();
-			child_exit(2);
+			ereport(FATAL,
+					(return_code(2),
+					errmsg("child exiting, %d connections reached", pool_config->child_max_connections)));
+//			send_frontend_exits();
+//			child_exit(2);
 		}
 	}
 	child_exit(0);
@@ -746,19 +694,19 @@ static POOL_CONNECTION *do_accept(int unix_fd, int inet_fd, struct timeval *time
 				found = 1;
 			}
 		}
+
 		if (found == 0)
 		{
-			pool_log("Cannot accept() new connection. all backends are down");
-			child_exit(1);
+			ereport(FATAL,
+				(errmsg("Cannot accept() new connection. all backends are down")));
+//			child_exit(1);
 		}
 	}
 
 	pool_debug("I am %d accept fd %d", getpid(), afd);
 
 	pool_getnameinfo_all(&saddr, remote_host, remote_port);
-	snprintf(remote_ps_data, sizeof(remote_ps_data),
-			 remote_port[0] == '\0' ? "%s" : "%s(%s)",
-			 remote_host, remote_port);
+	print_process_status(remote_host,remote_port);
 
 	set_ps_display("accept connection", false);
 
@@ -819,58 +767,25 @@ static StartupPacket *read_startup_packet(POOL_CONNECTION *cp)
 	int len;
 	char *p;
 
-	sp = (StartupPacket *)calloc(sizeof(*sp), 1);
-	if (!sp)
-	{
-		pool_error("read_startup_packet: out of memory");
-		return NULL;
-	}
-
-	if (pool_config->authentication_timeout > 0)
-	{
-		pool_signal(SIGALRM, authentication_timeout);
-		alarm(pool_config->authentication_timeout);
-	}
+	sp = (StartupPacket *)palloc0(sizeof(*sp));
+	enable_authentication_timeout();
 
 	/* read startup packet length */
-	if (pool_read(cp, &len, sizeof(len)))
-	{
-		pool_error("read_startup_packet: incorrect packet length (%d)", len);
-		pool_free_startup_packet(sp);
-		alarm(0);
-		pool_signal(SIGALRM, SIG_IGN);
-		return NULL;
-	}
+    pool_read_with_error(cp, &len, sizeof(len),
+                         "startup packet length");
+
 	len = ntohl(len);
 	len -= sizeof(len);
 
 	if (len <= 0 || len >= MAX_STARTUP_PACKET_LENGTH)
-	{
-		pool_error("read_startup_packet: incorrect packet length (%d)", len);
-		pool_free_startup_packet(sp);
-		alarm(0);
-		pool_signal(SIGALRM, SIG_IGN);
-		return NULL;
-	}
+		ereport(ERROR,
+			(errmsg("incorrect packet length (%d)", len)));
 
-	sp->startup_packet = calloc(len, 1);
-	if (!sp->startup_packet)
-	{
-		pool_error("read_startup_packet: out of memory");
-		pool_free_startup_packet(sp);
-		alarm(0);
-		pool_signal(SIGALRM, SIG_IGN);
-		return NULL;
-	}
+	sp->startup_packet = palloc0(len);
 
 	/* read startup packet */
-	if (pool_read(cp, sp->startup_packet, len))
-	{
-		pool_free_startup_packet(sp);
-		alarm(0);
-		pool_signal(SIGALRM, SIG_IGN);
-		return NULL;
-	}
+    pool_read_with_error(cp, sp->startup_packet, len,
+                         "startup packet");
 
 	sp->len = len;
 	memcpy(&protov, sp->startup_packet, sizeof(protov));
@@ -883,26 +798,10 @@ static StartupPacket *read_startup_packet(POOL_CONNECTION *cp)
 		case PROTO_MAJOR_V2: /* V2 */
 			sp2 = (StartupPacket_v2 *)(sp->startup_packet);
 
-			sp->database = calloc(SM_DATABASE+1, 1);
-			if (!sp->database)
-			{
-				pool_error("read_startup_packet: out of memory");
-				pool_free_startup_packet(sp);
-				alarm(0);
-				pool_signal(SIGALRM, SIG_IGN);
-				return NULL;
-			}
+			sp->database = palloc0(SM_DATABASE+1);
 			strncpy(sp->database, sp2->database, SM_DATABASE);
 
-			sp->user = calloc(SM_USER+1, 1);
-			if (!sp->user)
-			{
-				pool_error("read_startup_packet: out of memory");
-				pool_free_startup_packet(sp);
-				alarm(0);
-				pool_signal(SIGALRM, SIG_IGN);
-				return NULL;
-			}
+			sp->user = palloc0(SM_USER+1);
 			strncpy(sp->user, sp2->user, SM_USER);
 
 			break;
@@ -915,28 +814,12 @@ static StartupPacket *read_startup_packet(POOL_CONNECTION *cp)
 				if (!strcmp("user", p))
 				{
 					p += (strlen(p) + 1);
-					sp->user = strdup(p);
-					if (!sp->user)
-					{
-						pool_error("read_startup_packet: out of memory");
-						pool_free_startup_packet(sp);
-						alarm(0);
-						pool_signal(SIGALRM, SIG_IGN);
-						return NULL;
-					}
+					sp->user = pstrdup(p);
 				}
 				else if (!strcmp("database", p))
 				{
 					p += (strlen(p) + 1);
-					sp->database = strdup(p);
-					if (!sp->database)
-					{
-						pool_error("read_startup_packet: out of memory");
-						pool_free_startup_packet(sp);
-						alarm(0);
-						pool_signal(SIGALRM, SIG_IGN);
-						return NULL;
-					}
+					sp->database = pstrdup(p);
 				}
 
 				/*
@@ -953,7 +836,8 @@ static StartupPacket *read_startup_packet(POOL_CONNECTION *cp)
 				{
 					p += (strlen(p) + 1);
 					sp->application_name = p;
-					pool_debug("read_startup_packet: application_name: %s", p);
+                    ereport(DEBUG1,
+                            (errmsg("read_startup_packet: application_name: %s", p)));
 				}
 
 				p += (strlen(p) + 1);
@@ -962,32 +846,13 @@ static StartupPacket *read_startup_packet(POOL_CONNECTION *cp)
 
 		case 1234:		/* cancel or SSL request */
 			/* set dummy database, user info */
-			sp->database = calloc(1, 1);
-			if (!sp->database)
-			{
-				pool_error("read_startup_packet: out of memory");
-				pool_free_startup_packet(sp);
-				alarm(0);
-				pool_signal(SIGALRM, SIG_IGN);
-				return NULL;
-			}
-			sp->user = calloc(1, 1);
-			if (!sp->user)
-			{
-				pool_error("read_startup_packet: out of memory");
-				pool_free_startup_packet(sp);
-				alarm(0);
-				pool_signal(SIGALRM, SIG_IGN);
-				return NULL;
-			}
+			sp->database = palloc0(1);
+			sp->user = palloc(1);
 			break;
 
 		default:
-			pool_error("read_startup_packet: invalid major no: %d", sp->major);
-			pool_free_startup_packet(sp);
-			alarm(0);
-			pool_signal(SIGALRM, SIG_IGN);
-			return NULL;
+			ereport(ERROR,
+				(errmsg("invalid major no: %d in startup packet", sp->major)));
 	}
 
 	/* Check a user name was given. */
@@ -999,23 +864,19 @@ static StartupPacket *read_startup_packet(POOL_CONNECTION *cp)
 								"",
 								"",
 								__FILE__, __LINE__);
-		pool_error("read_startup_packet: no PostgreSQL user name specified in startup packet");
-		pool_free_startup_packet(sp);
-		alarm(0);
-		pool_signal(SIGALRM, SIG_IGN);
-		return NULL;
+		ereport(ERROR,
+			(errmsg("read_startup_packet: no PostgreSQL user name specified in startup packet")));
 	}
 
 	/* The database defaults to ther user name. */
 	if (sp->database == NULL || sp->database[0] == '\0')
 	{
-		sp->database = strdup(sp->user);
+		sp->database = pstrdup(sp->user);
 	}
 
 	pool_debug("Protocol Major: %d Minor: %d database: %s user: %s",
 			   sp->major, sp->minor, sp->database, sp->user);
-	alarm(0);
-	pool_signal(SIGALRM, SIG_IGN);
+	disable_authentication_timeout();
 	return sp;
 }
 
@@ -1039,6 +900,7 @@ static bool connect_using_existing_connection(POOL_CONNECTION *frontend,
 											  StartupPacket *sp)
 {
 	int i, freed = 0;
+	StartupPacket	*topmem_sp = NULL;
 	/*
 	 * Save startup packet info
 	 */
@@ -1048,10 +910,14 @@ static bool connect_using_existing_connection(POOL_CONNECTION *frontend,
 		{
 			if (!freed)
 			{
+				MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext);
+				topmem_sp = StartupPacketCopy(sp);
+				MemoryContextSwitchTo(oldContext);
+
 				pool_free_startup_packet(backend->slots[i]->sp);
 				freed = 1;
 			}
-			backend->slots[i]->sp = sp;
+			backend->slots[i]->sp = topmem_sp;
 		}
 	}
 
@@ -1059,8 +925,6 @@ static bool connect_using_existing_connection(POOL_CONNECTION *frontend,
 
 	if (pool_do_reauth(frontend, backend))
 	{
-		pool_close(frontend);
-		connection_count_down();
 		return false;
 	}
 
@@ -1094,8 +958,6 @@ static bool connect_using_existing_connection(POOL_CONNECTION *frontend,
 
 		if (send_params(frontend, backend))
 		{
-			pool_close(frontend);
-			connection_count_down();
 			return false;
 		}
 	}
@@ -1116,8 +978,6 @@ static bool connect_using_existing_connection(POOL_CONNECTION *frontend,
 
 	if (pool_flush(frontend) < 0)
 	{
-		pool_close(frontend);
-		connection_count_down();
 		return false;
 	}
 	return true;
@@ -1136,7 +996,8 @@ void cancel_request(CancelPacket *sp)
 	CancelPacket cp;
 	bool found = false;
 
-	pool_debug("Cancel request received");
+    ereport(DEBUG1,
+            (errmsg("Cancel request received")));
 
 	/* look for cancel key from shmem info */
 	for (i=0;i<pool_config->num_init_children;i++)
@@ -1209,9 +1070,38 @@ void cancel_request(CancelPacket *sp)
 	}
 }
 
+static StartupPacket *StartupPacketCopy(StartupPacket *sp)
+{
+	StartupPacket *new_sp;
+
+	/* verify the length first */
+	if (sp->len <= 0 || sp->len >= MAX_STARTUP_PACKET_LENGTH)
+		ereport(ERROR,
+			(errmsg("incorrect packet length (%d)", sp->len)));
+
+	new_sp = (StartupPacket *)palloc0(sizeof(*sp));
+	new_sp->startup_packet = palloc0(sp->len);
+	memcpy(new_sp->startup_packet,sp->startup_packet,sp->len);
+	new_sp->len = sp->len;
+
+	new_sp->major = sp->major;
+	new_sp->minor = sp->minor;
+
+	new_sp->database = pstrdup(sp->database);
+	new_sp->user = pstrdup(sp->user);
+
+	if(new_sp->major == PROTO_MAJOR_V3)
+	{
+		/* adjust the application name pointer in new packet */
+		new_sp->application_name = new_sp->startup_packet + (sp->application_name - sp->startup_packet);
+	}
+	return new_sp;
+}
+
 static POOL_CONNECTION_POOL *connect_backend(StartupPacket *sp, POOL_CONNECTION *frontend)
 {
 	POOL_CONNECTION_POOL *backend;
+	StartupPacket *topmem_sp;
 	int i;
 
 	/* connect to the backend */
@@ -1220,47 +1110,55 @@ static POOL_CONNECTION_POOL *connect_backend(StartupPacket *sp, POOL_CONNECTION
 	{
 		pool_send_error_message(frontend, sp->major, "XX000", "connection cache is full", "",
 								"increase max_pool", __FILE__, __LINE__);
-		pool_close(frontend);
-		pool_free_startup_packet(sp);
-		return NULL;
+		ereport(ERROR,
+			(errmsg("unable to to connect to backend"),
+				errdetail("connection cache is full"),
+					errhint("increase the \"max_pool\" configuration value, current max_pool is %d",pool_config->max_pool)));
 	}
-
-	for (i=0;i<NUM_BACKENDS;i++)
+	
+	PG_TRY();
 	{
-		if (VALID_BACKEND(i))
+		MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext);
+		topmem_sp = StartupPacketCopy(sp);
+		MemoryContextSwitchTo(oldContext);
+
+		for (i=0; i < NUM_BACKENDS; i++)
 		{
-			/* set DB node id */
-			CONNECTION(backend, i)->db_node_id = i;
+			if (VALID_BACKEND(i))
+			{
 
-			/* mark this is a backend connection */
-			CONNECTION(backend, i)->isbackend = 1;
-			pool_ssl_negotiate_clientserver(CONNECTION(backend, i));
+				/* set DB node id */
+				CONNECTION(backend, i)->db_node_id = i;
 
-			/*
-			 * save startup packet info
-			 */
-			CONNECTION_SLOT(backend, i)->sp = sp;
+				/* mark this is a backend connection */
+				CONNECTION(backend, i)->isbackend = 1;
+				pool_ssl_negotiate_clientserver(CONNECTION(backend, i));
 
-			/* send startup packet */
-			if (send_startup_packet(CONNECTION_SLOT(backend, i)) < 0)
-			{
-				pool_error("do_child: fails to send startup packet to the %d th backend", i);
-				pool_discard_cp(sp->user, sp->database, sp->major);
-				pool_close(frontend);
-				return NULL;
+				/*
+				 * save startup packet info
+				 */
+				CONNECTION_SLOT(backend, i)->sp = topmem_sp;
+
+				/* send startup packet */
+				if (send_startup_packet(CONNECTION_SLOT(backend, i)) < 0)
+				{
+					ereport(ERROR,
+						(errmsg("unable to to connect to backend"),
+							errdetail("failed to send startup packet to backend [%d].",i)));
+				}
 			}
 		}
+		/*
+		 * do authentication stuff
+		 */
+		pool_do_auth(frontend, backend);
 	}
-
-	/*
-	 * do authentication stuff
-	 */
-	if (pool_do_auth(frontend, backend))
+	PG_CATCH();
 	{
-		pool_close(frontend);
 		pool_discard_cp(sp->user, sp->database, sp->major);
-		return NULL;
+		PG_RE_THROW();
 	}
+	PG_END_TRY();
 
 	return backend;
 }
@@ -1345,10 +1243,30 @@ static RETSIGTYPE close_idle_connection(int sig)
  */
 static RETSIGTYPE authentication_timeout(int sig)
 {
+	alarm_enabled = false;
 	pool_log("authentication is timeout");
 	child_exit(1);
 }
 
+static void enable_authentication_timeout()
+{
+	if(pool_config->authentication_timeout <= 0)
+		return;
+	pool_signal(SIGALRM, authentication_timeout);
+	alarm(pool_config->authentication_timeout);
+	alarm_enabled = true;
+}
+
+static void disable_authentication_timeout()
+{
+	if(alarm_enabled)
+	{
+		alarm(0);
+		pool_signal(SIGALRM, SIG_IGN);
+		alarm_enabled = false;
+	}
+}
+
 /*
  * send frontend exiting messages to all connections.  this is called
  * in any case when child process exits, for example failover, child
@@ -1411,12 +1329,12 @@ void pool_free_startup_packet(StartupPacket *sp)
 	if (sp)
 	{
 		if (sp->startup_packet)
-			free(sp->startup_packet);
+			pfree(sp->startup_packet);
 		if (sp->database)
-			free(sp->database);
+			pfree(sp->database);
 		if (sp->user)
-			free(sp->user);
-		free(sp);
+			pfree(sp->user);
+		pfree(sp);
 	}
 	sp = NULL;
 }
@@ -1426,9 +1344,10 @@ void pool_free_startup_packet(StartupPacket *sp)
  */
 void child_exit(int code)
 {
-	if (getpid() == mypid)
+	if(processType != PT_CHILD)
 	{
-		pool_log("child_exit: called from pgpool main. ignored.");
+		/* should not happen */
+		pool_log("child_exit: called from invalid process. ignored.");
 		return;
 	}
 
@@ -1478,21 +1397,8 @@ POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection(
 	int len, len1;
 	int status;
 
-	cp = malloc(sizeof(POOL_CONNECTION_POOL_SLOT));
-	if (cp == NULL)
-	{
-		pool_error("make_persistent_db_connection: could not allocate memory");
-		return NULL;
-	}
-	memset(cp, 0, sizeof(POOL_CONNECTION_POOL_SLOT));
-
-	startup_packet = malloc(sizeof(*startup_packet));
-	if (startup_packet == NULL)
-	{
-		pool_error("make_persistent_db_connection: could not allocate memory");
-		return NULL;
-	}
-	memset(startup_packet, 0, sizeof(*startup_packet));
+	cp = palloc0(sizeof(POOL_CONNECTION_POOL_SLOT));
+	startup_packet = palloc0(sizeof(*startup_packet));
 	startup_packet->protoVersion = htonl(0x00030000);	/* set V3 proto major/minor */
 
 	/*
@@ -1509,8 +1415,10 @@ POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection(
 
 	if (fd < 0)
 	{
-		pool_error("make_persistent_db_connection: connection to %s(%d) failed", hostname, port);
-		return NULL;
+        ereport(ERROR,
+                (errmsg("failed to make persistent db connection"),
+                 errdetail("connection to %s(%d) failed", hostname, port)));
+
 	}
 
 	cp->con = pool_open(fd);
@@ -1525,51 +1433,39 @@ POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection(
 	len1 = snprintf(&startup_packet->data[len], sizeof(startup_packet->data)-len, "%s", user) + 1;
 	if (len1 >= (sizeof(startup_packet->data)-len))
 	{
-		pool_error("make_persistent_db_connection: too long user name");
-		return NULL;
+        ereport(ERROR,
+                (errmsg("failed to make persistent db connection"),
+                 errdetail("user name is too long")));
 	}
 
 	len += len1;
 	len1 = snprintf(&startup_packet->data[len], sizeof(startup_packet->data)-len, "database") + 1;
 	if (len1 >= (sizeof(startup_packet->data)-len))
 	{
-		pool_error("make_persistent_db_connection: too long user name");
-		return NULL;
+        ereport(ERROR,
+                (errmsg("failed to make persistent db connection"),
+                 errdetail("user name is too long")));
 	}
 
 	len += len1;
 	len1 = snprintf(&startup_packet->data[len], sizeof(startup_packet->data)-len, "%s", dbname) + 1;
 	if (len1 >= (sizeof(startup_packet->data)-len))
 	{
-		pool_error("make_persistent_db_connection: too long database name");
-		return NULL;
+        ereport(ERROR,
+                (errmsg("failed to make persistent db connection"),
+                 errdetail("database name is too long")));
 	}
 	len += len1;
 	startup_packet->data[len++] = '\0';
 
-	cp->sp = malloc(sizeof(StartupPacket));
-	if (cp->sp == NULL)
-	{
-		pool_error("make_persistent_db_connection: could not allocate memory");
-		return NULL;
-	}
+	cp->sp = palloc(sizeof(StartupPacket));
 
 	cp->sp->startup_packet = (char *)startup_packet;
 	cp->sp->len = len + 4;
 	cp->sp->major = 3;
 	cp->sp->minor = 0;
-	cp->sp->database = strdup(dbname);
-	if (cp->sp->database == NULL)
-	{
-		pool_error("make_persistent_db_connection: could not allocate memory");
-		return NULL;
-	}
-	cp->sp->user = strdup(user);
-	if (cp->sp->user == NULL)
-	{
-		pool_error("make_persistent_db_connection: could not allocate memory");
-		return NULL;
-	}
+	cp->sp->database = pstrdup(dbname);
+	cp->sp->user = pstrdup(user);
 
 	/*
 	 * send startup packet
@@ -1577,8 +1473,10 @@ POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection(
 	status = send_startup_packet(cp);
 	if (status)
 	{
-		pool_error("make_persistent_db_connection: send_startup_packet failed");
-		return NULL;
+        ereport(ERROR,
+                (errmsg("failed to make persistent db connection"),
+                 errdetail("unable to send startup packet")));
+
 	}
 
 	/*
@@ -1586,8 +1484,9 @@ POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection(
 	 */
 	if (s_do_auth(cp, password))
 	{
-		pool_error("make_persistent_db_connection: s_do_auth failed");
-		return NULL;
+        ereport(ERROR,
+                (errmsg("failed to make persistent db connection"),
+                 errdetail("authentication failed")));
 	}
 
 	return cp;
@@ -1620,11 +1519,11 @@ void discard_persistent_db_connection(POOL_CONNECTION_POOL_SLOT *cp)
 	pool_unset_nonblock(cp->con->fd);
 
 	pool_close(cp->con);
-	free(cp->sp->startup_packet);
-	free(cp->sp->database);
-	free(cp->sp->user);
-	free(cp->sp);
-	free(cp);
+	pfree(cp->sp->startup_packet);
+	pfree(cp->sp->database);
+	pfree(cp->sp->user);
+	pfree(cp->sp);
+	pfree(cp);
 }
 
 /*
@@ -1645,37 +1544,28 @@ static int s_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password)
 	/*
 	 * read kind expecting 'R' packet (authentication response)
 	 */
-	status = pool_read(cp->con, &kind, sizeof(kind));
-	if (status < 0)
-	{
-		pool_error("s_do_auth: error while reading message kind");
-		return -1;
-	}
+	pool_read_with_error(cp->con, &kind, sizeof(kind),
+                                  "authentication message response type");
 
 	if (kind != 'R')
 	{
-		pool_error("s_do_auth: expecting R got %c", kind);
-		return -1;
+        ereport(ERROR,
+                (errmsg("failed to authenticate"),
+                 errdetail("invalid authentication message response type, Expecting 'R' and received '%c'",kind)));
 	}
 
 	/* read message length */
-	status = pool_read(cp->con, &length, sizeof(length));
-	if (status < 0)
-	{
-		pool_error("s_do_auth: error while reading message length");
-		return -1;
-	}
+	pool_read_with_error(cp->con, &length, sizeof(length),
+                         "authentication message response length");
+
 	length = ntohl(length);
 
 	/* read auth kind */
-	status = pool_read(cp->con, &auth_kind, sizeof(auth_kind));
-	if (status < 0)
-	{
-		pool_error("s_do_auth: error while reading auth kind");
-		return -1;
-	}
+	pool_read_with_error(cp->con, &auth_kind, sizeof(auth_kind),
+                       "authentication method from response");
 	auth_kind = ntohl(auth_kind);
-	pool_debug("s_do_auth: auth kind: %d", auth_kind);
+    ereport(DEBUG1,
+            (errmsg("authenticate kind = %d",auth_kind)));
 
 	if (auth_kind == 0)	/* trust authentication? */
 	{
@@ -1691,8 +1581,9 @@ static int s_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password)
 		status = pool_flush(cp->con);
 		if (status > 0)
 		{
-			pool_error("s_do_auth: error while sending clear text password");
-			return -1;
+            ereport(ERROR,
+                    (errmsg("failed to authenticate"),
+                     errdetail("error while sending clear text password")));
 		}
 		return s_do_auth(cp, password);
 	}
@@ -1702,12 +1593,7 @@ static int s_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password)
 		char salt[3];
 		char *crypt_password;
 
-		status = pool_read(cp->con, &salt, 2);
-		if (status > 0)
-		{
-			pool_error("s_do_auth: error while reading crypt salt");
-			return -1;
-		}
+		pool_read_with_error(cp->con, &salt, 2,"crypt salt");
 		salt[2] = '\0';
 
 		crypt_password = crypt(password, salt);
@@ -1718,8 +1604,9 @@ static int s_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password)
 		status = pool_flush(cp->con);
 		if (status > 0)
 		{
-			pool_error("s_do_auth: error while sending crypt password");
-			return -1;
+            ereport(ERROR,
+                    (errmsg("failed to authenticate"),
+                     errdetail("error while sending crypt password")));
 		}
 		return s_do_auth(cp, password);
 	}
@@ -1729,20 +1616,9 @@ static int s_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password)
 		char *buf, *buf1;
 		int size;
 
-		status = pool_read(cp->con, &salt, 4);
-		if (status > 0)
-		{
-			pool_error("s_do_auth: error while reading md5 salt");
-			return -1;
-		}
+		pool_read_with_error(cp->con, &salt, 4,"authentication md5 salt");
 
-		buf = malloc(2 * (MD5_PASSWD_LEN + 4)); /* hash + "md5" + '\0' */
-		if (buf == NULL)
-		{
-			pool_error("s_do_auth(): malloc failed: %s", strerror(errno));
-			return -1;
-		}
-		memset(buf, 0, 2 * (MD5_PASSWD_LEN + 4));
+		buf = palloc0(2 * (MD5_PASSWD_LEN + 4)); /* hash + "md5" + '\0' */
 
 		/* build md5 password */
 		buf1 = buf + MD5_PASSWD_LEN + 4;
@@ -1757,18 +1633,20 @@ static int s_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password)
 		status = pool_flush(cp->con);
 		if (status > 0)
 		{
-			pool_error("s_do_auth: error while sending md5 password");
-			return -1;
+            ereport(ERROR,
+                    (errmsg("failed to authenticate"),
+                     errdetail("error while sending md5 password")));
 		}
 
 		status = s_do_auth(cp, password);
-		free(buf);
+		pfree(buf);
 		return status;
 	}
 	else
 	{
-		pool_error("s_do_auth: auth kind %d not supported yet", auth_kind);
-		return -1;
+        ereport(ERROR,
+                (errmsg("failed to authenticate"),
+                 errdetail("auth kind %d not supported yet", auth_kind)));
 	}
 
 	/*
@@ -1780,12 +1658,8 @@ static int s_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password)
 
 	for (;;)
 	{
-		status = pool_read(cp->con, &kind, sizeof(kind));
-		if (status < 0)
-		{
-			pool_error("s_do_auth: error while reading message kind");
-			return -1;
-		}
+		pool_read_with_error(cp->con, &kind, sizeof(kind),
+                                      "authentication message kind");
 
 		switch (kind)
 		{
@@ -1794,52 +1668,32 @@ static int s_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password)
 				pool_debug("s_do_auth: backend key data received");
 
 				/* read message length */
-				status = pool_read(cp->con, &length, sizeof(length));
-				if (status < 0)
-				{
-					pool_error("s_do_auth: error while reading message length");
-					return -1;
-				}
+				pool_read_with_error(cp->con, &length, sizeof(length),"message length for authentication kind 'K'");
 				if (ntohl(length) != 12)
 				{
 					pool_error("s_do_auth: backend key data length is not 12 (%d)", ntohl(length));
 				}
 
 				/* read pid */
-				if (pool_read(cp->con, &pid, sizeof(pid)) < 0)
-				{
-					pool_error("s_do_auth: failed to read pid");
-					return -1;
-				}
+				pool_read_with_error(cp->con, &pid, sizeof(pid),"pid for authentication kind 'K'");
 				cp->pid = pid;
 
 				/* read key */
-				if (pool_read(cp->con, &key, sizeof(key)) < 0)
-				{
-					pool_error("s_do_auth: failed to read key");
-					return -1;
-				}
+				pool_read_with_error(cp->con, &key, sizeof(key),
+                                     "key for authentication kind 'K'");
 				cp->key = key;
 				break;
 
 			case 'Z':	/* Ready for query */
 				/* read message length */
-				status = pool_read(cp->con, &length, sizeof(length));
-				if (status < 0)
-				{
-					pool_error("s_do_auth: error while reading message length");
-					return -1;
-				}
+				pool_read_with_error(cp->con, &length, sizeof(length),
+                                   "message length for authentication kind 'Z'");
 				length = ntohl(length);
 
 				/* read transaction state */
-				status = pool_read(cp->con, &state, sizeof(state));
-				if (status < 0)
-				{
-					pool_error("s_do_auth: error while reading transaction state");
-					return -1;
-				}
-
+				pool_read_with_error(cp->con, &state, sizeof(state),
+                                     "transaction state  for authentication kind 'Z'");
+			
 				pool_debug("s_do_auth: transaction state: %c", state);
 				cp->con->tstate = state;
 
@@ -1854,13 +1708,9 @@ static int s_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password)
 			case 'N':	/* notice response */
 			case 'E':	/* error response */
 				/* Just throw away data */
-				status = pool_read(cp->con, &length, sizeof(length));
-				if (status < 0)
-				{
-					pool_error("s_do_auth: error while reading message length. kind:%c", kind);
-					return -1;
-				}
-
+				pool_read_with_error(cp->con, &length, sizeof(length),
+                                   "backend message length");
+			
 				length = ntohl(length);
 				length -= 4;
 
@@ -2013,7 +1863,10 @@ static void init_system_db_connection(void)
 		system_db_connect();
 		if (PQstatus(system_db_info->pgconn) != CONNECTION_OK)
 		{
-			pool_error("Could not make persistent libpq system DB connection");
+            ereport(ERROR,
+                    (errmsg("failed to make persistent system db connection"),
+                     errdetail("system_db_connect failed")));
+
 		}
 
 		system_db_info->connection = make_persistent_db_connection(pool_config->system_db_hostname,
@@ -2021,10 +1874,6 @@ static void init_system_db_connection(void)
 																   pool_config->system_db_dbname,
 																   pool_config->system_db_user,
 																   pool_config->system_db_password, false);
-		if (system_db_info->connection == NULL)
-		{
-			pool_error("Could not make persistent system DB connection");
-		}
 	}
 }
 
@@ -2048,3 +1897,517 @@ void pool_initialize_private_backend_status(void)
 
 	my_master_node_id = REAL_MASTER_NODE_ID;
 }
+
+static void check_restart_request()
+{
+	/* Check if restart request is set because of failback event
+	* happend.  If so, exit myself with exit code 1 to be
+	* restarted by pgpool parent.
+	*/
+	if (pool_get_my_process_info()->need_to_restart)
+	{
+		pool_log("do_child: failback event found. restart myself.");
+		pool_get_my_process_info()->need_to_restart = 0;
+		child_exit(1);
+	}
+}
+
+/*
+ * wait_for_new_connections()
+ * functions calls select on sockets and wait for new client
+ * to connect, on successfull connection returns the socket descriptor
+ * and returns -1 if timeout has occured
+ */
+static int wait_for_new_connections(int unix_fd, int inet_fd, struct timeval *timeout, SockAddr *saddr)
+{
+	fd_set	readmask;
+    int fds;
+	int save_errno;
+
+	int fd = 0;
+	int afd;
+
+#ifdef ACCEPT_PERFORMANCE
+	struct timeval now1, now2;
+	static long atime;
+	static int cnt;
+#endif
+	struct timeval *timeoutval;
+	struct timeval tv1, tv2, tmback = {0, 0};
+
+	set_ps_display("wait for connection request", false);
+
+	FD_ZERO(&readmask);
+	FD_SET(unix_fd, &readmask);
+	if (inet_fd)
+		FD_SET(inet_fd, &readmask);
+
+	if (timeout->tv_sec == 0 && timeout->tv_usec == 0)
+		timeoutval = NULL;
+	else
+	{
+		timeoutval = timeout;
+		tmback.tv_sec = timeout->tv_sec;
+		tmback.tv_usec = timeout->tv_usec;
+		gettimeofday(&tv1, NULL);
+
+#ifdef DEBUG
+		pool_log("before select = {%d, %d}", timeoutval->tv_sec, timeoutval->tv_usec);
+		pool_log("g:before select = {%d, %d}", tv1.tv_sec, tv1.tv_usec);
+#endif
+	}
+
+	fds = select(Max(unix_fd, inet_fd)+1, &readmask, NULL, NULL, timeoutval);
+
+	save_errno = errno;
+	/* check backend timer is expired */
+	if (backend_timer_expired)
+	{
+		pool_backend_timer();
+		backend_timer_expired = 0;
+	}
+
+	/*
+	 * following code fragment computes remaining timeout val in a
+	 * portable way. Linux does this automatically but other platforms do not.
+	 */
+	if (timeoutval)
+	{
+		gettimeofday(&tv2, NULL);
+
+		tmback.tv_usec -= tv2.tv_usec - tv1.tv_usec;
+		tmback.tv_sec -= tv2.tv_sec - tv1.tv_sec;
+
+		if (tmback.tv_usec < 0)
+		{
+			tmback.tv_sec--;
+			if (tmback.tv_sec < 0)
+			{
+				timeout->tv_sec = 0;
+				timeout->tv_usec = 0;
+			}
+			else
+			{
+				tmback.tv_usec += 1000000;
+				timeout->tv_sec = tmback.tv_sec;
+				timeout->tv_usec = tmback.tv_usec;
+			}
+		}
+#ifdef DEBUG
+		pool_log("g:after select = {%d, %d}", tv2.tv_sec, tv2.tv_usec);
+		pool_log("after select = {%d, %d}", timeout->tv_sec, timeout->tv_usec);
+#endif
+	}
+
+	errno = save_errno;
+
+	if (fds == -1)
+	{
+		if (errno == EAGAIN || errno == EINTR)
+			return RETRY;
+		ereport(ERROR,
+			(errmsg("failed to accept user connection"),
+				errdetail("select on socket failed with error : \"%s\"",strerror(errno))));
+	}
+
+	/* timeout */
+	if (fds == 0)
+	{
+		return OPERATION_TIMEOUT;
+	}
+	/* check unix domain socket */
+	if (FD_ISSET(unix_fd, &readmask))
+	{
+		fd = unix_fd;
+	}
+	/* check inet socket */
+	if (FD_ISSET(inet_fd, &readmask))
+	{
+		fd = inet_fd;
+		//inet++;
+//		*inet = true;
+	}
+	/*
+	 * Note that some SysV systems do not work here. For those
+	 * systems, we need some locking mechanism for the fd.
+	 */
+	memset(saddr, 0, sizeof(*saddr));
+	saddr->salen = sizeof(saddr->addr);
+
+#ifdef ACCEPT_PERFORMANCE
+	gettimeofday(&now1,0);
+#endif
+
+ retry_accept:
+
+	/* wait if recovery is started */
+	while (*InRecovery == 1)
+	{
+		pause();
+	}
+
+	afd = accept(fd, (struct sockaddr *)&saddr->addr, &saddr->salen);
+	
+	save_errno = errno;
+	/* check backend timer is expired */
+	if (backend_timer_expired)
+	{
+		pool_backend_timer();
+		backend_timer_expired = 0;
+	}
+	errno = save_errno;
+	if (afd < 0)
+	{
+		if (errno == EINTR && *InRecovery)
+			goto retry_accept;
+
+		/*
+		 * "Resource temporarily unavailable" (EAGAIN or EWOULDBLOCK)
+		 * can be silently ignored. And EINTR can be ignored.
+		 */
+		if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
+			ereport(ERROR,
+				(errmsg("failed to accept user connection"),
+					errdetail("accept on socket failed with error : \"%s\"",strerror(errno))));
+		return RETRY;
+
+	}
+#ifdef ACCEPT_PERFORMANCE
+	gettimeofday(&now2,0);
+	atime += (now2.tv_sec - now1.tv_sec)*1000000 + (now2.tv_usec - now1.tv_usec);
+	cnt++;
+	if (cnt % 100 == 0)
+	{
+		pool_log("cnt: %d atime: %ld", cnt, atime);
+	}
+#endif
+	return afd;
+}
+
+static void check_config_reload()
+{
+	/* reload config file */
+	if (got_sighup)
+	{
+		pool_get_config(get_config_file_name(), RELOAD_CONFIG);
+		if (pool_config->enable_pool_hba)
+		{
+			load_hba(get_hba_file_name());
+			if (strcmp("", pool_config->pool_passwd))
+				pool_reopen_passwd_file();
+		}
+		if (pool_config->parallel_mode)
+			pool_memset_system_db_info(system_db_info->info);
+		got_sighup = 0;
+	}
+}
+
+static void get_backends_status(unsigned int *valid_backends, unsigned int *down_backends)
+{
+	int i;
+	*down_backends = 0;
+	*valid_backends = 0;	
+	for (i=0;i<NUM_BACKENDS;i++)
+	{
+		if (BACKEND_INFO(i).backend_status == CON_DOWN)
+			(*down_backends)++;
+		else if(VALID_BACKEND(i))
+			(*valid_backends)++;
+	}
+}
+
+static void validate_backend_connectivity(int front_end_fd)
+{
+	unsigned int valid_backends;
+	unsigned int down_backends;
+	bool fatal_error = false;
+	char *error_msg = NULL;
+	char *error_detail= NULL;
+	char *error_hint = NULL;
+
+	get_backends_status(&valid_backends,&down_backends);
+	if (pool_config->parallel_mode)
+	{
+		/* Not even a single node is allowed to be down
+		 * when opperating in the parallel mode 
+		 */
+		 if(SYSDB_STATUS == CON_DOWN || down_backends > 0)
+		 {
+			 fatal_error = true;
+			 error_msg = "pgpool is not available in parallel query mode";
+			if(SYSDB_STATUS == CON_DOWN)
+			{
+				error_detail = "SystemDB status is down";
+				error_hint = "repair the SystemDB and restart pgpool";
+			}
+			else
+			{
+				error_detail = palloc(255);
+				snprintf(error_detail, 255, "%d backend nodes are down", down_backends);
+				error_hint = "repair the backend nodes and restart pgpool";
+			}
+		 }
+	}
+	else
+	{
+		/* In non parallel mode single valid backend is all we need 
+		 * to continue 
+		 */
+		if(valid_backends == 0)
+		{
+			fatal_error = true;
+			error_msg = "pgpool is not accepting any new connections";
+			error_detail = "all backend nodes are down, pgpool requires atleast one valid node";
+			error_hint = "repair the backend nodes and restart pgpool";
+		}
+	}
+	if(fatal_error)
+	{
+		/* check if we can inform the connecting client about the current
+		 * situation before throwing the error
+		 */
+		 
+		if(front_end_fd > 0)
+		{
+			POOL_CONNECTION *cp;
+			StartupPacket *sp;
+
+			/* we do not want to report socket error, as above errors
+			 * will be more informative 
+			 */
+			PG_TRY();
+			{
+				if ((cp = pool_open(front_end_fd)) == NULL)
+				{
+					close(front_end_fd); //todo
+					child_exit(1);
+				}
+				sp = read_startup_packet(cp);
+				ereport(DEBUG1,
+					(errmsg("forwarding error message to frontend")));
+
+				if (sp->major == PROTO_MAJOR_V3)
+				{
+					pool_send_error_message(cp, sp->major, "08S01",
+											error_msg,
+											error_detail,
+											error_hint,
+											__FILE__,
+											__LINE__);
+				}
+				else
+				{
+					pool_send_error_message(cp, sp->major,
+											0,
+											error_msg,
+											error_detail,
+											error_hint,
+											__FILE__,
+											__LINE__);
+				}
+			}
+			PG_CATCH();
+			{
+				ereport(FATAL,
+					(errmsg("%s",error_msg),errdetail("%s",error_detail),errhint("%s",error_hint)));
+			}
+			PG_END_TRY();
+		}
+		ereport(FATAL,
+			(errmsg("%s",error_msg),errdetail("%s",error_detail),errhint("%s",error_hint)));
+	}
+	/* Every thing is good if we have reached this point */
+}
+
+/*
+ * returns the POOL_CONNECTION object from socket descriptor
+ * the socket must be already accepted
+ */
+static POOL_CONNECTION *get_connection(int front_end_fd, SockAddr *saddr)
+{
+	POOL_CONNECTION *cp;
+
+	ereport(DEBUG1,
+		(errmsg("I am %d accept fd %d", getpid(), front_end_fd)));
+
+	pool_getnameinfo_all(saddr, remote_host, remote_port);
+	print_process_status(remote_host, remote_port);
+
+	set_ps_display("accept connection", false);
+
+	/* log who is connecting */
+//	if (pool_config->log_connections)
+//	{
+		pool_log("connection received: host=%s%s%s",
+				 remote_host, remote_port[0] ? " port=" : "", remote_port);
+//	}
+
+	/* set NODELAY and KEEPALIVE options if INET connection */
+	if (saddr->addr.ss_family == AF_INET)
+	{
+		int on = 1;
+
+		if (setsockopt(front_end_fd, IPPROTO_TCP, TCP_NODELAY,
+					   (char *) &on,
+					   sizeof(on)) < 0)
+		{
+//			close(front_end_fd);
+			ereport(ERROR,
+				(errmsg("failed to accept user connection"),
+					errdetail("setsockopt on socket failed with error : \"%s\"",strerror(errno))));
+		}
+		if (setsockopt(front_end_fd, SOL_SOCKET, SO_KEEPALIVE,
+					   (char *) &on,
+					   sizeof(on)) < 0)
+		{
+			ereport(ERROR,
+				(errmsg("failed to accept user connection"),
+					errdetail("setsockopt on socket failed with error : \"%s\"",strerror(errno))));
+		}
+	}
+
+	if ((cp = pool_open(front_end_fd)) == NULL)
+	{
+		close(front_end_fd);
+			ereport(ERROR,
+				(errmsg("failed to accept user connection"),
+					errdetail("unable to open connection with remote end : \"%s\"",strerror(errno))));
+	}
+
+	/* save ip address for hba */
+	memcpy(&cp->raddr, saddr, sizeof(SockAddr));
+	if (cp->raddr.addr.ss_family == 0)
+		cp->raddr.addr.ss_family = AF_UNIX;
+
+	return cp;
+}
+
+static POOL_CONNECTION_POOL *get_backend_connection(POOL_CONNECTION *frontend)
+{
+	int found = 0;
+	StartupPacket *sp;
+	POOL_CONNECTION_POOL *backend;
+	/* read the startup packet */
+retry_startup:
+	sp = read_startup_packet(frontend);
+
+	/* cancel request? */
+	if (sp->major == 1234 && sp->minor == 5678)
+	{
+		cancel_request((CancelPacket *)sp->startup_packet);
+		pool_free_startup_packet(sp);
+		return NULL;
+	}
+
+	/* SSL? */
+	if (sp->major == 1234 && sp->minor == 5679 && !frontend->ssl_active)
+	{
+		pool_debug("SSLRequest from client");
+		pool_ssl_negotiate_serverclient(frontend);
+		pool_free_startup_packet(sp);
+		goto retry_startup;
+	}
+
+	if (pool_config->enable_pool_hba)
+	{
+		/*
+		 * do client authentication.
+		 * Note that ClientAuthentication does not return if frontend
+		 * was rejected; it simply terminates this process.
+		 */
+		frontend->protoVersion = sp->major;
+		frontend->database = pstrdup(sp->database);
+		frontend->username = pstrdup(sp->user);
+		ClientAuthentication(frontend);
+	}
+
+	/*
+	 * Ok, negotiation with frontend has been done. Let's go to the
+	 * next step.  Connect to backend if there's no existing
+	 * connection which can be reused by this frontend.
+	 * Authentication is also done in this step.
+	 */
+
+	/* Check if restart request is set because of failback event
+	 * happened.  If so, close idle connections to backend and make
+	 * a new copy of backend status.
+	 */
+	if (pool_get_my_process_info()->need_to_restart)
+	{
+		pool_log("do_child: failback event found. discard existing connections");
+		pool_get_my_process_info()->need_to_restart = 0;
+		close_idle_connection(0);
+		pool_initialize_private_backend_status();
+	}
+
+	/*
+	 * if there's no connection associated with user and database,
+	 * we need to connect to the backend and send the startup packet.
+	 */
+
+	/* look for an existing connection */
+	found = 0;
+
+	backend = pool_get_cp(sp->user, sp->database, sp->major, 1);
+	
+	if (backend != NULL)
+	{
+		found = 1;
+		/* 
+		 * existing connection associated with same user/database/major found.
+		 * however we should make sure that the startup packet contents are identical.
+		 * OPTION data and others might be different.
+		 */
+		if (sp->len != MASTER_CONNECTION(backend)->sp->len)
+		{
+			ereport(DEBUG1,
+				(errmsg("connection exists but startup packet length is not identical")));
+			found = 0;
+		}
+		else if(memcmp(sp->startup_packet, MASTER_CONNECTION(backend)->sp->startup_packet, sp->len) != 0)
+		{
+			ereport(DEBUG1,
+				(errmsg("connection exists but startup packet contents is not identical")));
+			found = 0;
+		}
+
+		if (found == 0)
+		{
+			/* we need to discard existing connection since startup packet is different */
+			pool_discard_cp(sp->user, sp->database, sp->major);
+			backend = NULL;
+		}
+	}
+
+	if (backend == NULL)
+	{
+		/* create a new connection to backend */
+		backend = connect_backend(sp, frontend);
+	}
+	else
+	{
+		/* reuse existing connection */
+		if (!connect_using_existing_connection(frontend, backend, sp))
+			return NULL;
+	}
+
+	pool_free_startup_packet(sp);
+	return backend;
+}
+
+static void print_process_status(char *remote_host,char* remote_port)
+{
+	if(remote_port[0] == '\0')
+		snprintf(remote_ps_data, sizeof(remote_ps_data),"%s",remote_port);
+	else
+		snprintf(remote_ps_data, sizeof(remote_ps_data),"%s(%s)",remote_host, remote_port);
+}
+
+bool is_session_connected()
+{
+	if(processType == PT_CHILD)
+		return (pool_get_session_context() != NULL);
+	return false;
+}
+
+
diff --git a/src/protocol/pool_connection_pool.c b/src/protocol/pool_connection_pool.c
index 7348305..10bcaf6 100644
--- a/src/protocol/pool_connection_pool.c
+++ b/src/protocol/pool_connection_pool.c
@@ -44,6 +44,7 @@
 
 #include "pool.h"
 #include "utils/pool_stream.h"
+#include "utils/palloc.h"
 #include "pool_config.h"
 #include "context/pool_process_context.h"
 
@@ -62,12 +63,7 @@ int pool_init_cp(void)
 {
 	int i;
 
-	pool_connection_pool = (POOL_CONNECTION_POOL *)malloc(sizeof(POOL_CONNECTION_POOL)*pool_config->max_pool);
-	if (pool_connection_pool == NULL)
-	{
-		pool_error("pool_init_cp: malloc() failed");
-		return -1;
-	}
+	pool_connection_pool = (POOL_CONNECTION_POOL *)palloc(sizeof(POOL_CONNECTION_POOL)*pool_config->max_pool);
 	memset(pool_connection_pool, 0, sizeof(POOL_CONNECTION_POOL)*pool_config->max_pool);
 
 	for (i = 0; i < pool_config->max_pool; i++)
@@ -157,7 +153,7 @@ POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, in
 						}
 
 						pool_close(CONNECTION(p, j));
-						free(CONNECTION_SLOT(p, j));
+						pfree(CONNECTION_SLOT(p, j));
 					}
 					info = p->info;
 					memset(p, 0, sizeof(POOL_CONNECTION_POOL_SLOT));
@@ -204,7 +200,7 @@ void pool_discard_cp(char *user, char *database, int protoMajor)
 			freed = 1;
 		}
 		pool_close(CONNECTION(p, i));
-		free(CONNECTION_SLOT(p, i));
+		pfree(CONNECTION_SLOT(p, i));
 	}
 
 	info = p->info;
@@ -726,12 +722,7 @@ static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p)
 			continue;
 		}
 
-		s = malloc(sizeof(POOL_CONNECTION_POOL_SLOT));
-		if (s == NULL)
-		{
-			pool_error("new_connection: malloc() failed");
-			return NULL;
-		}
+		s = palloc(sizeof(POOL_CONNECTION_POOL_SLOT));
 
 		if (create_cp(s, i) == NULL)
 		{
diff --git a/src/protocol/pool_process_query.c b/src/protocol/pool_process_query.c
index 6d94f12..d04532d 100644
--- a/src/protocol/pool_process_query.c
+++ b/src/protocol/pool_process_query.c
@@ -237,7 +237,7 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend,
 
 			/*
 			 * ProcessFrontendResponse() may start query
-			 * processing. We need to recheck
+			 * processing. We need to re-check
 			 * pool_is_query_in_progress() here.
 			 */
 			if (pool_is_query_in_progress())
@@ -300,12 +300,8 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend,
 									/* If master does not have pending
 									 * data, we discard one packet from
 									 * other backend */
-									status = pool_read(CONNECTION(backend, i), &kind, sizeof(kind));
-									if (status < 0)
-									{
-										pool_error("pool_process_query: error while reading message kind from backend %d", i);
-										return POOL_ERROR;
-									}
+									pool_read_with_error(CONNECTION(backend, i), &kind, sizeof(kind),
+											"reading message kind from backend");
 
 									if (kind == 'A')
 									{
@@ -318,11 +314,9 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend,
 										 */
 										pool_unread(CONNECTION(backend, i), &kind, sizeof(kind));
 										pool_log("pool_process_query: received %c packet from backend %d. Don't dicard and read %c packet from master", kind, i, kind);
-										if (pool_read(CONNECTION(backend, MASTER_NODE_ID), &kind, sizeof(kind)) < 0)
-										{
-											pool_error("pool_process_query: error while reading message kind from backend %d", MASTER_NODE_ID);
-											return POOL_ERROR;
-										}
+										pool_read_with_error(CONNECTION(backend, MASTER_NODE_ID), &kind, sizeof(kind),
+												"reading message kind from backend");
+
 										pool_unread(CONNECTION(backend, MASTER_NODE_ID), &kind, sizeof(kind));
 									}
 									else
@@ -331,11 +325,8 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend,
 
 										if (MAJOR(backend) == PROTO_MAJOR_V3)
 										{
-											if (pool_read(CONNECTION(backend, i), &len, sizeof(len)) < 0)
-											{
-												pool_error("pool_process_query: error while reading message length from backend %d", i);
-												return POOL_ERROR;
-											}
+											pool_read_with_error(CONNECTION(backend, i), &len, sizeof(len),
+													"reading message length from backend");
 											len = ntohl(len) - 4;
 											string = pool_read2(CONNECTION(backend, i), len);
 											if (string == NULL)
@@ -973,7 +964,7 @@ int pool_check_fd(POOL_CONNECTION *cp)
 /*
  * send "terminate"(X) message to all backends, indicating that
  * backend should prepare to close connection to frontend (actually
- * pgpool). Note that caller must be protecedt from a signal
+ * pgpool). Note that caller must be proteceted from a signal
  * interruption while calling this function. Otherwise the number of
  * valid backends might be changed by failover/failback.
  */
@@ -2316,7 +2307,7 @@ void free_select_result(POOL_SELECT_RESULT *result)
 		return;
 
 	if (result->nullflags)
-		free(result->nullflags);
+		pfree(result->nullflags);
 
 	if (result->data)
 	{
@@ -2326,11 +2317,11 @@ void free_select_result(POOL_SELECT_RESULT *result)
 			for (j=0;j<result->rowdesc->num_attrs;j++)
 			{
 				if (result->data[index])
-					free(result->data[index]);
+					pfree(result->data[index]);
 				index++;
 			}
 		}
-		free(result->data);
+		pfree(result->data);
 	}
 
 	if (result->rowdesc)
@@ -2340,14 +2331,14 @@ void free_select_result(POOL_SELECT_RESULT *result)
 			for(i=0;i<result->rowdesc->num_attrs;i++)
 			{
 				if (result->rowdesc->attrinfo[i].attrname)
-					free(result->rowdesc->attrinfo[i].attrname);
+					pfree(result->rowdesc->attrinfo[i].attrname);
 			}
-			free(result->rowdesc->attrinfo);
+			pfree(result->rowdesc->attrinfo);
 		}
-		free(result->rowdesc);
+		pfree(result->rowdesc);
 	}
 
-	free(result);
+	pfree(result);
 }
 
 /*
@@ -2402,41 +2393,16 @@ POOL_STATUS do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT *
 	pool_debug("do_query: extended:%d query:%s", doing_extended, query);
 
 	*result = NULL;
-	res = malloc(sizeof(*res));
-	if (!res)
-	{
-		pool_error("pool_query: malloc failed");
-		return POOL_ERROR;
-	}
-	rowdesc = malloc(sizeof(*rowdesc));
-	if (!rowdesc)
-	{
-		if (res)
-			free(res);
-		pool_error("pool_query: malloc failed");
-		return POOL_ERROR;
-	}
-	memset(res, 0, sizeof(*res));
-	memset(rowdesc, 0, sizeof(*rowdesc));
+	res = palloc0(sizeof(*res));
+	rowdesc = palloc0(sizeof(*rowdesc));
 	*result = res;
 
 	res->rowdesc = rowdesc;
 
 	num_data = 0;
 
-	res->nullflags = malloc(DO_QUERY_ALLOC_NUM*sizeof(int));
-	if (!res->nullflags)
-	{
-		pool_error("do_query: malloc failed");
-		return POOL_ERROR;
-	}
-	res->data = malloc(DO_QUERY_ALLOC_NUM*sizeof(char *));
-	if (!res->data)
-	{
-		pool_error("do_query: malloc failed");
-		return POOL_ERROR;
-	}
-	memset(res->data, 0, DO_QUERY_ALLOC_NUM*sizeof(char *));
+	res->nullflags = palloc(DO_QUERY_ALLOC_NUM*sizeof(int));
+	res->data = palloc0(DO_QUERY_ALLOC_NUM*sizeof(char *));
 
 	/*
 	 * Send a query to the backend. We use extended query proctocol
@@ -2696,12 +2662,7 @@ POOL_STATUS do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT *
 				if (num_fields > 0)
 				{
 					rowdesc->num_attrs = num_fields;
-					attrinfo = malloc(sizeof(*attrinfo)*num_fields);
-					if (!attrinfo)
-					{
-						pool_error("do_query: malloc failed");
-						return POOL_ERROR;
-					}
+					attrinfo = palloc(sizeof(*attrinfo)*num_fields);
 					rowdesc->attrinfo = attrinfo;
 
 					/* extract attribute info */
@@ -2710,12 +2671,7 @@ POOL_STATUS do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT *
 						if (major == PROTO_MAJOR_V3)
 						{
 							len = strlen(p) + 1;
-							attrinfo->attrname = malloc(len);
-							if (!attrinfo->attrname)
-							{
-								pool_error("do_query: malloc failed");
-								return POOL_ERROR;
-							}
+							attrinfo->attrname = palloc(len);
 							memcpy(attrinfo->attrname, p, len);
 							p += len;
 							memcpy(&intval, p, sizeof(int));
@@ -2738,12 +2694,7 @@ POOL_STATUS do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT *
 						else
 						{
 							p = pool_read_string(backend, &len, 0);
-							attrinfo->attrname = malloc(len);
-							if (!attrinfo->attrname)
-							{
-								pool_error("do_query: malloc failed");
-								return POOL_ERROR;
-							}
+							attrinfo->attrname = palloc(len);
 							memcpy(attrinfo->attrname, p, len);
 							if (pool_read(backend, &intval, sizeof(int)) < 0)
 							{
@@ -2811,12 +2762,7 @@ POOL_STATUS do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT *
 
 							if (len > 0)	/* NOT NULL? */
 							{
-								res->data[num_data] = malloc(len + 1);
-								if (!res->data[num_data])
-								{
-									pool_error("do_query: malloc failed");
-									return POOL_ERROR;
-								}
+								res->data[num_data] = palloc(len + 1);
 								memcpy(res->data[num_data], p, len);
 								*(res->data[num_data] + len) = '\0';
 
@@ -2844,12 +2790,7 @@ POOL_STATUS do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT *
 								if (len > 0)
 								{
 									p = pool_read2(backend, len);
-									res->data[num_data] = malloc(len + 1);
-									if (!res->data[num_data])
-									{
-										pool_error("do_query: malloc failed");
-										return POOL_ERROR;
-									}
+									res->data[num_data] = palloc(len + 1);
 									memcpy(res->data[num_data], p, len);
 									*(res->data[num_data] + len) = '\0';
 									if (res->data[num_data] == NULL)
@@ -2871,20 +2812,10 @@ POOL_STATUS do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT *
 
 						if (num_data % DO_QUERY_ALLOC_NUM == 0)
 						{
-							res->nullflags = realloc(res->nullflags,
+							res->nullflags = repalloc(res->nullflags,
 													 (num_data/DO_QUERY_ALLOC_NUM +1)*DO_QUERY_ALLOC_NUM*sizeof(int));
-							if (!res->nullflags)
-							{
-								pool_error("do_query: malloc failed");
-								return POOL_ERROR;
-							}
-							res->data = realloc(res->data,
+							res->data = repalloc(res->data,
 												(num_data/DO_QUERY_ALLOC_NUM +1)*DO_QUERY_ALLOC_NUM*sizeof(char *));
-							if (!res->data)
-							{
-								pool_error("do_query: malloc failed");
-								return POOL_ERROR;
-							}
 						}
 					}
 				}
@@ -3484,7 +3415,7 @@ bool is_partition_table(POOL_CONNECTION_POOL *backend, Node *node)
 static char *get_insert_command_table_name(InsertStmt *node)
 {
 	POOL_SESSION_CONTEXT *session_context;
-	POOL_MEMORY_POOL *old_context;
+	MemoryContext old_context;
 	static char table[128];
 	char *p;
 
@@ -3493,9 +3424,9 @@ static char *get_insert_command_table_name(InsertStmt *node)
 		return NULL;
 
 	if (session_context->query_context)
-		old_context = pool_memory_context_switch_to(session_context->query_context->memory_context);
+		old_context = MemoryContextSwitchTo(session_context->query_context->memory_context);
 	else
-		old_context = pool_memory_context_switch_to(session_context->memory_context);
+		old_context = MemoryContextSwitchTo(session_context->memory_context);
 
 	p = nodeToString(node->relation);
 	if (p == NULL)
@@ -3506,7 +3437,7 @@ static char *get_insert_command_table_name(InsertStmt *node)
 	strlcpy(table, p, sizeof(table));
 	pfree(p);
 
-	pool_memory_context_switch_to(old_context);
+	MemoryContextSwitchTo(old_context);
 
 	pool_debug("get_insert_command_table_name: extracted table name: %s", p);
 	return table;
@@ -3704,7 +3635,7 @@ POOL_STATUS read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_PO
 	int degenerate_node[MAX_NUM_BACKENDS];		/* degeneration requested backend list */
 	POOL_STATUS status;
 
-	POOL_MEMORY_POOL *old_context;
+	MemoryContext old_context;
 
 	POOL_SESSION_CONTEXT *session_context = pool_get_session_context();
 	POOL_QUERY_CONTEXT *query_context = session_context->query_context;
@@ -3876,9 +3807,9 @@ POOL_STATUS read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_PO
 	if (degenerate_node_num)
 	{
 		if (query_context)
-			old_context = pool_memory_context_switch_to(query_context->memory_context);
+			old_context = MemoryContextSwitchTo(query_context->memory_context);
 		else
-			old_context = pool_memory_context_switch_to(session_context->memory_context);
+			old_context = MemoryContextSwitchTo(session_context->memory_context);
 
 		String *msg = init_string("kind mismatch among backends. ");
 
@@ -3963,7 +3894,7 @@ POOL_STATUS read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_PO
 		free_string(msg);
 
 		/* Switch to old memory context */
-		pool_memory_context_switch_to(old_context);
+		MemoryContextSwitchTo(old_context);
 
 		if (pool_config->replication_stop_on_mismatch)
 		{
@@ -4915,7 +4846,7 @@ SELECT_RETRY:
 					pool_error("connection on node %d was terminated due to conflict with recovery", i);
 					pool_send_fatal_message(frontend, MAJOR(backend),
 											SERIALIZATION_FAIL_ERROR_CODE,
-											"connection was terminated due to confilict with recovery",
+											"connection was terminated due to conflict with recovery",
 											"User was holding a relation lock for too long.",
 											"In a moment you should be able to reconnect to the database and repeat your command.",
 											__FILE__, __LINE__);
diff --git a/src/protocol/pool_proto_modules.c b/src/protocol/pool_proto_modules.c
index 542b087..4d9bd24 100644
--- a/src/protocol/pool_proto_modules.c
+++ b/src/protocol/pool_proto_modules.c
@@ -114,7 +114,7 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend,
 
 	POOL_SESSION_CONTEXT *session_context;
 	POOL_QUERY_CONTEXT *query_context;
-	POOL_MEMORY_POOL *old_context;
+	MemoryContext old_context;
 
 	/* Get session context */
 	session_context = pool_get_session_context();
@@ -188,9 +188,7 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend,
 	}
 
 	/* switch memory context */
-	if (pool_memory == NULL)
-		pool_memory = pool_memory_create(PARSER_BLOCK_SIZE);
-	old_context = pool_memory_context_switch_to(query_context->memory_context);
+	old_context = MemoryContextSwitchTo(query_context->memory_context);
 
 	/* parse SQL string */
 	parse_tree_list = raw_parser(contents);
@@ -279,7 +277,7 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend,
 			if (parallel)
 			{
 				pool_query_context_destroy(query_context);
-				pool_memory_context_switch_to(old_context);
+				MemoryContextSwitchTo(old_context);
 				return status;
 			}
 		}
@@ -337,7 +335,7 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend,
 				pool_ps_idle_display(backend);
 				pool_query_context_destroy(query_context);
 				pool_set_skip_reading_from_backends();
-				pool_memory_context_switch_to(old_context);
+				MemoryContextSwitchTo(old_context);
 				return POOL_CONTINUE;
 			}
 		}
@@ -614,7 +612,7 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend,
 	}
 
 	/* switch memory context */
-	pool_memory_context_switch_to(old_context);
+	MemoryContextSwitchTo(old_context);
 
 	return POOL_CONTINUE;
 }
@@ -867,7 +865,7 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
 	Node *node = NULL;
 	POOL_SENT_MESSAGE *msg;
 	POOL_STATUS status;
-	POOL_MEMORY_POOL *old_context;
+	MemoryContext old_context;
 	POOL_SESSION_CONTEXT *session_context;
 	POOL_QUERY_CONTEXT *query_context;
 
@@ -888,9 +886,7 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
 	stmt = contents + strlen(contents) + 1;
 
 	/* switch memory context */
-	if (pool_memory == NULL)
-		pool_memory = pool_memory_create(PARSER_BLOCK_SIZE);
-	old_context = pool_memory_context_switch_to(query_context->memory_context);
+	old_context = MemoryContextSwitchTo(query_context->memory_context);
 
 	/* parse SQL string */
 	parse_tree_list = raw_parser(stmt);
@@ -1025,8 +1021,13 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
 			if (rewrite_query != NULL)
 			{
 				int alloc_len = len - strlen(stmt) + strlen(rewrite_query);
-				contents = pool_memory_realloc(session_context->memory_context,
-                                                                      msg->contents, alloc_len);
+					/* switch memory context */
+				MemoryContext oldcxt = MemoryContextSwitchTo(session_context->memory_context);
+				contents = repalloc(msg->contents,alloc_len);
+//				contents = pool_memory_realloc(session_context->memory_context,
+//                                                                      msg->contents, alloc_len);
+				MemoryContextSwitchTo(oldcxt);
+
 				strcpy(contents, name);
 				strcpy(contents + strlen(name) + 1, rewrite_query);
 				memcpy(contents + strlen(name) + strlen(rewrite_query) + 2,
@@ -1059,7 +1060,7 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
 		}
 	}
 
-	pool_memory_context_switch_to(old_context);
+	MemoryContextSwitchTo(old_context);
 
 	/*
 	 * If in replication mode, send "SYNC" message if not in a transaction.
@@ -1545,12 +1546,12 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend,
 			{
 				int i;
 				String *msg;
-				POOL_MEMORY_POOL *old_context;
+				MemoryContext old_context;
 
 				if (session_context->query_context)
-					old_context = pool_memory_context_switch_to(session_context->query_context->memory_context);
+					old_context = MemoryContextSwitchTo(session_context->query_context->memory_context);
 				else
-					old_context = pool_memory_context_switch_to(session_context->memory_context);
+					old_context = MemoryContextSwitchTo(session_context->memory_context);
 
 				msg = init_string("ReadyForQuery: Degenerate backends:");
 
@@ -1572,7 +1573,7 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend,
 				pool_log("%s", msg->data);
 				free_string(msg);
 
-				pool_memory_context_switch_to(old_context);
+				MemoryContextSwitchTo(old_context);
 
 				degenerate_backend_set(victim_nodes, number_of_nodes);
 				child_exit(1);
@@ -2146,12 +2147,12 @@ POOL_STATUS CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac
 	if (session_context->mismatch_ntuples)
 	{
 		char msgbuf[128];
-		POOL_MEMORY_POOL *old_context;
+		MemoryContext old_context;
 
 		if (session_context->query_context)
-			old_context = pool_memory_context_switch_to(session_context->query_context->memory_context);
+			old_context = MemoryContextSwitchTo(session_context->query_context->memory_context);
 		else
-			old_context = pool_memory_context_switch_to(session_context->memory_context);
+			old_context = MemoryContextSwitchTo(session_context->memory_context);
 
 		String *msg = init_string("pgpool detected difference of the number of inserted, updated or deleted tuples. Possible last query was: \"");
 		string_append_char(msg, query_string_buffer);
@@ -2172,7 +2173,7 @@ POOL_STATUS CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac
 		pool_log("%s", msg->data);
 		free_string(msg);
 
-		pool_memory_context_switch_to(old_context);
+		MemoryContextSwitchTo(old_context);
 	}
 	else
 	{
@@ -2467,7 +2468,7 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend,
 		char *query;
 		Node *node;
 		List *parse_tree_list;
-		POOL_MEMORY_POOL *old_context;
+		MemoryContext old_context;
 
 		case 'X':	/* Terminate */
 			free(contents);
@@ -2534,7 +2535,7 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend,
 				free(contents);
 				return POOL_END;
 			}
-			old_context = pool_memory_context_switch_to(query_context->memory_context);
+			old_context = MemoryContextSwitchTo(query_context->memory_context);
 			query = "INSERT INTO foo VALUES(1)";
 			parse_tree_list = raw_parser(query);
 			node = (Node *) lfirst(list_head(parse_tree_list));
@@ -2547,7 +2548,7 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend,
 			else
 				status = FunctionCall(frontend, backend);
 
-			pool_memory_context_switch_to(old_context);
+			MemoryContextSwitchTo(old_context);
 			break;
 
 		case 'c':	/* CopyDone */
@@ -3183,7 +3184,7 @@ static int check_errors(POOL_CONNECTION_POOL *backend, int backend_id)
 static void generate_error_message(char *prefix, int specific_error, char *query)
 {
 	POOL_SESSION_CONTEXT *session_context;
-	POOL_MEMORY_POOL *old_context;
+	MemoryContext old_context;
 
 	session_context = pool_get_session_context();
 	if (!session_context)
@@ -3207,16 +3208,16 @@ static void generate_error_message(char *prefix, int specific_error, char *query
 	specific_error--;
 
 	if (session_context->query_context)
-		old_context = pool_memory_context_switch_to(session_context->query_context->memory_context);
+		old_context = MemoryContextSwitchTo(session_context->query_context->memory_context);
 	else
-		old_context = pool_memory_context_switch_to(session_context->memory_context);
+		old_context = MemoryContextSwitchTo(session_context->memory_context);
 
 	msg = init_string(prefix);
 	string_append_char(msg, error_messages[specific_error]);
 	pool_error(msg->data, query);
 	free_string(msg);
 
-	pool_memory_context_switch_to(old_context);
+	MemoryContextSwitchTo(old_context);
 }
 
 /*
diff --git a/src/query_cache/pool_memqcache.c b/src/query_cache/pool_memqcache.c
index 6c62fc3..98a36b8 100644
--- a/src/query_cache/pool_memqcache.c
+++ b/src/query_cache/pool_memqcache.c
@@ -51,6 +51,7 @@
 #include "utils/pool_select_walker.h"
 #include "utils/pool_stream.h"
 #include "utils/pool_stream.h"
+#include "utils/elog.h"
 
 #ifdef USE_MEMCACHED
 memcached_st *memc;
@@ -1641,23 +1642,25 @@ size_t pool_shared_memory_cache_size(void)
 	size_t size;
 
 	if (pool_config->memqcache_maxcache > pool_config->memqcache_cache_block_size)
-	{
-		pool_error("pool_shared_memory_cache_size: memqcache_cache_block_size %d should be greater or equal to memqcache_maxcache %d",
-				   pool_config->memqcache_cache_block_size, pool_config->memqcache_maxcache);
-		return 0;
-	}
+		ereport(FATAL,
+			(errmsg("invalid memory cache configuration"),
+					errdetail("memqcache_cache_block_size %d should be greater or equal to memqcache_maxcache %d",
+								pool_config->memqcache_cache_block_size,
+								pool_config->memqcache_maxcache)));
+
 
 	num_blocks = pool_config->memqcache_total_size/
 		pool_config->memqcache_cache_block_size;
 	if (num_blocks == 0)
-	{
-		pool_error("pool_shared_memory_cache_size: memqcache_total_size %d should be greater or equal to memqcache_cache_block_size %d",
-				   pool_config->memqcache_total_size, pool_config->memqcache_cache_block_size);
-		return 0;
-	}
-
-	pool_log("pool_shared_memory_cache_size: number of blocks: %d", num_blocks);
-
+		ereport(FATAL,
+			(errmsg("invalid memory cache configuration"),
+					errdetail("memqcache_total_size %d should be greater or equal to memqcache_cache_block_size %d",
+								pool_config->memqcache_total_size,
+								pool_config->memqcache_cache_block_size)));
+
+		ereport(LOG,
+			(errmsg("memory cache initialized"),
+					errdetail("memcache blocks :%d",num_blocks)));
 	/* Remember # of blocks */
 	pool_set_memqcache_blocks(num_blocks);
 	size = pool_config->memqcache_cache_block_size * num_blocks;
@@ -1671,13 +1674,10 @@ size_t pool_shared_memory_cache_size(void)
 static void *shmem;
 int pool_init_memory_cache(size_t size)
 {
-	pool_debug("pool_init_memory_cache: request size:%zd", size);
+	ereport(DEBUG1,
+		(errmsg("memory cache request size : %d",size)));
+
 	shmem = pool_shared_memory_create(size);
-	if (shmem == NULL)
-	{
-		pool_error("pool_init_memory_cache: failed to allocate shared memory cache. request size: %zd", size);
-		return -1;
-	}
 	return 0;
 }
 
@@ -2997,10 +2997,10 @@ void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *n
 	if (pool_is_cache_safe())
 	{
 		SelectContext ctx;
-		POOL_MEMORY_POOL *old_context;
-		old_context = pool_memory_context_switch_to(session_context->memory_context);
+		MemoryContext old_context;
+		old_context = MemoryContextSwitchTo(session_context->memory_context);
 		num_oids = pool_extract_table_oids_from_select_stmt(node, &ctx);
-		pool_memory_context_switch_to(old_context);
+		MemoryContextSwitchTo(old_context);
 		oids = ctx.table_oids;;
 		pool_debug("num_oids: %d oid: %d", num_oids, *oids);
 
@@ -3222,15 +3222,7 @@ static POOL_QUERY_CACHE_STATS *stats;
 int pool_init_memqcache_stats(void)
 {
 	stats = pool_shared_memory_create(sizeof(POOL_QUERY_CACHE_STATS));
-	if (stats == NULL)
-	{
-		pool_error("pool_init_meqcache_stats: failed to allocate shared memory stats. request size: %zd",
-				   sizeof(POOL_QUERY_CACHE_STATS));
-			return -1;
-	}
-
 	pool_reset_memqcache_stats();
-
 	return 0;
 }
 
diff --git a/src/rewrite/pool_timestamp.c b/src/rewrite/pool_timestamp.c
index c87498b..363d9f2 100644
--- a/src/rewrite/pool_timestamp.c
+++ b/src/rewrite/pool_timestamp.c
@@ -30,8 +30,8 @@
 #include "pool_config.h"
 #include "parser/parsenodes.h"
 #include "parser/parser.h"
-#include "parser/pool_memory.h"
-
+//#include "parser/pool_memory.h"
+#include "utils/palloc.h"
 
 typedef struct {
 	char	*attrname;	/* attribute name */
diff --git a/src/streaming_replication/pool_worker_child.c b/src/streaming_replication/pool_worker_child.c
index 093c8cc..160c758 100644
--- a/src/streaming_replication/pool_worker_child.c
+++ b/src/streaming_replication/pool_worker_child.c
@@ -23,6 +23,7 @@
  */
 #include "config.h"
 
+
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -50,6 +51,10 @@
 #endif
 
 #include "pool.h"
+#include "utils/palloc.h"
+#include "utils/memutils.h"
+#include "utils/elog.h"
+
 #include "context/pool_process_context.h"
 #include "context/pool_session_context.h"
 #include "pool_config.h"
@@ -72,7 +77,6 @@ static long text_to_lsn(char *text);
 static RETSIGTYPE my_signal_handler(int sig);
 static RETSIGTYPE reload_config_handler(int sig);
 static void reload_config(void);
-
 #define CHECK_REQUEST \
 	do { \
 		if (reload_config_request) \
@@ -91,6 +95,9 @@ static void reload_config(void);
 */
 void do_worker_child(void)
 {
+    sigjmp_buf	local_sigjmp_buf;
+	MemoryContext WorkerMemoryContext;
+
 	pool_debug("I am %d", getpid());
 
 	/* Identify myself via ps */
@@ -108,14 +115,38 @@ void do_worker_child(void)
 	signal(SIGUSR2, SIG_IGN);
 	signal(SIGPIPE, SIG_IGN);
 
+    /* Create per loop iteration memory context */
+	WorkerMemoryContext = AllocSetContextCreate(TopMemoryContext,
+                                             "Worker_main_loop",
+                                             ALLOCSET_DEFAULT_MINSIZE,
+                                             ALLOCSET_DEFAULT_INITSIZE,
+                                             ALLOCSET_DEFAULT_MAXSIZE);
+    
+	MemoryContextSwitchTo(TopMemoryContext);
+
 	/* Initialize my backend status */
 	pool_initialize_private_backend_status();
 
 	/* Initialize per process context */
 	pool_init_process_context();
 
+    if (sigsetjmp(local_sigjmp_buf, 1) != 0)
+	{
+		pool_signal(SIGALRM, SIG_IGN);
+		error_context_stack = NULL;
+		EmitErrorReport();
+		MemoryContextSwitchTo(TopMemoryContext);
+		FlushErrorState();
+	}
+	/* We can now handle ereport(ERROR) */
+	PG_exception_stack = &local_sigjmp_buf;
+
+
 	for (;;)
 	{
+        MemoryContextSwitchTo(WorkerMemoryContext);
+		MemoryContextResetAndDeleteChildren(WorkerMemoryContext);
+
 		CHECK_REQUEST;
 
 		if (pool_config->sr_check_period <= 0)
@@ -129,12 +160,21 @@ void do_worker_child(void)
 
 		if (pool_config->sr_check_period > 0 && MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
 		{
-			/* Check and establish persistent connections to the backend */
 			establish_persistent_connection();
-
-			/* Do replication time lag checking */
-			check_replication_time_lag();
-
+            PG_TRY();
+            {
+
+            	/* Do replication time lag checking */
+            	check_replication_time_lag();
+            }
+            PG_CATCH();
+            {
+	    		discard_persistent_connection();
+	    		sleep(pool_config->sr_check_period);
+	    		PG_RE_THROW();
+            }
+            PG_END_TRY();
+            
 			/* Discard persistent connections */
 			discard_persistent_connection();
 		}
@@ -144,14 +184,22 @@ void do_worker_child(void)
 }
 
 /*
+ * Error context callback for errors occurring after persistent db connection
+ * was created.
+ */
+static void
+clean_persistent_connection_error_callback(void *arg)
+{
+    discard_persistent_connection();
+}
+/*
  * Establish persistent connection to backend
  */
 static void establish_persistent_connection(void)
 {
 	int i;
 	BackendInfo *bkinfo;
-	POOL_CONNECTION_POOL_SLOT *s;
-
+	
 	for (i=0;i<NUM_BACKENDS;i++)
 	{
 		if (!VALID_BACKEND(i))
@@ -159,16 +207,25 @@ static void establish_persistent_connection(void)
 
 		if (slots[i] == NULL)
 		{
-			bkinfo = pool_get_node_info(i);
-			s = make_persistent_db_connection(bkinfo->backend_hostname, 
+            PG_TRY();
+            {
+                bkinfo = pool_get_node_info(i);
+                slots[i] = make_persistent_db_connection(bkinfo->backend_hostname,
 											  bkinfo->backend_port,
 											  "postgres",
 											  pool_config->sr_check_user,
 											  pool_config->sr_check_password, true);
-			if (s)
-				slots[i] = s;
-			else
+            }
+		    PG_CATCH();
+            {
+	        	ErrorData  *edata;
+	        	edata = CopyErrorData();
+	        	printf("%s",edata->message);
+	        	FlushErrorState();
 				slots[i] = NULL;
+            }
+            PG_END_TRY();
+
 		}
 	}
 }
@@ -231,10 +288,11 @@ static void check_replication_time_lag(void)
 
 		if (!slots[i])
 		{
-			pool_debug("check_replication_time_lag: DB node is valid but no persistent connection");
-			pool_error("check_replication_time_lag: could not connect to DB node %d, check sr_check_user and sr_check_password", i);
+            ereport(ERROR,
+                    (errmsg("Failed to check replication time lag"),
+                     errdetail("No persistent db connection for the node %d",i),
+                        errhint("check sr_check_user and sr_check_password")));
 
-			return;
 		}
 
 		if (PRIMARY_NODE_ID == i)
@@ -256,27 +314,32 @@ static void check_replication_time_lag(void)
 		}
 		if (!res)
 		{
-			pool_error("check_replication_time_lag: %s result is null", query);
-			return;
+            ereport(ERROR,
+                (errmsg("Failed to check replication time lag"),
+                     errdetail("Query to node (%d) returned no result for node",i)));
 		}
 		if (res->numrows <= 0)
 		{
-			pool_error("check_replication_time_lag: %s returns no rows", query);
 			free_select_result(res);
-			return;
+            ereport(ERROR,
+                (errmsg("Failed to check replication time lag"),
+                     errdetail("Query to node (%d) returned result with no rows",i)));
 		}
 		if (res->data[0] == NULL)
 		{
-			pool_error("check_replication_time_lag: %s returns no data", query);
 			free_select_result(res);
-			return;
+            ereport(ERROR,
+                (errmsg("Failed to check replication time lag"),
+                     errdetail("Query to node (%d) returned no data",i)));
 		}
 
 		if (res->nullflags[0] == -1)
 		{
-			pool_log("check_replication_time_lag: %s returns NULL", query);
 			free_select_result(res);
 			lsn[i] = 0;
+            ereport(ERROR,
+                (errmsg("Failed to check replication time lag"),
+                     errdetail("Query to node (%d) returned NULL data",i)));
 		}
 		else
 		{
@@ -308,8 +371,9 @@ static void check_replication_time_lag(void)
 				 !strcmp(pool_config->log_standby_delay, "if_over_threshold") &&
 				 lag > pool_config->delay_threshold))
 			{
-				pool_log("Replication of node:%d is behind %llu bytes from the primary server (node:%d)",
-				         i, lsn[PRIMARY_NODE_ID] - lsn[i], PRIMARY_NODE_ID);
+                ereport(LOG,
+                        (errmsg("Replication of node:%d is behind %llu bytes from the primary server (node:%d)",
+                                i, lsn[PRIMARY_NODE_ID] - lsn[i], PRIMARY_NODE_ID)));
 			}
 		}
 	}
@@ -332,8 +396,10 @@ static long text_to_lsn(char *text)
 
 	if (sscanf(text, "%X/%X", &xlogid, &xrecoff) != 2)
 	{
-		pool_error("text_to_lsn: wrong log location format: %s", text);
-		return 0;
+        ereport(ERROR,
+            (errmsg("Invalid lsn format"),
+                 errdetail("wrong log location format: %s", text)));
+
 	}
 	lsn = xlogid * ((unsigned long long int)0xffffffff - WALSEGMENTSIZE) + xrecoff;
 #ifdef DEBUG
diff --git a/src/system_db/pool_system.c b/src/system_db/pool_system.c
index 3a6270e..55bf63b 100644
--- a/src/system_db/pool_system.c
+++ b/src/system_db/pool_system.c
@@ -25,6 +25,7 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include "utils/elog.h"
 #include "pool.h"
 #include "pool_config.h"
 
@@ -657,3 +658,90 @@ static int create_prepared_statement(DistDefInfo *dist_info)
 	dist_info->is_created_prepare = 1;
 	return 0;
 }
+
+/*
+ * system_db_health_check()
+ * check if we can connect to the SystemDB
+ * returns 0 for OK. otherwise returns -1
+ */
+int
+system_db_health_check(void)
+{
+	int fd;
+
+	/* V2 startup packet */
+	typedef struct {
+		int len;		/* startup packet length */
+		StartupPacket_v2 sp;
+	} MySp;
+	MySp mysp;
+	char kind;
+
+	memset(&mysp, 0, sizeof(mysp));
+	mysp.len = htonl(296);
+	mysp.sp.protoVersion = htonl(PROTO_MAJOR_V2 << 16);
+	strcpy(mysp.sp.database, "template1");
+	strncpy(mysp.sp.user, SYSDB_INFO->user, sizeof(mysp.sp.user) - 1);
+	*mysp.sp.options = '\0';
+	*mysp.sp.unused = '\0';
+	*mysp.sp.tty = '\0';
+
+	ereport(DEBUG1,
+		(errmsg("health_check: SystemDB status: %d", SYSDB_STATUS)));
+
+	/* if SystemDB is already down, ignore */
+	if (SYSDB_STATUS == CON_UNUSED || SYSDB_STATUS == CON_DOWN)
+		return 0;
+
+	if (*SYSDB_INFO->hostname == '/')
+		fd = connect_unix_domain_socket_by_port(SYSDB_INFO->port, SYSDB_INFO->hostname, FALSE);
+	else
+		fd = connect_inet_domain_socket_by_port(SYSDB_INFO->hostname, SYSDB_INFO->port, FALSE);
+
+	if (fd < 0)
+	{
+		ereport(ERROR,
+			(errmsg("SystemDB health check failed"),
+				   errdetail("DB host \"%s\" at port %d is down",
+						   	   SYSDB_INFO->hostname,
+						   	   SYSDB_INFO->port)));
+	}
+
+	if (write(fd, &mysp, sizeof(mysp)) < 0)
+	{
+		close(fd);
+		ereport(ERROR,
+				(errmsg("SystemDB health check failed"),
+				   errdetail("Write failed on DB host \"%s\" at port %d is down",
+						   	   SYSDB_INFO->hostname,
+						   	   SYSDB_INFO->port)));
+	}
+
+	read(fd, &kind, 1);
+
+	if (write(fd, "X", 1) < 0)
+	{
+		close(fd);
+		ereport(ERROR,
+				(errmsg("SystemDB health check failed"),
+				   errdetail("Write failed on DB host \"%s\" at port %d is down",
+						   	   SYSDB_INFO->hostname,
+						   	   SYSDB_INFO->port)));
+	}
+
+	close(fd);
+	return 0;
+}
+
+/*
+ * get System DB information
+ */
+SystemDBInfo *
+pool_get_system_db_info(void)
+{
+	if (system_db_info == NULL)
+		return NULL;
+
+	return system_db_info->info;
+}
+
diff --git a/src/tools/Makefile.in b/src/tools/Makefile.in
index 3130616..f2ddb07 100644
--- a/src/tools/Makefile.in
+++ b/src/tools/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -466,10 +466,15 @@ install-am: all-am
 
 installcheck: installcheck-recursive
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
diff --git a/src/tools/fe_memutils.c b/src/tools/fe_memutils.c
new file mode 100644
index 0000000..0f6ccb3
--- /dev/null
+++ b/src/tools/fe_memutils.c
@@ -0,0 +1,131 @@
+/*-------------------------------------------------------------------------
+ *
+ * fe_memutils.c
+ *	  memory management support for frontend code
+ *
+ * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *	  src/common/fe_memutils.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef POOL_PRIVATE
+#error "This file is not expected to be compiled for pgpool utilities only"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "utils/fe_ports.h"
+
+void *
+pg_malloc(size_t size)
+{
+	void	   *tmp;
+
+	/* Avoid unportable behavior of malloc(0) */
+	if (size == 0)
+		size = 1;
+	tmp = malloc(size);
+	if (!tmp)
+	{
+		fprintf(stderr, "out of memory\n");
+		exit(EXIT_FAILURE);
+	}
+	return tmp;
+}
+
+void *
+pg_malloc0(size_t size)
+{
+	void	   *tmp;
+
+	tmp = pg_malloc(size);
+	memset(tmp, 0, size);
+	return tmp;
+}
+
+void *
+pg_realloc(void *ptr, size_t size)
+{
+	void	   *tmp;
+
+	/* Avoid unportable behavior of realloc(NULL, 0) */
+	if (ptr == NULL && size == 0)
+		size = 1;
+	tmp = realloc(ptr, size);
+	if (!tmp)
+	{
+		fprintf(stderr, "out of memory\n");
+		exit(EXIT_FAILURE);
+	}
+	return tmp;
+}
+
+/*
+ * "Safe" wrapper around strdup().
+ */
+char *
+pg_strdup(const char *in)
+{
+	char	   *tmp;
+
+	if (!in)
+	{
+		fprintf(stderr,
+				"cannot duplicate null pointer (internal error)\n");
+		exit(EXIT_FAILURE);
+	}
+	tmp = strdup(in);
+	if (!tmp)
+	{
+		fprintf(stderr, "out of memory\n");
+		exit(EXIT_FAILURE);
+	}
+	return tmp;
+}
+
+void
+pg_free(void *ptr)
+{
+	if (ptr != NULL)
+		free(ptr);
+}
+
+/*
+ * Frontend emulation of backend memory management functions.  Useful for
+ * programs that compile backend files.
+ */
+void *
+palloc(unsigned int size)
+{
+	return pg_malloc(size);
+}
+
+void *
+palloc0(unsigned int size)
+{
+	return pg_malloc0(size);
+}
+
+void
+pfree(void *pointer)
+{
+	pg_free(pointer);
+}
+
+char *
+pstrdup(const char *in)
+{
+	return pg_strdup(in);
+}
+
+void *
+repalloc(void *pointer, unsigned int size)
+{
+	return pg_realloc(pointer, size);
+}
diff --git a/src/tools/pcp/Makefile.in b/src/tools/pcp/Makefile.in
index 2716a96..006506f 100644
--- a/src/tools/pcp/Makefile.in
+++ b/src/tools/pcp/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -350,40 +350,40 @@ clean-binPROGRAMS:
 	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
 	echo " rm -f" $$list; \
 	rm -f $$list
-pcp_attach_node$(EXEEXT): $(pcp_attach_node_OBJECTS) $(pcp_attach_node_DEPENDENCIES) 
+pcp_attach_node$(EXEEXT): $(pcp_attach_node_OBJECTS) $(pcp_attach_node_DEPENDENCIES) $(EXTRA_pcp_attach_node_DEPENDENCIES) 
 	@rm -f pcp_attach_node$(EXEEXT)
 	$(LINK) $(pcp_attach_node_OBJECTS) $(pcp_attach_node_LDADD) $(LIBS)
-pcp_detach_node$(EXEEXT): $(pcp_detach_node_OBJECTS) $(pcp_detach_node_DEPENDENCIES) 
+pcp_detach_node$(EXEEXT): $(pcp_detach_node_OBJECTS) $(pcp_detach_node_DEPENDENCIES) $(EXTRA_pcp_detach_node_DEPENDENCIES) 
 	@rm -f pcp_detach_node$(EXEEXT)
 	$(LINK) $(pcp_detach_node_OBJECTS) $(pcp_detach_node_LDADD) $(LIBS)
-pcp_node_count$(EXEEXT): $(pcp_node_count_OBJECTS) $(pcp_node_count_DEPENDENCIES) 
+pcp_node_count$(EXEEXT): $(pcp_node_count_OBJECTS) $(pcp_node_count_DEPENDENCIES) $(EXTRA_pcp_node_count_DEPENDENCIES) 
 	@rm -f pcp_node_count$(EXEEXT)
 	$(LINK) $(pcp_node_count_OBJECTS) $(pcp_node_count_LDADD) $(LIBS)
-pcp_node_info$(EXEEXT): $(pcp_node_info_OBJECTS) $(pcp_node_info_DEPENDENCIES) 
+pcp_node_info$(EXEEXT): $(pcp_node_info_OBJECTS) $(pcp_node_info_DEPENDENCIES) $(EXTRA_pcp_node_info_DEPENDENCIES) 
 	@rm -f pcp_node_info$(EXEEXT)
 	$(LINK) $(pcp_node_info_OBJECTS) $(pcp_node_info_LDADD) $(LIBS)
-pcp_pool_status$(EXEEXT): $(pcp_pool_status_OBJECTS) $(pcp_pool_status_DEPENDENCIES) 
+pcp_pool_status$(EXEEXT): $(pcp_pool_status_OBJECTS) $(pcp_pool_status_DEPENDENCIES) $(EXTRA_pcp_pool_status_DEPENDENCIES) 
 	@rm -f pcp_pool_status$(EXEEXT)
 	$(LINK) $(pcp_pool_status_OBJECTS) $(pcp_pool_status_LDADD) $(LIBS)
-pcp_proc_count$(EXEEXT): $(pcp_proc_count_OBJECTS) $(pcp_proc_count_DEPENDENCIES) 
+pcp_proc_count$(EXEEXT): $(pcp_proc_count_OBJECTS) $(pcp_proc_count_DEPENDENCIES) $(EXTRA_pcp_proc_count_DEPENDENCIES) 
 	@rm -f pcp_proc_count$(EXEEXT)
 	$(LINK) $(pcp_proc_count_OBJECTS) $(pcp_proc_count_LDADD) $(LIBS)
-pcp_proc_info$(EXEEXT): $(pcp_proc_info_OBJECTS) $(pcp_proc_info_DEPENDENCIES) 
+pcp_proc_info$(EXEEXT): $(pcp_proc_info_OBJECTS) $(pcp_proc_info_DEPENDENCIES) $(EXTRA_pcp_proc_info_DEPENDENCIES) 
 	@rm -f pcp_proc_info$(EXEEXT)
 	$(LINK) $(pcp_proc_info_OBJECTS) $(pcp_proc_info_LDADD) $(LIBS)
-pcp_promote_node$(EXEEXT): $(pcp_promote_node_OBJECTS) $(pcp_promote_node_DEPENDENCIES) 
+pcp_promote_node$(EXEEXT): $(pcp_promote_node_OBJECTS) $(pcp_promote_node_DEPENDENCIES) $(EXTRA_pcp_promote_node_DEPENDENCIES) 
 	@rm -f pcp_promote_node$(EXEEXT)
 	$(LINK) $(pcp_promote_node_OBJECTS) $(pcp_promote_node_LDADD) $(LIBS)
-pcp_recovery_node$(EXEEXT): $(pcp_recovery_node_OBJECTS) $(pcp_recovery_node_DEPENDENCIES) 
+pcp_recovery_node$(EXEEXT): $(pcp_recovery_node_OBJECTS) $(pcp_recovery_node_DEPENDENCIES) $(EXTRA_pcp_recovery_node_DEPENDENCIES) 
 	@rm -f pcp_recovery_node$(EXEEXT)
 	$(LINK) $(pcp_recovery_node_OBJECTS) $(pcp_recovery_node_LDADD) $(LIBS)
-pcp_stop_pgpool$(EXEEXT): $(pcp_stop_pgpool_OBJECTS) $(pcp_stop_pgpool_DEPENDENCIES) 
+pcp_stop_pgpool$(EXEEXT): $(pcp_stop_pgpool_OBJECTS) $(pcp_stop_pgpool_DEPENDENCIES) $(EXTRA_pcp_stop_pgpool_DEPENDENCIES) 
 	@rm -f pcp_stop_pgpool$(EXEEXT)
 	$(LINK) $(pcp_stop_pgpool_OBJECTS) $(pcp_stop_pgpool_LDADD) $(LIBS)
-pcp_systemdb_info$(EXEEXT): $(pcp_systemdb_info_OBJECTS) $(pcp_systemdb_info_DEPENDENCIES) 
+pcp_systemdb_info$(EXEEXT): $(pcp_systemdb_info_OBJECTS) $(pcp_systemdb_info_DEPENDENCIES) $(EXTRA_pcp_systemdb_info_DEPENDENCIES) 
 	@rm -f pcp_systemdb_info$(EXEEXT)
 	$(LINK) $(pcp_systemdb_info_OBJECTS) $(pcp_systemdb_info_LDADD) $(LIBS)
-pcp_watchdog_info$(EXEEXT): $(pcp_watchdog_info_OBJECTS) $(pcp_watchdog_info_DEPENDENCIES) 
+pcp_watchdog_info$(EXEEXT): $(pcp_watchdog_info_OBJECTS) $(pcp_watchdog_info_DEPENDENCIES) $(EXTRA_pcp_watchdog_info_DEPENDENCIES) 
 	@rm -f pcp_watchdog_info$(EXEEXT)
 	$(LINK) $(pcp_watchdog_info_OBJECTS) $(pcp_watchdog_info_LDADD) $(LIBS)
 
@@ -532,10 +532,15 @@ install-am: all-am
 
 installcheck: installcheck-am
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
diff --git a/src/tools/pgmd5/Makefile.am b/src/tools/pgmd5/Makefile.am
index 5743c90..c676cfb 100644
--- a/src/tools/pgmd5/Makefile.am
+++ b/src/tools/pgmd5/Makefile.am
@@ -4,12 +4,13 @@ bin_PROGRAMS = pg_md5
 pg_md5_SOURCES = pg_md5.c \
 			$(top_srcdir)/src/auth/md5.c \
 			$(top_srcdir)/src/auth/pool_passwd.c \
-		    	$(top_srcdir)/src/utils/pool_error.c \
+		    $(top_srcdir)/src/utils/pool_error.c \
 			$(top_srcdir)/src/utils/pool_signal.c \
 			$(top_srcdir)/src/utils/strlcpy.c \
-	    		$(top_srcdir)/src/config/pool_config_md5.c \
+			$(top_srcdir)/src/config/pool_config_md5.c \
 			$(top_srcdir)/src/main/pool_globals.c
 
+
 DEFS = @DEFS@ \
     -DDEFAULT_CONFIGDIR=\"$(sysconfdir)\"
-
+ 
diff --git a/src/tools/pgmd5/Makefile.in b/src/tools/pgmd5/Makefile.in
index 3aa8beb..30170ee 100644
--- a/src/tools/pgmd5/Makefile.in
+++ b/src/tools/pgmd5/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -208,10 +208,10 @@ AM_CPPFLAGS = -D_GNU_SOURCE -I @PGSQL_INCLUDE_DIR@
 pg_md5_SOURCES = pg_md5.c \
 			$(top_srcdir)/src/auth/md5.c \
 			$(top_srcdir)/src/auth/pool_passwd.c \
-		    	$(top_srcdir)/src/utils/pool_error.c \
+		    $(top_srcdir)/src/utils/pool_error.c \
 			$(top_srcdir)/src/utils/pool_signal.c \
 			$(top_srcdir)/src/utils/strlcpy.c \
-	    		$(top_srcdir)/src/config/pool_config_md5.c \
+			$(top_srcdir)/src/config/pool_config_md5.c \
 			$(top_srcdir)/src/main/pool_globals.c
 
 all: all-am
@@ -291,7 +291,7 @@ clean-binPROGRAMS:
 	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
 	echo " rm -f" $$list; \
 	rm -f $$list
-pg_md5$(EXEEXT): $(pg_md5_OBJECTS) $(pg_md5_DEPENDENCIES) 
+pg_md5$(EXEEXT): $(pg_md5_OBJECTS) $(pg_md5_DEPENDENCIES) $(EXTRA_pg_md5_DEPENDENCIES) 
 	@rm -f pg_md5$(EXEEXT)
 	$(LINK) $(pg_md5_OBJECTS) $(pg_md5_LDADD) $(LIBS)
 
@@ -534,10 +534,15 @@ install-am: all-am
 
 installcheck: installcheck-am
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
diff --git a/src/utils/error/elog.c b/src/utils/error/elog.c
new file mode 100644
index 0000000..a8c7766
--- /dev/null
+++ b/src/utils/error/elog.c
@@ -0,0 +1,2449 @@
+/*-------------------------------------------------------------------------
+ *
+ * elog.c
+ *	  error logging and reporting
+ *
+ * Because of the extremely high rate at which log messages can be generated,
+ * we need to be mindful of the performance cost of obtaining any information
+ * that may be logged.	Also, it's important to keep in mind that this code may
+ * get called from within an aborted transaction, in which case operations
+ * such as syscache lookups are unsafe.
+ *
+ * Some notes about recursion and errors during error processing:
+ *
+ * We need to be robust about recursive-error scenarios --- for example,
+ * if we run out of memory, it's important to be able to report that fact.
+ * There are a number of considerations that go into this.
+ *
+ * First, distinguish between re-entrant use and actual recursion.	It
+ * is possible for an error or warning message to be emitted while the
+ * parameters for an error message are being computed.	In this case
+ * errstart has been called for the outer message, and some field values
+ * may have already been saved, but we are not actually recursing.	We handle
+ * this by providing a (small) stack of ErrorData records.	The inner message
+ * can be computed and sent without disturbing the state of the outer message.
+ * (If the inner message is actually an error, this isn't very interesting
+ * because control won't come back to the outer message generator ... but
+ * if the inner message is only debug or log data, this is critical.)
+ *
+ * Second, actual recursion will occur if an error is reported by one of
+ * the elog.c routines or something they call.	By far the most probable
+ * scenario of this sort is "out of memory"; and it's also the nastiest
+ * to handle because we'd likely also run out of memory while trying to
+ * report this error!  Our escape hatch for this case is to reset the
+ * ErrorContext to empty before trying to process the inner error.	Since
+ * ErrorContext is guaranteed to have at least 8K of space in it (see mcxt.c),
+ * we should be able to process an "out of memory" message successfully.
+ * Since we lose the prior error state due to the reset, we won't be able
+ * to return to processing the original error, but we wouldn't have anyway.
+ * (NOTE: the escape hatch is not used for recursive situations where the
+ * inner message is of less than ERROR severity; in that case we just
+ * try to process it and return normally.  Usually this will work, but if
+ * it ends up in infinite recursion, we will PANIC due to error stack
+ * overflow.)
+ *
+ *
+ * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *	  src/utils/error/elog.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "pool.h"
+#include "pool_type.h"
+#include "utils/palloc.h"
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+#include <signal.h>
+#include <ctype.h>
+#ifdef HAVE_SYSLOG
+#include <syslog.h>
+#endif
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <sys/fcntl.h>
+#include "utils/elog.h"
+#include "utils/memutils.h"
+#include "pool_config.h"
+
+#define MAX_ON_EXITS 64
+
+static struct ONEXIT
+{
+	void		(*function) (int code, Datum arg);
+	Datum		arg;
+} on_proc_exit_list[MAX_ON_EXITS], on_shmem_exit_list[MAX_ON_EXITS];
+
+static int	on_proc_exit_index,
+			on_shmem_exit_index;
+/*
+ * This flag tracks whether we've called atexit() in the current process
+ * (or in the parent postmaster).
+ */
+static bool atexit_callback_setup = false;
+/*
+ * This flag is set during proc_exit() to change ereport()'s behavior,
+ * so that an ereport() from an on_proc_exit routine cannot get us out
+ * of the exit procedure.  We do NOT want to go back to the idle loop...
+ */
+bool		proc_exit_inprogress = false;
+/* local functions */
+static void proc_exit_prepare(int code);
+
+int		log_min_error_statement = LOG;
+int		log_min_messages = LOG;
+int		client_min_messages = LOG;
+
+/* Note: whereToSendOutput is initialized for the bootstrap/standalone case */
+CommandDest whereToSendOutput = DestDebug;
+char		OutputFileName[1024];	/* debugging output file */
+static void set_errdata_field(MemoryContextData *cxt, char **ptr, const char *str);
+
+/* Global variables */
+ErrorContextCallback *error_context_stack = NULL;
+
+sigjmp_buf *PG_exception_stack = NULL;
+
+extern bool redirection_done;
+
+/*
+ * Hook for intercepting messages before they are sent to the server log.
+ * Note that the hook will not get called for messages that are suppressed
+ * by log_min_messages.  Also note that logging hooks implemented in preload
+ * libraries will miss any log messages that are generated before the
+ * library is loaded.
+ */
+emit_log_hook_type emit_log_hook = NULL;
+
+/* GUC parameters */
+int			Log_error_verbosity = PGERROR_VERBOSE;
+char	   *Log_line_prefix = NULL;		/* format for extra log line info */
+int			Log_destination = LOG_DESTINATION_STDERR;
+char	   *Log_destination_string = NULL;
+
+#ifdef HAVE_SYSLOG
+
+/*
+ * Max string length to send to syslog().  Note that this doesn't count the
+ * sequence-number prefix we add, and of course it doesn't count the prefix
+ * added by syslog itself.	Solaris and sysklogd truncate the final message
+ * at 1024 bytes, so this value leaves 124 bytes for those prefixes.  (Most
+ * other syslog implementations seem to have limits of 2KB or so.)
+ */
+#ifndef PG_SYSLOG_LIMIT
+#define PG_SYSLOG_LIMIT 900
+#endif
+
+static bool openlog_done = false;
+static char *syslog_ident = NULL;
+static int	syslog_facility = LOG_LOCAL0;
+
+static void write_syslog(int level, const char *line);
+#endif
+
+static void send_message_to_server_log(ErrorData *edata);
+static void write_console(const char *line, int len);
+
+#ifdef WIN32
+extern char *event_source;
+static void write_eventlog(int level, const char *line, int len);
+#endif
+
+/* We provide a small stack of ErrorData records for re-entrant cases */
+#define ERRORDATA_STACK_SIZE  5
+
+static ErrorData errordata[ERRORDATA_STACK_SIZE];
+
+static int	errordata_stack_depth = -1; /* index of topmost active frame */
+
+static int	recursion_depth = 0;	/* to detect actual recursion */
+
+/* buffers for formatted timestamps that might be used by both
+ * log_line_prefix and csv logs.
+ */
+
+#define FORMATTED_TS_LEN 128
+static char formatted_start_time[FORMATTED_TS_LEN];
+static char formatted_log_time[FORMATTED_TS_LEN];
+
+
+/* Macro for checking errordata_stack_depth is reasonable */
+#define CHECK_STACK_DEPTH() \
+	do { \
+		if (errordata_stack_depth < 0) \
+		{ \
+			errordata_stack_depth = -1; \
+			ereport(ERROR, (errmsg_internal("errstart was not called"))); \
+		} \
+	} while (0)
+
+
+static void log_line_prefix(StringInfo buf, ErrorData *edata);
+static char *expand_fmt_string(const char *fmt, ErrorData *edata);
+static const char *useful_strerror(int errnum);
+static const char *error_severity(int elevel);
+static void append_with_tabs(StringInfo buf, const char *str);
+static bool is_log_level_output(int elevel, int log_min_level);
+static void setup_formatted_log_time(void);
+static void setup_formatted_start_time(void);
+
+
+/*
+ * in_error_recursion_trouble --- are we at risk of infinite error recursion?
+ *
+ * This function exists to provide common control of various fallback steps
+ * that we take if we think we are facing infinite error recursion.  See the
+ * callers for details.
+ */
+bool
+in_error_recursion_trouble(void)
+{
+	/* Pull the plug if recurse more than once */
+	return (recursion_depth > 2);
+}
+
+/*
+ * One of those fallback steps is to stop trying to localize the error
+ * message, since there's a significant probability that that's exactly
+ * what's causing the recursion.
+ */
+static inline const char *
+err_gettext(const char *str)
+{
+#ifdef ENABLE_NLS
+	if (in_error_recursion_trouble())
+		return str;
+	else
+		return gettext(str);
+#else
+	return str;
+#endif
+}
+
+
+/*
+ * errstart --- begin an error-reporting cycle
+ *
+ * Create a stack entry and store the given parameters in it.  Subsequently,
+ * errmsg() and perhaps other routines will be called to further populate
+ * the stack entry.  Finally, errfinish() will be called to actually process
+ * the error report.
+ *
+ * Returns TRUE in normal case.  Returns FALSE to short-circuit the error
+ * report (if it's a warning or lower and not to be reported anywhere).
+ */
+bool
+errstart(int elevel, const char *filename, int lineno,
+		 const char *funcname, const char *domain)
+{
+	ErrorData  *edata;
+	bool		output_to_server;
+	bool		output_to_client = false;
+	int			i;
+
+	/*
+	 * Check some cases in which we want to promote an error into a more
+	 * severe error.  None of this logic applies for non-error messages.
+	 */
+	if (elevel >= ERROR)
+	{
+		/*
+		 * Check reasons for treating ERROR as FATAL:
+		 *
+		 * 1. we have no handler to pass the error to (implies we are in the
+		 * postmaster or in backend startup).
+		 *
+		 * 2. ExitOnAnyError mode switch is set (initdb uses this).
+		 *
+		 * 3. the error occurred after proc_exit has begun to run.	(It's
+		 * proc_exit's responsibility to see that this doesn't turn into
+		 * infinite recursion!)
+		 */
+		if (elevel == ERROR)
+		{
+			if (PG_exception_stack == NULL ||
+				proc_exit_inprogress)
+				elevel = FATAL;
+		}
+
+		if(elevel  == ERROR)
+		{
+			if(processType == PT_CHILD)
+			{
+				/*
+				 * If the frontend connection exists, treat this error as FATAL
+				 */
+				if(is_session_connected())
+					elevel = FATAL;
+			}
+		}
+		/*
+		 * If the error level is ERROR or more, errfinish is not going to
+		 * return to caller; therefore, if there is any stacked error already
+		 * in progress it will be lost.  This is more or less okay, except we
+		 * do not want to have a FATAL or PANIC error downgraded because the
+		 * reporting process was interrupted by a lower-grade error.  So check
+		 * the stack and make sure we panic if panic is warranted.
+		 */
+		for (i = 0; i <= errordata_stack_depth; i++)
+			elevel = Max(elevel, errordata[i].elevel);
+	}
+
+	/*
+	 * Now decide whether we need to process this report at all; if it's
+	 * warning or less and not enabled for logging, just return FALSE without
+	 * starting up any error logging machinery.
+	 */
+
+	/* Determine whether message is enabled for server log output */
+	output_to_server = is_log_level_output(elevel, log_min_messages);
+
+	/* Determine whether message is enabled for client output */
+	if (whereToSendOutput == DestRemote && elevel != COMMERROR)
+	{
+		/*
+		 * client_min_messages is honored only after we complete the
+		 * authentication handshake.  This is required both for security
+		 * reasons and because many clients can't handle NOTICE messages
+		 * during authentication.
+		 */
+//		if (ClientAuthInProgress)
+//			output_to_client = (elevel >= ERROR);
+//		else
+			output_to_client = (elevel >= client_min_messages ||
+								elevel == INFO);
+	}
+
+	/* Skip processing effort if non-error message will not be output */
+	if (elevel < ERROR && !output_to_server && !output_to_client)
+		return false;
+
+	/*
+	 * Okay, crank up a stack entry to store the info in.
+	 */
+
+	if (recursion_depth++ > 0 && elevel >= ERROR)
+	{
+		/*
+		 * Ooops, error during error processing.  Clear ErrorContext as
+		 * discussed at top of file.  We will not return to the original
+		 * error's reporter or handler, so we don't need it.
+		 */
+		MemoryContextReset(ErrorContext);
+
+		/*
+		 * Infinite error recursion might be due to something broken in a
+		 * context traceback routine.  Abandon them too.  We also abandon
+		 * attempting to print the error statement (which, if long, could
+		 * itself be the source of the recursive failure).
+		 */
+		if (in_error_recursion_trouble())
+		{
+			error_context_stack = NULL;
+//			debug_query_string = NULL;
+		}
+	}
+	if (++errordata_stack_depth >= ERRORDATA_STACK_SIZE)
+	{
+		/*
+		 * Wups, stack not big enough.	We treat this as a PANIC condition
+		 * because it suggests an infinite loop of errors during error
+		 * recovery.
+		 */
+		errordata_stack_depth = -1;		/* make room on stack */
+		ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded")));
+	}
+
+	/* Initialize data for this error frame */
+	edata = &errordata[errordata_stack_depth];
+	MemSet(edata, 0, sizeof(ErrorData));
+	edata->elevel = elevel;
+	edata->output_to_server = output_to_server;
+	edata->output_to_client = output_to_client;
+	if (filename)
+	{
+		const char *slash;
+
+		/* keep only base name, useful especially for vpath builds */
+		slash = strrchr(filename, '/');
+		if (slash)
+			filename = slash + 1;
+	}
+	edata->filename = filename;
+	edata->lineno = lineno;
+	edata->funcname = funcname;
+	/* the default text domain is the backend's */
+	edata->domain = domain ? domain : PG_TEXTDOMAIN("postgres");
+	/* Select default errcode based on elevel */
+//	if (elevel >= ERROR)
+//		edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
+//	else if (elevel == WARNING)
+//		edata->sqlerrcode = ERRCODE_WARNING;
+//	else
+//		edata->sqlerrcode = ERRCODE_SUCCESSFUL_COMPLETION;
+	/* errno is saved here so that error parameter eval can't change it */
+//	edata->saved_errno = errno;
+
+	/*
+	 * Any allocations for this error state level should go into ErrorContext
+	 */
+	edata->assoc_context = ErrorContext;
+
+	recursion_depth--;
+	return true;
+}
+
+/*
+ * errfinish --- end an error-reporting cycle
+ *
+ * Produce the appropriate error report(s) and pop the error stack.
+ *
+ * If elevel is ERROR or worse, control does not return to the caller.
+ * See elog.h for the error level definitions.
+ */
+void
+errfinish(int dummy,...)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+	int			elevel = edata->elevel;
+	int 		retcode = edata->retcode;
+	MemoryContext oldcontext;
+	ErrorContextCallback *econtext;
+
+	recursion_depth++;
+	CHECK_STACK_DEPTH();
+
+	/*
+	 * Do processing in ErrorContext, which we hope has enough reserved space
+	 * to report an error.
+	 */
+	oldcontext = MemoryContextSwitchTo(ErrorContext);
+
+	/*
+	 * Call any context callback functions.  Errors occurring in callback
+	 * functions will be treated as recursive errors --- this ensures we will
+	 * avoid infinite recursion (see errstart).
+	 */
+	for (econtext = error_context_stack;
+		 econtext != NULL;
+		 econtext = econtext->previous)
+		(*econtext->callback) (econtext->arg);
+
+	/*
+	 * If ERROR (not more nor less) we pass it off to the current handler.
+	 * Printing it and popping the stack is the responsibility of the handler.
+	 */
+	if (elevel == ERROR)
+	{
+		/*
+		 * We do some minimal cleanup before longjmp'ing so that handlers can
+		 * execute in a reasonably sane state.
+		 */
+
+		/* This is just in case the error came while waiting for input */
+//		ImmediateInterruptOK = false;
+
+		/*
+		 * Reset InterruptHoldoffCount in case we ereport'd from inside an
+		 * interrupt holdoff section.  (We assume here that no handler will
+		 * itself be inside a holdoff section.	If necessary, such a handler
+		 * could save and restore InterruptHoldoffCount for itself, but this
+		 * should make life easier for most.)
+		 */
+//		InterruptHoldoffCount = 0;
+
+//		CritSectionCount = 0;	/* should be unnecessary, but... */
+
+		/*
+		 * Note that we leave CurrentMemoryContext set to ErrorContext. The
+		 * handler should reset it to something else soon.
+		 */
+
+		recursion_depth--;
+		PG_RE_THROW();
+	}
+
+	/*
+	 * If we are doing FATAL or PANIC, abort any old-style COPY OUT in
+	 * progress, so that we can report the message before dying.  (Without
+	 * this, pq_putmessage will refuse to send the message at all, which is
+	 * what we want for NOTICE messages, but not for fatal exits.) This hack
+	 * is necessary because of poor design of old-style copy protocol.	Note
+	 * we must do this even if client is fool enough to have set
+	 * client_min_messages above FATAL, so don't look at output_to_client.
+	 */
+//	if (elevel >= FATAL && whereToSendOutput == DestRemote)
+//		pq_endcopyout(true);
+
+	/* Emit the message to the right places */
+	EmitErrorReport();
+
+	/* Now free up subsidiary data attached to stack entry, and release it */
+	if (edata->message)
+		pfree(edata->message);
+	if (edata->detail)
+		pfree(edata->detail);
+	if (edata->detail_log)
+		pfree(edata->detail_log);
+	if (edata->hint)
+		pfree(edata->hint);
+	if (edata->context)
+		pfree(edata->context);
+	if (edata->schema_name)
+		pfree(edata->schema_name);
+	if (edata->table_name)
+		pfree(edata->table_name);
+	if (edata->column_name)
+		pfree(edata->column_name);
+	if (edata->datatype_name)
+		pfree(edata->datatype_name);
+	if (edata->constraint_name)
+		pfree(edata->constraint_name);
+	if (edata->internalquery)
+		pfree(edata->internalquery);
+
+	errordata_stack_depth--;
+
+	/* Exit error-handling context */
+	MemoryContextSwitchTo(oldcontext);
+	recursion_depth--;
+
+	/*
+	 * Perform error recovery action as specified by elevel.
+	 */
+	if (elevel == FATAL)
+	{
+		/*
+		 * For a FATAL error, we let proc_exit clean up and exit.
+		 */
+//		ImmediateInterruptOK = false;
+
+		/*
+		 * If we just reported a startup failure, the client will disconnect
+		 * on receiving it, so don't send any more to the client.
+		 */
+		if (PG_exception_stack == NULL && whereToSendOutput == DestRemote)
+			whereToSendOutput = DestNone;
+
+		/*
+		 * fflush here is just to improve the odds that we get to see the
+		 * error message, in case things are so hosed that proc_exit crashes.
+		 * Any other code you might be tempted to add here should probably be
+		 * in an on_proc_exit or on_shmem_exit callback instead.
+		 */
+		fflush(stdout);
+		fflush(stderr);
+
+		/*
+		 * Do normal process-exit cleanup, then return exit code 1 to indicate
+		 * FATAL termination.  The postmaster may or may not consider this
+		 * worthy of panic, depending on which subprocess returns it.
+		 */
+		proc_exit(retcode);
+	}
+
+	if (elevel >= PANIC)
+	{
+		/*
+		 * Serious crash time. Postmaster will observe SIGABRT process exit
+		 * status and kill the other backends too.
+		 *
+		 * XXX: what if we are *in* the postmaster?  abort() won't kill our
+		 * children...
+		 */
+//		ImmediateInterruptOK = false;
+		fflush(stdout);
+		fflush(stderr);
+		abort();
+	}
+
+	/*
+	 * We reach here if elevel <= WARNING. OK to return to caller.
+	 *
+	 * But check for cancel/die interrupt first --- this is so that the user
+	 * can stop a query emitting tons of notice or warning messages, even if
+	 * it's in a loop that otherwise fails to check for interrupts.
+	 */
+	//CHECK_FOR_INTERRUPTS();
+}
+
+
+/*
+ * errcode --- add SQLSTATE error code to the current error
+ *
+ * The code is expected to be represented as per MAKE_SQLSTATE().
+ */
+int
+errcode_ign(int sqlerrcode)
+{
+//	ErrorData  *edata = &errordata[errordata_stack_depth];
+//
+//	/* we don't bother incrementing recursion_depth */
+//	CHECK_STACK_DEPTH();
+//
+//	edata->sqlerrcode = sqlerrcode;
+
+	return 0;					/* return value does not matter */
+}
+
+
+/*
+ * errcode_for_socket_access --- add SQLSTATE error code to the current error
+ *
+ * The SQLSTATE code is chosen based on the saved errno value.	We assume
+ * that the failing operation was some type of socket access.
+ *
+ * NOTE: the primary error message string should generally include %m
+ * when this is used.
+ */
+
+/*
+ * This macro handles expansion of a format string and associated parameters;
+ * it's common code for errmsg(), errdetail(), etc.  Must be called inside
+ * a routine that is declared like "const char *fmt, ..." and has an edata
+ * pointer set up.	The message is assigned to edata->targetfield, or
+ * appended to it if appendval is true.  The message is subject to translation
+ * if translateit is true.
+ *
+ * Note: we pstrdup the buffer rather than just transferring its storage
+ * to the edata field because the buffer might be considerably larger than
+ * really necessary.
+ */
+#define EVALUATE_MESSAGE(domain, targetfield, appendval, translateit)	\
+	{ \
+		char		   *fmtbuf; \
+		StringInfoData	buf; \
+		/* Internationalize the error format string */ \
+		if (translateit && !in_error_recursion_trouble()) \
+			fmt = dgettext((domain), fmt);				  \
+		/* Expand %m in format string */ \
+		fmtbuf = expand_fmt_string(fmt, edata); \
+		initStringInfo(&buf); \
+		if ((appendval) && edata->targetfield) { \
+			appendStringInfoString(&buf, edata->targetfield); \
+			appendStringInfoChar(&buf, '\n'); \
+		} \
+		/* Generate actual output --- have to use appendStringInfoVA */ \
+		for (;;) \
+		{ \
+			va_list		args; \
+			bool		success; \
+			va_start(args, fmt); \
+			success = appendStringInfoVA(&buf, fmtbuf, args); \
+			va_end(args); \
+			if (success) \
+				break; \
+			enlargeStringInfo(&buf, buf.maxlen); \
+		} \
+		/* Done with expanded fmt */ \
+		pfree(fmtbuf); \
+		/* Save the completed message into the stack item */ \
+		if (edata->targetfield) \
+			pfree(edata->targetfield); \
+		edata->targetfield = pstrdup(buf.data); \
+		pfree(buf.data); \
+	}
+
+/*
+ * Same as above, except for pluralized error messages.  The calling routine
+ * must be declared like "const char *fmt_singular, const char *fmt_plural,
+ * unsigned long n, ...".  Translation is assumed always wanted.
+ */
+#define EVALUATE_MESSAGE_PLURAL(domain, targetfield, appendval)  \
+	{ \
+		const char	   *fmt; \
+		char		   *fmtbuf; \
+		StringInfoData	buf; \
+		/* Internationalize the error format string */ \
+		if (!in_error_recursion_trouble()) \
+			fmt = dngettext((domain), fmt_singular, fmt_plural, n); \
+		else \
+			fmt = (n == 1 ? fmt_singular : fmt_plural); \
+		/* Expand %m in format string */ \
+		fmtbuf = expand_fmt_string(fmt, edata); \
+		initStringInfo(&buf); \
+		if ((appendval) && edata->targetfield) { \
+			appendStringInfoString(&buf, edata->targetfield); \
+			appendStringInfoChar(&buf, '\n'); \
+		} \
+		/* Generate actual output --- have to use appendStringInfoVA */ \
+		for (;;) \
+		{ \
+			va_list		args; \
+			bool		success; \
+			va_start(args, n); \
+			success = appendStringInfoVA(&buf, fmtbuf, args); \
+			va_end(args); \
+			if (success) \
+				break; \
+			enlargeStringInfo(&buf, buf.maxlen); \
+		} \
+		/* Done with expanded fmt */ \
+		pfree(fmtbuf); \
+		/* Save the completed message into the stack item */ \
+		if (edata->targetfield) \
+			pfree(edata->targetfield); \
+		edata->targetfield = pstrdup(buf.data); \
+		pfree(buf.data); \
+	}
+
+
+/*
+ * errmsg --- add a primary error message text to the current error
+ *
+ * In addition to the usual %-escapes recognized by printf, "%m" in
+ * fmt is replaced by the error message for the caller's value of errno.
+ *
+ * Note: no newline is needed at the end of the fmt string, since
+ * ereport will provide one for the output methods that need it.
+ */
+int
+errmsg(const char *fmt,...)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+	MemoryContext oldcontext;
+
+	recursion_depth++;
+	CHECK_STACK_DEPTH();
+	oldcontext = MemoryContextSwitchTo(edata->assoc_context);
+
+	EVALUATE_MESSAGE(edata->domain, message, false, true);
+
+	MemoryContextSwitchTo(oldcontext);
+	recursion_depth--;
+	return 0;					/* return value does not matter */
+}
+
+
+/*
+ * errmsg_internal --- add a primary error message text to the current error
+ *
+ * This is exactly like errmsg() except that strings passed to errmsg_internal
+ * are not translated, and are customarily left out of the
+ * internationalization message dictionary.  This should be used for "can't
+ * happen" cases that are probably not worth spending translation effort on.
+ * We also use this for certain cases where we *must* not try to translate
+ * the message because the translation would fail and result in infinite
+ * error recursion.
+ */
+int
+errmsg_internal(const char *fmt,...)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+	MemoryContext oldcontext;
+
+	recursion_depth++;
+	CHECK_STACK_DEPTH();
+	oldcontext = MemoryContextSwitchTo(edata->assoc_context);
+
+	EVALUATE_MESSAGE(edata->domain, message, false, false);
+
+	MemoryContextSwitchTo(oldcontext);
+	recursion_depth--;
+	return 0;					/* return value does not matter */
+}
+
+
+/*
+ * errmsg_plural --- add a primary error message text to the current error,
+ * with support for pluralization of the message text
+ */
+int
+errmsg_plural(const char *fmt_singular, const char *fmt_plural,
+			  unsigned long n,...)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+	MemoryContext oldcontext;
+
+	recursion_depth++;
+	CHECK_STACK_DEPTH();
+	oldcontext = MemoryContextSwitchTo(edata->assoc_context);
+
+	EVALUATE_MESSAGE_PLURAL(edata->domain, message, false);
+
+	MemoryContextSwitchTo(oldcontext);
+	recursion_depth--;
+	return 0;					/* return value does not matter */
+}
+
+
+/*
+ * errdetail --- add a detail error message text to the current error
+ */
+int
+errdetail(const char *fmt,...)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+	MemoryContext oldcontext;
+
+	recursion_depth++;
+	CHECK_STACK_DEPTH();
+	oldcontext = MemoryContextSwitchTo(edata->assoc_context);
+
+	EVALUATE_MESSAGE(edata->domain, detail, false, true);
+
+	MemoryContextSwitchTo(oldcontext);
+	recursion_depth--;
+	return 0;					/* return value does not matter */
+}
+
+
+/*
+ * errdetail_internal --- add a detail error message text to the current error
+ *
+ * This is exactly like errdetail() except that strings passed to
+ * errdetail_internal are not translated, and are customarily left out of the
+ * internationalization message dictionary.  This should be used for detail
+ * messages that seem not worth translating for one reason or another
+ * (typically, that they don't seem to be useful to average users).
+ */
+int
+errdetail_internal(const char *fmt,...)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+	MemoryContext oldcontext;
+
+	recursion_depth++;
+	CHECK_STACK_DEPTH();
+	oldcontext = MemoryContextSwitchTo(edata->assoc_context);
+
+	EVALUATE_MESSAGE(edata->domain, detail, false, false);
+
+	MemoryContextSwitchTo(oldcontext);
+	recursion_depth--;
+	return 0;					/* return value does not matter */
+}
+
+
+/*
+ * errdetail_log --- add a detail_log error message text to the current error
+ */
+int
+errdetail_log(const char *fmt,...)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+	MemoryContext oldcontext;
+
+	recursion_depth++;
+	CHECK_STACK_DEPTH();
+	oldcontext = MemoryContextSwitchTo(edata->assoc_context);
+
+	EVALUATE_MESSAGE(edata->domain, detail_log, false, true);
+
+	MemoryContextSwitchTo(oldcontext);
+	recursion_depth--;
+	return 0;					/* return value does not matter */
+}
+
+
+/*
+ * errdetail_plural --- add a detail error message text to the current error,
+ * with support for pluralization of the message text
+ */
+int
+errdetail_plural(const char *fmt_singular, const char *fmt_plural,
+				 unsigned long n,...)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+	MemoryContext oldcontext;
+
+	recursion_depth++;
+	CHECK_STACK_DEPTH();
+	oldcontext = MemoryContextSwitchTo(edata->assoc_context);
+
+	EVALUATE_MESSAGE_PLURAL(edata->domain, detail, false);
+
+	MemoryContextSwitchTo(oldcontext);
+	recursion_depth--;
+	return 0;					/* return value does not matter */
+}
+
+
+/*
+ * errhint --- add a hint error message text to the current error
+ */
+int
+errhint(const char *fmt,...)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+	MemoryContext oldcontext;
+
+	recursion_depth++;
+	CHECK_STACK_DEPTH();
+	oldcontext = MemoryContextSwitchTo(edata->assoc_context);
+
+	EVALUATE_MESSAGE(edata->domain, hint, false, true);
+
+	MemoryContextSwitchTo(oldcontext);
+	recursion_depth--;
+	return 0;					/* return value does not matter */
+}
+
+
+/*
+ * errcontext_msg --- add a context error message text to the current error
+ *
+ * Unlike other cases, multiple calls are allowed to build up a stack of
+ * context information.  We assume earlier calls represent more-closely-nested
+ * states.
+ */
+int
+errcontext_msg(const char *fmt,...)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+	MemoryContext oldcontext;
+
+	recursion_depth++;
+	CHECK_STACK_DEPTH();
+	oldcontext = MemoryContextSwitchTo(edata->assoc_context);
+
+	EVALUATE_MESSAGE(edata->context_domain, context, true, true);
+
+	MemoryContextSwitchTo(oldcontext);
+	recursion_depth--;
+	return 0;					/* return value does not matter */
+}
+
+/*
+ * set_errcontext_domain --- set message domain to be used by errcontext()
+ *
+ * errcontext_msg() can be called from a different module than the original
+ * ereport(), so we cannot use the message domain passed in errstart() to
+ * translate it.  Instead, each errcontext_msg() call should be preceded by
+ * a set_errcontext_domain() call to specify the domain.  This is usually
+ * done transparently by the errcontext() macro.
+ */
+int
+set_errcontext_domain(const char *domain)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+
+	/* we don't bother incrementing recursion_depth */
+	CHECK_STACK_DEPTH();
+
+	edata->context_domain = domain;
+
+	return 0;					/* return value does not matter */
+}
+
+
+/*
+ * errhidestmt --- optionally suppress STATEMENT: field of log entry
+ *
+ * This should be called if the message text already includes the statement.
+ */
+int
+errhidestmt(bool hide_stmt)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+
+	/* we don't bother incrementing recursion_depth */
+	CHECK_STACK_DEPTH();
+
+	edata->hide_stmt = hide_stmt;
+
+	return 0;					/* return value does not matter */
+}
+
+
+/*
+ * errfunction --- add reporting function name to the current error
+ *
+ * This is used when backwards compatibility demands that the function
+ * name appear in messages sent to old-protocol clients.  Note that the
+ * passed string is expected to be a non-freeable constant string.
+ */
+int
+errfunction(const char *funcname)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+
+	/* we don't bother incrementing recursion_depth */
+	CHECK_STACK_DEPTH();
+
+	edata->funcname = funcname;
+	edata->show_funcname = true;
+
+	return 0;					/* return value does not matter */
+}
+
+/*
+ * errposition --- add cursor position to the current error
+ */
+int
+errposition(int cursorpos)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+
+	/* we don't bother incrementing recursion_depth */
+	CHECK_STACK_DEPTH();
+
+	edata->cursorpos = cursorpos;
+
+	return 0;					/* return value does not matter */
+}
+
+int	return_code(int retcode)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+
+	/* we don't bother incrementing recursion_depth */
+	CHECK_STACK_DEPTH();
+
+	edata->retcode = retcode;
+
+	return retcode;					/* return value does not matter */
+}
+
+int	get_return_code(void)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+
+	/* we don't bother incrementing recursion_depth */
+	CHECK_STACK_DEPTH();
+
+	return edata->retcode;
+}
+/*
+ * set_errdata_field --- set an ErrorData string field
+ */
+static void
+set_errdata_field(MemoryContextData *cxt, char **ptr, const char *str)
+{
+	Assert(*ptr == NULL);
+	*ptr = MemoryContextStrdup(cxt, str);
+}
+
+/*
+ * geterrcode --- return the currently set SQLSTATE error code
+ *
+ * This is only intended for use in error callback subroutines, since there
+ * is no other place outside elog.c where the concept is meaningful.
+ */
+int
+geterrcode(void)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+
+	/* we don't bother incrementing recursion_depth */
+	CHECK_STACK_DEPTH();
+
+	return edata->sqlerrcode;
+}
+
+/*
+ * geterrposition --- return the currently set error position (0 if none)
+ *
+ * This is only intended for use in error callback subroutines, since there
+ * is no other place outside elog.c where the concept is meaningful.
+ */
+int
+geterrposition(void)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+
+	/* we don't bother incrementing recursion_depth */
+	CHECK_STACK_DEPTH();
+
+	return edata->cursorpos;
+}
+
+/*
+ * elog_start --- startup for old-style API
+ *
+ * All that we do here is stash the hidden filename/lineno/funcname
+ * arguments into a stack entry, along with the current value of errno.
+ *
+ * We need this to be separate from elog_finish because there's no other
+ * C89-compliant way to deal with inserting extra arguments into the elog
+ * call.  (When using C99's __VA_ARGS__, we could possibly merge this with
+ * elog_finish, but there doesn't seem to be a good way to save errno before
+ * evaluating the format arguments if we do that.)
+ */
+void
+elog_start(const char *filename, int lineno, const char *funcname)
+{
+	ErrorData  *edata;
+
+	if (++errordata_stack_depth >= ERRORDATA_STACK_SIZE)
+	{
+		/*
+		 * Wups, stack not big enough.	We treat this as a PANIC condition
+		 * because it suggests an infinite loop of errors during error
+		 * recovery.  Note that the message is intentionally not localized,
+		 * else failure to convert it to client encoding could cause further
+		 * recursion.
+		 */
+		errordata_stack_depth = -1;		/* make room on stack */
+		ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded")));
+	}
+
+	edata = &errordata[errordata_stack_depth];
+	if (filename)
+	{
+		const char *slash;
+
+		/* keep only base name, useful especially for vpath builds */
+		slash = strrchr(filename, '/');
+		if (slash)
+			filename = slash + 1;
+	}
+	edata->filename = filename;
+	edata->lineno = lineno;
+	edata->funcname = funcname;
+	/* errno is saved now so that error parameter eval can't change it */
+	edata->saved_errno = errno;
+
+	/* Use ErrorContext for any allocations done at this level. */
+	edata->assoc_context = ErrorContext;
+}
+
+/*
+ * elog_finish --- finish up for old-style API
+ */
+void
+elog_finish(int elevel, const char *fmt,...)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+	MemoryContext oldcontext;
+
+	CHECK_STACK_DEPTH();
+
+	/*
+	 * Do errstart() to see if we actually want to report the message.
+	 */
+	errordata_stack_depth--;
+	errno = edata->saved_errno;
+	if (!errstart(elevel, edata->filename, edata->lineno, edata->funcname, NULL))
+		return;					/* nothing to do */
+
+	/*
+	 * Format error message just like errmsg_internal().
+	 */
+	recursion_depth++;
+	oldcontext = MemoryContextSwitchTo(edata->assoc_context);
+
+	EVALUATE_MESSAGE(edata->domain, message, false, false);
+
+	MemoryContextSwitchTo(oldcontext);
+	recursion_depth--;
+
+	/*
+	 * And let errfinish() finish up.
+	 */
+	errfinish(0);
+}
+
+/*
+ * Actual output of the top-of-stack error message
+ *
+ * In the ereport(ERROR) case this is called from PostgresMain (or not at all,
+ * if the error is caught by somebody).  For all other severity levels this
+ * is called by errfinish.
+ */
+void
+EmitErrorReport(void)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+	MemoryContext oldcontext;
+
+	recursion_depth++;
+	CHECK_STACK_DEPTH();
+
+
+	oldcontext = MemoryContextSwitchTo(edata->assoc_context);
+
+	/*
+	 * Call hook before sending message to log.  The hook function is allowed
+	 * to turn off edata->output_to_server, so we must recheck that afterward.
+	 * Making any other change in the content of edata is not considered
+	 * supported.
+	 *
+	 * Note: the reason why the hook can only turn off output_to_server, and
+	 * not turn it on, is that it'd be unreliable: we will never get here at
+	 * all if errstart() deems the message uninteresting.  A hook that could
+	 * make decisions in that direction would have to hook into errstart(),
+	 * where it would have much less information available.  emit_log_hook is
+	 * intended for custom log filtering and custom log message transmission
+	 * mechanisms.
+	 */
+	if (edata->output_to_server && emit_log_hook)
+		(*emit_log_hook) (edata);
+
+	/* Send to server log, if enabled */
+	if (edata->output_to_server)
+		send_message_to_server_log(edata);
+
+	/* Send to client, if enabled */
+//	if (edata->output_to_client)
+//		send_message_to_frontend(edata);
+
+	MemoryContextSwitchTo(oldcontext);
+	recursion_depth--;
+}
+
+/*
+ * CopyErrorData --- obtain a copy of the topmost error stack entry
+ *
+ * This is only for use in error handler code.	The data is copied into the
+ * current memory context, so callers should always switch away from
+ * ErrorContext first; otherwise it will be lost when FlushErrorState is done.
+ */
+ErrorData *
+CopyErrorData(void)
+{
+	ErrorData  *edata = &errordata[errordata_stack_depth];
+	ErrorData  *newedata;
+
+	/*
+	 * we don't increment recursion_depth because out-of-memory here does not
+	 * indicate a problem within the error subsystem.
+	 */
+	CHECK_STACK_DEPTH();
+
+	Assert(CurrentMemoryContext != ErrorContext);
+
+	/* Copy the struct itself */
+	newedata = (ErrorData *) palloc(sizeof(ErrorData));
+	memcpy(newedata, edata, sizeof(ErrorData));
+
+	/* Make copies of separately-allocated fields */
+	if (newedata->message)
+		newedata->message = pstrdup(newedata->message);
+	if (newedata->detail)
+		newedata->detail = pstrdup(newedata->detail);
+	if (newedata->detail_log)
+		newedata->detail_log = pstrdup(newedata->detail_log);
+	if (newedata->hint)
+		newedata->hint = pstrdup(newedata->hint);
+	if (newedata->context)
+		newedata->context = pstrdup(newedata->context);
+	if (newedata->schema_name)
+		newedata->schema_name = pstrdup(newedata->schema_name);
+	if (newedata->table_name)
+		newedata->table_name = pstrdup(newedata->table_name);
+	if (newedata->column_name)
+		newedata->column_name = pstrdup(newedata->column_name);
+	if (newedata->datatype_name)
+		newedata->datatype_name = pstrdup(newedata->datatype_name);
+	if (newedata->constraint_name)
+		newedata->constraint_name = pstrdup(newedata->constraint_name);
+	if (newedata->internalquery)
+		newedata->internalquery = pstrdup(newedata->internalquery);
+
+	/* Use the calling context for string allocation */
+//	newedata->assoc_context = CurrentMemoryContext;
+
+	return newedata;
+}
+
+/*
+ * FreeErrorData --- free the structure returned by CopyErrorData.
+ *
+ * Error handlers should use this in preference to assuming they know all
+ * the separately-allocated fields.
+ */
+void
+FreeErrorData(ErrorData *edata)
+{
+	if (edata->message)
+		pfree(edata->message);
+	if (edata->detail)
+		pfree(edata->detail);
+	if (edata->detail_log)
+		pfree(edata->detail_log);
+	if (edata->hint)
+		pfree(edata->hint);
+	if (edata->context)
+		pfree(edata->context);
+	if (edata->schema_name)
+		pfree(edata->schema_name);
+	if (edata->table_name)
+		pfree(edata->table_name);
+	if (edata->column_name)
+		pfree(edata->column_name);
+	if (edata->datatype_name)
+		pfree(edata->datatype_name);
+	if (edata->constraint_name)
+		pfree(edata->constraint_name);
+	if (edata->internalquery)
+		pfree(edata->internalquery);
+	pfree(edata);
+}
+
+/*
+ * FlushErrorState --- flush the error state after error recovery
+ *
+ * This should be called by an error handler after it's done processing
+ * the error; or as soon as it's done CopyErrorData, if it intends to
+ * do stuff that is likely to provoke another error.  You are not "out" of
+ * the error subsystem until you have done this.
+ */
+void
+FlushErrorState(void)
+{
+	/*
+	 * Reset stack to empty.  The only case where it would be more than one
+	 * deep is if we serviced an error that interrupted construction of
+	 * another message.  We assume control escaped out of that message
+	 * construction and won't ever go back.
+	 */
+	errordata_stack_depth = -1;
+	recursion_depth = 0;
+	/* Delete all data in ErrorContext */
+	MemoryContextResetAndDeleteChildren(ErrorContext);
+}
+
+/*
+ * ReThrowError --- re-throw a previously copied error
+ *
+ * A handler can do CopyErrorData/FlushErrorState to get out of the error
+ * subsystem, then do some processing, and finally ReThrowError to re-throw
+ * the original error.	This is slower than just PG_RE_THROW() but should
+ * be used if the "some processing" is likely to incur another error.
+ */
+void
+ReThrowError(ErrorData *edata)
+{
+	ErrorData  *newedata;
+
+	Assert(edata->elevel == ERROR);
+
+	/* Push the data back into the error context */
+	recursion_depth++;
+	MemoryContextSwitchTo(ErrorContext);
+
+	if (++errordata_stack_depth >= ERRORDATA_STACK_SIZE)
+	{
+		/*
+		 * Wups, stack not big enough.	We treat this as a PANIC condition
+		 * because it suggests an infinite loop of errors during error
+		 * recovery.
+		 */
+		errordata_stack_depth = -1;		/* make room on stack */
+		ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded")));
+	}
+
+	newedata = &errordata[errordata_stack_depth];
+	memcpy(newedata, edata, sizeof(ErrorData));
+
+	/* Make copies of separately-allocated fields */
+	if (newedata->message)
+		newedata->message = pstrdup(newedata->message);
+	if (newedata->detail)
+		newedata->detail = pstrdup(newedata->detail);
+	if (newedata->detail_log)
+		newedata->detail_log = pstrdup(newedata->detail_log);
+	if (newedata->hint)
+		newedata->hint = pstrdup(newedata->hint);
+	if (newedata->context)
+		newedata->context = pstrdup(newedata->context);
+	if (newedata->schema_name)
+		newedata->schema_name = pstrdup(newedata->schema_name);
+	if (newedata->table_name)
+		newedata->table_name = pstrdup(newedata->table_name);
+	if (newedata->column_name)
+		newedata->column_name = pstrdup(newedata->column_name);
+	if (newedata->datatype_name)
+		newedata->datatype_name = pstrdup(newedata->datatype_name);
+	if (newedata->constraint_name)
+		newedata->constraint_name = pstrdup(newedata->constraint_name);
+	if (newedata->internalquery)
+		newedata->internalquery = pstrdup(newedata->internalquery);
+
+	/* Reset the assoc_context to be ErrorContext */
+	newedata->assoc_context = ErrorContext;
+
+	recursion_depth--;
+	PG_RE_THROW();
+}
+
+/*
+ * pg_re_throw --- out-of-line implementation of PG_RE_THROW() macro
+ */
+void
+pg_re_throw(void)
+{
+	/* If possible, throw the error to the next outer setjmp handler */
+	if (PG_exception_stack != NULL)
+		siglongjmp(*PG_exception_stack, 1);
+	else
+	{
+		/*
+		 * If we get here, elog(ERROR) was thrown inside a PG_TRY block, which
+		 * we have now exited only to discover that there is no outer setjmp
+		 * handler to pass the error to.  Had the error been thrown outside
+		 * the block to begin with, we'd have promoted the error to FATAL, so
+		 * the correct behavior is to make it FATAL now; that is, emit it and
+		 * then call proc_exit.
+		 */
+		ErrorData  *edata = &errordata[errordata_stack_depth];
+
+		Assert(errordata_stack_depth >= 0);
+		Assert(edata->elevel == ERROR);
+		edata->elevel = FATAL;
+
+		/*
+		 * At least in principle, the increase in severity could have changed
+		 * where-to-output decisions, so recalculate.  This should stay in
+		 * sync with errstart(), which see for comments.
+		 */
+//		if (IsPostmasterEnvironment)
+//			edata->output_to_server = is_log_level_output(FATAL,
+//														  log_min_messages);
+//		else
+			edata->output_to_server = (FATAL >= log_min_messages);
+		if (whereToSendOutput == DestRemote)
+		{
+//			if (ClientAuthInProgress)
+//				edata->output_to_client = true;
+//			else
+				edata->output_to_client = (FATAL >= client_min_messages);
+		}
+
+		/*
+		 * We can use errfinish() for the rest, but we don't want it to call
+		 * any error context routines a second time.  Since we know we are
+		 * about to exit, it should be OK to just clear the context stack.
+		 */
+		error_context_stack = NULL;
+
+		errfinish(0);
+	}
+
+	/* Doesn't return ... */
+	fprintf(stderr,"pg_re_throw tried to return %s %d\n",
+						 __FILE__, __LINE__);
+}
+
+
+/*
+ * GetErrorContextStack - Return the context stack, for display/diags
+ *
+ * Returns a pstrdup'd string in the caller's context which includes the PG
+ * error call stack.  It is the caller's responsibility to ensure this string
+ * is pfree'd (or its context cleaned up) when done.
+ *
+ * This information is collected by traversing the error contexts and calling
+ * each context's callback function, each of which is expected to call
+ * errcontext() to return a string which can be presented to the user.
+ */
+char *
+GetErrorContextStack(void)
+{
+	ErrorData			   *edata;
+	ErrorContextCallback   *econtext;
+
+	/*
+	 * Okay, crank up a stack entry to store the info in.
+	 */
+	recursion_depth++;
+
+	if (++errordata_stack_depth >= ERRORDATA_STACK_SIZE)
+	{
+		/*
+		 * Wups, stack not big enough.	We treat this as a PANIC condition
+		 * because it suggests an infinite loop of errors during error
+		 * recovery.
+		 */
+		errordata_stack_depth = -1;		/* make room on stack */
+		ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded")));
+	}
+
+	/*
+	 * Things look good so far, so initialize our error frame
+	 */
+	edata = &errordata[errordata_stack_depth];
+	MemSet(edata, 0, sizeof(ErrorData));
+
+	/*
+	 * Set up assoc_context to be the caller's context, so any allocations
+	 * done (which will include edata->context) will use their context.
+	 */
+//	edata->assoc_context = CurrentMemoryContext;
+
+	/*
+	 * Call any context callback functions to collect the context information
+	 * into edata->context.
+	 *
+	 * Errors occurring in callback functions should go through the regular
+	 * error handling code which should handle any recursive errors, though
+	 * we double-check above, just in case.
+	 */
+	for (econtext = error_context_stack;
+		 econtext != NULL;
+		 econtext = econtext->previous)
+		(*econtext->callback) (econtext->arg);
+
+	/*
+	 * Clean ourselves off the stack, any allocations done should have been
+	 * using edata->assoc_context, which we set up earlier to be the caller's
+	 * context, so we're free to just remove our entry off the stack and
+	 * decrement recursion depth and exit.
+	 */
+	errordata_stack_depth--;
+	recursion_depth--;
+
+	/*
+	 * Return a pointer to the string the caller asked for, which should have
+	 * been allocated in their context.
+	 */
+	return edata->context;
+}
+
+
+#ifdef HAVE_SYSLOG
+
+/*
+ * Set or update the parameters for syslog logging
+ */
+void
+set_syslog_parameters(const char *ident, int facility)
+{
+	/*
+	 * guc.c is likely to call us repeatedly with same parameters, so don't
+	 * thrash the syslog connection unnecessarily.	Also, we do not re-open
+	 * the connection until needed, since this routine will get called whether
+	 * or not Log_destination actually mentions syslog.
+	 *
+	 * Note that we make our own copy of the ident string rather than relying
+	 * on guc.c's.  This may be overly paranoid, but it ensures that we cannot
+	 * accidentally free a string that syslog is still using.
+	 */
+	if (syslog_ident == NULL || strcmp(syslog_ident, ident) != 0 ||
+		syslog_facility != facility)
+	{
+		if (openlog_done)
+		{
+			closelog();
+			openlog_done = false;
+		}
+		if (syslog_ident)
+			free(syslog_ident);
+		syslog_ident = strdup(ident);
+		/* if the strdup fails, we will cope in write_syslog() */
+		syslog_facility = facility;
+	}
+}
+
+
+/*
+ * Write a message line to syslog
+ */
+static void
+write_syslog(int level, const char *line)
+{
+	static unsigned long seq = 0;
+
+	int			len;
+	const char *nlpos;
+
+	/* Open syslog connection if not done yet */
+	if (!openlog_done)
+	{
+		openlog(pool_config->syslog_ident ? pool_config->syslog_ident : "pgpool-II",
+				LOG_PID | LOG_NDELAY | LOG_NOWAIT,
+				pool_config->syslog_facility);
+		openlog_done = true;
+	}
+
+	/*
+	 * We add a sequence number to each log message to suppress "same"
+	 * messages.
+	 */
+	seq++;
+
+	/*
+	 * Our problem here is that many syslog implementations don't handle long
+	 * messages in an acceptable manner. While this function doesn't help that
+	 * fact, it does work around by splitting up messages into smaller pieces.
+	 *
+	 * We divide into multiple syslog() calls if message is too long or if the
+	 * message contains embedded newline(s).
+	 */
+	len = strlen(line);
+	nlpos = strchr(line, '\n');
+	if (len > PG_SYSLOG_LIMIT || nlpos != NULL)
+	{
+		int			chunk_nr = 0;
+
+		while (len > 0)
+		{
+			char		buf[PG_SYSLOG_LIMIT + 1];
+			int			buflen;
+			int			i;
+
+			/* if we start at a newline, move ahead one char */
+			if (line[0] == '\n')
+			{
+				line++;
+				len--;
+				/* we need to recompute the next newline's position, too */
+				nlpos = strchr(line, '\n');
+				continue;
+			}
+
+			/* copy one line, or as much as will fit, to buf */
+			if (nlpos != NULL)
+				buflen = nlpos - line;
+			else
+				buflen = len;
+			buflen = Min(buflen, PG_SYSLOG_LIMIT);
+			memcpy(buf, line, buflen);
+			buf[buflen] = '\0';
+
+			/* trim to multibyte letter boundary */
+			buflen = pg_mbcliplen(buf, buflen, buflen);
+			if (buflen <= 0)
+				return;
+			buf[buflen] = '\0';
+
+			/* already word boundary? */
+			if (line[buflen] != '\0' &&
+				!isspace((unsigned char) line[buflen]))
+			{
+				/* try to divide at word boundary */
+				i = buflen - 1;
+				while (i > 0 && !isspace((unsigned char) buf[i]))
+					i--;
+
+				if (i > 0)		/* else couldn't divide word boundary */
+				{
+					buflen = i;
+					buf[i] = '\0';
+				}
+			}
+
+			chunk_nr++;
+
+			syslog(level, "[%lu-%d] %s", seq, chunk_nr, buf);
+			line += buflen;
+			len -= buflen;
+		}
+	}
+	else
+	{
+		/* message short enough */
+		syslog(level, "[%lu] %s", seq, line);
+	}
+}
+#endif   /* HAVE_SYSLOG */
+
+#ifdef WIN32
+/*
+ * Get the PostgreSQL equivalent of the Windows ANSI code page.  "ANSI" system
+ * interfaces (e.g. CreateFileA()) expect string arguments in this encoding.
+ * Every process in a given system will find the same value at all times.
+ */
+static int
+GetACPEncoding(void)
+{
+	static int	encoding = -2;
+
+	if (encoding == -2)
+		encoding = pg_codepage_to_encoding(GetACP());
+
+	return encoding;
+}
+
+/*
+ * Write a message line to the windows event log
+ */
+static void
+write_eventlog(int level, const char *line, int len)
+{
+	WCHAR	   *utf16;
+	int			eventlevel = EVENTLOG_ERROR_TYPE;
+	static HANDLE evtHandle = INVALID_HANDLE_VALUE;
+
+	if (evtHandle == INVALID_HANDLE_VALUE)
+	{
+		evtHandle = RegisterEventSource(NULL, event_source ? event_source : "PostgreSQL");
+		if (evtHandle == NULL)
+		{
+			evtHandle = INVALID_HANDLE_VALUE;
+			return;
+		}
+	}
+
+	switch (level)
+	{
+		case DEBUG5:
+		case DEBUG4:
+		case DEBUG3:
+		case DEBUG2:
+		case DEBUG1:
+		case LOG:
+		case COMMERROR:
+		case INFO:
+		case NOTICE:
+			eventlevel = EVENTLOG_INFORMATION_TYPE;
+			break;
+		case WARNING:
+			eventlevel = EVENTLOG_WARNING_TYPE;
+			break;
+		case ERROR:
+		case FATAL:
+		case PANIC:
+		default:
+			eventlevel = EVENTLOG_ERROR_TYPE;
+			break;
+	}
+
+	/*
+	 * If message character encoding matches the encoding expected by
+	 * ReportEventA(), call it to avoid the hazards of conversion.  Otherwise,
+	 * try to convert the message to UTF16 and write it with ReportEventW().
+	 * Fall back on ReportEventA() if conversion failed.
+	 *
+	 * Also verify that we are not on our way into error recursion trouble due
+	 * to error messages thrown deep inside pgwin32_message_to_UTF16().
+	 */
+	if (!in_error_recursion_trouble() &&
+		GetMessageEncoding() != GetACPEncoding())
+	{
+		utf16 = pgwin32_message_to_UTF16(line, len, NULL);
+		if (utf16)
+		{
+			ReportEventW(evtHandle,
+						 eventlevel,
+						 0,
+						 0,		/* All events are Id 0 */
+						 NULL,
+						 1,
+						 0,
+						 (LPCWSTR *) &utf16,
+						 NULL);
+			/* XXX Try ReportEventA() when ReportEventW() fails? */
+
+			pfree(utf16);
+			return;
+		}
+	}
+	ReportEventA(evtHandle,
+				 eventlevel,
+				 0,
+				 0,				/* All events are Id 0 */
+				 NULL,
+				 1,
+				 0,
+				 &line,
+				 NULL);
+}
+#endif   /* WIN32 */
+
+static void
+write_console(const char *line, int len)
+{
+	int			rc;
+
+#ifdef WIN32
+
+	/*
+	 * Try to convert the message to UTF16 and write it with WriteConsoleW().
+	 * Fall back on write() if anything fails.
+	 *
+	 * In contrast to write_eventlog(), don't skip straight to write() based
+	 * on the applicable encodings.  Unlike WriteConsoleW(), write() depends
+	 * on the suitability of the console output code page.  Since we put
+	 * stderr into binary mode in SubPostmasterMain(), write() skips the
+	 * necessary translation anyway.
+	 *
+	 * WriteConsoleW() will fail if stderr is redirected, so just fall through
+	 * to writing unconverted to the logfile in this case.
+	 *
+	 * Since we palloc the structure required for conversion, also fall
+	 * through to writing unconverted if we have not yet set up
+	 * CurrentMemoryContext.
+	 */
+	if (!in_error_recursion_trouble() &&
+		!redirection_done &&
+		CurrentMemoryContext != NULL)
+	{
+		WCHAR	   *utf16;
+		int			utf16len;
+
+		utf16 = pgwin32_message_to_UTF16(line, len, &utf16len);
+		if (utf16 != NULL)
+		{
+			HANDLE		stdHandle;
+			DWORD		written;
+
+			stdHandle = GetStdHandle(STD_ERROR_HANDLE);
+			if (WriteConsoleW(stdHandle, utf16, utf16len, &written, NULL))
+			{
+				pfree(utf16);
+				return;
+			}
+
+			/*
+			 * In case WriteConsoleW() failed, fall back to writing the
+			 * message unconverted.
+			 */
+			pfree(utf16);
+		}
+	}
+#else
+
+	/*
+	 * Conversion on non-win32 platforms is not implemented yet. It requires
+	 * non-throw version of pg_do_encoding_conversion(), that converts
+	 * unconvertable characters to '?' without errors.
+	 */
+#endif
+
+	/*
+	 * We ignore any error from write() here.  We have no useful way to report
+	 * it ... certainly whining on stderr isn't likely to be productive.
+	 */
+	rc = write(fileno(stderr), line, len);
+	(void) rc;
+}
+
+/*
+ * setup formatted_log_time, for consistent times between CSV and regular logs
+ */
+static void
+setup_formatted_log_time(void)
+{
+}
+
+/*
+ * setup formatted_start_time
+ */
+static void
+setup_formatted_start_time(void)
+{
+	time_t now = time(NULL);
+	strftime(formatted_start_time, FORMATTED_TS_LEN, "%Y-%m-%d %H:%M:%S", localtime(&now));
+}
+
+/*
+ * Format tag info for log lines; append to the provided buffer.
+ */
+static void
+log_line_prefix(StringInfo buf, ErrorData *edata)
+{
+}
+
+/*
+ * Write error report to server's log
+ */
+static void
+send_message_to_server_log(ErrorData *edata)
+{
+	StringInfoData buf;
+
+	initStringInfo(&buf);
+
+	formatted_log_time[0] = '\0';
+
+	log_line_prefix(&buf, edata);
+	appendStringInfo(&buf, "%s:  ", error_severity(edata->elevel));
+
+//	if (Log_error_verbosity >= PGERROR_VERBOSE)
+//		appendStringInfo(&buf, "%s: ", unpack_sql_state(edata->sqlerrcode));
+
+	if (edata->message)
+		append_with_tabs(&buf, edata->message);
+	else
+		append_with_tabs(&buf, _("missing error text"));
+
+	if (edata->cursorpos > 0)
+		appendStringInfo(&buf, _(" at character %d"),
+						 edata->cursorpos);
+	else if (edata->internalpos > 0)
+		appendStringInfo(&buf, _(" at character %d"),
+						 edata->internalpos);
+
+	appendStringInfoChar(&buf, '\n');
+
+	if (Log_error_verbosity >= PGERROR_DEFAULT)
+	{
+		if (edata->detail_log)
+		{
+			log_line_prefix(&buf, edata);
+			appendStringInfoString(&buf, _("DETAIL:  "));
+			append_with_tabs(&buf, edata->detail_log);
+			appendStringInfoChar(&buf, '\n');
+		}
+		else if (edata->detail)
+		{
+			log_line_prefix(&buf, edata);
+			appendStringInfoString(&buf, _("DETAIL:  "));
+			append_with_tabs(&buf, edata->detail);
+			appendStringInfoChar(&buf, '\n');
+		}
+		if (edata->hint)
+		{
+			log_line_prefix(&buf, edata);
+			appendStringInfoString(&buf, _("HINT:  "));
+			append_with_tabs(&buf, edata->hint);
+			appendStringInfoChar(&buf, '\n');
+		}
+		if (edata->internalquery)
+		{
+			log_line_prefix(&buf, edata);
+			appendStringInfoString(&buf, _("QUERY:  "));
+			append_with_tabs(&buf, edata->internalquery);
+			appendStringInfoChar(&buf, '\n');
+		}
+		if (edata->context)
+		{
+			log_line_prefix(&buf, edata);
+			appendStringInfoString(&buf, _("CONTEXT:  "));
+			append_with_tabs(&buf, edata->context);
+			appendStringInfoChar(&buf, '\n');
+		}
+		if (Log_error_verbosity >= PGERROR_VERBOSE)
+		{
+			/* assume no newlines in funcname or filename... */
+			if (edata->funcname && edata->filename)
+			{
+				log_line_prefix(&buf, edata);
+				appendStringInfo(&buf, _("LOCATION:  %s, %s:%d\n"),
+								 edata->funcname, edata->filename,
+								 edata->lineno);
+			}
+			else if (edata->filename)
+			{
+				log_line_prefix(&buf, edata);
+				appendStringInfo(&buf, _("LOCATION:  %s:%d\n"),
+								 edata->filename, edata->lineno);
+			}
+		}
+	}
+
+	/*
+	 * If the user wants the query that generated this error logged, do it.
+	 
+	if (is_log_level_output(edata->elevel, log_min_error_statement) &&
+		debug_query_string != NULL &&
+		!edata->hide_stmt)
+	{
+		log_line_prefix(&buf, edata);
+		appendStringInfoString(&buf, _("STATEMENT:  "));
+		append_with_tabs(&buf, debug_query_string);
+		appendStringInfoChar(&buf, '\n');
+	}
+*/
+#ifdef HAVE_SYSLOG
+	/* Write to syslog, if enabled */
+	if (Log_destination & LOG_DESTINATION_SYSLOG)
+	{
+		int			syslog_level;
+
+		switch (edata->elevel)
+		{
+			case DEBUG5:
+			case DEBUG4:
+			case DEBUG3:
+			case DEBUG2:
+			case DEBUG1:
+				syslog_level = LOG_DEBUG;
+				break;
+			case LOG:
+			case COMMERROR:
+			case INFO:
+				syslog_level = LOG_INFO;
+				break;
+			case NOTICE:
+			case WARNING:
+				syslog_level = LOG_NOTICE;
+				break;
+			case ERROR:
+				syslog_level = LOG_WARNING;
+				break;
+			case FATAL:
+				syslog_level = LOG_ERR;
+				break;
+			case PANIC:
+			default:
+				syslog_level = LOG_CRIT;
+				break;
+		}
+		if (pool_config->logsyslog = 1)
+			write_syslog(syslog_level, buf.data);
+	}
+#endif   /* HAVE_SYSLOG */
+
+#ifdef WIN32
+	/* Write to eventlog, if enabled */
+	if (Log_destination & LOG_DESTINATION_EVENTLOG)
+	{
+		write_eventlog(edata->elevel, buf.data, buf.len);
+	}
+#endif   /* WIN32 */
+
+	/* Write to stderr, if enabled */
+	if ((Log_destination & LOG_DESTINATION_STDERR) || whereToSendOutput == DestDebug)
+	{
+		/*
+		 * Use the chunking protocol if we know the syslogger should be
+		 * catching stderr output, and we are not ourselves the syslogger.
+		 * Otherwise, just do a vanilla write to stderr.
+		 */
+#ifdef WIN32
+
+		/*
+		 * In a win32 service environment, there is no usable stderr. Capture
+		 * anything going there and write it to the eventlog instead.
+		 *
+		 * If stderr redirection is active, it was OK to write to stderr above
+		 * because that's really a pipe to the syslogger process.
+		 */
+		else if (pgwin32_is_service())
+			write_eventlog(edata->elevel, buf.data, buf.len);
+#endif
+		write_console(buf.data, buf.len);
+	}
+
+
+	pfree(buf.data);
+}
+
+
+/*
+ * expand_fmt_string --- process special format codes in a format string
+ *
+ * We must replace %m with the appropriate strerror string, since vsnprintf
+ * won't know what to do with it.
+ *
+ * The result is a palloc'd string.
+ */
+static char *
+expand_fmt_string(const char *fmt, ErrorData *edata)
+{
+	StringInfoData buf;
+	const char *cp;
+
+	initStringInfo(&buf);
+
+	for (cp = fmt; *cp; cp++)
+	{
+		if (cp[0] == '%' && cp[1] != '\0')
+		{
+			cp++;
+			if (*cp == 'm')
+			{
+				/*
+				 * Replace %m by system error string.  If there are any %'s in
+				 * the string, we'd better double them so that vsnprintf won't
+				 * misinterpret.
+				 */
+				const char *cp2;
+
+				cp2 = useful_strerror(edata->saved_errno);
+				for (; *cp2; cp2++)
+				{
+					if (*cp2 == '%')
+						appendStringInfoCharMacro(&buf, '%');
+					appendStringInfoCharMacro(&buf, *cp2);
+				}
+			}
+			else
+			{
+				/* copy % and next char --- this avoids trouble with %%m */
+				appendStringInfoCharMacro(&buf, '%');
+				appendStringInfoCharMacro(&buf, *cp);
+			}
+		}
+		else
+			appendStringInfoCharMacro(&buf, *cp);
+	}
+
+	return buf.data;
+}
+
+
+/*
+ * A slightly cleaned-up version of strerror()
+ */
+static const char *
+useful_strerror(int errnum)
+{
+	/* this buffer is only used if errno has a bogus value */
+	static char errorstr_buf[48];
+	const char *str;
+
+#ifdef WIN32
+	/* Winsock error code range, per WinError.h */
+	if (errnum >= 10000 && errnum <= 11999)
+		return pgwin32_socket_strerror(errnum);
+#endif
+	str = strerror(errnum);
+
+	/*
+	 * Some strerror()s return an empty string for out-of-range errno. This is
+	 * ANSI C spec compliant, but not exactly useful.
+	 */
+	if (str == NULL || *str == '\0')
+	{
+		snprintf(errorstr_buf, sizeof(errorstr_buf),
+		/*------
+		  translator: This string will be truncated at 47
+		  characters expanded. */
+				 _("operating system error %d"), errnum);
+		str = errorstr_buf;
+	}
+
+	return str;
+}
+
+
+/*
+ * error_severity --- get localized string representing elevel
+ */
+static const char *
+error_severity(int elevel)
+{
+	const char *prefix;
+
+	switch (elevel)
+	{
+		case DEBUG1:
+		case DEBUG2:
+		case DEBUG3:
+		case DEBUG4:
+		case DEBUG5:
+			prefix = _("DEBUG");
+			break;
+		case LOG:
+		case COMMERROR:
+			prefix = _("LOG");
+			break;
+		case INFO:
+			prefix = _("INFO");
+			break;
+		case NOTICE:
+			prefix = _("NOTICE");
+			break;
+		case WARNING:
+			prefix = _("WARNING");
+			break;
+		case ERROR:
+			prefix = _("ERROR");
+			break;
+		case FATAL:
+			prefix = _("FATAL");
+			break;
+		case PANIC:
+			prefix = _("PANIC");
+			break;
+		default:
+			prefix = "???";
+			break;
+	}
+
+	return prefix;
+}
+
+
+/*
+ *	append_with_tabs
+ *
+ *	Append the string to the StringInfo buffer, inserting a tab after any
+ *	newline.
+ */
+static void
+append_with_tabs(StringInfo buf, const char *str)
+{
+	char		ch;
+
+	while ((ch = *str++) != '\0')
+	{
+		appendStringInfoCharMacro(buf, ch);
+		if (ch == '\n')
+			appendStringInfoCharMacro(buf, '\t');
+	}
+}
+
+
+/*
+ * Write errors to stderr (or by equal means when stderr is
+ * not available). Used before ereport/elog can be used
+ * safely (memory context, GUC load etc)
+ */
+void
+write_stderr(const char *fmt,...)
+{
+	va_list		ap;
+
+#ifdef WIN32
+	char		errbuf[2048];	/* Arbitrary size? */
+#endif
+
+	fmt = _(fmt);
+
+	va_start(ap, fmt);
+#ifndef WIN32
+	/* On Unix, we just fprintf to stderr */
+	vfprintf(stderr, fmt, ap);
+	fflush(stderr);
+#else
+	vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
+
+	/*
+	 * On Win32, we print to stderr if running on a console, or write to
+	 * eventlog if running as a service
+	 */
+	if (pgwin32_is_service())	/* Running as a service */
+	{
+		write_eventlog(ERROR, errbuf, strlen(errbuf));
+	}
+	else
+	{
+		/* Not running as service, write to stderr */
+		write_console(errbuf, strlen(errbuf));
+		fflush(stderr);
+	}
+#endif
+	va_end(ap);
+}
+
+
+/*
+ * is_log_level_output -- is elevel logically >= log_min_level?
+ *
+ * We use this for tests that should consider LOG to sort out-of-order,
+ * between ERROR and FATAL.  Generally this is the right thing for testing
+ * whether a message should go to the postmaster log, whereas a simple >=
+ * test is correct for testing whether the message should go to the client.
+ */
+static bool
+is_log_level_output(int elevel, int log_min_level)
+{
+	if (elevel == LOG || elevel == COMMERROR)
+	{
+		if (log_min_level == LOG || log_min_level <= ERROR)
+			return true;
+	}
+	else if (log_min_level == LOG)
+	{
+		/* elevel != LOG */
+		if (elevel >= FATAL)
+			return true;
+	}
+	/* Neither is LOG */
+	else if (elevel >= log_min_level)
+		return true;
+
+	return false;
+}
+
+/* error cleanup routines */
+
+/* ----------------------------------------------------------------
+ *		proc_exit
+ *
+ *		this function calls all the callbacks registered
+ *		for it (to free resources) and then calls exit.
+ *
+ *		This should be the only function to call exit().
+ *		-cim 2/6/90
+ *
+ *		Unfortunately, we can't really guarantee that add-on code
+ *		obeys the rule of not calling exit() directly.	So, while
+ *		this is the preferred way out of the system, we also register
+ *		an atexit callback that will make sure cleanup happens.
+ * ----------------------------------------------------------------
+ */
+void
+proc_exit(int code)
+{
+	/* Clean up everything that must be cleaned up */
+	proc_exit_prepare(code);
+
+	elog(DEBUG3, "exit(%d)", code);
+
+	exit(code);
+}
+
+/*
+ * Code shared between proc_exit and the atexit handler.  Note that in
+ * normal exit through proc_exit, this will actually be called twice ...
+ * but the second call will have nothing to do.
+ */
+static void
+proc_exit_prepare(int code)
+{
+	/*
+	 * Once we set this flag, we are committed to exit.  Any ereport() will
+	 * NOT send control back to the main loop, but right back here.
+	 */
+	proc_exit_inprogress = true;
+
+	/*
+	 * Forget any pending cancel or die requests; we're doing our best to
+	 * close up shop already.  Note that the signal handlers will not set
+	 * these flags again, now that proc_exit_inprogress is set.
+	 */
+
+	/*
+	 * Also clear the error context stack, to prevent error callbacks from
+	 * being invoked by any elog/ereport calls made during proc_exit. Whatever
+	 * context they might want to offer is probably not relevant, and in any
+	 * case they are likely to fail outright after we've done things like
+	 * aborting any open transaction.  (In normal exit scenarios the context
+	 * stack should be empty anyway, but it might not be in the case of
+	 * elog(FATAL) for example.)
+	 */
+	error_context_stack = NULL;
+
+	/* do our shared memory exits first */
+	shmem_exit(code);
+
+	elog(DEBUG3, "proc_exit(%d): %d callbacks to make",
+		 code, on_proc_exit_index);
+
+	/*
+	 * call all the registered callbacks.
+	 *
+	 * Note that since we decrement on_proc_exit_index each time, if a
+	 * callback calls ereport(ERROR) or ereport(FATAL) then it won't be
+	 * invoked again when control comes back here (nor will the
+	 * previously-completed callbacks).  So, an infinite loop should not be
+	 * possible.
+	 */
+	while (--on_proc_exit_index >= 0)
+		(*on_proc_exit_list[on_proc_exit_index].function) (code,
+								  on_proc_exit_list[on_proc_exit_index].arg);
+
+	on_proc_exit_index = 0;
+}
+
+/* ------------------
+ * Run all of the on_shmem_exit routines --- but don't actually exit.
+ * This is used by the postmaster to re-initialize shared memory and
+ * semaphores after a backend dies horribly.
+ * ------------------
+ */
+void
+shmem_exit(int code)
+{
+	elog(DEBUG3, "shmem_exit(%d): %d callbacks to make",
+		 code, on_shmem_exit_index);
+
+	/*
+	 * call all the registered callbacks.
+	 *
+	 * As with proc_exit(), we remove each callback from the list before
+	 * calling it, to avoid infinite loop in case of error.
+	 */
+	while (--on_shmem_exit_index >= 0)
+		(*on_shmem_exit_list[on_shmem_exit_index].function) (code,
+								on_shmem_exit_list[on_shmem_exit_index].arg);
+
+	on_shmem_exit_index = 0;
+}
+
+/* ----------------------------------------------------------------
+ *		atexit_callback
+ *
+ *		Backstop to ensure that direct calls of exit() don't mess us up.
+ *
+ * Somebody who was being really uncooperative could call _exit(),
+ * but for that case we have a "dead man switch" that will make the
+ * postmaster treat it as a crash --- see pmsignal.c.
+ * ----------------------------------------------------------------
+ */
+static void
+atexit_callback(void)
+{
+	/* Clean up everything that must be cleaned up */
+	/* ... too bad we don't know the real exit code ... */
+	proc_exit_prepare(-1);
+}
+
+/* ----------------------------------------------------------------
+ *		on_proc_exit
+ *
+ *		this function adds a callback function to the list of
+ *		functions invoked by proc_exit().	-cim 2/6/90
+ * ----------------------------------------------------------------
+ */
+void
+on_proc_exit(pg_on_exit_callback function, Datum arg)
+{
+	if (on_proc_exit_index >= MAX_ON_EXITS)
+		ereport(FATAL,
+				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+				 errmsg_internal("out of on_proc_exit slots")));
+
+	on_proc_exit_list[on_proc_exit_index].function = function;
+	on_proc_exit_list[on_proc_exit_index].arg = arg;
+
+	++on_proc_exit_index;
+
+	if (!atexit_callback_setup)
+	{
+		atexit(atexit_callback);
+		atexit_callback_setup = true;
+	}
+}
+
+/* ----------------------------------------------------------------
+ *		on_shmem_exit
+ *
+ *		this function adds a callback function to the list of
+ *		functions invoked by shmem_exit().	-cim 2/6/90
+ * ----------------------------------------------------------------
+ */
+void
+on_shmem_exit(pg_on_exit_callback function, Datum arg)
+{
+	if (on_shmem_exit_index >= MAX_ON_EXITS)
+		ereport(FATAL,
+				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+				 errmsg_internal("out of on_shmem_exit slots")));
+
+	on_shmem_exit_list[on_shmem_exit_index].function = function;
+	on_shmem_exit_list[on_shmem_exit_index].arg = arg;
+
+	++on_shmem_exit_index;
+
+	if (!atexit_callback_setup)
+	{
+		atexit(atexit_callback);
+		atexit_callback_setup = true;
+	}
+}
+
+/* ----------------------------------------------------------------
+ *		cancel_shmem_exit
+ *
+ *		this function removes an entry, if present, from the list of
+ *		functions to be invoked by shmem_exit().  For simplicity,
+ *		only the latest entry can be removed.  (We could work harder
+ *		but there is no need for current uses.)
+ * ----------------------------------------------------------------
+ */
+void
+cancel_shmem_exit(pg_on_exit_callback function, Datum arg)
+{
+	if (on_shmem_exit_index > 0 &&
+		on_shmem_exit_list[on_shmem_exit_index - 1].function == function &&
+		on_shmem_exit_list[on_shmem_exit_index - 1].arg == arg)
+		--on_shmem_exit_index;
+}
+
+/* ----------------------------------------------------------------
+ *		on_exit_reset
+ *
+ *		this function clears all on_proc_exit() and on_shmem_exit()
+ *		registered functions.  This is used just after forking a backend,
+ *		so that the backend doesn't believe it should call the postmaster's
+ *		on-exit routines when it exits...
+ * ----------------------------------------------------------------
+ */
+void
+on_exit_reset(void)
+{
+	on_shmem_exit_index = 0;
+	on_proc_exit_index = 0;
+}
diff --git a/src/utils/mmgr/aset.c b/src/utils/mmgr/aset.c
new file mode 100644
index 0000000..c0dba65
--- /dev/null
+++ b/src/utils/mmgr/aset.c
@@ -0,0 +1,1383 @@
+/*-------------------------------------------------------------------------
+ *
+ * aset.c
+ *	  Allocation set definitions.
+ *
+ * AllocSet is our standard implementation of the abstract MemoryContext
+ * type.
+ *
+ *
+ * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ *	  src/backend/utils/mmgr/aset.c
+ *
+ * NOTE:
+ *	This is a new (Feb. 05, 1999) implementation of the allocation set
+ *	routines. AllocSet...() does not use OrderedSet...() any more.
+ *	Instead it manages allocations in a block pool by itself, combining
+ *	many small allocations in a few bigger blocks. AllocSetFree() normally
+ *	doesn't free() memory really. It just add's the free'd area to some
+ *	list for later reuse by AllocSetAlloc(). All memory blocks are free()'d
+ *	at once on AllocSetReset(), which happens when the memory context gets
+ *	destroyed.
+ *				Jan Wieck
+ *
+ *	Performance improvement from Tom Lane, 8/99: for extremely large request
+ *	sizes, we do want to be able to give the memory back to free() as soon
+ *	as it is pfree()'d.  Otherwise we risk tying up a lot of memory in
+ *	freelist entries that might never be usable.  This is specially needed
+ *	when the caller is repeatedly repalloc()'ing a block bigger and bigger;
+ *	the previous instances of the block were guaranteed to be wasted until
+ *	AllocSetReset() under the old way.
+ *
+ *	Further improvement 12/00: as the code stood, request sizes in the
+ *	midrange between "small" and "large" were handled very inefficiently,
+ *	because any sufficiently large free chunk would be used to satisfy a
+ *	request, even if it was much larger than necessary.  This led to more
+ *	and more wasted space in allocated chunks over time.  To fix, get rid
+ *	of the midrange behavior: we now handle only "small" power-of-2-size
+ *	chunks as chunks.  Anything "large" is passed off to malloc().	Change
+ *	the number of freelists to change the small/large boundary.
+ *
+ *
+ *	About CLOBBER_FREED_MEMORY:
+ *
+ *	If this symbol is defined, all freed memory is overwritten with 0x7F's.
+ *	This is useful for catching places that reference already-freed memory.
+ *
+ *	About MEMORY_CONTEXT_CHECKING:
+ *
+ *	Since we usually round request sizes up to the next power of 2, there
+ *	is often some unused space immediately after a requested data area.
+ *	Thus, if someone makes the common error of writing past what they've
+ *	requested, the problem is likely to go unnoticed ... until the day when
+ *	there *isn't* any wasted space, perhaps because of different memory
+ *	alignment on a new platform, or some other effect.	To catch this sort
+ *	of problem, the MEMORY_CONTEXT_CHECKING option stores 0x7E just beyond
+ *	the requested space whenever the request is less than the actual chunk
+ *	size, and verifies that the byte is undamaged when the chunk is freed.
+ *
+ *
+ *	About USE_VALGRIND and Valgrind client requests:
+ *
+ *	Valgrind provides "client request" macros that exchange information with
+ *	the host Valgrind (if any).  Under !USE_VALGRIND, memdebug.h stubs out
+ *	currently-used macros.
+ *
+ *	When running under Valgrind, we want a NOACCESS memory region both before
+ *	and after the allocation.  The chunk header is tempting as the preceding
+ *	region, but mcxt.c expects to able to examine the standard chunk header
+ *	fields.  Therefore, we use, when available, the requested_size field and
+ *	any subsequent padding.  requested_size is made NOACCESS before returning
+ *	a chunk pointer to a caller.  However, to reduce client request traffic,
+ *	it is kept DEFINED in chunks on the free list.
+ *
+ *	The rounded-up capacity of the chunk usually acts as a post-allocation
+ *	NOACCESS region.  If the request consumes precisely the entire chunk,
+ *	there is no such region; another chunk header may immediately follow.  In
+ *	that case, Valgrind will not detect access beyond the end of the chunk.
+ *
+ *	See also the cooperating Valgrind client requests in mcxt.c.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+//#include "postgres.h"
+
+#include "pool_type.h"
+#include "utils/palloc.h"
+#include "utils/memdebug.h"
+#include "utils/memutils.h"
+#include "utils/elog.h"
+#include <string.h>
+#include <stdint.h>
+/* Define this to detail debug alloc information */
+/* #define HAVE_ALLOCINFO */
+
+/*--------------------
+ * Chunk freelist k holds chunks of size 1 << (k + ALLOC_MINBITS),
+ * for k = 0 .. ALLOCSET_NUM_FREELISTS-1.
+ *
+ * Note that all chunks in the freelists have power-of-2 sizes.  This
+ * improves recyclability: we may waste some space, but the wasted space
+ * should stay pretty constant as requests are made and released.
+ *
+ * A request too large for the last freelist is handled by allocating a
+ * dedicated block from malloc().  The block still has a block header and
+ * chunk header, but when the chunk is freed we'll return the whole block
+ * to malloc(), not put it on our freelists.
+ *
+ * CAUTION: ALLOC_MINBITS must be large enough so that
+ * 1<<ALLOC_MINBITS is at least MAXALIGN,
+ * or we may fail to align the smallest chunks adequately.
+ * 8-byte alignment is enough on all currently known machines.
+ *
+ * With the current parameters, request sizes up to 8K are treated as chunks,
+ * larger requests go into dedicated blocks.  Change ALLOCSET_NUM_FREELISTS
+ * to adjust the boundary point.  (But in contexts with small maxBlockSize,
+ * we may set the allocChunkLimit to less than 8K, so as to avoid space
+ * wastage.)
+ *--------------------
+ */
+
+#define ALLOC_MINBITS		3	/* smallest chunk size is 8 bytes */
+#define ALLOCSET_NUM_FREELISTS	11
+#define ALLOC_CHUNK_LIMIT	(1 << (ALLOCSET_NUM_FREELISTS-1+ALLOC_MINBITS))
+/* Size of largest chunk that we use a fixed size for */
+#define ALLOC_CHUNK_FRACTION	4
+/* We allow chunks to be at most 1/4 of maxBlockSize (less overhead) */
+
+/*--------------------
+ * The first block allocated for an allocset has size initBlockSize.
+ * Each time we have to allocate another block, we double the block size
+ * (if possible, and without exceeding maxBlockSize), so as to reduce
+ * the bookkeeping load on malloc().
+ *
+ * Blocks allocated to hold oversize chunks do not follow this rule, however;
+ * they are just however big they need to be to hold that single chunk.
+ *--------------------
+ */
+
+#define ALLOC_BLOCKHDRSZ	MAXALIGN(sizeof(AllocBlockData))
+#define ALLOC_CHUNKHDRSZ	MAXALIGN(sizeof(AllocChunkData))
+
+/* Portion of ALLOC_CHUNKHDRSZ examined outside aset.c. */
+#define ALLOC_CHUNK_PUBLIC	\
+	(offsetof(AllocChunkData, size) + sizeof(Size))
+
+/* Portion of ALLOC_CHUNKHDRSZ excluding trailing padding. */
+#ifdef MEMORY_CONTEXT_CHECKING
+#define ALLOC_CHUNK_USED	\
+	(offsetof(AllocChunkData, requested_size) + sizeof(Size))
+#else
+#define ALLOC_CHUNK_USED	\
+	(offsetof(AllocChunkData, size) + sizeof(Size))
+#endif
+
+typedef struct AllocBlockData *AllocBlock;		/* forward reference */
+typedef struct AllocChunkData *AllocChunk;
+
+/*
+ * AllocPointer
+ *		Aligned pointer which may be a member of an allocation set.
+ */
+typedef void *AllocPointer;
+
+/*
+ * AllocSetContext is our standard implementation of MemoryContext.
+ *
+ * Note: header.isReset means there is nothing for AllocSetReset to do.
+ * This is different from the aset being physically empty (empty blocks list)
+ * because we may still have a keeper block.  It's also different from the set
+ * being logically empty, because we don't attempt to detect pfree'ing the
+ * last active chunk.
+ */
+typedef struct AllocSetContext
+{
+	MemoryContextData header;	/* Standard memory-context fields */
+	/* Info about storage allocated in this context: */
+	AllocBlock	blocks;			/* head of list of blocks in this set */
+	AllocChunk	freelist[ALLOCSET_NUM_FREELISTS];		/* free chunk lists */
+	/* Allocation parameters for this context: */
+	Size		initBlockSize;	/* initial block size */
+	Size		maxBlockSize;	/* maximum block size */
+	Size		nextBlockSize;	/* next block size to allocate */
+	Size		allocChunkLimit;	/* effective chunk size limit */
+	AllocBlock	keeper;			/* if not NULL, keep this block over resets */
+} AllocSetContext;
+
+typedef AllocSetContext *AllocSet;
+
+/*
+ * AllocBlock
+ *		An AllocBlock is the unit of memory that is obtained by aset.c
+ *		from malloc().	It contains one or more AllocChunks, which are
+ *		the units requested by palloc() and freed by pfree().  AllocChunks
+ *		cannot be returned to malloc() individually, instead they are put
+ *		on freelists by pfree() and re-used by the next palloc() that has
+ *		a matching request size.
+ *
+ *		AllocBlockData is the header data for a block --- the usable space
+ *		within the block begins at the next alignment boundary.
+ */
+typedef struct AllocBlockData
+{
+	AllocSet	aset;			/* aset that owns this block */
+	AllocBlock	next;			/* next block in aset's blocks list */
+	char	   *freeptr;		/* start of free space in this block */
+	char	   *endptr;			/* end of space in this block */
+}	AllocBlockData;
+
+/*
+ * AllocChunk
+ *		The prefix of each piece of memory in an AllocBlock
+ *
+ * NB: this MUST match StandardChunkHeader as defined by utils/memutils.h.
+ */
+typedef struct AllocChunkData
+{
+	/* aset is the owning aset if allocated, or the freelist link if free */
+	void	   *aset;
+	/* size is always the size of the usable space in the chunk */
+	Size		size;
+#ifdef MEMORY_CONTEXT_CHECKING
+	/* when debugging memory usage, also store actual requested size */
+	/* this is zero in a free chunk */
+	Size		requested_size;
+#endif
+}	AllocChunkData;
+
+/*
+ * AllocPointerIsValid
+ *		True iff pointer is valid allocation pointer.
+ */
+#define AllocPointerIsValid(pointer) PointerIsValid(pointer)
+
+/*
+ * AllocSetIsValid
+ *		True iff set is valid allocation set.
+ */
+#define AllocSetIsValid(set) PointerIsValid(set)
+
+#define AllocPointerGetChunk(ptr)	\
+					((AllocChunk)(((char *)(ptr)) - ALLOC_CHUNKHDRSZ))
+#define AllocChunkGetPointer(chk)	\
+					((AllocPointer)(((char *)(chk)) + ALLOC_CHUNKHDRSZ))
+
+/*
+ * These functions implement the MemoryContext API for AllocSet contexts.
+ */
+static void *AllocSetAlloc(MemoryContext context, Size size);
+static void AllocSetFree(MemoryContext context, void *pointer);
+static void *AllocSetRealloc(MemoryContext context, void *pointer, Size size);
+static void AllocSetInit(MemoryContext context);
+static void AllocSetReset(MemoryContext context);
+static void AllocSetDelete(MemoryContext context);
+static Size AllocSetGetChunkSpace(MemoryContext context, void *pointer);
+static bool AllocSetIsEmpty(MemoryContext context);
+static void AllocSetStats(MemoryContext context, int level);
+
+#ifdef MEMORY_CONTEXT_CHECKING
+static void AllocSetCheck(MemoryContext context);
+#endif
+
+/*
+ * This is the virtual function table for AllocSet contexts.
+ */
+static MemoryContextMethods AllocSetMethods = {
+	AllocSetAlloc,
+	AllocSetFree,
+	AllocSetRealloc,
+	AllocSetInit,
+	AllocSetReset,
+	AllocSetDelete,
+	AllocSetGetChunkSpace,
+	AllocSetIsEmpty,
+	AllocSetStats
+#ifdef MEMORY_CONTEXT_CHECKING
+	,AllocSetCheck
+#endif
+};
+
+/*
+ * Table for AllocSetFreeIndex
+ */
+#define LT16(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
+
+static const unsigned char LogTable256[256] =
+{
+	0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+	LT16(5), LT16(6), LT16(6), LT16(7), LT16(7), LT16(7), LT16(7),
+	LT16(8), LT16(8), LT16(8), LT16(8), LT16(8), LT16(8), LT16(8), LT16(8)
+};
+
+/* ----------
+ * Debug macros
+ * ----------
+ */
+#ifdef HAVE_ALLOCINFO
+#define AllocFreeInfo(_cxt, _chunk) \
+			fprintf(stderr, "AllocFree: %s: %p, %d\n", \
+				(_cxt)->header.name, (_chunk), (_chunk)->size)
+#define AllocAllocInfo(_cxt, _chunk) \
+			fprintf(stderr, "AllocAlloc: %s: %p, %d\n", \
+				(_cxt)->header.name, (_chunk), (_chunk)->size)
+#else
+#define AllocFreeInfo(_cxt, _chunk)
+#define AllocAllocInfo(_cxt, _chunk)
+#endif
+
+/* ----------
+ * AllocSetFreeIndex -
+ *
+ *		Depending on the size of an allocation compute which freechunk
+ *		list of the alloc set it belongs to.  Caller must have verified
+ *		that size <= ALLOC_CHUNK_LIMIT.
+ * ----------
+ */
+static inline int
+AllocSetFreeIndex(Size size)
+{
+	int			idx;
+	unsigned int t,
+				tsize;
+
+	if (size > (1 << ALLOC_MINBITS))
+	{
+		tsize = (size - 1) >> ALLOC_MINBITS;
+
+		/*
+		 * At this point we need to obtain log2(tsize)+1, ie, the number of
+		 * not-all-zero bits at the right.	We used to do this with a
+		 * shift-and-count loop, but this function is enough of a hotspot to
+		 * justify micro-optimization effort.  The best approach seems to be
+		 * to use a lookup table.  Note that this code assumes that
+		 * ALLOCSET_NUM_FREELISTS <= 17, since we only cope with two bytes of
+		 * the tsize value.
+		 */
+		t = tsize >> 8;
+		idx = t ? LogTable256[t] + 8 : LogTable256[tsize];
+
+		Assert(idx < ALLOCSET_NUM_FREELISTS);
+	}
+	else
+		idx = 0;
+
+	return idx;
+}
+
+#ifdef CLOBBER_FREED_MEMORY
+
+/* Wipe freed memory for debugging purposes */
+static void
+wipe_mem(void *ptr, size_t size)
+{
+	VALGRIND_MAKE_MEM_UNDEFINED(ptr, size);
+	memset(ptr, 0x7F, size);
+	VALGRIND_MAKE_MEM_NOACCESS(ptr, size);
+}
+#endif
+
+#ifdef MEMORY_CONTEXT_CHECKING
+static void
+set_sentinel(void *base, Size offset)
+{
+	char	   *ptr = (char *) base + offset;
+
+	VALGRIND_MAKE_MEM_UNDEFINED(ptr, 1);
+	*ptr = 0x7E;
+	VALGRIND_MAKE_MEM_NOACCESS(ptr, 1);
+}
+
+static bool
+sentinel_ok(const void *base, Size offset)
+{
+	const char *ptr = (const char *) base + offset;
+	bool		ret;
+
+	VALGRIND_MAKE_MEM_DEFINED(ptr, 1);
+	ret = *ptr == 0x7E;
+	VALGRIND_MAKE_MEM_NOACCESS(ptr, 1);
+
+	return ret;
+}
+#endif
+
+#ifdef RANDOMIZE_ALLOCATED_MEMORY
+
+/*
+ * Fill a just-allocated piece of memory with "random" data.  It's not really
+ * very random, just a repeating sequence with a length that's prime.  What
+ * we mainly want out of it is to have a good probability that two palloc's
+ * of the same number of bytes start out containing different data.
+ *
+ * The region may be NOACCESS, so make it UNDEFINED first to avoid errors as
+ * we fill it.  Filling the region makes it DEFINED, so make it UNDEFINED
+ * again afterward.  Whether to finally make it UNDEFINED or NOACCESS is
+ * fairly arbitrary.  UNDEFINED is more convenient for AllocSetRealloc(), and
+ * other callers have no preference.
+ */
+static void
+randomize_mem(char *ptr, size_t size)
+{
+	static int	save_ctr = 1;
+	size_t		remaining = size;
+	int			ctr;
+
+	ctr = save_ctr;
+	VALGRIND_MAKE_MEM_UNDEFINED(ptr, size);
+	while (remaining-- > 0)
+	{
+		*ptr++ = ctr;
+		if (++ctr > 251)
+			ctr = 1;
+	}
+	VALGRIND_MAKE_MEM_UNDEFINED(ptr - size, size);
+	save_ctr = ctr;
+}
+#endif   /* RANDOMIZE_ALLOCATED_MEMORY */
+
+
+/*
+ * Public routines
+ */
+
+
+/*
+ * AllocSetContextCreate
+ *		Create a new AllocSet context.
+ *
+ * parent: parent context, or NULL if top-level context
+ * name: name of context (for debugging --- string will be copied)
+ * minContextSize: minimum context size
+ * initBlockSize: initial allocation block size
+ * maxBlockSize: maximum allocation block size
+ */
+MemoryContext
+AllocSetContextCreate(MemoryContext parent,
+					  const char *name,
+					  Size minContextSize,
+					  Size initBlockSize,
+					  Size maxBlockSize)
+{
+	AllocSet	context;
+
+	/* Do the type-independent part of context creation */
+	context = (AllocSet) MemoryContextCreate(T_AllocSetContext,
+											 sizeof(AllocSetContext),
+											 &AllocSetMethods,
+											 parent,
+											 name);
+
+	/*
+	 * Make sure alloc parameters are reasonable, and save them.
+	 *
+	 * We somewhat arbitrarily enforce a minimum 1K block size.
+	 */
+	initBlockSize = MAXALIGN(initBlockSize);
+	if (initBlockSize < 1024)
+		initBlockSize = 1024;
+	maxBlockSize = MAXALIGN(maxBlockSize);
+	if (maxBlockSize < initBlockSize)
+		maxBlockSize = initBlockSize;
+	Assert(AllocHugeSizeIsValid(maxBlockSize)); /* must be safe to double */
+	context->initBlockSize = initBlockSize;
+	context->maxBlockSize = maxBlockSize;
+	context->nextBlockSize = initBlockSize;
+
+	/*
+	 * Compute the allocation chunk size limit for this context.  It can't be
+	 * more than ALLOC_CHUNK_LIMIT because of the fixed number of freelists.
+	 * If maxBlockSize is small then requests exceeding the maxBlockSize, or
+	 * even a significant fraction of it, should be treated as large chunks
+	 * too.  For the typical case of maxBlockSize a power of 2, the chunk size
+	 * limit will be at most 1/8th maxBlockSize, so that given a stream of
+	 * requests that are all the maximum chunk size we will waste at most
+	 * 1/8th of the allocated space.
+	 *
+	 * We have to have allocChunkLimit a power of two, because the requested
+	 * and actually-allocated sizes of any chunk must be on the same side of
+	 * the limit, else we get confused about whether the chunk is "big".
+	 */
+	context->allocChunkLimit = ALLOC_CHUNK_LIMIT;
+	while ((Size) (context->allocChunkLimit + ALLOC_CHUNKHDRSZ) >
+		   (Size) ((maxBlockSize - ALLOC_BLOCKHDRSZ) / ALLOC_CHUNK_FRACTION))
+		context->allocChunkLimit >>= 1;
+
+	/*
+	 * Grab always-allocated space, if requested
+	 */
+	if (minContextSize > ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ)
+	{
+		Size		blksize = MAXALIGN(minContextSize);
+		AllocBlock	block;
+
+		block = (AllocBlock) malloc(blksize);
+		if (block == NULL)
+		{
+			MemoryContextStats(TopMemoryContext);
+			ereport(ERROR,
+					(errcode(ERRCODE_OUT_OF_MEMORY),
+					 errmsg("out of memory"),
+					 errdetail("Failed while creating memory context \"%s\".",
+							   name)));
+		}
+		block->aset = context;
+		block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ;
+		block->endptr = ((char *) block) + blksize;
+		block->next = context->blocks;
+		context->blocks = block;
+		/* Mark block as not to be released at reset time */
+		context->keeper = block;
+
+		/* Mark unallocated space NOACCESS; leave the block header alone. */
+		VALGRIND_MAKE_MEM_NOACCESS(block->freeptr,
+								   blksize - ALLOC_BLOCKHDRSZ);
+	}
+
+	return (MemoryContext) context;
+}
+
+/*
+ * AllocSetInit
+ *		Context-type-specific initialization routine.
+ *
+ * This is called by MemoryContextCreate() after setting up the
+ * generic MemoryContext fields and before linking the new context
+ * into the context tree.  We must do whatever is needed to make the
+ * new context minimally valid for deletion.  We must *not* risk
+ * failure --- thus, for example, allocating more memory is not cool.
+ * (AllocSetContextCreate can allocate memory when it gets control
+ * back, however.)
+ */
+static void
+AllocSetInit(MemoryContext context)
+{
+	/*
+	 * Since MemoryContextCreate already zeroed the context node, we don't
+	 * have to do anything here: it's already OK.
+	 */
+}
+
+/*
+ * AllocSetReset
+ *		Frees all memory which is allocated in the given set.
+ *
+ * Actually, this routine has some discretion about what to do.
+ * It should mark all allocated chunks freed, but it need not necessarily
+ * give back all the resources the set owns.  Our actual implementation is
+ * that we hang onto any "keeper" block specified for the set.	In this way,
+ * we don't thrash malloc() when a context is repeatedly reset after small
+ * allocations, which is typical behavior for per-tuple contexts.
+ */
+static void
+AllocSetReset(MemoryContext context)
+{
+	AllocSet	set = (AllocSet) context;
+	AllocBlock	block;
+
+	AssertArg(AllocSetIsValid(set));
+
+#ifdef MEMORY_CONTEXT_CHECKING
+	/* Check for corruption and leaks before freeing */
+	AllocSetCheck(context);
+#endif
+
+	/* Clear chunk freelists */
+	MemSetAligned(set->freelist, 0, sizeof(set->freelist));
+
+	block = set->blocks;
+
+	/* New blocks list is either empty or just the keeper block */
+	set->blocks = set->keeper;
+
+	while (block != NULL)
+	{
+		AllocBlock	next = block->next;
+
+		if (block == set->keeper)
+		{
+			/* Reset the block, but don't return it to malloc */
+			char	   *datastart = ((char *) block) + ALLOC_BLOCKHDRSZ;
+
+#ifdef CLOBBER_FREED_MEMORY
+			wipe_mem(datastart, block->freeptr - datastart);
+#else
+			/* wipe_mem() would have done this */
+			VALGRIND_MAKE_MEM_NOACCESS(datastart, block->freeptr - datastart);
+#endif
+			block->freeptr = datastart;
+			block->next = NULL;
+		}
+		else
+		{
+			/* Normal case, release the block */
+#ifdef CLOBBER_FREED_MEMORY
+			wipe_mem(block, block->freeptr - ((char *) block));
+#endif
+			free(block);
+		}
+		block = next;
+	}
+
+	/* Reset block size allocation sequence, too */
+	set->nextBlockSize = set->initBlockSize;
+}
+
+/*
+ * AllocSetDelete
+ *		Frees all memory which is allocated in the given set,
+ *		in preparation for deletion of the set.
+ *
+ * Unlike AllocSetReset, this *must* free all resources of the set.
+ * But note we are not responsible for deleting the context node itself.
+ */
+static void
+AllocSetDelete(MemoryContext context)
+{
+	AllocSet	set = (AllocSet) context;
+	AllocBlock	block = set->blocks;
+
+	AssertArg(AllocSetIsValid(set));
+
+#ifdef MEMORY_CONTEXT_CHECKING
+	/* Check for corruption and leaks before freeing */
+	AllocSetCheck(context);
+#endif
+
+	/* Make it look empty, just in case... */
+	MemSetAligned(set->freelist, 0, sizeof(set->freelist));
+	set->blocks = NULL;
+	set->keeper = NULL;
+
+	while (block != NULL)
+	{
+		AllocBlock	next = block->next;
+
+#ifdef CLOBBER_FREED_MEMORY
+		wipe_mem(block, block->freeptr - ((char *) block));
+#endif
+		free(block);
+		block = next;
+	}
+}
+
+/*
+ * AllocSetAlloc
+ *		Returns pointer to allocated memory of given size; memory is added
+ *		to the set.
+ *
+ * No request may exceed:
+ *		MAXALIGN_DOWN(SIZE_MAX) - ALLOC_BLOCKHDRSZ - ALLOC_CHUNKHDRSZ
+ * All callers use a much-lower limit.
+ */
+static void *
+AllocSetAlloc(MemoryContext context, Size size)
+{
+	AllocSet	set = (AllocSet) context;
+	AllocBlock	block;
+	AllocChunk	chunk;
+	int			fidx;
+	Size		chunk_size;
+	Size		blksize;
+
+	AssertArg(AllocSetIsValid(set));
+
+	/*
+	 * If requested size exceeds maximum for chunks, allocate an entire block
+	 * for this request.
+	 */
+	if (size > set->allocChunkLimit)
+	{
+		chunk_size = MAXALIGN(size);
+		blksize = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
+		block = (AllocBlock) malloc(blksize);
+		if (block == NULL)
+		{
+			MemoryContextStats(TopMemoryContext);
+			ereport(ERROR,
+					(errcode(ERRCODE_OUT_OF_MEMORY),
+					 errmsg("out of memory"),
+					 errdetail("Failed on request of size %lu.",
+							   (unsigned long) size)));
+		}
+		block->aset = set;
+		block->freeptr = block->endptr = ((char *) block) + blksize;
+
+		chunk = (AllocChunk) (((char *) block) + ALLOC_BLOCKHDRSZ);
+		chunk->aset = set;
+		chunk->size = chunk_size;
+#ifdef MEMORY_CONTEXT_CHECKING
+		/* Valgrind: Will be made NOACCESS below. */
+		chunk->requested_size = size;
+		/* set mark to catch clobber of "unused" space */
+		if (size < chunk_size)
+			set_sentinel(AllocChunkGetPointer(chunk), size);
+#endif
+#ifdef RANDOMIZE_ALLOCATED_MEMORY
+		/* fill the allocated space with junk */
+		randomize_mem((char *) AllocChunkGetPointer(chunk), size);
+#endif
+
+		/*
+		 * Stick the new block underneath the active allocation block, so that
+		 * we don't lose the use of the space remaining therein.
+		 */
+		if (set->blocks != NULL)
+		{
+			block->next = set->blocks->next;
+			set->blocks->next = block;
+		}
+		else
+		{
+			block->next = NULL;
+			set->blocks = block;
+		}
+
+		AllocAllocInfo(set, chunk);
+
+		/*
+		 * Chunk header public fields remain DEFINED.  The requested
+		 * allocation itself can be NOACCESS or UNDEFINED; our caller will
+		 * soon make it UNDEFINED.  Make extra space at the end of the chunk,
+		 * if any, NOACCESS.
+		 */
+		VALGRIND_MAKE_MEM_NOACCESS((char *) chunk + ALLOC_CHUNK_PUBLIC,
+						 chunk_size + ALLOC_CHUNKHDRSZ - ALLOC_CHUNK_PUBLIC);
+
+		return AllocChunkGetPointer(chunk);
+	}
+
+	/*
+	 * Request is small enough to be treated as a chunk.  Look in the
+	 * corresponding free list to see if there is a free chunk we could reuse.
+	 * If one is found, remove it from the free list, make it again a member
+	 * of the alloc set and return its data address.
+	 */
+	fidx = AllocSetFreeIndex(size);
+	chunk = set->freelist[fidx];
+	if (chunk != NULL)
+	{
+		Assert(chunk->size >= size);
+
+		set->freelist[fidx] = (AllocChunk) chunk->aset;
+
+		chunk->aset = (void *) set;
+
+#ifdef MEMORY_CONTEXT_CHECKING
+		/* Valgrind: Free list requested_size should be DEFINED. */
+		chunk->requested_size = size;
+		VALGRIND_MAKE_MEM_NOACCESS(&chunk->requested_size,
+								   sizeof(chunk->requested_size));
+		/* set mark to catch clobber of "unused" space */
+		if (size < chunk->size)
+			set_sentinel(AllocChunkGetPointer(chunk), size);
+#endif
+#ifdef RANDOMIZE_ALLOCATED_MEMORY
+		/* fill the allocated space with junk */
+		randomize_mem((char *) AllocChunkGetPointer(chunk), size);
+#endif
+
+		AllocAllocInfo(set, chunk);
+		return AllocChunkGetPointer(chunk);
+	}
+
+	/*
+	 * Choose the actual chunk size to allocate.
+	 */
+	chunk_size = (1 << ALLOC_MINBITS) << fidx;
+	Assert(chunk_size >= size);
+
+	/*
+	 * If there is enough room in the active allocation block, we will put the
+	 * chunk into that block.  Else must start a new one.
+	 */
+	if ((block = set->blocks) != NULL)
+	{
+		Size		availspace = block->endptr - block->freeptr;
+
+		if (availspace < (chunk_size + ALLOC_CHUNKHDRSZ))
+		{
+			/*
+			 * The existing active (top) block does not have enough room for
+			 * the requested allocation, but it might still have a useful
+			 * amount of space in it.  Once we push it down in the block list,
+			 * we'll never try to allocate more space from it. So, before we
+			 * do that, carve up its free space into chunks that we can put on
+			 * the set's freelists.
+			 *
+			 * Because we can only get here when there's less than
+			 * ALLOC_CHUNK_LIMIT left in the block, this loop cannot iterate
+			 * more than ALLOCSET_NUM_FREELISTS-1 times.
+			 */
+			while (availspace >= ((1 << ALLOC_MINBITS) + ALLOC_CHUNKHDRSZ))
+			{
+				Size		availchunk = availspace - ALLOC_CHUNKHDRSZ;
+				int			a_fidx = AllocSetFreeIndex(availchunk);
+
+				/*
+				 * In most cases, we'll get back the index of the next larger
+				 * freelist than the one we need to put this chunk on.	The
+				 * exception is when availchunk is exactly a power of 2.
+				 */
+				if (availchunk != ((Size) 1 << (a_fidx + ALLOC_MINBITS)))
+				{
+					a_fidx--;
+					Assert(a_fidx >= 0);
+					availchunk = ((Size) 1 << (a_fidx + ALLOC_MINBITS));
+				}
+
+				chunk = (AllocChunk) (block->freeptr);
+
+				/* Prepare to initialize the chunk header. */
+				VALGRIND_MAKE_MEM_UNDEFINED(chunk, ALLOC_CHUNK_USED);
+
+				block->freeptr += (availchunk + ALLOC_CHUNKHDRSZ);
+				availspace -= (availchunk + ALLOC_CHUNKHDRSZ);
+
+				chunk->size = availchunk;
+#ifdef MEMORY_CONTEXT_CHECKING
+				chunk->requested_size = 0;		/* mark it free */
+#endif
+				chunk->aset = (void *) set->freelist[a_fidx];
+				set->freelist[a_fidx] = chunk;
+			}
+
+			/* Mark that we need to create a new block */
+			block = NULL;
+		}
+	}
+
+	/*
+	 * Time to create a new regular (multi-chunk) block?
+	 */
+	if (block == NULL)
+	{
+		Size		required_size;
+
+		/*
+		 * The first such block has size initBlockSize, and we double the
+		 * space in each succeeding block, but not more than maxBlockSize.
+		 */
+		blksize = set->nextBlockSize;
+		set->nextBlockSize <<= 1;
+		if (set->nextBlockSize > set->maxBlockSize)
+			set->nextBlockSize = set->maxBlockSize;
+
+		/*
+		 * If initBlockSize is less than ALLOC_CHUNK_LIMIT, we could need more
+		 * space... but try to keep it a power of 2.
+		 */
+		required_size = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
+		while (blksize < required_size)
+			blksize <<= 1;
+
+		/* Try to allocate it */
+		block = (AllocBlock) malloc(blksize);
+
+		/*
+		 * We could be asking for pretty big blocks here, so cope if malloc
+		 * fails.  But give up if there's less than a meg or so available...
+		 */
+		while (block == NULL && blksize > 1024 * 1024)
+		{
+			blksize >>= 1;
+			if (blksize < required_size)
+				break;
+			block = (AllocBlock) malloc(blksize);
+		}
+
+		if (block == NULL)
+		{
+			MemoryContextStats(TopMemoryContext);
+			ereport(ERROR,
+					(errcode(ERRCODE_OUT_OF_MEMORY),
+					 errmsg("out of memory"),
+					 errdetail("Failed on request of size %lu.",
+							   (unsigned long) size)));
+		}
+
+		block->aset = set;
+		block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ;
+		block->endptr = ((char *) block) + blksize;
+
+		/*
+		 * If this is the first block of the set, make it the "keeper" block.
+		 * Formerly, a keeper block could only be created during context
+		 * creation, but allowing it to happen here lets us have fast reset
+		 * cycling even for contexts created with minContextSize = 0; that way
+		 * we don't have to force space to be allocated in contexts that might
+		 * never need any space.  Don't mark an oversize block as a keeper,
+		 * however.
+		 */
+		if (set->keeper == NULL && blksize == set->initBlockSize)
+			set->keeper = block;
+
+		/* Mark unallocated space NOACCESS. */
+		VALGRIND_MAKE_MEM_NOACCESS(block->freeptr,
+								   blksize - ALLOC_BLOCKHDRSZ);
+
+		block->next = set->blocks;
+		set->blocks = block;
+	}
+
+	/*
+	 * OK, do the allocation
+	 */
+	chunk = (AllocChunk) (block->freeptr);
+
+	/* Prepare to initialize the chunk header. */
+	VALGRIND_MAKE_MEM_UNDEFINED(chunk, ALLOC_CHUNK_USED);
+
+	block->freeptr += (chunk_size + ALLOC_CHUNKHDRSZ);
+	Assert(block->freeptr <= block->endptr);
+
+	chunk->aset = (void *) set;
+	chunk->size = chunk_size;
+#ifdef MEMORY_CONTEXT_CHECKING
+	chunk->requested_size = size;
+	VALGRIND_MAKE_MEM_NOACCESS(&chunk->requested_size,
+							   sizeof(chunk->requested_size));
+	/* set mark to catch clobber of "unused" space */
+	if (size < chunk->size)
+		set_sentinel(AllocChunkGetPointer(chunk), size);
+#endif
+#ifdef RANDOMIZE_ALLOCATED_MEMORY
+	/* fill the allocated space with junk */
+	randomize_mem((char *) AllocChunkGetPointer(chunk), size);
+#endif
+
+	AllocAllocInfo(set, chunk);
+	return AllocChunkGetPointer(chunk);
+}
+
+/*
+ * AllocSetFree
+ *		Frees allocated memory; memory is removed from the set.
+ */
+static void
+AllocSetFree(MemoryContext context, void *pointer)
+{
+	AllocSet	set = (AllocSet) context;
+	AllocChunk	chunk = AllocPointerGetChunk(pointer);
+
+	AllocFreeInfo(set, chunk);
+
+#ifdef MEMORY_CONTEXT_CHECKING
+	VALGRIND_MAKE_MEM_DEFINED(&chunk->requested_size,
+							  sizeof(chunk->requested_size));
+	/* Test for someone scribbling on unused space in chunk */
+	if (chunk->requested_size < chunk->size)
+		if (!sentinel_ok(pointer, chunk->requested_size))
+			elog(WARNING, "detected write past chunk end in %s %p",
+				 set->header.name, chunk);
+#endif
+
+	if (chunk->size > set->allocChunkLimit)
+	{
+		/*
+		 * Big chunks are certain to have been allocated as single-chunk
+		 * blocks.	Find the containing block and return it to malloc().
+		 */
+		AllocBlock	block = set->blocks;
+		AllocBlock	prevblock = NULL;
+
+		while (block != NULL)
+		{
+			if (chunk == (AllocChunk) (((char *) block) + ALLOC_BLOCKHDRSZ))
+				break;
+			prevblock = block;
+			block = block->next;
+		}
+		if (block == NULL)
+			elog(ERROR, "could not find block containing chunk %p", chunk);
+		/* let's just make sure chunk is the only one in the block */
+		Assert(block->freeptr == ((char *) block) +
+			   (chunk->size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ));
+
+		/* OK, remove block from aset's list and free it */
+		if (prevblock == NULL)
+			set->blocks = block->next;
+		else
+			prevblock->next = block->next;
+#ifdef CLOBBER_FREED_MEMORY
+		wipe_mem(block, block->freeptr - ((char *) block));
+#endif
+		free(block);
+	}
+	else
+	{
+		/* Normal case, put the chunk into appropriate freelist */
+		int			fidx = AllocSetFreeIndex(chunk->size);
+
+		chunk->aset = (void *) set->freelist[fidx];
+
+#ifdef CLOBBER_FREED_MEMORY
+		wipe_mem(pointer, chunk->size);
+#endif
+
+#ifdef MEMORY_CONTEXT_CHECKING
+		/* Reset requested_size to 0 in chunks that are on freelist */
+		chunk->requested_size = 0;
+#endif
+		set->freelist[fidx] = chunk;
+	}
+}
+
+/*
+ * AllocSetRealloc
+ *		Returns new pointer to allocated memory of given size; this memory
+ *		is added to the set.  Memory associated with given pointer is copied
+ *		into the new memory, and the old memory is freed.
+ *
+ * Without MEMORY_CONTEXT_CHECKING, we don't know the old request size.  This
+ * makes our Valgrind client requests less-precise, hazarding false negatives.
+ * (In principle, we could use VALGRIND_GET_VBITS() to rediscover the old
+ * request size.)
+ */
+static void *
+AllocSetRealloc(MemoryContext context, void *pointer, Size size)
+{
+	AllocSet	set = (AllocSet) context;
+	AllocChunk	chunk = AllocPointerGetChunk(pointer);
+	Size		oldsize = chunk->size;
+
+#ifdef MEMORY_CONTEXT_CHECKING
+	VALGRIND_MAKE_MEM_DEFINED(&chunk->requested_size,
+							  sizeof(chunk->requested_size));
+	/* Test for someone scribbling on unused space in chunk */
+	if (chunk->requested_size < oldsize)
+		if (!sentinel_ok(pointer, chunk->requested_size))
+			elog(WARNING, "detected write past chunk end in %s %p",
+				 set->header.name, chunk);
+#endif
+
+	/*
+	 * Chunk sizes are aligned to power of 2 in AllocSetAlloc(). Maybe the
+	 * allocated area already is >= the new size.  (In particular, we always
+	 * fall out here if the requested size is a decrease.)
+	 */
+	if (oldsize >= size)
+	{
+#ifdef MEMORY_CONTEXT_CHECKING
+		Size		oldrequest = chunk->requested_size;
+
+#ifdef RANDOMIZE_ALLOCATED_MEMORY
+		/* We can only fill the extra space if we know the prior request */
+		if (size > oldrequest)
+			randomize_mem((char *) pointer + oldrequest,
+						  size - oldrequest);
+#endif
+
+		chunk->requested_size = size;
+		VALGRIND_MAKE_MEM_NOACCESS(&chunk->requested_size,
+								   sizeof(chunk->requested_size));
+
+		/*
+		 * If this is an increase, mark any newly-available part UNDEFINED.
+		 * Otherwise, mark the obsolete part NOACCESS.
+		 */
+		if (size > oldrequest)
+			VALGRIND_MAKE_MEM_UNDEFINED((char *) pointer + oldrequest,
+										size - oldrequest);
+		else
+			VALGRIND_MAKE_MEM_NOACCESS((char *) pointer + size,
+									   oldsize - size);
+
+		/* set mark to catch clobber of "unused" space */
+		if (size < oldsize)
+			set_sentinel(pointer, size);
+#else							/* !MEMORY_CONTEXT_CHECKING */
+
+		/*
+		 * We don't have the information to determine whether we're growing
+		 * the old request or shrinking it, so we conservatively mark the
+		 * entire new allocation DEFINED.
+		 */
+		VALGRIND_MAKE_MEM_NOACCESS(pointer, oldsize);
+		VALGRIND_MAKE_MEM_DEFINED(pointer, size);
+#endif
+
+		return pointer;
+	}
+
+	if (oldsize > set->allocChunkLimit)
+	{
+		/*
+		 * The chunk must have been allocated as a single-chunk block.	Find
+		 * the containing block and use realloc() to make it bigger with
+		 * minimum space wastage.
+		 */
+		AllocBlock	block = set->blocks;
+		AllocBlock	prevblock = NULL;
+		Size		chksize;
+		Size		blksize;
+
+		while (block != NULL)
+		{
+			if (chunk == (AllocChunk) (((char *) block) + ALLOC_BLOCKHDRSZ))
+				break;
+			prevblock = block;
+			block = block->next;
+		}
+		if (block == NULL)
+			elog(ERROR, "could not find block containing chunk %p", chunk);
+		/* let's just make sure chunk is the only one in the block */
+		Assert(block->freeptr == ((char *) block) +
+			   (chunk->size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ));
+
+		/* Do the realloc */
+		chksize = MAXALIGN(size);
+		blksize = chksize + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
+		block = (AllocBlock) realloc(block, blksize);
+		if (block == NULL)
+		{
+			MemoryContextStats(TopMemoryContext);
+			ereport(ERROR,
+					(errcode(ERRCODE_OUT_OF_MEMORY),
+					 errmsg("out of memory"),
+					 errdetail("Failed on request of size %lu.",
+							   (unsigned long) size)));
+		}
+		block->freeptr = block->endptr = ((char *) block) + blksize;
+
+		/* Update pointers since block has likely been moved */
+		chunk = (AllocChunk) (((char *) block) + ALLOC_BLOCKHDRSZ);
+		pointer = AllocChunkGetPointer(chunk);
+		if (prevblock == NULL)
+			set->blocks = block;
+		else
+			prevblock->next = block;
+		chunk->size = chksize;
+
+#ifdef MEMORY_CONTEXT_CHECKING
+#ifdef RANDOMIZE_ALLOCATED_MEMORY
+		/* We can only fill the extra space if we know the prior request */
+		randomize_mem((char *) pointer + chunk->requested_size,
+					  size - chunk->requested_size);
+#endif
+
+		/*
+		 * realloc() (or randomize_mem()) will have left the newly-allocated
+		 * part UNDEFINED, but we may need to adjust trailing bytes from the
+		 * old allocation.
+		 */
+		VALGRIND_MAKE_MEM_UNDEFINED((char *) pointer + chunk->requested_size,
+									oldsize - chunk->requested_size);
+
+		chunk->requested_size = size;
+		VALGRIND_MAKE_MEM_NOACCESS(&chunk->requested_size,
+								   sizeof(chunk->requested_size));
+
+		/* set mark to catch clobber of "unused" space */
+		if (size < chunk->size)
+			set_sentinel(AllocChunkGetPointer(chunk), size);
+#else							/* !MEMORY_CONTEXT_CHECKING */
+
+		/*
+		 * We don't know how much of the old chunk size was the actual
+		 * allocation; it could have been as small as one byte.  We have to be
+		 * conservative and just mark the entire old portion DEFINED.
+		 */
+		VALGRIND_MAKE_MEM_DEFINED(pointer, oldsize);
+#endif
+
+		/* Make any trailing alignment padding NOACCESS. */
+		VALGRIND_MAKE_MEM_NOACCESS((char *) pointer + size, chksize - size);
+		return AllocChunkGetPointer(chunk);
+	}
+	else
+	{
+		/*
+		 * Small-chunk case.  We just do this by brute force, ie, allocate a
+		 * new chunk and copy the data.  Since we know the existing data isn't
+		 * huge, this won't involve any great memcpy expense, so it's not
+		 * worth being smarter.  (At one time we tried to avoid memcpy when it
+		 * was possible to enlarge the chunk in-place, but that turns out to
+		 * misbehave unpleasantly for repeated cycles of
+		 * palloc/repalloc/pfree: the eventually freed chunks go into the
+		 * wrong freelist for the next initial palloc request, and so we leak
+		 * memory indefinitely.  See pgsql-hackers archives for 2007-08-11.)
+		 */
+		AllocPointer newPointer;
+
+		/* allocate new chunk */
+		newPointer = AllocSetAlloc((MemoryContext) set, size);
+
+		/*
+		 * AllocSetAlloc() just made the region NOACCESS.  Change it to
+		 * UNDEFINED for the moment; memcpy() will then transfer definedness
+		 * from the old allocation to the new.  If we know the old allocation,
+		 * copy just that much.  Otherwise, make the entire old chunk defined
+		 * to avoid errors as we copy the currently-NOACCESS trailing bytes.
+		 */
+		VALGRIND_MAKE_MEM_UNDEFINED(newPointer, size);
+#ifdef MEMORY_CONTEXT_CHECKING
+		oldsize = chunk->requested_size;
+#else
+		VALGRIND_MAKE_MEM_DEFINED(pointer, oldsize);
+#endif
+
+		/* transfer existing data (certain to fit) */
+		memcpy(newPointer, pointer, oldsize);
+
+		/* free old chunk */
+		AllocSetFree((MemoryContext) set, pointer);
+
+		return newPointer;
+	}
+}
+
+/*
+ * AllocSetGetChunkSpace
+ *		Given a currently-allocated chunk, determine the total space
+ *		it occupies (including all memory-allocation overhead).
+ */
+static Size
+AllocSetGetChunkSpace(MemoryContext context, void *pointer)
+{
+	AllocChunk	chunk = AllocPointerGetChunk(pointer);
+
+	return chunk->size + ALLOC_CHUNKHDRSZ;
+}
+
+/*
+ * AllocSetIsEmpty
+ *		Is an allocset empty of any allocated space?
+ */
+static bool
+AllocSetIsEmpty(MemoryContext context)
+{
+	/*
+	 * For now, we say "empty" only if the context is new or just reset. We
+	 * could examine the freelists to determine if all space has been freed,
+	 * but it's not really worth the trouble for present uses of this
+	 * functionality.
+	 */
+	if (context->isReset)
+		return true;
+	return false;
+}
+
+/*
+ * AllocSetStats
+ *		Displays stats about memory consumption of an allocset.
+ */
+static void
+AllocSetStats(MemoryContext context, int level)
+{
+	AllocSet	set = (AllocSet) context;
+	long		nblocks = 0;
+	long		nchunks = 0;
+	long		totalspace = 0;
+	long		freespace = 0;
+	AllocBlock	block;
+	AllocChunk	chunk;
+	int			fidx;
+	int			i;
+
+	for (block = set->blocks; block != NULL; block = block->next)
+	{
+		nblocks++;
+		totalspace += block->endptr - ((char *) block);
+		freespace += block->endptr - block->freeptr;
+	}
+	for (fidx = 0; fidx < ALLOCSET_NUM_FREELISTS; fidx++)
+	{
+		for (chunk = set->freelist[fidx]; chunk != NULL;
+			 chunk = (AllocChunk) chunk->aset)
+		{
+			nchunks++;
+			freespace += chunk->size + ALLOC_CHUNKHDRSZ;
+		}
+	}
+
+	for (i = 0; i < level; i++)
+		fprintf(stderr, "  ");
+
+	fprintf(stderr,
+			"%s: %lu total in %ld blocks; %lu free (%ld chunks); %lu used\n",
+			set->header.name, totalspace, nblocks, freespace, nchunks,
+			totalspace - freespace);
+}
+
+
+#ifdef MEMORY_CONTEXT_CHECKING
+
+/*
+ * AllocSetCheck
+ *		Walk through chunks and check consistency of memory.
+ *
+ * NOTE: report errors as WARNING, *not* ERROR or FATAL.  Otherwise you'll
+ * find yourself in an infinite loop when trouble occurs, because this
+ * routine will be entered again when elog cleanup tries to release memory!
+ */
+static void
+AllocSetCheck(MemoryContext context)
+{
+	AllocSet	set = (AllocSet) context;
+	char	   *name = set->header.name;
+	AllocBlock	block;
+
+	for (block = set->blocks; block != NULL; block = block->next)
+	{
+		char	   *bpoz = ((char *) block) + ALLOC_BLOCKHDRSZ;
+		long		blk_used = block->freeptr - bpoz;
+		long		blk_data = 0;
+		long		nchunks = 0;
+
+		/*
+		 * Empty block - empty can be keeper-block only
+		 */
+		if (!blk_used)
+		{
+			if (set->keeper != block)
+				elog(WARNING, "problem in alloc set %s: empty block %p",
+					 name, block);
+		}
+
+		/*
+		 * Chunk walker
+		 */
+		while (bpoz < block->freeptr)
+		{
+			AllocChunk	chunk = (AllocChunk) bpoz;
+			Size		chsize,
+						dsize;
+
+			chsize = chunk->size;		/* aligned chunk size */
+			VALGRIND_MAKE_MEM_DEFINED(&chunk->requested_size,
+									  sizeof(chunk->requested_size));
+			dsize = chunk->requested_size;		/* real data */
+			if (dsize > 0)		/* not on a free list */
+				VALGRIND_MAKE_MEM_NOACCESS(&chunk->requested_size,
+										   sizeof(chunk->requested_size));
+
+			/*
+			 * Check chunk size
+			 */
+			if (dsize > chsize)
+				elog(WARNING, "problem in alloc set %s: req size > alloc size for chunk %p in block %p",
+					 name, chunk, block);
+			if (chsize < (1 << ALLOC_MINBITS))
+				elog(WARNING, "problem in alloc set %s: bad size %lu for chunk %p in block %p",
+					 name, (unsigned long) chsize, chunk, block);
+
+			/* single-chunk block? */
+			if (chsize > set->allocChunkLimit &&
+				chsize + ALLOC_CHUNKHDRSZ != blk_used)
+				elog(WARNING, "problem in alloc set %s: bad single-chunk %p in block %p",
+					 name, chunk, block);
+
+			/*
+			 * If chunk is allocated, check for correct aset pointer. (If it's
+			 * free, the aset is the freelist pointer, which we can't check as
+			 * easily...)
+			 */
+			if (dsize > 0 && chunk->aset != (void *) set)
+				elog(WARNING, "problem in alloc set %s: bogus aset link in block %p, chunk %p",
+					 name, block, chunk);
+
+			/*
+			 * Check for overwrite of "unallocated" space in chunk
+			 */
+			if (dsize > 0 && dsize < chsize &&
+				!sentinel_ok(chunk, ALLOC_CHUNKHDRSZ + dsize))
+				elog(WARNING, "problem in alloc set %s: detected write past chunk end in block %p, chunk %p",
+					 name, block, chunk);
+
+			blk_data += chsize;
+			nchunks++;
+
+			bpoz += ALLOC_CHUNKHDRSZ + chsize;
+		}
+
+		if ((blk_data + (nchunks * ALLOC_CHUNKHDRSZ)) != blk_used)
+			elog(WARNING, "problem in alloc set %s: found inconsistent memory block %p",
+				 name, block);
+	}
+}
+
+#endif   /* MEMORY_CONTEXT_CHECKING */
diff --git a/src/utils/mmgr/mcxt.c b/src/utils/mmgr/mcxt.c
new file mode 100644
index 0000000..3a91f21
--- /dev/null
+++ b/src/utils/mmgr/mcxt.c
@@ -0,0 +1,858 @@
+/*-------------------------------------------------------------------------
+ *
+ * mcxt.c
+ *	  POSTGRES memory context management code.
+ *
+ * This module handles context management operations that are independent
+ * of the particular kind of context being operated on.  It calls
+ * context-type-specific operations via the function pointers in a
+ * context's MemoryContextMethods struct.
+ *
+ *
+ * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *	  src/backend/utils/mmgr/mcxt.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/* see palloc.h.  Must be before postgres.h */
+#define MCXT_INCLUDE_DEFINITIONS
+
+#include <stdint.h>
+#include <string.h>
+#include "pool_type.h"
+#include "utils/palloc.h"
+#include "utils/memutils.h"
+#include "utils/memdebug.h"
+#include "utils/memutils.h"
+#include "utils/elog.h"
+
+
+/*****************************************************************************
+ *	  GLOBAL MEMORY															 *
+ *****************************************************************************/
+
+/*
+ * CurrentMemoryContext
+ *		Default memory context for allocations.
+ */
+MemoryContext CurrentMemoryContext = NULL;
+
+/*
+ * Standard top-level contexts. For a description of the purpose of each
+ * of these contexts, refer to src/backend/utils/mmgr/README
+ */
+MemoryContext TopMemoryContext = NULL;
+MemoryContext ErrorContext = NULL;
+MemoryContext PostmasterContext = NULL;
+MemoryContext CacheMemoryContext = NULL;
+MemoryContext MessageContext = NULL;
+MemoryContext TopTransactionContext = NULL;
+MemoryContext CurTransactionContext = NULL;
+
+/* This is a transient link to the active portal's memory context: */
+MemoryContext PortalContext = NULL;
+
+static void MemoryContextStatsInternal(MemoryContext context, int level);
+
+
+/*****************************************************************************
+ *	  EXPORTED ROUTINES														 *
+ *****************************************************************************/
+
+
+/*
+ * MemoryContextInit
+ *		Start up the memory-context subsystem.
+ *
+ * This must be called before creating contexts or allocating memory in
+ * contexts.  TopMemoryContext and ErrorContext are initialized here;
+ * other contexts must be created afterwards.
+ *
+ * In normal multi-backend operation, this is called once during
+ * postmaster startup, and not at all by individual backend startup
+ * (since the backends inherit an already-initialized context subsystem
+ * by virtue of being forked off the postmaster).
+ *
+ * In a standalone backend this must be called during backend startup.
+ */
+void
+MemoryContextInit(void)
+{
+	AssertState(TopMemoryContext == NULL);
+
+	/*
+	 * Initialize TopMemoryContext as an AllocSetContext with slow growth rate
+	 * --- we don't really expect much to be allocated in it.
+	 *
+	 * (There is special-case code in MemoryContextCreate() for this call.)
+	 */
+	TopMemoryContext = AllocSetContextCreate((MemoryContext) NULL,
+											 "TopMemoryContext",
+											 0,
+											 8 * 1024,
+											 8 * 1024);
+
+	/*
+	 * Not having any other place to point CurrentMemoryContext, make it point
+	 * to TopMemoryContext.  Caller should change this soon!
+	 */
+	CurrentMemoryContext = TopMemoryContext;
+
+	/*
+	 * Initialize ErrorContext as an AllocSetContext with slow growth rate ---
+	 * we don't really expect much to be allocated in it. More to the point,
+	 * require it to contain at least 8K at all times. This is the only case
+	 * where retained memory in a context is *essential* --- we want to be
+	 * sure ErrorContext still has some memory even if we've run out
+	 * elsewhere!
+	 */
+	ErrorContext = AllocSetContextCreate(TopMemoryContext,
+										 "ErrorContext",
+										 8 * 1024,
+										 8 * 1024,
+										 8 * 1024);
+}
+
+/*
+ * MemoryContextReset
+ *		Release all space allocated within a context and its descendants,
+ *		but don't delete the contexts themselves.
+ *
+ * The type-specific reset routine handles the context itself, but we
+ * have to do the recursion for the children.
+ */
+void
+MemoryContextReset(MemoryContext context)
+{
+	AssertArg(MemoryContextIsValid(context));
+
+	/* save a function call in common case where there are no children */
+	if (context->firstchild != NULL)
+		MemoryContextResetChildren(context);
+
+	/* Nothing to do if no pallocs since startup or last reset */
+	if (!context->isReset)
+	{
+		(*context->methods->reset) (context);
+		context->isReset = true;
+		VALGRIND_DESTROY_MEMPOOL(context);
+		VALGRIND_CREATE_MEMPOOL(context, 0, false);
+	}
+}
+
+/*
+ * MemoryContextResetChildren
+ *		Release all space allocated within a context's descendants,
+ *		but don't delete the contexts themselves.  The named context
+ *		itself is not touched.
+ */
+void
+MemoryContextResetChildren(MemoryContext context)
+{
+	MemoryContext child;
+
+	AssertArg(MemoryContextIsValid(context));
+
+	for (child = context->firstchild; child != NULL; child = child->nextchild)
+		MemoryContextReset(child);
+}
+
+/*
+ * MemoryContextDelete
+ *		Delete a context and its descendants, and release all space
+ *		allocated therein.
+ *
+ * The type-specific delete routine removes all subsidiary storage
+ * for the context, but we have to delete the context node itself,
+ * as well as recurse to get the children.	We must also delink the
+ * node from its parent, if it has one.
+ */
+void
+MemoryContextDelete(MemoryContext context)
+{
+	AssertArg(MemoryContextIsValid(context));
+	/* We had better not be deleting TopMemoryContext ... */
+	Assert(context != TopMemoryContext);
+	/* And not CurrentMemoryContext, either */
+	Assert(context != CurrentMemoryContext);
+
+	MemoryContextDeleteChildren(context);
+
+	/*
+	 * We delink the context from its parent before deleting it, so that if
+	 * there's an error we won't have deleted/busted contexts still attached
+	 * to the context tree.  Better a leak than a crash.
+	 */
+	MemoryContextSetParent(context, NULL);
+
+	(*context->methods->delete_context) (context);
+	VALGRIND_DESTROY_MEMPOOL(context);
+	pfree(context);
+}
+
+/*
+ * MemoryContextDeleteChildren
+ *		Delete all the descendants of the named context and release all
+ *		space allocated therein.  The named context itself is not touched.
+ */
+void
+MemoryContextDeleteChildren(MemoryContext context)
+{
+	AssertArg(MemoryContextIsValid(context));
+
+	/*
+	 * MemoryContextDelete will delink the child from me, so just iterate as
+	 * long as there is a child.
+	 */
+	while (context->firstchild != NULL)
+		MemoryContextDelete(context->firstchild);
+}
+
+/*
+ * MemoryContextResetAndDeleteChildren
+ *		Release all space allocated within a context and delete all
+ *		its descendants.
+ *
+ * This is a common combination case where we want to preserve the
+ * specific context but get rid of absolutely everything under it.
+ */
+void
+MemoryContextResetAndDeleteChildren(MemoryContext context)
+{
+	AssertArg(MemoryContextIsValid(context));
+
+	MemoryContextDeleteChildren(context);
+	MemoryContextReset(context);
+}
+
+/*
+ * MemoryContextSetParent
+ *		Change a context to belong to a new parent (or no parent).
+ *
+ * We provide this as an API function because it is sometimes useful to
+ * change a context's lifespan after creation.  For example, a context
+ * might be created underneath a transient context, filled with data,
+ * and then reparented underneath CacheMemoryContext to make it long-lived.
+ * In this way no special effort is needed to get rid of the context in case
+ * a failure occurs before its contents are completely set up.
+ *
+ * Callers often assume that this function cannot fail, so don't put any
+ * elog(ERROR) calls in it.
+ *
+ * A possible caller error is to reparent a context under itself, creating
+ * a loop in the context graph.  We assert here that context != new_parent,
+ * but checking for multi-level loops seems more trouble than it's worth.
+ */
+void
+MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
+{
+	AssertArg(MemoryContextIsValid(context));
+	AssertArg(context != new_parent);
+
+	/* Delink from existing parent, if any */
+	if (context->parent)
+	{
+		MemoryContext parent = context->parent;
+
+		if (context == parent->firstchild)
+			parent->firstchild = context->nextchild;
+		else
+		{
+			MemoryContext child;
+
+			for (child = parent->firstchild; child; child = child->nextchild)
+			{
+				if (context == child->nextchild)
+				{
+					child->nextchild = context->nextchild;
+					break;
+				}
+			}
+		}
+	}
+
+	/* And relink */
+	if (new_parent)
+	{
+		AssertArg(MemoryContextIsValid(new_parent));
+		context->parent = new_parent;
+		context->nextchild = new_parent->firstchild;
+		new_parent->firstchild = context;
+	}
+	else
+	{
+		context->parent = NULL;
+		context->nextchild = NULL;
+	}
+}
+
+/*
+ * GetMemoryChunkSpace
+ *		Given a currently-allocated chunk, determine the total space
+ *		it occupies (including all memory-allocation overhead).
+ *
+ * This is useful for measuring the total space occupied by a set of
+ * allocated chunks.
+ */
+Size
+GetMemoryChunkSpace(void *pointer)
+{
+	StandardChunkHeader *header;
+
+	/*
+	 * Try to detect bogus pointers handed to us, poorly though we can.
+	 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
+	 * allocated chunk.
+	 */
+	Assert(pointer != NULL);
+	Assert(pointer == (void *) MAXALIGN(pointer));
+
+	/*
+	 * OK, it's probably safe to look at the chunk header.
+	 */
+	header = (StandardChunkHeader *)
+		((char *) pointer - STANDARDCHUNKHEADERSIZE);
+
+	AssertArg(MemoryContextIsValid(header->context));
+
+	return (*header->context->methods->get_chunk_space) (header->context,
+														 pointer);
+}
+
+/*
+ * GetMemoryChunkContext
+ *		Given a currently-allocated chunk, determine the context
+ *		it belongs to.
+ */
+MemoryContext
+GetMemoryChunkContext(void *pointer)
+{
+	StandardChunkHeader *header;
+
+	/*
+	 * Try to detect bogus pointers handed to us, poorly though we can.
+	 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
+	 * allocated chunk.
+	 */
+	Assert(pointer != NULL);
+	Assert(pointer == (void *) MAXALIGN(pointer));
+
+	/*
+	 * OK, it's probably safe to look at the chunk header.
+	 */
+	header = (StandardChunkHeader *)
+		((char *) pointer - STANDARDCHUNKHEADERSIZE);
+
+	AssertArg(MemoryContextIsValid(header->context));
+
+	return header->context;
+}
+
+/*
+ * MemoryContextGetParent
+ *		Get the parent context (if any) of the specified context
+ */
+MemoryContext
+MemoryContextGetParent(MemoryContext context)
+{
+	AssertArg(MemoryContextIsValid(context));
+
+	return context->parent;
+}
+
+/*
+ * MemoryContextIsEmpty
+ *		Is a memory context empty of any allocated space?
+ */
+bool
+MemoryContextIsEmpty(MemoryContext context)
+{
+	AssertArg(MemoryContextIsValid(context));
+
+	/*
+	 * For now, we consider a memory context nonempty if it has any children;
+	 * perhaps this should be changed later.
+	 */
+	if (context->firstchild != NULL)
+		return false;
+	/* Otherwise use the type-specific inquiry */
+	return (*context->methods->is_empty) (context);
+}
+
+/*
+ * MemoryContextStats
+ *		Print statistics about the named context and all its descendants.
+ *
+ * This is just a debugging utility, so it's not fancy.  The statistics
+ * are merely sent to stderr.
+ */
+void
+MemoryContextStats(MemoryContext context)
+{
+	MemoryContextStatsInternal(context, 0);
+}
+
+static void
+MemoryContextStatsInternal(MemoryContext context, int level)
+{
+	MemoryContext child;
+
+	AssertArg(MemoryContextIsValid(context));
+
+	(*context->methods->stats) (context, level);
+	for (child = context->firstchild; child != NULL; child = child->nextchild)
+		MemoryContextStatsInternal(child, level + 1);
+}
+
+/*
+ * MemoryContextCheck
+ *		Check all chunks in the named context.
+ *
+ * This is just a debugging utility, so it's not fancy.
+ */
+#ifdef MEMORY_CONTEXT_CHECKING
+void
+MemoryContextCheck(MemoryContext context)
+{
+	MemoryContext child;
+
+	AssertArg(MemoryContextIsValid(context));
+
+	(*context->methods->check) (context);
+	for (child = context->firstchild; child != NULL; child = child->nextchild)
+		MemoryContextCheck(child);
+}
+#endif
+
+/*
+ * MemoryContextContains
+ *		Detect whether an allocated chunk of memory belongs to a given
+ *		context or not.
+ *
+ * Caution: this test is reliable as long as 'pointer' does point to
+ * a chunk of memory allocated from *some* context.  If 'pointer' points
+ * at memory obtained in some other way, there is a small chance of a
+ * false-positive result, since the bits right before it might look like
+ * a valid chunk header by chance.
+ */
+bool
+MemoryContextContains(MemoryContext context, void *pointer)
+{
+	StandardChunkHeader *header;
+
+	/*
+	 * Try to detect bogus pointers handed to us, poorly though we can.
+	 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
+	 * allocated chunk.
+	 */
+	if (pointer == NULL || pointer != (void *) MAXALIGN(pointer))
+		return false;
+
+	/*
+	 * OK, it's probably safe to look at the chunk header.
+	 */
+	header = (StandardChunkHeader *)
+		((char *) pointer - STANDARDCHUNKHEADERSIZE);
+
+	return header->context == context;
+}
+
+/*--------------------
+ * MemoryContextCreate
+ *		Context-type-independent part of context creation.
+ *
+ * This is only intended to be called by context-type-specific
+ * context creation routines, not by the unwashed masses.
+ *
+ * The context creation procedure is a little bit tricky because
+ * we want to be sure that we don't leave the context tree invalid
+ * in case of failure (such as insufficient memory to allocate the
+ * context node itself).  The procedure goes like this:
+ *	1.	Context-type-specific routine first calls MemoryContextCreate(),
+ *		passing the appropriate tag/size/methods values (the methods
+ *		pointer will ordinarily point to statically allocated data).
+ *		The parent and name parameters usually come from the caller.
+ *	2.	MemoryContextCreate() attempts to allocate the context node,
+ *		plus space for the name.  If this fails we can ereport() with no
+ *		damage done.
+ *	3.	We fill in all of the type-independent MemoryContext fields.
+ *	4.	We call the type-specific init routine (using the methods pointer).
+ *		The init routine is required to make the node minimally valid
+ *		with zero chance of failure --- it can't allocate more memory,
+ *		for example.
+ *	5.	Now we have a minimally valid node that can behave correctly
+ *		when told to reset or delete itself.  We link the node to its
+ *		parent (if any), making the node part of the context tree.
+ *	6.	We return to the context-type-specific routine, which finishes
+ *		up type-specific initialization.  This routine can now do things
+ *		that might fail (like allocate more memory), so long as it's
+ *		sure the node is left in a state that delete will handle.
+ *
+ * This protocol doesn't prevent us from leaking memory if step 6 fails
+ * during creation of a top-level context, since there's no parent link
+ * in that case.  However, if you run out of memory while you're building
+ * a top-level context, you might as well go home anyway...
+ *
+ * Normally, the context node and the name are allocated from
+ * TopMemoryContext (NOT from the parent context, since the node must
+ * survive resets of its parent context!).	However, this routine is itself
+ * used to create TopMemoryContext!  If we see that TopMemoryContext is NULL,
+ * we assume we are creating TopMemoryContext and use malloc() to allocate
+ * the node.
+ *
+ * Note that the name field of a MemoryContext does not point to
+ * separately-allocated storage, so it should not be freed at context
+ * deletion.
+ *--------------------
+ */
+MemoryContext
+MemoryContextCreate(NodeTag tag, Size size,
+					MemoryContextMethods *methods,
+					MemoryContext parent,
+					const char *name)
+{
+	MemoryContext node;
+	Size		needed = size + strlen(name) + 1;
+
+	/* Get space for node and name */
+	if (TopMemoryContext != NULL)
+	{
+		/* Normal case: allocate the node in TopMemoryContext */
+		node = (MemoryContext) MemoryContextAlloc(TopMemoryContext,
+												  needed);
+	}
+	else
+	{
+		/* Special case for startup: use good ol' malloc */
+		node = (MemoryContext) malloc(needed);
+		Assert(node != NULL);
+	}
+
+	/* Initialize the node as best we can */
+	MemSet(node, 0, size);
+	node->type = tag;
+	node->methods = methods;
+	node->parent = NULL;		/* for the moment */
+	node->firstchild = NULL;
+	node->nextchild = NULL;
+	node->isReset = true;
+	node->name = ((char *) node) + size;
+	strcpy(node->name, name);
+
+	/* Type-specific routine finishes any other essential initialization */
+	(*node->methods->init) (node);
+
+	/* OK to link node to parent (if any) */
+	/* Could use MemoryContextSetParent here, but doesn't seem worthwhile */
+	if (parent)
+	{
+		node->parent = parent;
+		node->nextchild = parent->firstchild;
+		parent->firstchild = node;
+	}
+
+	VALGRIND_CREATE_MEMPOOL(node, 0, false);
+
+	/* Return to type-specific creation routine to finish up */
+	return node;
+}
+
+/*
+ * MemoryContextAlloc
+ *		Allocate space within the specified context.
+ *
+ * This could be turned into a macro, but we'd have to import
+ * nodes/memnodes.h into postgres.h which seems a bad idea.
+ */
+void *
+MemoryContextAlloc(MemoryContext context, Size size)
+{
+	void	   *ret;
+
+	AssertArg(MemoryContextIsValid(context));
+
+	if (!AllocSizeIsValid(size))
+		elog(ERROR, "invalid memory alloc request size %lu",
+			 (unsigned long) size);
+
+	context->isReset = false;
+
+	ret = (*context->methods->alloc) (context, size);
+	VALGRIND_MEMPOOL_ALLOC(context, ret, size);
+
+	return ret;
+}
+
+/*
+ * MemoryContextAllocZero
+ *		Like MemoryContextAlloc, but clears allocated memory
+ *
+ *	We could just call MemoryContextAlloc then clear the memory, but this
+ *	is a very common combination, so we provide the combined operation.
+ */
+void *
+MemoryContextAllocZero(MemoryContext context, Size size)
+{
+	void	   *ret;
+
+	AssertArg(MemoryContextIsValid(context));
+
+	if (!AllocSizeIsValid(size))
+		elog(ERROR, "invalid memory alloc request size %lu",
+			 (unsigned long) size);
+
+	context->isReset = false;
+
+	ret = (*context->methods->alloc) (context, size);
+	VALGRIND_MEMPOOL_ALLOC(context, ret, size);
+
+	MemSetAligned(ret, 0, size);
+
+	return ret;
+}
+
+/*
+ * MemoryContextAllocZeroAligned
+ *		MemoryContextAllocZero where length is suitable for MemSetLoop
+ *
+ *	This might seem overly specialized, but it's not because newNode()
+ *	is so often called with compile-time-constant sizes.
+ */
+void *
+MemoryContextAllocZeroAligned(MemoryContext context, Size size)
+{
+	void	   *ret;
+
+	AssertArg(MemoryContextIsValid(context));
+
+	if (!AllocSizeIsValid(size))
+		elog(ERROR, "invalid memory alloc request size %lu",
+			 (unsigned long) size);
+
+	context->isReset = false;
+
+	ret = (*context->methods->alloc) (context, size);
+	VALGRIND_MEMPOOL_ALLOC(context, ret, size);
+
+	MemSetLoop(ret, 0, size);
+
+	return ret;
+}
+
+void *
+palloc(Size size)
+{
+	/* duplicates MemoryContextAlloc to avoid increased overhead */
+	void	   *ret;
+
+	AssertArg(MemoryContextIsValid(CurrentMemoryContext));
+
+	if (!AllocSizeIsValid(size))
+		elog(ERROR, "invalid memory alloc request size %lu",
+			 (unsigned long) size);
+
+	CurrentMemoryContext->isReset = false;
+
+	ret = (*CurrentMemoryContext->methods->alloc) (CurrentMemoryContext, size);
+	VALGRIND_MEMPOOL_ALLOC(CurrentMemoryContext, ret, size);
+
+	return ret;
+}
+
+void *
+palloc0(Size size)
+{
+	/* duplicates MemoryContextAllocZero to avoid increased overhead */
+	void	   *ret;
+
+	AssertArg(MemoryContextIsValid(CurrentMemoryContext));
+
+	if (!AllocSizeIsValid(size))
+		elog(ERROR, "invalid memory alloc request size %lu",
+			 (unsigned long) size);
+
+	CurrentMemoryContext->isReset = false;
+
+	ret = (*CurrentMemoryContext->methods->alloc) (CurrentMemoryContext, size);
+	VALGRIND_MEMPOOL_ALLOC(CurrentMemoryContext, ret, size);
+
+	MemSetAligned(ret, 0, size);
+
+	return ret;
+}
+
+/*
+ * pfree
+ *		Release an allocated chunk.
+ */
+void
+pfree(void *pointer)
+{
+	MemoryContext context;
+
+	/*
+	 * Try to detect bogus pointers handed to us, poorly though we can.
+	 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
+	 * allocated chunk.
+	 */
+	Assert(pointer != NULL);
+	Assert(pointer == (void *) MAXALIGN(pointer));
+
+	/*
+	 * OK, it's probably safe to look at the chunk header.
+	 */
+	context = ((StandardChunkHeader *)
+			   ((char *) pointer - STANDARDCHUNKHEADERSIZE))->context;
+
+	AssertArg(MemoryContextIsValid(context));
+
+	(*context->methods->free_p) (context, pointer);
+	VALGRIND_MEMPOOL_FREE(context, pointer);
+}
+
+/*
+ * repalloc
+ *		Adjust the size of a previously allocated chunk.
+ */
+void *
+repalloc(void *pointer, Size size)
+{
+	MemoryContext context;
+	void	   *ret;
+
+	if (!AllocSizeIsValid(size))
+		elog(ERROR, "invalid memory alloc request size %lu",
+			 (unsigned long) size);
+
+	/*
+	 * Try to detect bogus pointers handed to us, poorly though we can.
+	 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
+	 * allocated chunk.
+	 */
+	Assert(pointer != NULL);
+	Assert(pointer == (void *) MAXALIGN(pointer));
+
+	/*
+	 * OK, it's probably safe to look at the chunk header.
+	 */
+	context = ((StandardChunkHeader *)
+			   ((char *) pointer - STANDARDCHUNKHEADERSIZE))->context;
+
+	AssertArg(MemoryContextIsValid(context));
+
+	/* isReset must be false already */
+	Assert(!context->isReset);
+
+	ret = (*context->methods->realloc) (context, pointer, size);
+	VALGRIND_MEMPOOL_CHANGE(context, pointer, ret, size);
+
+	return ret;
+}
+
+/*
+ * MemoryContextAllocHuge
+ *		Allocate (possibly-expansive) space within the specified context.
+ *
+ * See considerations in comment at MaxAllocHugeSize.
+ */
+void *
+MemoryContextAllocHuge(MemoryContext context, Size size)
+{
+	void	   *ret;
+
+	AssertArg(MemoryContextIsValid(context));
+
+	if (!AllocHugeSizeIsValid(size))
+		elog(ERROR, "invalid memory alloc request size %lu",
+			 (unsigned long) size);
+
+	context->isReset = false;
+
+	ret = (*context->methods->alloc) (context, size);
+	VALGRIND_MEMPOOL_ALLOC(context, ret, size);
+
+	return ret;
+}
+
+/*
+ * repalloc_huge
+ *		Adjust the size of a previously allocated chunk, permitting a large
+ *		value.  The previous allocation need not have been "huge".
+ */
+void *
+repalloc_huge(void *pointer, Size size)
+{
+	MemoryContext context;
+	void	   *ret;
+
+	if (!AllocHugeSizeIsValid(size))
+		elog(ERROR, "invalid memory alloc request size %lu",
+			 (unsigned long) size);
+
+	/*
+	 * Try to detect bogus pointers handed to us, poorly though we can.
+	 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
+	 * allocated chunk.
+	 */
+	Assert(pointer != NULL);
+	Assert(pointer == (void *) MAXALIGN(pointer));
+
+	/*
+	 * OK, it's probably safe to look at the chunk header.
+	 */
+	context = ((StandardChunkHeader *)
+			   ((char *) pointer - STANDARDCHUNKHEADERSIZE))->context;
+
+	AssertArg(MemoryContextIsValid(context));
+
+	/* isReset must be false already */
+	Assert(!context->isReset);
+
+	ret = (*context->methods->realloc) (context, pointer, size);
+	VALGRIND_MEMPOOL_CHANGE(context, pointer, ret, size);
+
+	return ret;
+}
+
+/*
+ * MemoryContextStrdup
+ *		Like strdup(), but allocate from the specified context
+ */
+char *
+MemoryContextStrdup(MemoryContext context, const char *string)
+{
+	char	   *nstr;
+	Size		len = strlen(string) + 1;
+
+	nstr = (char *) MemoryContextAlloc(context, len);
+
+	memcpy(nstr, string, len);
+
+	return nstr;
+}
+
+char *
+pstrdup(const char *in)
+{
+	return MemoryContextStrdup(CurrentMemoryContext, in);
+}
+
+/*
+ * pnstrdup
+ *		Like pstrdup(), but append null byte to a
+ *		not-necessarily-null-terminated input string.
+ */
+char *
+pnstrdup(const char *in, Size len)
+{
+	char	   *out = palloc(len + 1);
+
+	memcpy(out, in, len);
+	out[len] = '\0';
+	return out;
+}
diff --git a/src/utils/pool_ip.c b/src/utils/pool_ip.c
index 7434133..e145005 100644
--- a/src/utils/pool_ip.c
+++ b/src/utils/pool_ip.c
@@ -163,15 +163,24 @@ getnameinfo_all(const struct sockaddr_storage * addr, int salen,
 	int			rc;
 
 	if (addr && addr->ss_family == AF_UNIX)
+	{
 		rc = getnameinfo_unix((const struct sockaddr_un *) addr, salen,
 							  node, nodelen,
 							  service, servicelen,
 							  flags);
+		printf("***** getnameinfo_unix() AF_UNIX\n");
+	}
 	else
+	{
 		rc = getnameinfo((const struct sockaddr *) addr, salen,
 						 node, nodelen,
 						 service, servicelen,
 						 flags);
+		printf("***** getnameinfo() OTHERS\n");
+
+	}
+			
+	printf("***** addr->ss_family = %u\n",(unsigned )addr->ss_family);
 
 	if (rc != 0)
 	{
diff --git a/src/utils/pool_process_reporting.c b/src/utils/pool_process_reporting.c
index b81334a..da8f19a 100644
--- a/src/utils/pool_process_reporting.c
+++ b/src/utils/pool_process_reporting.c
@@ -145,11 +145,11 @@ POOL_REPORT_CONFIG* get_config(int *nrows)
  */
 #define MAXITEMS (256 + MAX_NUM_BACKENDS*4)		
 
-	POOL_REPORT_CONFIG* status = malloc(MAXITEMS * sizeof(POOL_REPORT_CONFIG));
+	POOL_REPORT_CONFIG* status = palloc0(MAXITEMS * sizeof(POOL_REPORT_CONFIG));
 
 	/* we initialize the array with NULL values so when looping
 	 * on it, we can use it as stop condition */
-	memset(status, 0, sizeof(POOL_REPORT_CONFIG) * MAXITEMS);
+//	memset(status, 0, sizeof(POOL_REPORT_CONFIG) * MAXITEMS);
 
 	i = 0;
 
@@ -995,7 +995,7 @@ void config_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend)
 
 	send_complete_and_ready(frontend, backend, nrows);
 
-	free(status);
+	pfree(status);
 }
 
 POOL_REPORT_NODES* get_nodes(int *nrows)
@@ -1148,7 +1148,7 @@ POOL_REPORT_POOLS* get_pools(int *nrows)
 
     int lines = 0;
 
-    POOL_REPORT_POOLS* pools = malloc(
+    POOL_REPORT_POOLS* pools = palloc(
 		pool_config->num_init_children * pool_config->max_pool * NUM_BACKENDS * sizeof(POOL_REPORT_POOLS)
 		);
 
@@ -1336,7 +1336,7 @@ void pools_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend)
 
 	send_complete_and_ready(frontend, backend, nrows);
 
-	free(pools);
+	pfree(pools);
 }
 
 POOL_REPORT_PROCESSES* get_processes(int *nrows)
diff --git a/src/utils/pool_shmem.c b/src/utils/pool_shmem.c
index c2c5df7..144af98 100644
--- a/src/utils/pool_shmem.c
+++ b/src/utils/pool_shmem.c
@@ -5,7 +5,7 @@
  * pgpool: a language independent connection pool server for PostgreSQL
  * written by Tatsuo Ishii
  *
- * Portions Copyright (c) 2003-2013, PgPool Global Development Group
+ * Portions Copyright (c) 2003-2011, PgPool Global Development Group
  * Portions Copyright (c) 2003-2004, PostgreSQL Global Development Group
  *
  * Permission to use, copy, modify, and distribute this software and
@@ -21,7 +21,7 @@
  *
  */
 #include "pool.h"
-
+#include "utils/elog.h"
 #include <errno.h>
 #include <string.h>
 #include <sys/shm.h>
@@ -35,18 +35,6 @@
 #define PG_SHMAT_FLAGS			0
 #endif
 
-
-#define MAX_ON_EXITS 64
-
-static struct ONEXIT
-{
-	void		(*function) (int code, Datum arg);
-	Datum		arg;
-}	on_shmem_exit_list[MAX_ON_EXITS];
-
-static int	on_shmem_exit_index;
-
-
 static void IpcMemoryDetach(int status, Datum shmaddr);
 static void IpcMemoryDelete(int status, Datum shmId);
 
@@ -65,11 +53,9 @@ pool_shared_memory_create(size_t size)
 	shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | IPC_EXCL | IPCProtection);
 
 	if (shmid < 0)
-	{
-		pool_error("could not create shared memory segment: %s",
-				   strerror(errno));
-		return NULL;
-	}
+		ereport(FATAL,
+			(errmsg("could not create shared memory for request size: %ld",size),
+				errdetail("shared memory creation failed with error \"%s\"",strerror(errno))));
 
 	/* Register on-exit routine to delete the new segment */
 	on_shmem_exit(IpcMemoryDelete, shmid);
@@ -78,10 +64,10 @@ pool_shared_memory_create(size_t size)
 	memAddress = shmat(shmid, NULL, PG_SHMAT_FLAGS);
 
 	if (memAddress == (void *) -1)
-	{
-		pool_error("shmat(id=%d) failed: %s", shmid, strerror(errno));
-		return NULL;
-	}
+		ereport(FATAL,
+			(errmsg("could not create shared memory for request size: %ld",size),
+				errdetail("attach to shared memory [id:%d] failed with reason: \"%s\"",shmid,strerror(errno))));
+
 
 	/* Register on-exit routine to detach new segment before deleting */
 	on_shmem_exit(IpcMemoryDetach, (Datum) memAddress);
@@ -130,56 +116,3 @@ pool_shmem_exit(int code)
 	/* Close syslog connection here as this function is always called on exit */
 	closelog();
 }
-
-/*
- * Run all of the on_shmem_exit routines --- but don't actually exit.  This
- * is used by the postmaster to re-initialize shared memory and semaphores
- * after a backend dies horribly.
- */
-void
-shmem_exit(int code)
-{
-	pool_debug("shmem_exit(%d)", code);
-
-	/*
-	 * Call all the registered callbacks.
-	 *
-	 * As with proc_exit(), we remove each callback from the list before
-	 * calling it, to avoid infinite loop in case of error.
-	 */
-	while (--on_shmem_exit_index >= 0)
-		(*on_shmem_exit_list[on_shmem_exit_index].function) (code,
-								on_shmem_exit_list[on_shmem_exit_index].arg);
-
-	on_shmem_exit_index = 0;
-}
-
-/*
- * This function adds a callback function to the list of functions invoked
- * by shmem_exit().
- */
-void
-on_shmem_exit(void (*function) (int code, Datum arg), Datum arg)
-{
-	if (on_shmem_exit_index >= MAX_ON_EXITS)
-		pool_error("out of on_shmem_exit slots");
-	else
-	{
-		on_shmem_exit_list[on_shmem_exit_index].function = function;
-		on_shmem_exit_list[on_shmem_exit_index].arg = arg;
-
-		++on_shmem_exit_index;
-	}
-}
-
-/*
- * This function clears all on_proc_exit() and on_shmem_exit() registered
- * functions.  This is used just after forking a backend, so that the
- * backend doesn't believe it should call the postmaster's on-exit routines
- * when it exits...
- */
-void
-on_exit_reset(void)
-{
-	on_shmem_exit_index = 0;
-}
diff --git a/src/utils/pool_stream.c b/src/utils/pool_stream.c
index 10de762..d864929 100644
--- a/src/utils/pool_stream.c
+++ b/src/utils/pool_stream.c
@@ -39,6 +39,7 @@
 #endif
 
 #include "pool.h"
+#include "utils/elog.h"
 #include "utils/pool_stream.h"
 #include "pool_config.h"
 
@@ -99,6 +100,7 @@ POOL_CONNECTION *pool_open(int fd)
 */
 void pool_close(POOL_CONNECTION *cp)
 {
+	
 	/*
 	 * shutdown connection to the client so that pgpool is not blocked
 	 */
@@ -119,6 +121,16 @@ void pool_close(POOL_CONNECTION *cp)
 	free(cp);
 }
 
+void pool_read_with_error(POOL_CONNECTION *cp, void *buf, int len,
+                          const char* err_context )
+{
+	if (pool_read(cp, buf, len) < 0)
+	{
+        ereport(ERROR,
+                (errmsg("failed to read data of length %d from DB node: %d",len,cp->db_node_id),
+                 errdetail("error occurred when reading: %s",err_context?err_context:"")));
+	}
+}
 /*
 * read len bytes from cp
 * returns 0 on success otherwise -1.
diff --git a/src/watchdog/Makefile.in b/src/watchdog/Makefile.in
index 0c144d9..27f116f 100644
--- a/src/watchdog/Makefile.in
+++ b/src/watchdog/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -253,7 +253,7 @@ $(am__aclocal_m4_deps):
 
 clean-noinstLIBRARIES:
 	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
-lib-watchdog.a: $(lib_watchdog_a_OBJECTS) $(lib_watchdog_a_DEPENDENCIES) 
+lib-watchdog.a: $(lib_watchdog_a_OBJECTS) $(lib_watchdog_a_DEPENDENCIES) $(EXTRA_lib_watchdog_a_DEPENDENCIES) 
 	-rm -f lib-watchdog.a
 	$(lib_watchdog_a_AR) lib-watchdog.a $(lib_watchdog_a_OBJECTS) $(lib_watchdog_a_LIBADD)
 	$(RANLIB) lib-watchdog.a
@@ -398,10 +398,15 @@ install-am: all-am
 
 installcheck: installcheck-am
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
diff --git a/src/watchdog/watchdog.c b/src/watchdog/watchdog.c
index c858910..55dacd5 100644
--- a/src/watchdog/watchdog.c
+++ b/src/watchdog/watchdog.c
@@ -34,6 +34,7 @@
 #include <errno.h>
 
 #include "pool.h"
+#include "utils/elog.h"
 #include "pool_config.h"
 #include "watchdog/watchdog.h"
 #include "watchdog/wd_ext.h"
@@ -123,10 +124,8 @@ wd_main(int fork_wait_time)
 	/* check pool_config data */
 	status = wd_check_config();
 	if (status != WD_OK)
-	{
-		pool_error("watchdog: wd_check_config failed");
-		return 0;
-	}
+		ereport(FATAL,
+			(errmsg("watchdog: wd_check_config failed")));
 
 	/* initialize */
 	status = wd_init();


More information about the pgpool-hackers mailing list