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 +#include +#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 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 +#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/main/pgpool_main.c b/src/main/pgpool_main.c new file mode 100644 index 0000000..8adb4e7 --- /dev/null +++ b/src/main/pgpool_main.c @@ -0,0 +1,2383 @@ +/* -*-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 +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_SELECT_H +#include +#endif +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#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 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 int health_check(void); +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; + int retrycnt; + int sys_retrycnt; + bool retrying; + MemoryContext MainLoopMemoryContext; + + sigjmp_buf local_sigjmp_buf; + + /* Set the process type variable */ + processType = PT_MAIN; + + /* + * 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;inum_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 */ + retrying = false; + + /* 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(); + } + /* We can now handle ereport(ERROR) */ + PG_exception_stack = &local_sigjmp_buf; + + /* This is the main loop */ + 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; + unsigned int max_retries; + + /* rest per iteration memory context */ + MemoryContextSwitchTo(MainLoopMemoryContext); + MemoryContextResetAndDeleteChildren(MainLoopMemoryContext); + + if (retrycnt == 0) + 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; + 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 || health_check_timer_expired)) + { + if(sts > 0 ) /* Backend connection failed */ + { + sts--; + retrycnt++; + pool_signal(SIGALRM, SIG_IGN); /* Cancel timer */ + CLEAR_ALARM; + + max_retries = pool_config->parallel_mode?NUM_BACKENDS:pool_config->health_check_max_retries; + + if (!pool_config->parallel_mode && POOL_DISALLOW_TO_FAILOVER(BACKEND_INFO(sts).flag)) + { + ereport(LOG, + (errmsg("health_check: %d failover is canceled because failover is disallowed", sts))); + } + if (retrycnt > max_retries) + { + /* retry count over */ + ereport(LOG, + (errmsg("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(); + if (pool_config->parallel_mode) + retrycnt = 0; + retrying = false; + } + else + { + /* continue to retry */ + if (pool_config->parallel_mode) + sleep_time = pool_config->health_check_period/NUM_BACKENDS; + else + sleep_time = pool_config->health_check_retry_delay; + + ereport(DEBUG2, + (errmsg("retry sleep time: %d seconds", sleep_time))); + + pool_sleep(sleep_time); + continue; + } + } + + if (sys_sts < 0) /* SystemDB is down */ + { + sys_retrycnt++; + + pool_signal(SIGALRM, SIG_IGN); + CLEAR_ALARM; + + if (sys_retrycnt > NUM_BACKENDS) + { + ereport(LOG, + (errmsg("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) + { + ereport(LOG, + (errmsg("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 /* Health Check is not enable and we have not much to do */ + { + for (;;) + { + int r; + struct timeval t = {3, 0}; + + POOL_SETMASK(&UnBlockSig); + r = pool_pause(&t); + POOL_SETMASK(&BlockSig); + if (r > 0) + break; + } + } + } +} + +/* + * 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)))); +// myexit(1); + } + 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;ibackend_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 >= 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); + 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;inum_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;inum_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;ibackend_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) + { + ereport(DEBUG1, + (errmsg("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); + + ereport(DEBUG1, + (errmsg("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; +} + +/* + * 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;inum_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; +} + +/* + * 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(¤t_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(¤t_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;ibackend_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) +{ + 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;ikind = 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/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 +#include +#include +#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/utils/error/elog.c b/src/utils/error/elog.c new file mode 100644 index 0000000..dc457e3 --- /dev/null +++ b/src/utils/error/elog.c @@ -0,0 +1,2438 @@ +/*------------------------------------------------------------------------- + * + * 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 +#include +#include +#include +#include +#ifdef HAVE_SYSLOG +#include +#endif +#include +#include +#include +#include +#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 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 +#include +/* 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<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 +#include +#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/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@context/$(DEPDIR)/pool_query_context.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@context/$(DEPDIR)/pool_session_context.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@main/$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@main/$(DEPDIR)/pgpool_main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@main/$(DEPDIR)/pool_globals.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@parallel_query/$(DEPDIR)/pool_rewrite_outfuncs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@parallel_query/$(DEPDIR)/pool_rewrite_query.Po@am__quote@ @@ -748,6 +785,9 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/pool_stream.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/ps_status.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/strlcpy.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@utils/error/$(DEPDIR)/elog.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@utils/mmgr/$(DEPDIR)/aset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@utils/mmgr/$(DEPDIR)/mcxt.Po@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 bda08aa..02bf225 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 #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;iinfo[i]:%p pid:%u", &cp->info[i], ntohl(pid)); @@ -366,8 +392,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; @@ -387,7 +414,11 @@ from pool_read_message_length and recheck the pg_hba.conf settings."); strncpy(cp->info->user, sp->user, sizeof(cp->info->user) - 1); cp->info->counter = 1; #endif - 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 frontedn"))); + 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 #include @@ -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 #include @@ -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 cf15282..8e0656d 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); @@ -935,6 +942,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..7b785be 100644 --- a/src/context/pool_session_context.c +++ b/src/context/pool_session_context.c @@ -25,6 +25,8 @@ #include #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 rething 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 #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..c7da1fe 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 #include #include @@ -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,16 @@ 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; + 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 +549,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 +562,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 +577,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); @@ -633,4 +651,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 #include #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 +#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/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/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 8e78c50..3cfaf80 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 -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_SELECT_H -#include -#endif - -#include -#include #include - -#include - -#include -#include +#include #include -#include -#include -#include #ifdef HAVE_GETOPT_H #include @@ -54,158 +31,41 @@ #include "utils/getopt_long.h" #endif +#include +#include #include +#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;ikind = 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;inum_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) { @@ -1021,1930 +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;ibackend_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 >= 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); - 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;inum_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;inum_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;ibackend_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;inum_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(¤t_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(¤t_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_config_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;ibackend_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/pool_globals.c b/src/main/pool_globals.c index 7da658e..6457be6 100644 --- a/src/main/pool_globals.c +++ b/src/main/pool_globals.c @@ -25,3 +25,4 @@ 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; 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 #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.@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 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aset.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/copyfuncs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elog.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gram.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keywords.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kwlookup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/makefuncs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mcxt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nodes.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/outfuncs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_memory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_string.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scansup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snprintf.Po@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 +@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 +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/mcxt.Tpo $(DEPDIR)/mcxt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/src/utils/mmgr/mcxt.c' object='mcxt.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@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 +@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` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/mcxt.Tpo $(DEPDIR)/mcxt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/src/utils/mmgr/mcxt.c' object='mcxt.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@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 +@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 +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/aset.Tpo $(DEPDIR)/aset.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/src/utils/mmgr/aset.c' object='aset.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@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 +@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` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/aset.Tpo $(DEPDIR)/aset.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/src/utils/mmgr/aset.c' object='aset.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@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 +@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 +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/elog.Tpo $(DEPDIR)/elog.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/src/utils/error/elog.c' object='elog.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@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 +@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` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/elog.Tpo $(DEPDIR)/elog.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/src/utils/error/elog.c' object='elog.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@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 #include -#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 . */ + 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 -#include -#include -#include -#include - -#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 +#include +#include +#include +#include + +#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 /* 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 /* 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 - - 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 #include #include @@ -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 -#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 #include 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 #include - -#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 #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 -#include -#include - -#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 #include -#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 #include 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 #include #include -#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 #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 -#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 #include #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/protocol/child.c b/src/protocol/child.c index 934712c..67d0607 100644 --- a/src/protocol/child.c +++ b/src/protocol/child.c @@ -37,7 +37,6 @@ #endif #include - #include #include #include @@ -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,137 +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); - 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); /* @@ -360,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); @@ -389,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); } @@ -399,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 @@ -461,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); @@ -745,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); @@ -818,58 +767,27 @@ 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; - } + ereport(ERROR, + (errmsg("Invalid startup packet"))); + 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; - } + ereport(ERROR, + (errmsg("Invalid startup packet"))); sp->len = len; memcpy(&protov, sp->startup_packet, sizeof(protov)); @@ -882,26 +800,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; @@ -914,28 +816,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); } /* @@ -961,32 +847,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. */ @@ -998,23 +865,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; } @@ -1038,6 +901,7 @@ static bool connect_using_existing_connection(POOL_CONNECTION *frontend, StartupPacket *sp) { int i, freed = 0; + StartupPacket *topmem_sp = NULL; /* * Save startup packet info */ @@ -1047,10 +911,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; } } @@ -1058,8 +926,6 @@ static bool connect_using_existing_connection(POOL_CONNECTION *frontend, if (pool_do_reauth(frontend, backend)) { - pool_close(frontend); - connection_count_down(); return false; } @@ -1093,8 +959,6 @@ static bool connect_using_existing_connection(POOL_CONNECTION *frontend, if (send_params(frontend, backend)) { - pool_close(frontend); - connection_count_down(); return false; } } @@ -1115,8 +979,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; @@ -1208,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 */ @@ -1219,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;idb_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; } @@ -1344,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 @@ -1410,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; } @@ -1425,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; } @@ -2047,3 +1967,507 @@ 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;iparallel_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); + 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 + * 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(); + } + + /* + * 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); +} 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 aad73ca..abef298 100644 --- a/src/protocol/pool_process_query.c +++ b/src/protocol/pool_process_query.c @@ -3481,7 +3481,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; @@ -3490,9 +3490,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) @@ -3503,7 +3503,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; @@ -3701,7 +3701,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; @@ -3868,9 +3868,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. "); @@ -3955,7 +3955,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) { diff --git a/src/protocol/pool_proto_modules.c b/src/protocol/pool_proto_modules.c index d921740..e59b0a1 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. @@ -1553,12 +1554,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:"); @@ -1580,7 +1581,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); @@ -2150,12 +2151,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); @@ -2176,7 +2177,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 { @@ -2471,7 +2472,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); @@ -2538,7 +2539,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)); @@ -2551,7 +2552,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 */ @@ -3186,7 +3187,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) @@ -3210,16 +3211,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 14346f2..b8f8fc1 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/system_db/pool_system.c b/src/system_db/pool_system.c index 3a6270e..82f01c5 100644 --- a/src/system_db/pool_system.c +++ b/src/system_db/pool_system.c @@ -25,6 +25,7 @@ #include #include #include +#include "utils/elog.h" #include "pool.h" #include "pool_config.h" @@ -657,3 +658,88 @@ 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) + { + 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; +} + +/* + * 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/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/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_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 #include #include @@ -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..ceb5d90 100644 --- a/src/utils/pool_stream.c +++ b/src/utils/pool_stream.c @@ -99,6 +99,7 @@ POOL_CONNECTION *pool_open(int fd) */ void pool_close(POOL_CONNECTION *cp) { + /* * shutdown connection to the client so that pgpool is not blocked */ 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 1cb5f2b..0d40de7 100644 --- a/src/watchdog/watchdog.c +++ b/src/watchdog/watchdog.c @@ -34,6 +34,7 @@ #include #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();