summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/access/gtm.h33
-rw-r--r--src/include/access/transam.h6
-rw-r--r--src/include/access/xact.h8
-rw-r--r--src/include/bootstrap/bootstrap.h4
-rw-r--r--src/include/catalog/dependency.h4
-rw-r--r--src/include/catalog/heap.h8
-rw-r--r--src/include/catalog/indexing.h6
-rw-r--r--src/include/catalog/pgxc_class.h39
-rw-r--r--src/include/gtm/assert.h72
-rw-r--r--src/include/gtm/elog.h253
-rw-r--r--src/include/gtm/gtm.h140
-rw-r--r--src/include/gtm/gtm_c.h101
-rw-r--r--src/include/gtm/gtm_client.h129
-rw-r--r--src/include/gtm/gtm_conn.h38
-rw-r--r--src/include/gtm/gtm_ext.h31
-rw-r--r--src/include/gtm/gtm_ip.h50
-rw-r--r--src/include/gtm/gtm_list.h280
-rw-r--r--src/include/gtm/gtm_lock.h59
-rw-r--r--src/include/gtm/gtm_msg.h88
-rw-r--r--src/include/gtm/gtm_proxy.h221
-rw-r--r--src/include/gtm/gtm_seq.h75
-rw-r--r--src/include/gtm/gtm_txn.h235
-rw-r--r--src/include/gtm/ip.h50
-rw-r--r--src/include/gtm/libpq-be.h86
-rw-r--r--src/include/gtm/libpq-fe.h138
-rw-r--r--src/include/gtm/libpq-int.h129
-rw-r--r--src/include/gtm/libpq.h47
-rw-r--r--src/include/gtm/memnodes.h79
-rw-r--r--src/include/gtm/memutils.h123
-rw-r--r--src/include/gtm/palloc.h90
-rw-r--r--src/include/gtm/path.h16
-rw-r--r--src/include/gtm/pqcomm.h57
-rw-r--r--src/include/gtm/pqexpbuffer.h181
-rw-r--r--src/include/gtm/pqformat.h48
-rw-r--r--src/include/gtm/pqsignal.h49
-rw-r--r--src/include/gtm/stringinfo.h149
-rw-r--r--src/include/nodes/nodes.h5
-rw-r--r--src/include/nodes/parsenodes.h17
-rw-r--r--src/include/nodes/primnodes.h27
-rw-r--r--src/include/parser/kwlist.h19
-rw-r--r--src/include/parser/parse_utilcmd.h4
-rw-r--r--src/include/pgxc/combiner.h63
-rw-r--r--src/include/pgxc/datanode.h76
-rw-r--r--src/include/pgxc/locator.h66
-rw-r--r--src/include/pgxc/pgxc.h23
-rw-r--r--src/include/pgxc/planner.h86
-rw-r--r--src/include/pgxc/poolcomm.h49
-rw-r--r--src/include/pgxc/poolmgr.h130
-rw-r--r--src/include/postgres.h4
-rw-r--r--src/include/postmaster/autovacuum.h5
-rw-r--r--src/include/storage/proc.h3
-rw-r--r--src/include/storage/procarray.h5
-rw-r--r--src/include/utils/guc_tables.h4
-rw-r--r--src/include/utils/rel.h7
-rw-r--r--src/include/utils/snapshot.h5
-rw-r--r--src/include/utils/syscache.h4
56 files changed, 3721 insertions, 3 deletions
diff --git a/src/include/access/gtm.h b/src/include/access/gtm.h
new file mode 100644
index 0000000000..66ca3f12c6
--- /dev/null
+++ b/src/include/access/gtm.h
@@ -0,0 +1,33 @@
+/*-------------------------------------------------------------------------
+ *
+ * gtm.h
+ *
+ * Module interfacing with GTM definitions
+ *
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef ACCESS_GTM_H
+#define ACCESS_GTM_H
+
+#include "gtm/gtm_c.h"
+
+/* Configuration variables */
+extern char *GtmHost;
+extern int GtmPort;
+extern int GtmCoordinatorId;
+
+extern bool IsGTMConnected(void);
+extern void InitGTM(void);
+extern void CloseGTM(void);
+extern GlobalTransactionId BeginTranGTM(void);
+extern GlobalTransactionId BeginTranAutovacuumGTM(void);
+extern int CommitTranGTM(GlobalTransactionId gxid);
+extern int RollbackTranGTM(GlobalTransactionId gxid);
+extern GTM_Snapshot GetSnapshotGTM(GlobalTransactionId gxid, bool canbe_grouped);
+extern GTM_Sequence GetNextValGTM(char *seqname);
+extern int CreateSequenceGTM(char *seqname, GTM_Sequence increment,
+ GTM_Sequence minval, GTM_Sequence maxval, GTM_Sequence startval,
+ bool cycle);
+extern int DropSequenceGTM(char *seqname);
+#endif /* ACCESS_GTM_H */
diff --git a/src/include/access/transam.h b/src/include/access/transam.h
index b23a663c53..a7a8230595 100644
--- a/src/include/access/transam.h
+++ b/src/include/access/transam.h
@@ -6,6 +6,7 @@
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
*
* $PostgreSQL: pgsql/src/include/access/transam.h,v 1.68 2009/05/08 03:21:35 momjian Exp $
*
@@ -152,6 +153,11 @@ extern TransactionId TransactionIdLatest(TransactionId mainxid,
extern XLogRecPtr TransactionIdGetCommitLSN(TransactionId xid);
/* in transam/varsup.c */
+#ifdef PGXC /* PGXC_DATANODE */
+extern void SetNextTransactionId(TransactionId xid);
+extern void SetForceXidFromGTM(bool value);
+extern bool GetForceXidFromGTM(void);
+#endif /* PGXC */
extern TransactionId GetNewTransactionId(bool isSubXact);
extern TransactionId ReadNewTransactionId(void);
extern void SetTransactionIdLimit(TransactionId oldest_datfrozenxid,
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index 880b41b707..7cd8e165ec 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -6,6 +6,7 @@
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
*
* $PostgreSQL: pgsql/src/include/access/xact.h,v 1.98 2009/06/11 14:49:09 momjian Exp $
*
@@ -18,7 +19,9 @@
#include "nodes/pg_list.h"
#include "storage/relfilenode.h"
#include "utils/timestamp.h"
-
+#ifdef PGXC /* PGXC_COORD */
+#include "gtm/gtm_c.h"
+#endif
/*
* Xact isolation levels
@@ -145,6 +148,9 @@ extern TransactionId GetTopTransactionId(void);
extern TransactionId GetTopTransactionIdIfAny(void);
extern TransactionId GetCurrentTransactionId(void);
extern TransactionId GetCurrentTransactionIdIfAny(void);
+#ifdef PGXC /* PGXC_COORD */
+extern GlobalTransactionId GetCurrentGlobalTransactionId(void);
+#endif
extern SubTransactionId GetCurrentSubTransactionId(void);
extern CommandId GetCurrentCommandId(bool used);
extern TimestampTz GetCurrentTransactionStartTimestamp(void);
diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h
index ab549eabb1..e8f96604ad 100644
--- a/src/include/bootstrap/bootstrap.h
+++ b/src/include/bootstrap/bootstrap.h
@@ -6,6 +6,7 @@
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
*
* $PostgreSQL: pgsql/src/include/bootstrap/bootstrap.h,v 1.51 2009/01/01 17:23:56 momjian Exp $
*
@@ -71,6 +72,9 @@ typedef enum
StartupProcess,
BgWriterProcess,
WalWriterProcess
+#ifdef PGXC
+ ,PoolerProcess
+#endif
} AuxProcType;
#endif /* BOOTSTRAP_H */
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
index fe04aab964..b2af292585 100644
--- a/src/include/catalog/dependency.h
+++ b/src/include/catalog/dependency.h
@@ -6,6 +6,7 @@
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
*
* $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.40 2009/06/11 14:49:09 momjian Exp $
*
@@ -146,6 +147,9 @@ typedef enum ObjectClass
OCLASS_FDW, /* pg_foreign_data_wrapper */
OCLASS_FOREIGN_SERVER, /* pg_foreign_server */
OCLASS_USER_MAPPING, /* pg_user_mapping */
+#ifdef PGXC
+ OCLASS_PGXC_CLASS, /* pgxc_class */
+#endif
MAX_OCLASS /* MUST BE LAST */
} ObjectClass;
diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h
index 2d6eb3c34a..baa9ecaf49 100644
--- a/src/include/catalog/heap.h
+++ b/src/include/catalog/heap.h
@@ -6,6 +6,7 @@
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
*
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.91 2009/06/11 14:49:09 momjian Exp $
*
@@ -107,4 +108,11 @@ extern void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind);
extern void CheckAttributeType(const char *attname, Oid atttypid);
+#ifdef PGXC
+extern void AddRelationDistribution (Oid relid,
+ DistributeBy *distributeby,
+ List *parentOids,
+ TupleDesc descriptor);
+#endif
+
#endif /* HEAP_H */
diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h
index ce117a8eec..5557021e30 100644
--- a/src/include/catalog/indexing.h
+++ b/src/include/catalog/indexing.h
@@ -7,6 +7,7 @@
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
*
* $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.108 2009/06/11 14:49:09 momjian Exp $
*
@@ -267,6 +268,11 @@ DECLARE_UNIQUE_INDEX(pg_user_mapping_oid_index, 174, on pg_user_mapping using bt
DECLARE_UNIQUE_INDEX(pg_user_mapping_user_server_index, 175, on pg_user_mapping using btree(umuser oid_ops, umserver oid_ops));
#define UserMappingUserServerIndexId 175
+#ifdef PGXC
+DECLARE_UNIQUE_INDEX(pgxc_class_pcrelid_index, 9002, on pgxc_class using btree(pcrelid oid_ops));
+#define PgxcClassPgxcRelIdIndexId 9002
+#endif
+
/* last step of initialization script: build the indexes declared above */
BUILD_INDICES
diff --git a/src/include/catalog/pgxc_class.h b/src/include/catalog/pgxc_class.h
new file mode 100644
index 0000000000..2104e53e42
--- /dev/null
+++ b/src/include/catalog/pgxc_class.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2004-2007 EnterpriseDB Corporation. All Rights Reserved.
+ */
+#ifndef PGXC_CLASS_H
+#define PGXC_CLASS_H
+
+#include "nodes/parsenodes.h"
+
+#define PgxcClassRelationId 9001
+
+CATALOG(pgxc_class,9001) BKI_WITHOUT_OIDS
+{
+ Oid pcrelid;
+ char pclocatortype;
+ int2 pcattnum;
+ int2 pchashalgorithm;
+ int2 pchashbuckets;
+} FormData_pgxc_class;
+
+typedef FormData_pgxc_class *Form_pgxc_class;
+
+#define Natts_pgxc_class 5
+
+#define Anum_pgxc_class_pcrelid 1
+#define Anum_pgxc_class_pclocatortype 2
+#define Anum_pgxc_class_pcattnum 3
+#define Anum_pgxc_class_pchashalgorithm 4
+#define Anum_pgxc_class_pchashbuckets 5
+
+extern void PgxcClassCreate(Oid pcrelid,
+ char pclocatortype,
+ int pcattnum,
+ int pchashalgorithm,
+ int pchashbuckets);
+
+extern void RemovePgxcClass(Oid pcrelid);
+
+#endif /* PGXC_CLASS_H */
+
diff --git a/src/include/gtm/assert.h b/src/include/gtm/assert.h
new file mode 100644
index 0000000000..5c71363832
--- /dev/null
+++ b/src/include/gtm/assert.h
@@ -0,0 +1,72 @@
+/*-------------------------------------------------------------------------
+ *
+ * assert.h
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL$
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef GTM_ASSERT_H
+#define GTM_ASSERT_H
+
+extern bool assert_enabled;
+
+/*
+ * 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
+ */
+
+/*
+ * 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__))))
+
+#ifndef USE_ASSERT_CHECKING
+#define Assert(condition)
+#define AssertMacro(condition) ((void)true)
+#define AssertArg(condition)
+#define AssertState(condition)
+#else
+#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 */
+
+extern int ExceptionalCondition(const char *conditionName,
+ const char *errorType,
+ const char *fileName, int lineNumber);
+
+#endif
diff --git a/src/include/gtm/elog.h b/src/include/gtm/elog.h
new file mode 100644
index 0000000000..49c463fa3e
--- /dev/null
+++ b/src/include/gtm/elog.h
@@ -0,0 +1,253 @@
+/*-------------------------------------------------------------------------
+ *
+ * elog.h
+ * POSTGRES error reporting/logging definitions.
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.98 2009/01/01 17:24:02 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef ELOG_H
+#define ELOG_H
+
+/* 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 */
+#define ERROR2 21 /* user error - only send error message to the
+ * client */
+#define FATAL 22 /* fatal error - abort process */
+#define PANIC 23 /* 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
+
+/*
+ * 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 */
+ 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 */
+ 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 */
+ int saved_errno; /* errno at entry */
+} ErrorData;
+
+
+/*----------
+ * 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.
+ *----------
+ */
+#define TEXTDOMAIN "GTM"
+
+#define ereport_domain(elevel, domain, rest) \
+ (errstart(elevel, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain) ? \
+ (errfinish rest) : (void) 0)
+
+#define ereport(level, rest) \
+ ereport_domain(level, TEXTDOMAIN, rest)
+
+
+#define PG_RE_THROW() pg_re_throw()
+
+extern bool errstart(int elevel, const char *filename, int lineno,
+ const char *funcname, const char *domain);
+extern void errfinish(int dummy,...);
+
+extern int
+errmsg(const char *fmt,...)
+/* This extension allows gcc to check the format string for consistency with
+ the supplied arguments. */
+__attribute__((format(printf, 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(printf, 1, 2)));
+
+extern int
+errdetail(const char *fmt,...)
+/* This extension allows gcc to check the format string for consistency with
+ the supplied arguments. */
+__attribute__((format(printf, 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(printf, 1, 2)));
+
+extern int
+errhint(const char *fmt,...)
+/* This extension allows gcc to check the format string for consistency with
+ the supplied arguments. */
+__attribute__((format(printf, 1, 2)));
+
+/*----------
+ * Old-style error reporting API: to be used in this way:
+ * elog(ERROR, "portal \"%s\" not found", stmt->portalname);
+ *----------
+ */
+#define elog elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO), elog_finish
+
+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(printf, 2, 3)));
+
+/*----------
+ * 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; \
+ 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; \
+
+#define PG_END_TRY() \
+ } \
+ PG_exception_stack = save_exception_stack; \
+ } while (0)
+
+int errfunction(const char *funcname);
+
+extern void EmitErrorReport(void *port);
+
+/* GUC-configurable parameters */
+
+typedef enum
+{
+ PGERROR_TERSE, /* single-line error messages */
+ PGERROR_DEFAULT, /* recommended style */
+ PGERROR_VERBOSE /* all the facts, ma'am */
+} PGErrorVerbosity;
+
+/* Log destination bitmap */
+#define LOG_DESTINATION_STDERR 1
+#define LOG_DESTINATION_SYSLOG 2
+#define LOG_DESTINATION_EVENTLOG 4
+#define LOG_DESTINATION_CSVLOG 8
+
+/* Other exported functions */
+extern void pg_re_throw(void);
+extern void DebugFileOpen(void);
+extern void FlushErrorState(void);
+
+
+/*
+ * 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(printf, 1, 2)));
+
+#endif /* ELOG_H */
diff --git a/src/include/gtm/gtm.h b/src/include/gtm/gtm.h
new file mode 100644
index 0000000000..37e23a7ffa
--- /dev/null
+++ b/src/include/gtm/gtm.h
@@ -0,0 +1,140 @@
+/*-------------------------------------------------------------------------
+ *
+ * gtm.h
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL$
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef _GTM_H
+#define _GTM_H
+
+#include <setjmp.h>
+
+#include "gtm/gtm_c.h"
+#include "gtm/palloc.h"
+#include "gtm/gtm_lock.h"
+#include "gtm/gtm_conn.h"
+#include "gtm/elog.h"
+#include "gtm/gtm_list.h"
+
+extern char *GTMLogFile;
+
+typedef enum GTM_ThreadStatus
+{
+ GTM_THREAD_STARTING,
+ GTM_THREAD_RUNNING,
+ GTM_THREAD_EXITING,
+ /* Must be the last */
+ GTM_THREAD_INVALID
+} GTM_ThreadStatus;
+
+struct GTM_ConnectionInfo;
+
+#define ERRORDATA_STACK_SIZE 5
+
+typedef struct GTM_ThreadInfo
+{
+ /*
+ * Thread specific information such as connection(s) served by it
+ */
+ GTM_ThreadID thr_id;
+ uint32 thr_localid;
+ void * (* thr_startroutine)(void *);
+
+ MemoryContext thr_thread_context;
+ MemoryContext thr_message_context;
+ MemoryContext thr_current_context;
+ MemoryContext thr_error_context;
+ MemoryContext thr_parent_context;
+
+ sigjmp_buf *thr_sigjmp_buf;
+
+ ErrorData thr_error_data[ERRORDATA_STACK_SIZE];
+ int thr_error_stack_depth;
+ int thr_error_recursion_depth;
+ int thr_criticalsec_count;
+
+ GTM_ThreadStatus thr_status;
+ GTM_ConnectionInfo *thr_conn;
+
+ GTM_RWLock thr_lock;
+ List *thr_cached_txninfo;
+
+} GTM_ThreadInfo;
+
+typedef struct GTM_Threads
+{
+ uint32 gt_thread_count;
+ uint32 gt_array_size;
+ GTM_ThreadInfo **gt_threads;
+ GTM_RWLock gt_lock;
+} GTM_Threads;
+
+extern GTM_Threads *GTMThreads;
+
+int GTM_ThreadAdd(GTM_ThreadInfo *thrinfo);
+int GTM_ThreadRemove(GTM_ThreadInfo *thrinfo);
+int GTM_ThreadJoin(GTM_ThreadInfo *thrinfo);
+void GTM_ThreadExit(void);
+void ConnFree(Port *port);
+
+GTM_ThreadInfo *GTM_ThreadCreate(GTM_ConnectionInfo *conninfo,
+ void *(* startroutine)(void *));
+GTM_ThreadInfo * GTM_GetThreadInfo(GTM_ThreadID thrid);
+
+/*
+ * pthread keys to get thread specific information
+ */
+extern pthread_key_t threadinfo_key;
+extern MemoryContext TopMostMemoryContext;
+
+#define SetMyThreadInfo(thrinfo) pthread_setspecific(threadinfo_key, (thrinfo))
+#define GetMyThreadInfo ((GTM_ThreadInfo *)pthread_getspecific(threadinfo_key))
+
+#define TopMemoryContext (GetMyThreadInfo->thr_thread_context)
+#define ThreadTopContext (GetMyThreadInfo->thr_thread_context)
+#define MessageContext (GetMyThreadInfo->thr_message_context)
+#define CurrentMemoryContext (GetMyThreadInfo->thr_current_context)
+#define ErrorContext (GetMyThreadInfo->thr_error_context)
+#define errordata (GetMyThreadInfo->thr_error_data)
+#define recursion_depth (GetMyThreadInfo->thr_error_recursion_depth)
+#define errordata_stack_depth (GetMyThreadInfo->thr_error_stack_depth)
+#define CritSectionCount (GetMyThreadInfo->thr_criticalsec_count)
+
+#define PG_exception_stack (GetMyThreadInfo->thr_sigjmp_buf)
+#define MyConnection (GetMyThreadInfo->thr_conn)
+#define MyPort ((GetMyThreadInfo->thr_conn != NULL) ? \
+ GetMyThreadInfo->thr_conn->con_port : \
+ NULL)
+#define MyThreadID (GetMyThreadInfo->thr_id)
+
+#define GTM_CachedTransInfo (GetMyThreadInfo->thr_cached_txninfo)
+#define GTM_HaveFreeCachedTransInfo() (list_length(GTM_CachedTransInfo))
+
+#define GTM_MAX_CACHED_TRANSINFO 0
+#define GTM_HaveEnoughCachedTransInfo() (list_length(GTM_CachedTransInfo) >= GTM_MAX_CACHED_TRANSINFO)
+
+#define START_CRIT_SECTION() (CritSectionCount++)
+
+#define END_CRIT_SECTION() \
+ do { \
+ Assert(CritSectionCount > 0); \
+ CritSectionCount--; \
+ } while(0)
+
+
+#if 0
+
+/* Coordinator registration */
+int GTM_RegisterCoordinator(GTM_CoordInfo *cinfo);
+int GTM_UnregisterCoordinator(GTM_CoordinatorId cid);
+
+#endif
+
+#endif
diff --git a/src/include/gtm/gtm_c.h b/src/include/gtm/gtm_c.h
new file mode 100644
index 0000000000..1a04064b6d
--- /dev/null
+++ b/src/include/gtm/gtm_c.h
@@ -0,0 +1,101 @@
+/*-------------------------------------------------------------------------
+ *
+ * c.h
+ * Fundamental C definitions. This is included by every .c file in
+ * PostgreSQL (via either postgres.h or postgres_fe.h, as appropriate).
+ *
+ * Note that the definitions here are not intended to be exposed to clients
+ * of the frontend interface libraries --- so we don't worry much about
+ * polluting the namespace with lots of stuff...
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL: pgsql/src/include/c.h,v 1.234 2009/01/01 17:23:55 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef GTM_C_H
+#define GTM_C_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdarg.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#include <sys/types.h>
+
+#include <errno.h>
+#include <pthread.h>
+#include "c.h"
+
+typedef uint32 GlobalTransactionId; /* 32-bit global transaction ids */
+typedef uint32 PGXC_NodeId;
+typedef uint32 GTM_CoordinatorId;
+typedef int16 GTMProxy_ConnID;
+
+#define InvalidGTMProxyConnID -1
+
+typedef pthread_t GTM_ThreadID;
+
+/*
+ * A unique handle to identify transaction at the GTM. It could just be
+ * an index in an array or a pointer to the structure
+ *
+ * Note: If we get rid of BEGIN transaction at the GTM, we can use GXID
+ * as a handle because we would never have a transaction state at the
+ * GTM without assigned GXID.
+ */
+typedef int32 GTM_TransactionHandle;
+
+#define InvalidTransactionHandle -1
+
+typedef int64 GTM_Sequence; /* a 64-bit sequence */
+typedef struct GTM_SequenceKeyData
+{
+ uint32 gsk_keylen;
+ char *gsk_key;
+} GTM_SequenceKeyData; /* Counter key, set by the client */
+
+typedef GTM_SequenceKeyData *GTM_SequenceKey;
+#define GTM_MAX_SEQKEY_LENGTH 1024
+
+#define InvalidSequenceValue 0x7fffffffffffffffLL
+#define SEQVAL_IS_VALID(v) ((v) != InvalidSequenceValue)
+
+#define GTM_MAX_GLOBAL_TRANSACTIONS 4096
+
+typedef enum GTM_IsolationLevel
+{
+ GTM_ISOLATION_SERIALIZABLE, /* serializable txn */
+ GTM_ISOLATION_RC /* read-committed txn */
+} GTM_IsolationLevel;
+
+typedef struct GTM_SnapshotData
+{
+ GlobalTransactionId sn_xmin;
+ GlobalTransactionId sn_xmax;
+ GlobalTransactionId sn_recent_global_xmin;
+ uint32 sn_xcnt;
+ GlobalTransactionId *sn_xip;
+} GTM_SnapshotData;
+
+typedef GTM_SnapshotData *GTM_Snapshot;
+
+typedef struct GTM_StartupPacket {
+ GTM_CoordinatorId sp_cid;
+ bool sp_isproxy;
+} GTM_StartupPacket;
+
+#define InvalidGlobalTransactionId ((GlobalTransactionId) 0)
+
+#define GlobalTransactionIdIsValid(gxid) ((GlobalTransactionId) (gxid)) != InvalidGlobalTransactionId
+
+#define _(x) gettext(x)
+
+#endif /* GTM_C_H */
diff --git a/src/include/gtm/gtm_client.h b/src/include/gtm/gtm_client.h
new file mode 100644
index 0000000000..29eeaf95f9
--- /dev/null
+++ b/src/include/gtm/gtm_client.h
@@ -0,0 +1,129 @@
+/*-------------------------------------------------------------------------
+ *
+ * gtm_client.h
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL$
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef GTM_CLIENT_H
+#define GTM_CLIENT_H
+
+#include "gtm/gtm_c.h"
+#include "gtm/gtm_msg.h"
+#include "gtm/libpq-fe.h"
+
+typedef union GTM_ResultData
+{
+ GTM_TransactionHandle grd_txnhandle; /* TXN_BEGIN */
+ GlobalTransactionId grd_gxid; /* TXN_BEGIN_GETGXID
+ * TXN_PREPARE
+ * TXN_COMMIT
+ * TXN_ROLLBACK
+ */
+
+ struct
+ {
+ GTM_TransactionHandle txnhandle;
+ GlobalTransactionId gxid;
+ } grd_txn; /* TXN_GET_GXID
+ * SNAPSHOT_GET
+ * SNAPSHOT_GXID_GET */
+
+ GTM_SequenceKeyData grd_seqkey; /* SEQUENCE_INIT
+ * SEQUENCE_RESET
+ * SEQUENCE_CLOSE */
+ struct
+ {
+ GTM_SequenceKeyData seqkey;
+ GTM_Sequence seqval;
+ } grd_seq; /* SEQUENCE_GET_CURRENT
+ SEQUENCE_GET_NEXT */
+
+ struct
+ {
+ int txn_count; /* TXN_BEGIN_GETGXID_MULTI */
+ GlobalTransactionId start_gxid;
+ } grd_txn_get_multi;
+
+ struct
+ {
+ int txn_count; /* TXN_COMMIT_MULTI */
+ int status[GTM_MAX_GLOBAL_TRANSACTIONS];
+ } grd_txn_rc_multi;
+
+ struct
+ {
+ int txn_count; /* GET_SNAPSHOT_MULTI */
+ int status[GTM_MAX_GLOBAL_TRANSACTIONS];
+ } grd_txn_snap_multi;
+
+ /*
+ * TODO
+ * TXN_GET_STATUS
+ * TXN_GET_ALL_PREPARED
+ */
+} GTM_ResultData;
+
+typedef struct GTM_Result
+{
+ GTM_ResultType gr_type;
+ int gr_msglen;
+ int gr_status;
+ GTM_ProxyMsgHeader gr_proxyhdr;
+ GTM_ResultData gr_resdata;
+ /*
+ * We keep these two items outside the union to avoid repeated malloc/free
+ * of the xip array. If these items are pushed inside the union, they may
+ * get overwritten by other members in the union
+ */
+ int gr_xip_size;
+ GTM_SnapshotData gr_snapshot;
+
+ /*
+ * Similarly, keep the buffer for proxying data outside the union
+ */
+ char *gr_proxy_data;
+ int gr_proxy_datalen;
+} GTM_Result;
+
+/*
+ * Connection Management API
+ */
+GTM_Conn *connect_gtm(const char *connect_string);
+void disconnect_gtm(GTM_Conn *conn);
+
+/*
+ * Transaction Management API
+ */
+GlobalTransactionId begin_transaction(GTM_Conn *conn, GTM_IsolationLevel isolevel);
+GlobalTransactionId begin_transaction_autovacuum(GTM_Conn *conn, GTM_IsolationLevel isolevel);
+int commit_transaction(GTM_Conn *conn, GlobalTransactionId gxid);
+int abort_transaction(GTM_Conn *conn, GlobalTransactionId gxid);
+int prepare_transaction(GTM_Conn *conn, GlobalTransactionId gxid,
+ int nodecnt, PGXC_NodeId nodes[]);
+
+/*
+ * Snapshot Management API
+ */
+GTM_SnapshotData *get_snapshot(GTM_Conn *conn, GlobalTransactionId gxid,
+ bool canbe_grouped);
+
+/*
+ * Sequence Management API
+ */
+int open_sequence(GTM_Conn *conn, GTM_SequenceKey key, GTM_Sequence increment,
+ GTM_Sequence minval, GTM_Sequence maxval,
+ GTM_Sequence startval, bool cycle);
+int close_sequence(GTM_Conn *conn, GTM_SequenceKey key);
+GTM_Sequence get_current(GTM_Conn *conn, GTM_SequenceKey key);
+GTM_Sequence get_next(GTM_Conn *conn, GTM_SequenceKey key);
+int reset_sequence(GTM_Conn *conn, GTM_SequenceKey key);
+
+
+#endif
diff --git a/src/include/gtm/gtm_conn.h b/src/include/gtm/gtm_conn.h
new file mode 100644
index 0000000000..911a345c4f
--- /dev/null
+++ b/src/include/gtm/gtm_conn.h
@@ -0,0 +1,38 @@
+/*-------------------------------------------------------------------------
+ *
+ * gtm_conn.h
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL$
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef GTM_CONN_H
+#define GTM_CONN_H
+
+#include "gtm/libpq-be.h"
+
+struct GTM_ThreadInfo;
+
+typedef struct GTM_ConnectionInfo
+{
+ /* Port contains all the vital information about this connection */
+ Port *con_port;
+ struct GTM_ThreadInfo *con_thrinfo;
+ bool con_authenticated;
+} GTM_ConnectionInfo;
+
+typedef struct GTM_Connections
+{
+ uint32 gc_conn_count;
+ uint32 gc_array_size;
+ GTM_ConnectionInfo *gc_connections;
+ GTM_RWLock gc_lock;
+} GTM_Connections;
+
+
+#endif
diff --git a/src/include/gtm/gtm_ext.h b/src/include/gtm/gtm_ext.h
new file mode 100644
index 0000000000..b492941779
--- /dev/null
+++ b/src/include/gtm/gtm_ext.h
@@ -0,0 +1,31 @@
+/*-------------------------------------------------------------------------
+ *
+ * gtm_ext.h
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL$
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef GTM_EXT_H
+#define GTM_EXT_H
+
+/*
+ * 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_MESSAGE_PRIMARY 'M'
+#define PG_DIAG_MESSAGE_DETAIL 'D'
+#define PG_DIAG_MESSAGE_HINT 'H'
+#define PG_DIAG_SOURCE_FILE 'F'
+#define PG_DIAG_SOURCE_LINE 'L'
+#define PG_DIAG_SOURCE_FUNCTION 'R'
+
+
+#endif
diff --git a/src/include/gtm/gtm_ip.h b/src/include/gtm/gtm_ip.h
new file mode 100644
index 0000000000..30da3081d3
--- /dev/null
+++ b/src/include/gtm/gtm_ip.h
@@ -0,0 +1,50 @@
+/*-------------------------------------------------------------------------
+ *
+ * ip.h
+ * Definitions for IPv6-aware network access.
+ *
+ * These definitions are used by both frontend and backend code. Be careful
+ * what you include here!
+ *
+ * Copyright (c) 2003-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL: pgsql/src/include/libpq/ip.h,v 1.20 2008/01/01 19:45:58 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef IP_H
+#define IP_H
+
+#include "gtm/pqcomm.h"
+
+
+extern int gtm_getaddrinfo_all(const char *hostname, const char *servname,
+ const struct addrinfo * hintp,
+ struct addrinfo ** result);
+extern void gtm_freeaddrinfo_all(int hint_ai_family, struct addrinfo * ai);
+
+extern int gtm_getnameinfo_all(const struct sockaddr_storage * addr, int salen,
+ char *node, int nodelen,
+ char *service, int servicelen,
+ int flags);
+
+extern int gtm_range_sockaddr(const struct sockaddr_storage * addr,
+ const struct sockaddr_storage * netaddr,
+ const struct sockaddr_storage * netmask);
+
+extern int gtm_sockaddr_cidr_mask(struct sockaddr_storage * mask,
+ char *numbits, int family);
+
+#ifdef HAVE_IPV6
+extern void gtm_promote_v4_to_v6_addr(struct sockaddr_storage * addr);
+extern void gtm_promote_v4_to_v6_mask(struct sockaddr_storage * addr);
+#endif
+
+#ifdef HAVE_UNIX_SOCKETS
+#define IS_AF_UNIX(fam) ((fam) == AF_UNIX)
+#else
+#define IS_AF_UNIX(fam) (0)
+#endif
+
+#endif /* IP_H */
diff --git a/src/include/gtm/gtm_list.h b/src/include/gtm/gtm_list.h
new file mode 100644
index 0000000000..6a5727f36a
--- /dev/null
+++ b/src/include/gtm/gtm_list.h
@@ -0,0 +1,280 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_list.h
+ * interface for PostgreSQL generic linked list package
+ *
+ * This package implements singly-linked homogeneous lists.
+ *
+ * It is important to have constant-time length, append, and prepend
+ * operations. To achieve this, we deal with two distinct data
+ * structures:
+ *
+ * 1. A set of "list cells": each cell contains a data field and
+ * a link to the next cell in the list or NULL.
+ * 2. A single structure containing metadata about the list: the
+ * type of the list, pointers to the head and tail cells, and
+ * the length of the list.
+ *
+ * We support three types of lists:
+ *
+ * T_List: lists of pointers
+ * (in practice usually pointers to Nodes, but not always;
+ * declared as "void *" to minimize casting annoyances)
+ * T_IntList: lists of integers
+ * T_OidList: lists of Oids
+ *
+ * (At the moment, ints and Oids are the same size, but they may not
+ * always be so; try to be careful to maintain the distinction.)
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL: pgsql/src/include/nodes/pg_list.h,v 1.59 2008/08/14 18:48:00 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef GTM_LIST_H
+#define GTM_LIST_H
+
+
+typedef struct ListCell ListCell;
+
+typedef struct List
+{
+ int length;
+ ListCell *head;
+ ListCell *tail;
+} List;
+
+struct ListCell
+{
+ union
+ {
+ void *ptr_value;
+ int int_value;
+ } data;
+ ListCell *next;
+};
+
+/*
+ * The *only* valid representation of an empty list is NIL; in other
+ * words, a non-NIL list is guaranteed to have length >= 1 and
+ * head/tail != NULL
+ */
+#define NIL ((List *) NULL)
+
+/*
+ * These routines are used frequently. However, we can't implement
+ * them as macros, since we want to avoid double-evaluation of macro
+ * arguments. Therefore, we implement them using GCC inline functions,
+ * and as regular functions with non-GCC compilers.
+ */
+#ifdef __GNUC__
+
+static __inline__ ListCell *
+list_head(List *l)
+{
+ return l ? l->head : NULL;
+}
+
+static __inline__ ListCell *
+list_tail(List *l)
+{
+ return l ? l->tail : NULL;
+}
+
+static __inline__ int
+list_length(List *l)
+{
+ return l ? l->length : 0;
+}
+#else
+
+extern ListCell *list_head(List *l);
+extern ListCell *list_tail(List *l);
+extern int list_length(List *l);
+#endif /* __GNUC__ */
+
+/*
+ * NB: There is an unfortunate legacy from a previous incarnation of
+ * the List API: the macro lfirst() was used to mean "the data in this
+ * cons cell". To avoid changing every usage of lfirst(), that meaning
+ * has been kept. As a result, lfirst() takes a ListCell and returns
+ * the data it contains; to get the data in the first cell of a
+ * List, use linitial(). Worse, lsecond() is more closely related to
+ * linitial() than lfirst(): given a List, lsecond() returns the data
+ * in the second cons cell.
+ */
+
+#define lnext(lc) ((lc)->next)
+#define lfirst(lc) ((lc)->data.ptr_value)
+#define lfirst_int(lc) ((lc)->data.int_value)
+
+#define linitial(l) lfirst(list_head(l))
+#define linitial_int(l) lfirst_int(list_head(l))
+
+#define lsecond(l) lfirst(lnext(list_head(l)))
+#define lsecond_int(l) lfirst_int(lnext(list_head(l)))
+
+#define lthird(l) lfirst(lnext(lnext(list_head(l))))
+#define lthird_int(l) lfirst_int(lnext(lnext(list_head(l))))
+
+#define lfourth(l) lfirst(lnext(lnext(lnext(list_head(l)))))
+#define lfourth_int(l) lfirst_int(lnext(lnext(lnext(list_head(l)))))
+
+#define llast(l) lfirst(list_tail(l))
+#define llast_int(l) lfirst_int(list_tail(l))
+
+/*
+ * Convenience macros for building fixed-length lists
+ */
+#define list_make1(x1) lcons(x1, NIL)
+#define list_make2(x1,x2) lcons(x1, list_make1(x2))
+#define list_make3(x1,x2,x3) lcons(x1, list_make2(x2, x3))
+#define list_make4(x1,x2,x3,x4) lcons(x1, list_make3(x2, x3, x4))
+
+#define list_make1_int(x1) lcons_int(x1, NIL)
+#define list_make2_int(x1,x2) lcons_int(x1, list_make1_int(x2))
+#define list_make3_int(x1,x2,x3) lcons_int(x1, list_make2_int(x2, x3))
+#define list_make4_int(x1,x2,x3,x4) lcons_int(x1, list_make3_int(x2, x3, x4))
+
+/*
+ * foreach -
+ * a convenience macro which loops through the list
+ */
+#define foreach(cell, l) \
+ for ((cell) = list_head(l); (cell) != NULL; (cell) = lnext(cell))
+
+/*
+ * for_each_cell -
+ * a convenience macro which loops through a list starting from a
+ * specified cell
+ */
+#define for_each_cell(cell, initcell) \
+ for ((cell) = (initcell); (cell) != NULL; (cell) = lnext(cell))
+
+/*
+ * forboth -
+ * a convenience macro for advancing through two linked lists
+ * simultaneously. This macro loops through both lists at the same
+ * time, stopping when either list runs out of elements. Depending
+ * on the requirements of the call site, it may also be wise to
+ * assert that the lengths of the two lists are equal.
+ */
+#define forboth(cell1, list1, cell2, list2) \
+ for ((cell1) = list_head(list1), (cell2) = list_head(list2); \
+ (cell1) != NULL && (cell2) != NULL; \
+ (cell1) = lnext(cell1), (cell2) = lnext(cell2))
+
+extern List *lappend(List *list, void *datum);
+extern List *lappend_int(List *list, int datum);
+
+extern ListCell *lappend_cell(List *list, ListCell *prev, void *datum);
+extern ListCell *lappend_cell_int(List *list, ListCell *prev, int datum);
+
+extern List *lcons(void *datum, List *list);
+extern List *lcons_int(int datum, List *list);
+
+extern List *list_concat(List *list1, List *list2);
+extern List *list_truncate(List *list, int new_size);
+
+extern void *list_nth(List *list, int n);
+extern int list_nth_int(List *list, int n);
+
+extern bool list_member(List *list, void *datum);
+extern bool list_member_ptr(List *list, void *datum);
+extern bool list_member_int(List *list, int datum);
+
+extern List *list_delete(List *list, void *datum);
+extern List *list_delete_ptr(List *list, void *datum);
+extern List *list_delete_int(List *list, int datum);
+extern List *list_delete_first(List *list);
+extern List *list_delete_cell(List *list, ListCell *cell, ListCell *prev);
+
+extern List *list_union(List *list1, List *list2);
+extern List *list_union_ptr(List *list1, List *list2);
+extern List *list_union_int(List *list1, List *list2);
+
+extern List *list_intersection(List *list1, List *list2);
+/* currently, there's no need for list_intersection_int etc */
+
+extern List *list_difference(List *list1, List *list2);
+extern List *list_difference_ptr(List *list1, List *list2);
+extern List *list_difference_int(List *list1, List *list2);
+
+extern List *list_append_unique(List *list, void *datum);
+extern List *list_append_unique_ptr(List *list, void *datum);
+extern List *list_append_unique_int(List *list, int datum);
+
+extern List *list_concat_unique(List *list1, List *list2);
+extern List *list_concat_unique_ptr(List *list1, List *list2);
+extern List *list_concat_unique_int(List *list1, List *list2);
+
+extern void list_free(List *list);
+extern void list_free_deep(List *list);
+
+extern List *list_copy(List *list);
+extern List *list_copy_tail(List *list, int nskip);
+
+/*
+ * To ease migration to the new list API, a set of compatibility
+ * macros are provided that reduce the impact of the list API changes
+ * as far as possible. Until client code has been rewritten to use the
+ * new list API, the ENABLE_LIST_COMPAT symbol can be defined before
+ * including pg_list.h
+ */
+#ifdef ENABLE_LIST_COMPAT
+
+#define lfirsti(lc) lfirst_int(lc)
+
+#define makeList1(x1) list_make1(x1)
+#define makeList2(x1, x2) list_make2(x1, x2)
+#define makeList3(x1, x2, x3) list_make3(x1, x2, x3)
+#define makeList4(x1, x2, x3, x4) list_make4(x1, x2, x3, x4)
+
+#define makeListi1(x1) list_make1_int(x1)
+#define makeListi2(x1, x2) list_make2_int(x1, x2)
+
+#define lconsi(datum, list) lcons_int(datum, list)
+
+#define lappendi(list, datum) lappend_int(list, datum)
+
+#define nconc(l1, l2) list_concat(l1, l2)
+
+#define nth(n, list) list_nth(list, n)
+
+#define member(datum, list) list_member(list, datum)
+#define ptrMember(datum, list) list_member_ptr(list, datum)
+#define intMember(datum, list) list_member_int(list, datum)
+
+/*
+ * Note that the old lremove() determined equality via pointer
+ * comparison, whereas the new list_delete() uses equal(); in order to
+ * keep the same behavior, we therefore need to map lremove() calls to
+ * list_delete_ptr() rather than list_delete()
+ */
+#define lremove(elem, list) list_delete_ptr(list, elem)
+#define LispRemove(elem, list) list_delete(list, elem)
+#define lremovei(elem, list) list_delete_int(list, elem)
+
+#define ltruncate(n, list) list_truncate(list, n)
+
+#define set_union(l1, l2) list_union(l1, l2)
+#define set_ptrUnion(l1, l2) list_union_ptr(l1, l2)
+
+#define set_difference(l1, l2) list_difference(l1, l2)
+#define set_ptrDifference(l1, l2) list_difference_ptr(l1, l2)
+
+#define equali(l1, l2) equal(l1, l2)
+#define equalo(l1, l2) equal(l1, l2)
+
+#define freeList(list) list_free(list)
+
+#define listCopy(list) list_copy(list)
+
+extern int length(List *list);
+#endif /* ENABLE_LIST_COMPAT */
+
+#endif /* GTM_LIST_H */
diff --git a/src/include/gtm/gtm_lock.h b/src/include/gtm/gtm_lock.h
new file mode 100644
index 0000000000..f4a5e025ba
--- /dev/null
+++ b/src/include/gtm/gtm_lock.h
@@ -0,0 +1,59 @@
+/*-------------------------------------------------------------------------
+ *
+ * gtm_lock.h
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL$
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef GTM_LOCK_H
+#define GTM_LOCK_H
+
+#include <pthread.h>
+
+typedef struct GTM_RWLock
+{
+ pthread_rwlock_t lk_lock;
+} GTM_RWLock;
+
+typedef struct GTM_MutexLock
+{
+ pthread_mutex_t lk_lock;
+} GTM_MutexLock;
+
+typedef enum GTM_LockMode
+{
+ GTM_LOCKMODE_WRITE,
+ GTM_LOCKMODE_READ
+} GTM_LockMode;
+
+typedef struct GTM_CV
+{
+ pthread_cond_t cv_condvar;
+} GTM_CV;
+
+extern bool GTM_RWLockAcquire(GTM_RWLock *lock, GTM_LockMode mode);
+extern bool GTM_RWLockRelease(GTM_RWLock *lock);
+extern int GTM_RWLockInit(GTM_RWLock *lock);
+extern int GTM_RWLockDestroy(GTM_RWLock *lock);
+extern bool GTM_RWLockConditionalAcquire(GTM_RWLock *lock, GTM_LockMode mode);
+
+extern bool GTM_MutexLockAcquire(GTM_MutexLock *lock);
+extern bool GTM_MutexLockRelease(GTM_MutexLock *lock);
+extern int GTM_MutexLockInit(GTM_MutexLock *lock);
+extern int GTM_MutexLockDestroy(GTM_MutexLock *lock);
+extern bool GTM_MutexLockConditionalAcquire(GTM_MutexLock *lock);
+
+extern int GTM_CVInit(GTM_CV *cv);
+extern int GTM_CVDestroy(GTM_CV *cv);
+extern int GTM_CVSignal(GTM_CV *cv);
+extern int GTM_CVBcast(GTM_CV *cv);
+extern int GTM_CVWait(GTM_CV *cv, GTM_MutexLock *lock);
+
+#endif
diff --git a/src/include/gtm/gtm_msg.h b/src/include/gtm/gtm_msg.h
new file mode 100644
index 0000000000..cae061437d
--- /dev/null
+++ b/src/include/gtm/gtm_msg.h
@@ -0,0 +1,88 @@
+/*-------------------------------------------------------------------------
+ *
+ * gtm_msg.h
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL$
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef GTM_MSG_H
+#define GTM_MSG_H
+
+typedef enum GTM_MessageType
+{
+ MSG_TYPE_INVALID,
+ MSG_REGISTER_COORD, /* Register a Coordinator with GTM */
+ MSG_UNREGISTER_COORD, /* Unregister a Coordinator with GTM */
+ MSG_TXN_BEGIN, /* Start a new transaction */
+ MSG_TXN_BEGIN_GETGXID, /* Start a new transaction and get GXID */
+ MSG_TXN_BEGIN_GETGXID_MULTI, /* Start multiple new transactions and get GXIDs */
+ MSG_TXN_PREPARE, /* Prepare a transation for commit */
+ MSG_TXN_COMMIT, /* Commit a running or prepared transaction */
+ MSG_TXN_COMMIT_MULTI, /* Commit multiple running or prepared transactions */
+ MSG_TXN_ROLLBACK, /* Rollback a transaction */
+ MSG_TXN_ROLLBACK_MULTI, /* Rollback multiple transactions */
+ MSG_TXN_GET_GXID, /* Get a GXID for a transaction */
+ MSG_SNAPSHOT_GET, /* Get a global snapshot */
+ MSG_SNAPSHOT_GET_MULTI, /* Get multiple global snapshots */
+ MSG_SNAPSHOT_GXID_GET, /* Get GXID and snapshot together */
+ MSG_SEQUENCE_INIT, /* Initialize a new global sequence */
+ MSG_SEQUENCE_GET_CURRENT,/* Get the current value of sequence */
+ MSG_SEQUENCE_GET_NEXT, /* Get the next sequence value of sequence */
+ MSG_SEQUENCE_RESET, /* Reset the sequence */
+ MSG_SEQUENCE_CLOSE, /* Close a previously inited sequence */
+ MSG_TXN_GET_STATUS, /* Get status of a given transaction */
+ MSG_TXN_GET_ALL_PREPARED, /* Get information about all outstanding
+ * prepared transactions */
+ MSG_TXN_BEGIN_GETGXID_AUTOVACUUM, /* Start a new transaction and get GXID for autovacuum */
+ MSG_DATA_FLUSH, /* flush pending data */
+ MSG_BACKEND_DISCONNECT, /* tell GTM that the backend diconnected from the proxy */
+
+ /*
+ * Must be at the end
+ */
+ MSG_TYPE_COUNT /* A dummmy entry just to count the message types */
+} GTM_MessageType;
+
+typedef enum GTM_ResultType
+{
+ TXN_BEGIN_RESULT,
+ TXN_BEGIN_GETGXID_RESULT,
+ TXN_BEGIN_GETGXID_MULTI_RESULT,
+ TXN_PREPARE_RESULT,
+ TXN_COMMIT_RESULT,
+ TXN_COMMIT_MULTI_RESULT,
+ TXN_ROLLBACK_RESULT,
+ TXN_ROLLBACK_MULTI_RESULT,
+ TXN_GET_GXID_RESULT,
+ SNAPSHOT_GET_RESULT,
+ SNAPSHOT_GET_MULTI_RESULT,
+ SNAPSHOT_GXID_GET_RESULT,
+ SEQUENCE_INIT_RESULT,
+ SEQUENCE_GET_CURRENT_RESULT,
+ SEQUENCE_GET_NEXT_RESULT,
+ SEQUENCE_RESET_RESULT,
+ SEQUENCE_CLOSE_RESULT,
+ TXN_GET_STATUS_RESULT,
+ TXN_GET_ALL_PREPARED_RESULT,
+ TXN_BEGIN_GETGXID_AUTOVACUUM_RESULT,
+} GTM_ResultType;
+
+/*
+ * Special message header for the messgaes exchanged between the GTM server and
+ * the proxy.
+ *
+ * ph_conid: connection identifier which is used to route
+ * the messages to the right backend.
+ */
+typedef struct GTM_ProxyMsgHeader
+{
+ GTMProxy_ConnID ph_conid;
+} GTM_ProxyMsgHeader;
+
+#endif
diff --git a/src/include/gtm/gtm_proxy.h b/src/include/gtm/gtm_proxy.h
new file mode 100644
index 0000000000..8dc16bca0e
--- /dev/null
+++ b/src/include/gtm/gtm_proxy.h
@@ -0,0 +1,221 @@
+/*-------------------------------------------------------------------------
+ *
+ * gtm_proxy.h
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL$
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef _GTM_PROXY_H
+#define _GTM_PROXY_H
+
+#include <setjmp.h>
+#include <poll.h>
+
+#include "gtm/gtm_c.h"
+#include "gtm/palloc.h"
+#include "gtm/gtm_lock.h"
+#include "gtm/gtm_conn.h"
+#include "gtm/elog.h"
+#include "gtm/gtm_list.h"
+#include "gtm/gtm_msg.h"
+#include "gtm/libpq-fe.h"
+
+extern char *GTMProxyLogFile;
+
+typedef enum GTMProxy_ThreadStatus
+{
+ GTM_PROXY_THREAD_STARTING,
+ GTM_PROXY_THREAD_RUNNING,
+ GTM_PROXY_THREAD_EXITING,
+ /* Must be the last */
+ GTM_PROXY_THREAD_INVALID
+} GTMProxy_ThreadStatus;
+
+typedef struct GTMProxy_ConnectionInfo
+{
+ /* Port contains all the vital information about this connection */
+ Port *con_port;
+ struct GTMProxy_ThreadInfo *con_thrinfo;
+ bool con_authenticated;
+ bool con_disconnected;
+ GTMProxy_ConnID con_id;
+
+ GTM_MessageType con_pending_msg;
+ GlobalTransactionId con_txid;
+ GTM_TransactionHandle con_handle;
+} GTMProxy_ConnectionInfo;
+
+typedef struct GTMProxy_Connections
+{
+ uint32 gc_conn_count;
+ uint32 gc_array_size;
+ GTMProxy_ConnectionInfo *gc_connections;
+ GTM_RWLock gc_lock;
+} GTMProxy_Connections;
+
+#define ERRORDATA_STACK_SIZE 5
+#define GTM_PROXY_MAX_CONNECTIONS 1024
+
+typedef struct GTMProxy_ThreadInfo
+{
+ /*
+ * Thread specific information such as connection(s) served by it
+ */
+ GTM_ThreadID thr_id;
+ uint32 thr_localid;
+ void * (* thr_startroutine)(void *);
+
+ MemoryContext thr_thread_context;
+ MemoryContext thr_message_context;
+ MemoryContext thr_current_context;
+ MemoryContext thr_error_context;
+ MemoryContext thr_parent_context;
+
+ sigjmp_buf *thr_sigjmp_buf;
+
+ ErrorData thr_error_data[ERRORDATA_STACK_SIZE];
+ int thr_error_stack_depth;
+ int thr_error_recursion_depth;
+ int thr_criticalsec_count;
+
+ GTMProxy_ThreadStatus thr_status;
+ GTMProxy_ConnectionInfo *thr_conn; /* Current active */
+
+ /*
+ * The structure member type/sequence upto this point must match the
+ * GTM_ThreadInfo structure in gtm.h since they are shared in some common
+ * library routines such as elog.c. Keeping them in sync helps us use the
+ * same library for the proxy as well as the server.
+ */
+ GTM_MutexLock thr_lock;
+ GTM_CV thr_cv;
+
+ /*
+ * We use a sequence number to track the state of connection/fd array.
+ * Whenever a new connection is added or an existing connection is deleted
+ * from the connection array, the sequence number is incremented. The
+ * thread main routine can then reconstruct the fd array again.
+ */
+ int32 thr_seqno;
+
+ /* number of connections served by this thread */
+ uint32 thr_conn_count;
+
+ /* connection array */
+ GTMProxy_ConnectionInfo *thr_all_conns[GTM_PROXY_MAX_CONNECTIONS];
+ struct pollfd thr_poll_fds[GTM_PROXY_MAX_CONNECTIONS];
+ List *thr_processed_commands;
+ List *thr_pending_commands[MSG_TYPE_COUNT];
+
+ GTM_Conn *thr_gtm_conn;
+
+} GTMProxy_ThreadInfo;
+
+typedef struct GTMProxy_Threads
+{
+ uint32 gt_thread_count;
+ uint32 gt_array_size;
+ uint32 gt_next_worker;
+ GTMProxy_ThreadInfo **gt_threads;
+ GTM_RWLock gt_lock;
+} GTMProxy_Threads;
+
+extern GTMProxy_Threads *GTMProxyThreads;
+
+int GTMProxy_ThreadAdd(GTMProxy_ThreadInfo *thrinfo);
+int GTMProxy_ThreadRemove(GTMProxy_ThreadInfo *thrinfo);
+int GTMProxy_ThreadJoin(GTMProxy_ThreadInfo *thrinfo);
+void GTMProxy_ThreadExit(void);
+
+extern GTMProxy_ThreadInfo *GTMProxy_ThreadCreate(void *(* startroutine)(void *));
+extern GTMProxy_ThreadInfo * GTMProxy_GetThreadInfo(GTM_ThreadID thrid);
+extern GTMProxy_ThreadInfo *GTMProxy_ThreadAddConnection(GTMProxy_ConnectionInfo *conninfo);
+extern int GTMProxy_ThreadRemoveConnection(GTMProxy_ThreadInfo *thrinfo,
+ GTMProxy_ConnectionInfo *conninfo);
+
+/*
+ * Command data - the only relevant information right now is the XID
+ */
+typedef union GTMProxy_CommandData
+{
+ struct
+ {
+ bool rdonly;
+ GTM_IsolationLevel iso_level;
+ } cd_beg;
+
+ struct
+ {
+ bool isgxid;
+ GlobalTransactionId gxid;
+ GTM_TransactionHandle handle;
+ } cd_rc;
+
+ struct
+ {
+ bool isgxid;
+ GlobalTransactionId gxid;
+ GTM_TransactionHandle handle;
+ } cd_snap;
+} GTMProxy_CommandData;
+
+/*
+ * Structures to be used for message proxing. There will be one such entry for
+ * each pending command from a backend. To keep it simple, we have a separate
+ * entry even if the commands are grouped together.
+ *
+ * An array of these entries is maintained which is sorted by the order in
+ * which the commands are sent to the GTM server. We expect the GTM server to
+ * respond back in the same order and the sorted array helps us in
+ * matching/confirming the responses.
+ */
+typedef struct GTMProxy_CommandInfo
+{
+ GTM_MessageType ci_mtype;
+ int ci_res_index;
+ GTMProxy_CommandData ci_data;
+ GTMProxy_ConnectionInfo *ci_conn;
+} GTMProxy_CommandInfo;
+
+/*
+ * pthread keys to get thread specific information
+ */
+extern pthread_key_t threadinfo_key;
+extern MemoryContext TopMostMemoryContext;
+extern char *GTMLogFile;
+
+#define SetMyThreadInfo(thrinfo) pthread_setspecific(threadinfo_key, (thrinfo))
+#define GetMyThreadInfo ((GTMProxy_ThreadInfo *)pthread_getspecific(threadinfo_key))
+
+#define TopMemoryContext (GetMyThreadInfo->thr_thread_context)
+#define ThreadTopContext (GetMyThreadInfo->thr_thread_context)
+#define MessageContext (GetMyThreadInfo->thr_message_context)
+#define CurrentMemoryContext (GetMyThreadInfo->thr_current_context)
+#define ErrorContext (GetMyThreadInfo->thr_error_context)
+#define errordata (GetMyThreadInfo->thr_error_data)
+#define recursion_depth (GetMyThreadInfo->thr_error_recursion_depth)
+#define errordata_stack_depth (GetMyThreadInfo->thr_error_stack_depth)
+#define CritSectionCount (GetMyThreadInfo->thr_criticalsec_count)
+
+#define PG_exception_stack (GetMyThreadInfo->thr_sigjmp_buf)
+#define MyConnection (GetMyThreadInfo->thr_conn)
+#define MyPort ((GetMyThreadInfo->thr_conn != NULL) ? \
+ GetMyThreadInfo->thr_conn->con_port : \
+ NULL)
+#define MyThreadID (GetMyThreadInfo->thr_id)
+
+#define START_CRIT_SECTION() (CritSectionCount++)
+
+#define END_CRIT_SECTION() \
+ do { \
+ Assert(CritSectionCount > 0); \
+ CritSectionCount--; \
+ } while(0)
+
+#endif
diff --git a/src/include/gtm/gtm_seq.h b/src/include/gtm/gtm_seq.h
new file mode 100644
index 0000000000..6cb8cb3027
--- /dev/null
+++ b/src/include/gtm/gtm_seq.h
@@ -0,0 +1,75 @@
+/*-------------------------------------------------------------------------
+ *
+ * gtm_seq.h
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL$
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef GTM_SEQ_H
+#define GTM_SEQ_H
+
+#include "gtm/stringinfo.h"
+
+/* Global sequence related structures */
+
+typedef struct GTM_SeqInfo
+{
+ GTM_SequenceKey gs_key;
+ GTM_Sequence gs_value;
+ GTM_Sequence gs_init_value;
+ GTM_Sequence gs_increment_by;
+ GTM_Sequence gs_min_value;
+ GTM_Sequence gs_max_value;
+ bool gs_cycle;
+ bool gs_called;
+
+ int32 gs_ref_count;
+ int32 gs_state;
+ GTM_RWLock gs_lock;
+} GTM_SeqInfo;
+
+#define SEQ_STATE_ACTIVE 1
+#define SEQ_STATE_DELETED 2
+
+#define SEQ_IS_ASCENDING(s) ((s)->gs_increment_by > 0)
+#define SEQ_IS_CYCLE(s) ((s)->gs_cycle)
+#define SEQ_IS_CALLED(s) ((s)->gs_called)
+
+#define SEQ_DEF_MAX_SEQVAL_ASCEND 0x7ffffffffffffffeLL
+#define SEQ_DEF_MIN_SEQVAL_ASCEND 0x1
+
+#define SEQ_DEF_MAX_SEQVAL_DESCEND -0x1
+#define SEQ_DEF_MIN_SEQVAL_DESCEND -0x7ffffffffffffffeLL
+
+#define SEQ_MAX_REFCOUNT 1024
+
+/* SEQUENCE Management */
+void GTM_InitSeqManager(void);
+int GTM_SeqOpen(GTM_SequenceKey seqkey,
+ GTM_Sequence increment_by,
+ GTM_Sequence minval,
+ GTM_Sequence maxval,
+ GTM_Sequence startval,
+ bool cycle);
+int GTM_SeqClose(GTM_SequenceKey sqkey);
+GTM_Sequence GTM_SeqGetNext(GTM_SequenceKey seqkey);
+GTM_Sequence GTM_SeqGetCurrent(GTM_SequenceKey seqkey);
+int GTM_SeqReset(GTM_SequenceKey seqkey);
+
+
+void ProcessSequenceInitCommand(Port *myport, StringInfo message);
+void ProcessSequenceGetCurrentCommand(Port *myport, StringInfo message);
+void ProcessSequenceGetNextCommand(Port *myport, StringInfo message);
+void ProcessSequenceResetCommand(Port *myport, StringInfo message);
+void ProcessSequenceCloseCommand(Port *myport, StringInfo message);
+
+void GTM_SaveSeqInfo(int ctlfd);
+void GTM_RestoreSeqInfo(int ctlfd);
+
+#endif
diff --git a/src/include/gtm/gtm_txn.h b/src/include/gtm/gtm_txn.h
new file mode 100644
index 0000000000..2d789463f7
--- /dev/null
+++ b/src/include/gtm/gtm_txn.h
@@ -0,0 +1,235 @@
+/*-------------------------------------------------------------------------
+ *
+ * gtm_txn.h
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL$
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef _GTM_TXN_H
+#define _GTM_TXN_H
+
+#include "gtm/gtm_c.h"
+#include "gtm/gtm_lock.h"
+#include "gtm/gtm_list.h"
+#include "gtm/stringinfo.h"
+
+/* ----------------
+ * Special transaction ID values
+ *
+ * BootstrapGlobalTransactionId is the XID for "bootstrap" operations, and
+ * FrozenGlobalTransactionId is used for very old tuples. Both should
+ * always be considered valid.
+ *
+ * FirstNormalGlobalTransactionId is the first "normal" transaction id.
+ * Note: if you need to change it, you must change pg_class.h as well.
+ * ----------------
+ */
+#define BootstrapGlobalTransactionId ((GlobalTransactionId) 1)
+#define FrozenGlobalTransactionId ((GlobalTransactionId) 2)
+#define FirstNormalGlobalTransactionId ((GlobalTransactionId) 3)
+#define MaxGlobalTransactionId ((GlobalTransactionId) 0xFFFFFFFF)
+
+/* ----------------
+ * transaction ID manipulation macros
+ * ----------------
+ */
+#define GlobalTransactionIdIsNormal(xid) ((xid) >= FirstNormalGlobalTransactionId)
+#define GlobalTransactionIdEquals(id1, id2) ((id1) == (id2))
+#define GlobalTransactionIdStore(xid, dest) (*(dest) = (xid))
+#define StoreInvalidGlobalTransactionId(dest) (*(dest) = InvalidGlobalTransactionId)
+
+/* advance a transaction ID variable, handling wraparound correctly */
+#define GlobalTransactionIdAdvance(dest) \
+ do { \
+ (dest)++; \
+ if ((dest) < FirstNormalGlobalTransactionId) \
+ (dest) = FirstNormalGlobalTransactionId; \
+ } while(0)
+
+/* back up a transaction ID variable, handling wraparound correctly */
+#define GlobalTransactionIdRetreat(dest) \
+ do { \
+ (dest)--; \
+ } while ((dest) < FirstNormalGlobalTransactionId)
+
+typedef int XidStatus;
+
+#define TRANSACTION_STATUS_IN_PROGRESS 0x00
+#define TRANSACTION_STATUS_COMMITTED 0x01
+#define TRANSACTION_STATUS_ABORTED 0x02
+
+/*
+ * prototypes for functions in transam/transam.c
+ */
+extern bool GlobalTransactionIdDidCommit(GlobalTransactionId transactionId);
+extern bool GlobalTransactionIdDidAbort(GlobalTransactionId transactionId);
+extern void GlobalTransactionIdAbort(GlobalTransactionId transactionId);
+extern bool GlobalTransactionIdPrecedes(GlobalTransactionId id1, GlobalTransactionId id2);
+extern bool GlobalTransactionIdPrecedesOrEquals(GlobalTransactionId id1, GlobalTransactionId id2);
+extern bool GlobalTransactionIdFollows(GlobalTransactionId id1, GlobalTransactionId id2);
+extern bool GlobalTransactionIdFollowsOrEquals(GlobalTransactionId id1, GlobalTransactionId id2);
+
+/* in transam/varsup.c */
+extern GlobalTransactionId GTM_GetGlobalTransactionId(GTM_TransactionHandle handle);
+extern GlobalTransactionId GTM_GetGlobalTransactionIdMulti(GTM_TransactionHandle handle[], int txn_count);
+extern GlobalTransactionId ReadNewGlobalTransactionId(void);
+extern void SetGlobalTransactionIdLimit(GlobalTransactionId oldest_datfrozenxid);
+extern void SetNextGlobalTransactionId(GlobalTransactionId gxid);
+extern void GTM_SetShuttingDown(void);
+
+typedef enum GTM_States
+{
+ GTM_STARTING,
+ GTM_RUNNING,
+ GTM_SHUTTING_DOWN
+} GTM_States;
+
+/* Global transaction states at the GTM */
+typedef enum GTM_TransactionStates
+{
+ GTM_TXN_STARTING,
+ GTM_TXN_IN_PROGRESS,
+ GTM_TXN_PREPARE_IN_PROGRESS,
+ GTM_TXN_PREPARED,
+ GTM_TXN_COMMIT_IN_PROGRESS,
+ GTM_TXN_COMMITTED,
+ GTM_TXN_ABORT_IN_PROGRESS,
+ GTM_TXN_ABORTED
+} GTM_TransactionStates;
+
+typedef struct GTM_TransactionInfo
+{
+ GTM_TransactionHandle gti_handle;
+ GTM_ThreadID gti_thread_id;
+
+ bool gti_in_use;
+ GlobalTransactionId gti_gxid;
+ GTM_TransactionStates gti_state;
+ PGXC_NodeId gti_coordid;
+ GlobalTransactionId gti_xmin;
+ GTM_IsolationLevel gti_isolevel;
+ bool gti_readonly;
+ GTMProxy_ConnID gti_backend_id;
+ uint32 gti_nodecount;
+ PGXC_NodeId *gti_nodes;
+
+ GTM_SnapshotData gti_current_snapshot;
+ bool gti_snapshot_set;
+
+ GTM_RWLock gti_lock;
+ bool gti_vacuum;
+} GTM_TransactionInfo;
+
+#define GTM_MAX_2PC_NODES 16
+#define GTM_CheckTransactionHandle(x) ((x) >= 0 && (x) < GTM_MAX_GLOBAL_TRANSACTIONS)
+#define GTM_IsTransSerializable(x) ((x)->gti_isolevel == GTM_ISOLATION_SERIALIZABLE)
+
+typedef struct GTM_Transactions
+{
+ uint32 gt_txn_count;
+ GTM_States gt_gtm_state;
+
+ GTM_RWLock gt_XidGenLock;
+
+ /*
+ * These fields are protected by XidGenLock
+ */
+ GlobalTransactionId gt_nextXid; /* next XID to assign */
+
+ GlobalTransactionId gt_oldestXid; /* cluster-wide minimum datfrozenxid */
+ GlobalTransactionId gt_xidVacLimit; /* start forcing autovacuums here */
+ GlobalTransactionId gt_xidWarnLimit; /* start complaining here */
+ GlobalTransactionId gt_xidStopLimit; /* refuse to advance nextXid beyond here */
+ GlobalTransactionId gt_xidWrapLimit; /* where the world ends */
+
+ /*
+ * These fields are protected by TransArrayLock.
+ */
+ GlobalTransactionId gt_latestCompletedXid; /* newest XID that has committed or
+ * aborted */
+
+ GlobalTransactionId gt_recent_global_xmin;
+
+ int32 gt_lastslot;
+ GTM_TransactionInfo gt_transactions_array[GTM_MAX_GLOBAL_TRANSACTIONS];
+ List *gt_open_transactions;
+
+ GTM_RWLock gt_TransArrayLock;
+} GTM_Transactions;
+
+extern GTM_Transactions GTMTransactions;
+
+#define GTM_CountOpenTransactions() (list_length(GTMTransactions.gt_open_transactions))
+
+/*
+ * Two hash tables will be maintained to quickly find the
+ * GTM_TransactionInfo block given either the GXID or the GTM_TransactionHandle.
+ */
+
+GTM_TransactionInfo *GTM_HandleToTransactionInfo(GTM_TransactionHandle handle);
+GTM_TransactionHandle GTM_GXIDToHandle(GlobalTransactionId gxid);
+
+/* Transaction Control */
+void GTM_InitTxnManager(void);
+GTM_TransactionHandle GTM_BeginTransaction(GTM_CoordinatorId coord_id,
+ GTM_IsolationLevel isolevel,
+ bool readonly);
+int GTM_BeginTransactionMulti(GTM_CoordinatorId coord_id,
+ GTM_IsolationLevel isolevel[],
+ bool readonly[],
+ GTMProxy_ConnID connid[],
+ int txn_count,
+ GTM_TransactionHandle txns[]);
+int GTM_RollbackTransaction(GTM_TransactionHandle txn);
+int GTM_RollbackTransactionMulti(GTM_TransactionHandle txn[], int txn_count, int status[]);
+int GTM_RollbackTransactionGXID(GlobalTransactionId gxid);
+int GTM_CommitTransaction(GTM_TransactionHandle txn);
+int GTM_CommitTransactionMulti(GTM_TransactionHandle txn[], int txn_count, int status[]);
+int GTM_CommitTransactionGXID(GlobalTransactionId gxid);
+int GTM_PrepareTransaction(GTM_TransactionHandle txn,
+ uint32 nodecnt,
+ PGXC_NodeId nodes[]);
+int GTM_PrepareTransactionGXID(GlobalTransactionId gxid,
+ uint32 nodecnt,
+ PGXC_NodeId nodes[]);
+uint32 GTM_GetAllPrepared(GlobalTransactionId gxids[], uint32 gxidcnt);
+GTM_TransactionStates GTM_GetStatus(GTM_TransactionHandle txn);
+GTM_TransactionStates GTM_GetStatusGXID(GlobalTransactionId gxid);
+int GTM_GetAllTransactions(GTM_TransactionInfo txninfo[], uint32 txncnt);
+void GTM_RemoveAllTransInfos(int backend_id);
+
+GTM_Snapshot GTM_GetSnapshotData(GTM_TransactionInfo *my_txninfo,
+ GTM_Snapshot snapshot);
+GTM_Snapshot GTM_GetTransactionSnapshot(GTM_TransactionHandle handle[],
+ int txn_count, int *status);
+void GTM_FreeCachedTransInfo(void);
+
+void ProcessBeginTransactionCommand(Port *myport, StringInfo message);
+void ProcessBeginTransactionCommandMulti(Port *myport, StringInfo message);
+void ProcessBeginTransactionGetGXIDCommand(Port *myport, StringInfo message);
+void ProcessCommitTransactionCommand(Port *myport, StringInfo message);
+void ProcessRollbackTransactionCommand(Port *myport, StringInfo message);
+void ProcessPrepareTransactionCommand(Port *myport, StringInfo message);
+void ProcessGetGXIDTransactionCommand(Port *myport, StringInfo message);
+
+void ProcessBeginTransactionGetGXIDAutovacuumCommand(Port *myport, StringInfo message);
+void ProcessBeginTransactionGetGXIDCommandMulti(Port *myport, StringInfo message);
+void ProcessCommitTransactionCommandMulti(Port *myport, StringInfo message);
+void ProcessRollbackTransactionCommandMulti(Port *myport, StringInfo message) ;
+
+void GTM_SaveTxnInfo(int ctlfd);
+void GTM_RestoreTxnInfo(int ctlfd, GlobalTransactionId next_gxid);
+
+/*
+ * In gtm_snap.c
+ */
+void ProcessGetSnapshotCommand(Port *myport, StringInfo message, bool get_gxid);
+void ProcessGetSnapshotCommandMulti(Port *myport, StringInfo message);
+void GTM_FreeSnapshotData(GTM_Snapshot snapshot);
+#endif
diff --git a/src/include/gtm/ip.h b/src/include/gtm/ip.h
new file mode 100644
index 0000000000..c5d975298b
--- /dev/null
+++ b/src/include/gtm/ip.h
@@ -0,0 +1,50 @@
+/*-------------------------------------------------------------------------
+ *
+ * ip.h
+ * Definitions for IPv6-aware network access.
+ *
+ * These definitions are used by both frontend and backend code. Be careful
+ * what you include here!
+ *
+ * Copyright (c) 2003-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL: pgsql/src/include/libpq/ip.h,v 1.20 2008/01/01 19:45:58 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef IP_H
+#define IP_H
+
+#include "gtm/pqcomm.h"
+
+
+extern int pg_getaddrinfo_all(const char *hostname, const char *servname,
+ const struct addrinfo * hintp,
+ struct addrinfo ** result);
+extern void pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo * ai);
+
+extern int pg_getnameinfo_all(const struct sockaddr_storage * addr, int salen,
+ char *node, int nodelen,
+ char *service, int servicelen,
+ int flags);
+
+extern int pg_range_sockaddr(const struct sockaddr_storage * addr,
+ const struct sockaddr_storage * netaddr,
+ const struct sockaddr_storage * netmask);
+
+extern int pg_sockaddr_cidr_mask(struct sockaddr_storage * mask,
+ char *numbits, int family);
+
+#ifdef HAVE_IPV6
+extern void pg_promote_v4_to_v6_addr(struct sockaddr_storage * addr);
+extern void pg_promote_v4_to_v6_mask(struct sockaddr_storage * addr);
+#endif
+
+#ifdef HAVE_UNIX_SOCKETS
+#define IS_AF_UNIX(fam) ((fam) == AF_UNIX)
+#else
+#define IS_AF_UNIX(fam) (0)
+#endif
+
+#endif /* IP_H */
diff --git a/src/include/gtm/libpq-be.h b/src/include/gtm/libpq-be.h
new file mode 100644
index 0000000000..0a795def67
--- /dev/null
+++ b/src/include/gtm/libpq-be.h
@@ -0,0 +1,86 @@
+/*-------------------------------------------------------------------------
+ *
+ * libpq_be.h
+ * This file contains definitions for structures and externs used
+ * by the postmaster during client authentication.
+ *
+ * Note that this is backend-internal and is NOT exported to clients.
+ * Structs that need to be client-visible are in pqcomm.h.
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL: pgsql/src/include/libpq/libpq-be.h,v 1.69 2009/01/01 17:23:59 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef LIBPQ_BE_H
+#define LIBPQ_BE_H
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+
+#include "gtm/pqcomm.h"
+
+/*
+ * This is used by the postmaster in its communication with frontends. It
+ * contains all state information needed during this communication before the
+ * backend is run. The Port structure is kept in malloc'd memory and is
+ * still available when a backend is running (see MyProcPort). The data
+ * it points to must also be malloc'd, or else palloc'd in TopMostMemoryContext,
+ * so that it survives into GTM_ThreadMain execution!
+ */
+
+typedef struct Port
+{
+ int sock; /* File descriptor */
+ SockAddr laddr; /* local addr (postmaster) */
+ SockAddr raddr; /* remote addr (client) */
+ char *remote_host; /* name (or ip addr) of remote host */
+ char *remote_port; /* text rep of remote port */
+
+ GTMProxy_ConnID conn_id; /* RequestID of this command */
+
+ GTM_CoordinatorId coordinator_id; /* Coordinator ID */
+ bool is_proxy; /* Is this a connection from GTM proxy ? */
+#define PQ_BUFFER_SIZE 8192
+
+ char PqSendBuffer[PQ_BUFFER_SIZE];
+ int PqSendPointer; /* Next index to store a byte in PqSendBuffer */
+
+ char PqRecvBuffer[PQ_BUFFER_SIZE];
+ int PqRecvPointer; /* Next index to read a byte from PqRecvBuffer */
+ int PqRecvLength; /* End of data available in PqRecvBuffer */
+
+ /*
+ * TCP keepalive settings.
+ *
+ * default values are 0 if AF_UNIX or not yet known; current values are 0
+ * if AF_UNIX or using the default. Also, -1 in a default value means we
+ * were unable to find out the default (getsockopt failed).
+ */
+ int default_keepalives_idle;
+ int default_keepalives_interval;
+ int default_keepalives_count;
+ int keepalives_idle;
+ int keepalives_interval;
+ int keepalives_count;
+} Port;
+
+/* TCP keepalives configuration. These are no-ops on an AF_UNIX socket. */
+
+extern int pq_getkeepalivesidle(Port *port);
+extern int pq_getkeepalivesinterval(Port *port);
+extern int pq_getkeepalivescount(Port *port);
+
+extern int pq_setkeepalivesidle(int idle, Port *port);
+extern int pq_setkeepalivesinterval(int interval, Port *port);
+extern int pq_setkeepalivescount(int count, Port *port);
+
+#endif /* LIBPQ_BE_H */
diff --git a/src/include/gtm/libpq-fe.h b/src/include/gtm/libpq-fe.h
new file mode 100644
index 0000000000..2c5c2c4e04
--- /dev/null
+++ b/src/include/gtm/libpq-fe.h
@@ -0,0 +1,138 @@
+/*-------------------------------------------------------------------------
+ *
+ * libpq-fe.h
+ * This file contains definitions for structures and
+ * externs for functions used by frontend postgres applications.
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.145 2009/01/01 17:24:03 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef LIBPQ_FE_H
+#define LIBPQ_FE_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdio.h>
+
+/*
+ * postgres_ext.h defines the backend's externally visible types,
+ * such as Oid.
+ */
+#include "gtm/gtm_ext.h"
+
+/*
+ * Option flags for PQcopyResult
+ */
+#define PG_COPYRES_ATTRS 0x01
+#define PG_COPYRES_TUPLES 0x02 /* Implies PG_COPYRES_ATTRS */
+#define PG_COPYRES_EVENTS 0x04
+#define PG_COPYRES_NOTICEHOOKS 0x08
+
+/* Application-visible enum types */
+
+typedef enum
+{
+ /*
+ * Although it is okay to add to this list, values which become unused
+ * should never be removed, nor should constants be redefined - that would
+ * break compatibility with existing code.
+ */
+ CONNECTION_OK,
+ CONNECTION_BAD,
+ /* Non-blocking mode only below here */
+
+ /*
+ * The existence of these should never be relied upon - they should only
+ * be used for user feedback or similar purposes.
+ */
+ CONNECTION_STARTED, /* Waiting for connection to be made. */
+ CONNECTION_MADE, /* Connection OK; waiting to send. */
+ CONNECTION_AWAITING_RESPONSE, /* Waiting for a response from the
+ * postmaster. */
+ CONNECTION_AUTH_OK, /* Received authentication; waiting for
+ * backend startup. */
+ CONNECTION_SETENV, /* Negotiating environment. */
+ CONNECTION_SSL_STARTUP, /* Negotiating SSL. */
+ CONNECTION_NEEDED /* Internal state: connect() needed */
+} ConnStatusType;
+
+typedef enum
+{
+ PGRES_POLLING_FAILED = 0,
+ PGRES_POLLING_READING, /* These two indicate that one may */
+ PGRES_POLLING_WRITING, /* use select before polling again. */
+ PGRES_POLLING_OK,
+ PGRES_POLLING_ACTIVE /* unused; keep for awhile for backwards
+ * compatibility */
+} GTMClientPollingStatusType;
+
+/* ----------------
+ * Structure for the conninfo parameter definitions returned by PQconndefaults
+ * or GTMPQconninfoParse.
+ *
+ * All fields except "val" point at static strings which must not be altered.
+ * "val" is either NULL or a malloc'd current-value string. GTMPQconninfoFree()
+ * will release both the val strings and the GTMPQconninfoOption array itself.
+ * ----------------
+ */
+typedef struct _GTMPQconninfoOption
+{
+ char *keyword; /* The keyword of the option */
+ char *val; /* Option's current value, or NULL */
+} GTMPQconninfoOption;
+
+typedef struct gtm_conn GTM_Conn;
+
+/* ----------------
+ * Exported functions of libpq
+ * ----------------
+ */
+
+/* === in fe-connect.c === */
+
+/* make a new client connection to the backend */
+/* Asynchronous (non-blocking) */
+extern GTM_Conn *PQconnectGTMStart(const char *conninfo);
+extern GTMClientPollingStatusType GTMPQconnectPoll(GTM_Conn *conn);
+
+/* Synchronous (blocking) */
+extern GTM_Conn *PQconnectGTM(const char *conninfo);
+
+/* close the current connection and free the GTM_Conn data structure */
+extern void GTMPQfinish(GTM_Conn *conn);
+
+/* parse connection options in same way as PQconnectGTM */
+extern GTMPQconninfoOption *GTMPQconninfoParse(const char *conninfo, char **errmsg);
+
+/* free the data structure returned by PQconndefaults() or GTMPQconninfoParse() */
+extern void GTMPQconninfoFree(GTMPQconninfoOption *connOptions);
+
+extern char *GTMPQhost(const GTM_Conn *conn);
+extern char *GTMPQport(const GTM_Conn *conn);
+extern ConnStatusType GTMPQstatus(const GTM_Conn *conn);
+extern char *GTMPQerrorMessage(const GTM_Conn *conn);
+extern int GTMPQsocket(const GTM_Conn *conn);
+
+/* Enable/disable tracing */
+extern void GTMPQtrace(GTM_Conn *conn, FILE *debug_port);
+extern void GTMPQuntrace(GTM_Conn *conn);
+
+/* Force the write buffer to be written (or at least try) */
+extern int PQflush(GTM_Conn *conn);
+
+#define libpq_gettext(x) x
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBPQ_FE_H */
diff --git a/src/include/gtm/libpq-int.h b/src/include/gtm/libpq-int.h
new file mode 100644
index 0000000000..5956de8ff2
--- /dev/null
+++ b/src/include/gtm/libpq-int.h
@@ -0,0 +1,129 @@
+/*-------------------------------------------------------------------------
+ *
+ * libpq-int.h
+ * This file contains internal definitions meant to be used only by
+ * the frontend libpq library, not by applications that call it.
+ *
+ * An application can include this file if it wants to bypass the
+ * official API defined by libpq-fe.h, but code that does so is much
+ * more likely to break across PostgreSQL releases than code that uses
+ * only the official API.
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.139 2009/01/01 17:24:03 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef LIBPQ_INT_H
+#define LIBPQ_INT_H
+
+#include <time.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include "gtm/pqcomm.h"
+#include "gtm/pqexpbuffer.h"
+#include "gtm/gtm_client.h"
+
+/*
+ * GTM_Conn stores all the state data associated with a single connection
+ * to a backend.
+ */
+struct gtm_conn
+{
+ /* Saved values of connection options */
+ char *pghost; /* the machine on which the server is running */
+ char *pghostaddr; /* the IPv4 address of the machine on which
+ * the server is running, in IPv4
+ * numbers-and-dots notation. Takes precedence
+ * over above. */
+ char *pgport; /* the server's communication port */
+ char *connect_timeout; /* connection timeout (numeric string) */
+ char *coordinator_id; /* coordinator id */
+ int is_proxy; /* is this a connection to/from a proxy ? */
+
+ /* Optional file to write trace info to */
+ FILE *Pfdebug;
+
+ /* Status indicators */
+ ConnStatusType status;
+
+ /* Connection data */
+ int sock; /* Unix FD for socket, -1 if not connected */
+ SockAddr laddr; /* Local address */
+ SockAddr raddr; /* Remote address */
+
+ /* Transient state needed while establishing connection */
+ struct addrinfo *addrlist; /* list of possible backend addresses */
+ struct addrinfo *addr_cur; /* the one currently being tried */
+ int addrlist_family; /* needed to know how to free addrlist */
+
+ /* Buffer for data received from backend and not yet processed */
+ char *inBuffer; /* currently allocated buffer */
+ int inBufSize; /* allocated size of buffer */
+ int inStart; /* offset to first unconsumed data in buffer */
+ int inCursor; /* next byte to tentatively consume */
+ int inEnd; /* offset to first position after avail data */
+
+ /* Buffer for data not yet sent to backend */
+ char *outBuffer; /* currently allocated buffer */
+ int outBufSize; /* allocated size of buffer */
+ int outCount; /* number of chars waiting in buffer */
+
+ /* State for constructing messages in outBuffer */
+ int outMsgStart; /* offset to msg start (length word); if -1,
+ * msg has no length word */
+ int outMsgEnd; /* offset to msg end (so far) */
+
+ /* Buffer for current error message */
+ PQExpBufferData errorMessage; /* expansible string */
+
+ /* Buffer for receiving various parts of messages */
+ PQExpBufferData workBuffer; /* expansible string */
+
+ /* Pointer to the result of last operation */
+ GTM_Result *result;
+};
+
+/* === in fe-misc.c === */
+
+ /*
+ * "Get" and "Put" routines return 0 if successful, EOF if not. Note that for
+ * Get, EOF merely means the buffer is exhausted, not that there is
+ * necessarily any error.
+ */
+extern int gtmpqCheckOutBufferSpace(size_t bytes_needed, GTM_Conn *conn);
+extern int gtmpqCheckInBufferSpace(size_t bytes_needed, GTM_Conn *conn);
+extern int gtmpqGetc(char *result, GTM_Conn *conn);
+extern int gtmpqPutc(char c, GTM_Conn *conn);
+extern int gtmpqGets(PQExpBuffer buf, GTM_Conn *conn);
+extern int gtmpqGets_append(PQExpBuffer buf, GTM_Conn *conn);
+extern int gtmpqPuts(const char *s, GTM_Conn *conn);
+extern int gtmpqGetnchar(char *s, size_t len, GTM_Conn *conn);
+extern int gtmpqPutnchar(const char *s, size_t len, GTM_Conn *conn);
+extern int gtmpqGetInt(int *result, size_t bytes, GTM_Conn *conn);
+extern int gtmpqPutInt(int value, size_t bytes, GTM_Conn *conn);
+extern int gtmpqPutMsgStart(char msg_type, bool force_len, GTM_Conn *conn);
+extern int gtmpqPutMsgEnd(GTM_Conn *conn);
+extern int gtmpqReadData(GTM_Conn *conn);
+extern int gtmpqFlush(GTM_Conn *conn);
+extern int gtmpqWait(int forRead, int forWrite, GTM_Conn *conn);
+extern int gtmpqWaitTimed(int forRead, int forWrite, GTM_Conn *conn,
+ time_t finish_time);
+extern int gtmpqReadReady(GTM_Conn *conn);
+extern int gtmpqWriteReady(GTM_Conn *conn);
+
+/*
+ * In fe-protocol.c
+ */
+GTM_Result * GTMPQgetResult(GTM_Conn *conn);
+extern int gtmpqGetError(GTM_Conn *conn, GTM_Result *result);
+void gtmpqFreeResultData(GTM_Result *result, bool is_proxy);
+
+#define SOCK_ERRNO errno
+#define SOCK_ERRNO_SET(e) (errno = (e))
+
+#endif /* LIBPQ_INT_H */
diff --git a/src/include/gtm/libpq.h b/src/include/gtm/libpq.h
new file mode 100644
index 0000000000..29621a43c4
--- /dev/null
+++ b/src/include/gtm/libpq.h
@@ -0,0 +1,47 @@
+/*-------------------------------------------------------------------------
+ *
+ * libpq.h
+ * POSTGRES LIBPQ buffer structure definitions.
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL: pgsql/src/include/libpq/libpq.h,v 1.70 2008/11/20 09:29:36 mha Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef LIBPQ_H
+#define LIBPQ_H
+
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#include "gtm/stringinfo.h"
+#include "gtm/libpq-be.h"
+
+/*
+ * External functions.
+ */
+
+/*
+ * prototypes for functions in pqcomm.c
+ */
+extern int StreamServerPort(int family, char *hostName,
+ unsigned short portNumber, int ListenSocket[],
+ int MaxListen);
+extern int StreamConnection(int server_fd, Port *port);
+extern void StreamClose(int sock);
+extern void TouchSocketFile(void);
+extern void pq_comm_reset(void);
+extern int pq_getbytes(Port *myport, char *s, size_t len);
+extern int pq_getstring(Port *myport, StringInfo s);
+extern int pq_getmessage(Port *myport, StringInfo s, int maxlen);
+extern int pq_getbyte(Port *myport);
+extern int pq_peekbyte(Port *myport);
+extern int pq_putbytes(Port *myport, const char *s, size_t len);
+extern int pq_flush(Port *myport);
+extern int pq_putmessage(Port *myport, char msgtype, const char *s, size_t len);
+
+#endif /* LIBPQ_H */
diff --git a/src/include/gtm/memnodes.h b/src/include/gtm/memnodes.h
new file mode 100644
index 0000000000..dea51b2bbd
--- /dev/null
+++ b/src/include/gtm/memnodes.h
@@ -0,0 +1,79 @@
+/*-------------------------------------------------------------------------
+ *
+ * memnodes.h
+ * POSTGRES memory context node definitions.
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL: pgsql/src/include/nodes/memnodes.h,v 1.34 2008/01/01 19:45:58 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef MEMNODES_H
+#define MEMNODES_H
+
+#include "gtm/gtm_lock.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.
+ *
+ * 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, int level);
+#ifdef MEMORY_CONTEXT_CHECKING
+ void (*check) (MemoryContext context);
+#endif
+} MemoryContextMethods;
+
+
+typedef struct MemoryContextData
+{
+ 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 is_shared; /* context is shared by threads */
+ GTM_RWLock lock; /* lock to protect members if the context is shared */
+} MemoryContextData;
+
+#define MemoryContextIsShared(context) \
+ (((MemoryContextData *)(context))->is_shared)
+
+#define MemoryContextLock(context) \
+ (GTM_RWLockAcquire(&((MemoryContextData *)(context))->lock, GTM_LOCKMODE_WRITE))
+#define MemoryContextUnlock(context) \
+ (GTM_RWLockRelease(&((MemoryContextData *)(context))->lock))
+/*
+ * MemoryContextIsValid
+ * True iff memory context is valid.
+ *
+ * Add new context types to the set accepted by this macro.
+ */
+#define MemoryContextIsValid(context) \
+ ((context) != NULL)
+
+#endif /* MEMNODES_H */
diff --git a/src/include/gtm/memutils.h b/src/include/gtm/memutils.h
new file mode 100644
index 0000000000..5d89995d4d
--- /dev/null
+++ b/src/include/gtm/memutils.h
@@ -0,0 +1,123 @@
+/*-------------------------------------------------------------------------
+ *
+ * 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-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL: pgsql/src/include/utils/memutils.h,v 1.64 2008/01/01 19:45:59 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef MEMUTILS_H
+#define MEMUTILS_H
+
+#include "gtm/gtm_c.h"
+#include "gtm/palloc.h"
+#include "gtm/memnodes.h"
+
+/*
+ * MaxAllocSize
+ * Quasi-arbitrary limit on size of allocations.
+ *
+ * Note:
+ * There is no guarantee that allocations smaller than MaxAllocSize
+ * will succeed. Allocation requests larger than MaxAllocSize will
+ * be summarily denied.
+ *
+ * XXX This is deliberately chosen to correspond to the limiting size
+ * of varlena objects under TOAST. See VARATT_MASK_SIZE in postgres.h.
+ *
+ * XXX Also, various places in aset.c assume they can compute twice an
+ * allocation's size without overflow, so beware of raising this.
+ */
+#define MaxAllocSize ((Size) 0x3fffffff) /* 1 gigabyte - 1 */
+
+#define AllocSizeIsValid(size) ((Size) (size) <= MaxAllocSize)
+
+/*
+ * 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))
+
+/*
+ * 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 Size GetMemoryChunkSpace(void *pointer);
+extern MemoryContext GetMemoryChunkContext(void *pointer);
+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(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,
+ bool isShared);
+
+/*
+ * 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/gtm/palloc.h b/src/include/gtm/palloc.h
new file mode 100644
index 0000000000..380e280694
--- /dev/null
+++ b/src/include/gtm/palloc.h
@@ -0,0 +1,90 @@
+/*-------------------------------------------------------------------------
+ *
+ * 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-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL: pgsql/src/include/utils/palloc.h,v 1.40 2008/06/28 16:45:22 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#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;
+
+/*
+ * 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);
+
+#define palloc(sz) MemoryContextAlloc(CurrentMemoryContext, (sz))
+
+#define palloc0(sz) MemoryContextAllocZero(CurrentMemoryContext, (sz))
+
+/*
+ * 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) )
+
+extern void pfree(void *pointer);
+
+extern void *repalloc(void *pointer, Size size);
+
+/*
+ * MemoryContextSwitchTo can't be a macro in standard C compilers.
+ * But we can make it an inline function when using GCC.
+ */
+
+extern MemoryContext MemoryContextSwitchTo(MemoryContext context);
+
+/*
+ * 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);
+
+#define pstrdup(str) MemoryContextStrdup(CurrentMemoryContext, (str))
+
+extern char *pnstrdup(const char *in, Size len);
+
+#if defined(WIN32) || defined(__CYGWIN__)
+extern void *pgport_palloc(Size sz);
+extern char *pgport_pstrdup(const char *str);
+extern void pgport_pfree(void *pointer);
+#endif
+
+#endif /* PALLOC_H */
diff --git a/src/include/gtm/path.h b/src/include/gtm/path.h
new file mode 100644
index 0000000000..624fd183c9
--- /dev/null
+++ b/src/include/gtm/path.h
@@ -0,0 +1,16 @@
+/*-------------------------------------------------------------------------
+ *
+ * path.h
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL$
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "gtm/gtm_c.h"
+
+extern void canonicalize_path(char *path);
diff --git a/src/include/gtm/pqcomm.h b/src/include/gtm/pqcomm.h
new file mode 100644
index 0000000000..cdae6ca284
--- /dev/null
+++ b/src/include/gtm/pqcomm.h
@@ -0,0 +1,57 @@
+/*-------------------------------------------------------------------------
+ *
+ * pqcomm.h
+ * Definitions common to frontends and backends.
+ *
+ * NOTE: for historical reasons, this does not correspond to pqcomm.c.
+ * pqcomm.c's routines are declared in libpq.h.
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL: pgsql/src/include/libpq/pqcomm.h,v 1.109 2008/10/28 12:10:44 mha Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PQCOMM_H
+#define PQCOMM_H
+
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+#include <netinet/in.h>
+
+typedef struct
+{
+ struct sockaddr_storage addr;
+ size_t salen;
+} SockAddr;
+
+/* Configure the UNIX socket location for the well known port. */
+
+#define UNIXSOCK_PATH(path, port, sockdir) \
+ snprintf(path, sizeof(path), "%s/.s.PGSQL.%d", \
+ ((sockdir) && *(sockdir) != '\0') ? (sockdir) : \
+ DEFAULT_PGSOCKET_DIR, \
+ (port))
+
+/*
+ * Packet lengths are 4 bytes in network byte order.
+ *
+ * The initial length is omitted from the packet layouts appearing below.
+ */
+
+typedef uint32 PacketLen;
+
+/*
+ * In protocol 3.0 and later, the startup packet length is not fixed, but
+ * we set an arbitrary limit on it anyway. This is just to prevent simple
+ * denial-of-service attacks via sending enough data to run the server
+ * out of memory.
+ */
+#define MAX_STARTUP_PACKET_LENGTH 10000
+
+#endif /* PQCOMM_H */
diff --git a/src/include/gtm/pqexpbuffer.h b/src/include/gtm/pqexpbuffer.h
new file mode 100644
index 0000000000..7ae0411423
--- /dev/null
+++ b/src/include/gtm/pqexpbuffer.h
@@ -0,0 +1,181 @@
+/*-------------------------------------------------------------------------
+ *
+ * pqexpbuffer.h
+ * Declarations/definitions for "PQExpBuffer" functions.
+ *
+ * PQExpBuffer provides an indefinitely-extensible string data type.
+ * It can be used to buffer either ordinary C strings (null-terminated text)
+ * or arbitrary binary data. All storage is allocated with malloc().
+ *
+ * This module is essentially the same as the backend's StringInfo data type,
+ * but it is intended for use in frontend libpq and client applications.
+ * Thus, it does not rely on palloc() nor elog().
+ *
+ * It does rely on vsnprintf(); if configure finds that libc doesn't provide
+ * a usable vsnprintf(), then a copy of our own implementation of it will
+ * be linked into libpq.
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL: pgsql/src/interfaces/libpq/pqexpbuffer.h,v 1.21 2008/11/26 16:23:11 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PQEXPBUFFER_H
+#define PQEXPBUFFER_H
+
+/*-------------------------
+ * PQExpBufferData holds information about an extensible string.
+ * data is the current buffer for the string (allocated with malloc).
+ * len is the current string length. There is guaranteed to be
+ * a terminating '\0' at data[len], although this is not very
+ * useful when the string holds binary data rather than text.
+ * maxlen is the allocated size in bytes of 'data', i.e. the maximum
+ * string size (including the terminating '\0' char) that we can
+ * currently store in 'data' without having to reallocate
+ * more space. We must always have maxlen > len.
+ *
+ * An exception occurs if we failed to allocate enough memory for the string
+ * buffer. In that case data points to a statically allocated empty string,
+ * and len = maxlen = 0.
+ *-------------------------
+ */
+typedef struct PQExpBufferData
+{
+ char *data;
+ size_t len;
+ size_t maxlen;
+} PQExpBufferData;
+
+typedef PQExpBufferData *PQExpBuffer;
+
+/*------------------------
+ * Test for a broken (out of memory) PQExpBuffer.
+ * When a buffer is "broken", all operations except resetting or deleting it
+ * are no-ops.
+ *------------------------
+ */
+#define PQExpBufferBroken(str) \
+ ((str) == NULL || (str)->maxlen == 0)
+
+/*------------------------
+ * Initial size of the data buffer in a PQExpBuffer.
+ * NB: this must be large enough to hold error messages that might
+ * be returned by PQrequestCancel().
+ *------------------------
+ */
+#define INITIAL_EXPBUFFER_SIZE 256
+
+/*------------------------
+ * There are two ways to create a PQExpBuffer object initially:
+ *
+ * PQExpBuffer stringptr = createGTMPQExpBuffer();
+ * Both the PQExpBufferData and the data buffer are malloc'd.
+ *
+ * PQExpBufferData string;
+ * initGTMPQExpBuffer(&string);
+ * The data buffer is malloc'd but the PQExpBufferData is presupplied.
+ * This is appropriate if the PQExpBufferData is a field of another
+ * struct.
+ *-------------------------
+ */
+
+/*------------------------
+ * createGTMPQExpBuffer
+ * Create an empty 'PQExpBufferData' & return a pointer to it.
+ */
+extern PQExpBuffer createGTMPQExpBuffer(void);
+
+/*------------------------
+ * initGTMPQExpBuffer
+ * Initialize a PQExpBufferData struct (with previously undefined contents)
+ * to describe an empty string.
+ */
+extern void initGTMPQExpBuffer(PQExpBuffer str);
+
+/*------------------------
+ * To destroy a PQExpBuffer, use either:
+ *
+ * destroyGTMPQExpBuffer(str);
+ * free()s both the data buffer and the PQExpBufferData.
+ * This is the inverse of createGTMPQExpBuffer().
+ *
+ * termGTMPQExpBuffer(str)
+ * free()s the data buffer but not the PQExpBufferData itself.
+ * This is the inverse of initGTMPQExpBuffer().
+ *
+ * NOTE: some routines build up a string using PQExpBuffer, and then
+ * release the PQExpBufferData but return the data string itself to their
+ * caller. At that point the data string looks like a plain malloc'd
+ * string.
+ */
+extern void destroyGTMPQExpBuffer(PQExpBuffer str);
+extern void termGTMPQExpBuffer(PQExpBuffer str);
+
+/*------------------------
+ * resetGTMPQExpBuffer
+ * Reset a PQExpBuffer to empty
+ *
+ * Note: if possible, a "broken" PQExpBuffer is returned to normal.
+ */
+extern void resetGTMPQExpBuffer(PQExpBuffer str);
+
+/*------------------------
+ * enlargeGTMPQExpBuffer
+ * Make sure there is enough space for 'needed' more bytes in the buffer
+ * ('needed' does not include the terminating null).
+ *
+ * Returns 1 if OK, 0 if failed to enlarge buffer. (In the latter case
+ * the buffer is left in "broken" state.)
+ */
+extern int enlargeGTMPQExpBuffer(PQExpBuffer str, size_t needed);
+
+/*------------------------
+ * printfGTMPQExpBuffer
+ * Format text data under the control of fmt (an sprintf-like format string)
+ * and insert it into str. More space is allocated to str if necessary.
+ * This is a convenience routine that does the same thing as
+ * resetGTMPQExpBuffer() followed by appendGTMPQExpBuffer().
+ */
+extern void
+printfGTMPQExpBuffer(PQExpBuffer str, const char *fmt,...)
+/* This extension allows gcc to check the format string */
+__attribute__((format(printf, 2, 3)));
+
+/*------------------------
+ * appendGTMPQExpBuffer
+ * Format text data under the control of fmt (an sprintf-like format string)
+ * and append it to whatever is already in str. More space is allocated
+ * to str if necessary. This is sort of like a combination of sprintf and
+ * strcat.
+ */
+extern void
+appendGTMPQExpBuffer(PQExpBuffer str, const char *fmt,...)
+/* This extension allows gcc to check the format string */
+__attribute__((format(printf, 2, 3)));
+
+/*------------------------
+ * appendGTMPQExpBufferStr
+ * Append the given string to a PQExpBuffer, allocating more space
+ * if necessary.
+ */
+extern void appendGTMPQExpBufferStr(PQExpBuffer str, const char *data);
+
+/*------------------------
+ * appendGTMPQExpBufferChar
+ * Append a single byte to str.
+ * Like appendGTMPQExpBuffer(str, "%c", ch) but much faster.
+ */
+extern void appendGTMPQExpBufferChar(PQExpBuffer str, char ch);
+
+/*------------------------
+ * appendBinaryGTMPQExpBuffer
+ * Append arbitrary binary data to a PQExpBuffer, allocating more space
+ * if necessary.
+ */
+extern void appendBinaryGTMPQExpBuffer(PQExpBuffer str,
+ const char *data, size_t datalen);
+
+#endif /* PQEXPBUFFER_H */
diff --git a/src/include/gtm/pqformat.h b/src/include/gtm/pqformat.h
new file mode 100644
index 0000000000..3febf2cf2e
--- /dev/null
+++ b/src/include/gtm/pqformat.h
@@ -0,0 +1,48 @@
+/*-------------------------------------------------------------------------
+ *
+ * pqformat.h
+ * Definitions for formatting and parsing frontend/backend messages
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL: pgsql/src/include/libpq/pqformat.h,v 1.27 2009/01/01 17:23:59 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PQFORMAT_H
+#define PQFORMAT_H
+
+#include "gtm/stringinfo.h"
+
+extern void pq_beginmessage(StringInfo buf, char msgtype);
+extern void pq_sendbyte(StringInfo buf, int byt);
+extern void pq_sendbytes(StringInfo buf, const char *data, int datalen);
+extern void pq_sendcountedtext(StringInfo buf, const char *str, int slen,
+ bool countincludesself);
+extern void pq_sendtext(StringInfo buf, const char *str, int slen);
+extern void pq_sendstring(StringInfo buf, const char *str);
+extern void pq_send_ascii_string(StringInfo buf, const char *str);
+extern void pq_sendint(StringInfo buf, int i, int b);
+extern void pq_sendint64(StringInfo buf, int64 i);
+extern void pq_sendfloat4(StringInfo buf, float4 f);
+extern void pq_sendfloat8(StringInfo buf, float8 f);
+extern void pq_endmessage(Port *myport, StringInfo buf);
+
+extern void pq_puttextmessage(Port *myport, char msgtype, const char *str);
+extern void pq_putemptymessage(Port *myport, char msgtype);
+
+extern int pq_getmsgbyte(StringInfo msg);
+extern unsigned int pq_getmsgint(StringInfo msg, int b);
+extern int64 pq_getmsgint64(StringInfo msg);
+extern float4 pq_getmsgfloat4(StringInfo msg);
+extern float8 pq_getmsgfloat8(StringInfo msg);
+extern const char *pq_getmsgbytes(StringInfo msg, int datalen);
+extern void pq_copymsgbytes(StringInfo msg, char *buf, int datalen);
+extern char *pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes);
+extern const char *pq_getmsgstring(StringInfo msg);
+extern void pq_getmsgend(StringInfo msg);
+extern int pq_getmsgunreadlen(StringInfo msg);
+
+#endif /* PQFORMAT_H */
diff --git a/src/include/gtm/pqsignal.h b/src/include/gtm/pqsignal.h
new file mode 100644
index 0000000000..e3a53dc3ed
--- /dev/null
+++ b/src/include/gtm/pqsignal.h
@@ -0,0 +1,49 @@
+/*-------------------------------------------------------------------------
+ *
+ * pqsignal.h
+ * prototypes for the reliable BSD-style signal(2) routine.
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL: pgsql/src/include/libpq/pqsignal.h,v 1.32 2008/01/01 19:45:58 momjian Exp $
+ *
+ * NOTES
+ * This shouldn't be in libpq, but the monitor and some other
+ * things need it...
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PQSIGNAL_H
+#define PQSIGNAL_H
+
+#include <signal.h>
+
+#ifdef HAVE_SIGPROCMASK
+extern sigset_t UnBlockSig,
+ BlockSig,
+ AuthBlockSig;
+
+#define PG_SETMASK(mask) sigprocmask(SIG_SETMASK, mask, NULL)
+#else
+extern int UnBlockSig,
+ BlockSig,
+ AuthBlockSig;
+
+#ifndef WIN32
+#define PG_SETMASK(mask) sigsetmask(*((int*)(mask)))
+#else
+#define PG_SETMASK(mask) pqsigsetmask(*((int*)(mask)))
+int pqsigsetmask(int mask);
+#endif
+#endif
+
+typedef void (*pqsigfunc) (int);
+
+extern void pqinitmask(void);
+
+extern pqsigfunc pqsignal(int signo, pqsigfunc func);
+
+#endif /* PQSIGNAL_H */
diff --git a/src/include/gtm/stringinfo.h b/src/include/gtm/stringinfo.h
new file mode 100644
index 0000000000..197aa877a1
--- /dev/null
+++ b/src/include/gtm/stringinfo.h
@@ -0,0 +1,149 @@
+/*-------------------------------------------------------------------------
+ *
+ * stringinfo.h
+ * Declarations/definitions for "StringInfo" functions.
+ *
+ * StringInfo provides an indefinitely-extensible string data type.
+ * It can be used to buffer either ordinary C strings (null-terminated text)
+ * or arbitrary binary data. All storage is allocated with palloc().
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * $PostgreSQL: pgsql/src/include/lib/stringinfo.h,v 1.35 2008/01/01 19:45:57 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef STRINGINFO_H
+#define STRINGINFO_H
+
+/*-------------------------
+ * StringInfoData holds information about an extensible string.
+ * data is the current buffer for the string (allocated with palloc).
+ * len is the current string length. There is guaranteed to be
+ * a terminating '\0' at data[len], although this is not very
+ * useful when the string holds binary data rather than text.
+ * maxlen is the allocated size in bytes of 'data', i.e. the maximum
+ * string size (including the terminating '\0' char) that we can
+ * currently store in 'data' without having to reallocate
+ * more space. We must always have maxlen > len.
+ * cursor is initialized to zero by makeStringInfo or initStringInfo,
+ * but is not otherwise touched by the stringinfo.c routines.
+ * Some routines use it to scan through a StringInfo.
+ *-------------------------
+ */
+typedef struct StringInfoData
+{
+ char *data;
+ int len;
+ int maxlen;
+ int cursor;
+} StringInfoData;
+
+typedef StringInfoData *StringInfo;
+
+
+/*------------------------
+ * There are two ways to create a StringInfo object initially:
+ *
+ * StringInfo stringptr = makeStringInfo();
+ * Both the StringInfoData and the data buffer are palloc'd.
+ *
+ * StringInfoData string;
+ * initStringInfo(&string);
+ * The data buffer is palloc'd but the StringInfoData is just local.
+ * This is the easiest approach for a StringInfo object that will
+ * only live as long as the current routine.
+ *
+ * To destroy a StringInfo, pfree() the data buffer, and then pfree() the
+ * StringInfoData if it was palloc'd. There's no special support for this.
+ *
+ * NOTE: some routines build up a string using StringInfo, and then
+ * release the StringInfoData but return the data string itself to their
+ * caller. At that point the data string looks like a plain palloc'd
+ * string.
+ *-------------------------
+ */
+
+/*------------------------
+ * makeStringInfo
+ * Create an empty 'StringInfoData' & return a pointer to it.
+ */
+extern StringInfo makeStringInfo(void);
+
+/*------------------------
+ * initStringInfo
+ * Initialize a StringInfoData struct (with previously undefined contents)
+ * to describe an empty string.
+ */
+extern void initStringInfo(StringInfo str);
+
+/*------------------------
+ * resetStringInfo
+ * Clears the current content of the StringInfo, if any. The
+ * StringInfo remains valid.
+ */
+extern void resetStringInfo(StringInfo str);
+
+/*------------------------
+ * appendStringInfo
+ * Format text data under the control of fmt (an sprintf-style format string)
+ * and append it to whatever is already in str. More space is allocated
+ * to str if necessary. This is sort of like a combination of sprintf and
+ * strcat.
+ */
+extern void
+appendStringInfo(StringInfo str, const char *fmt,...)
+/* This extension allows gcc to check the format string */
+__attribute__((format(printf, 2, 3)));
+
+/*------------------------
+ * appendStringInfoVA
+ * Attempt to format text data under the control of fmt (an sprintf-style
+ * format string) and append it to whatever is already in str. If successful
+ * return true; if not (because there's not enough space), return false
+ * without modifying str. Typically the caller would enlarge str and retry
+ * on false return --- see appendStringInfo for standard usage pattern.
+ */
+extern bool appendStringInfoVA(StringInfo str, const char *fmt, va_list args);
+
+/*------------------------
+ * appendStringInfoString
+ * Append a null-terminated string to str.
+ * Like appendStringInfo(str, "%s", s) but faster.
+ */
+extern void appendStringInfoString(StringInfo str, const char *s);
+
+/*------------------------
+ * appendStringInfoChar
+ * Append a single byte to str.
+ * Like appendStringInfo(str, "%c", ch) but much faster.
+ */
+extern void appendStringInfoChar(StringInfo str, char ch);
+
+/*------------------------
+ * appendStringInfoCharMacro
+ * As above, but a macro for even more speed where it matters.
+ * Caution: str argument will be evaluated multiple times.
+ */
+#define appendStringInfoCharMacro(str,ch) \
+ (((str)->len + 1 >= (str)->maxlen) ? \
+ appendStringInfoChar(str, ch) : \
+ (void)((str)->data[(str)->len] = (ch), (str)->data[++(str)->len] = '\0'))
+
+/*------------------------
+ * appendBinaryStringInfo
+ * Append arbitrary binary data to a StringInfo, allocating more space
+ * if necessary.
+ */
+extern void appendBinaryStringInfo(StringInfo str,
+ const char *data, int datalen);
+
+/*------------------------
+ * enlargeStringInfo
+ * Make sure a StringInfo's buffer can hold at least 'needed' more bytes.
+ */
+extern void enlargeStringInfo(StringInfo str, int needed);
+
+#endif /* STRINGINFO_H */
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index f255c44d1c..078b6733e7 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -6,6 +6,7 @@
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
*
* $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.223 2009/06/11 14:49:11 momjian Exp $
*
@@ -157,6 +158,9 @@ typedef enum NodeTag
T_JoinExpr,
T_FromExpr,
T_IntoClause,
+#ifdef PGXC
+ T_DistributeBy,
+#endif
/*
* TAGS FOR EXPRESSION STATE NODES (execnodes.h)
@@ -337,6 +341,7 @@ typedef enum NodeTag
T_CreateUserMappingStmt,
T_AlterUserMappingStmt,
T_DropUserMappingStmt,
+ T_ExecDirectStmt,
/*
* TAGS FOR PARSE TREE NODES (parsenodes.h)
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 7793f66f20..e0515ba95d 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -12,6 +12,7 @@
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
*
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.395 2009/06/18 01:27:02 tgl Exp $
*
@@ -1335,6 +1336,9 @@ typedef struct CreateStmt
List *options; /* options from WITH clause */
OnCommitAction oncommit; /* what do we do at COMMIT? */
char *tablespacename; /* table space to use, or NULL */
+#ifdef PGXC
+ DistributeBy *distributeby; /* distribution to use, or NULL */
+#endif
} CreateStmt;
/* ----------
@@ -2389,4 +2393,17 @@ typedef struct AlterTSConfigurationStmt
bool missing_ok; /* for DROP - skip error if missing? */
} AlterTSConfigurationStmt;
+/* PGXC_BEGIN */
+/*
+ * EXECUTE DIRECT statement
+ */
+typedef struct ExecDirectStmt
+{
+ NodeTag type;
+ bool coordinator;
+ List *nodes;
+ char *query;
+} ExecDirectStmt;
+/* PGXC_END */
+
#endif /* PARSENODES_H */
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index a41b0e2f7d..36c5e6e633 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -9,6 +9,7 @@
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
*
* $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.149 2009/06/11 14:49:11 momjian Exp $
*
@@ -1174,4 +1175,30 @@ typedef struct FromExpr
Node *quals; /* qualifiers on join, if any */
} FromExpr;
+#ifdef PGXC
+/*----------
+ * DistributionType - how to distribute the data
+ *
+ *----------
+ */
+typedef enum DistributionType
+{
+ DISTTYPE_REPLICATION, /* Replicated */
+ DISTTYPE_HASH, /* Hash partitioned */
+ DISTTYPE_ROUNDROBIN /* Round Robin */
+} DistributionType;
+
+/*----------
+ * DistributeBy - represents a DISTRIBUTE BY clause in a CREATE TABLE statement
+ *
+ *----------
+ */
+typedef struct DistributeBy
+{
+ NodeTag type;
+ DistributionType disttype; /* Distribution type */
+ char *colname; /* Distribution column name */
+} DistributeBy;
+#endif
+
#endif /* PRIMNODES_H */
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index 23f5d87a7a..aec7b6b3d9 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -9,6 +9,7 @@
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/include/parser/kwlist.h,v 1.2 2009/04/06 08:42:53 heikki Exp $
@@ -90,6 +91,7 @@ PG_KEYWORD("constraints", CONSTRAINTS, UNRESERVED_KEYWORD)
PG_KEYWORD("content", CONTENT_P, UNRESERVED_KEYWORD)
PG_KEYWORD("continue", CONTINUE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("conversion", CONVERSION_P, UNRESERVED_KEYWORD)
+PG_KEYWORD("coordinator", COORDINATOR, UNRESERVED_KEYWORD)
PG_KEYWORD("copy", COPY, UNRESERVED_KEYWORD)
PG_KEYWORD("cost", COST, UNRESERVED_KEYWORD)
PG_KEYWORD("create", CREATE, RESERVED_KEYWORD)
@@ -125,9 +127,13 @@ PG_KEYWORD("delimiter", DELIMITER, UNRESERVED_KEYWORD)
PG_KEYWORD("delimiters", DELIMITERS, UNRESERVED_KEYWORD)
PG_KEYWORD("desc", DESC, RESERVED_KEYWORD)
PG_KEYWORD("dictionary", DICTIONARY, UNRESERVED_KEYWORD)
+PG_KEYWORD("direct", DIRECT, UNRESERVED_KEYWORD)
PG_KEYWORD("disable", DISABLE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("discard", DISCARD, UNRESERVED_KEYWORD)
PG_KEYWORD("distinct", DISTINCT, RESERVED_KEYWORD)
+#ifdef PGXC
+PG_KEYWORD("distribute", DISTRIBUTE, UNRESERVED_KEYWORD)
+#endif
PG_KEYWORD("do", DO, RESERVED_KEYWORD)
PG_KEYWORD("document", DOCUMENT_P, UNRESERVED_KEYWORD)
PG_KEYWORD("domain", DOMAIN_P, UNRESERVED_KEYWORD)
@@ -169,6 +175,9 @@ PG_KEYWORD("granted", GRANTED, UNRESERVED_KEYWORD)
PG_KEYWORD("greatest", GREATEST, COL_NAME_KEYWORD)
PG_KEYWORD("group", GROUP_P, RESERVED_KEYWORD)
PG_KEYWORD("handler", HANDLER, UNRESERVED_KEYWORD)
+#ifdef PGXC
+PG_KEYWORD("hash", HASH, UNRESERVED_KEYWORD)
+#endif
PG_KEYWORD("having", HAVING, RESERVED_KEYWORD)
PG_KEYWORD("header", HEADER_P, UNRESERVED_KEYWORD)
PG_KEYWORD("hold", HOLD, UNRESERVED_KEYWORD)
@@ -243,6 +252,7 @@ PG_KEYWORD("no", NO, UNRESERVED_KEYWORD)
PG_KEYWORD("nocreatedb", NOCREATEDB, UNRESERVED_KEYWORD)
PG_KEYWORD("nocreaterole", NOCREATEROLE, UNRESERVED_KEYWORD)
PG_KEYWORD("nocreateuser", NOCREATEUSER, UNRESERVED_KEYWORD)
+PG_KEYWORD("node", NODE, UNRESERVED_KEYWORD)
PG_KEYWORD("noinherit", NOINHERIT, UNRESERVED_KEYWORD)
PG_KEYWORD("nologin", NOLOGIN_P, UNRESERVED_KEYWORD)
PG_KEYWORD("none", NONE, COL_NAME_KEYWORD)
@@ -308,6 +318,9 @@ PG_KEYWORD("rename", RENAME, UNRESERVED_KEYWORD)
PG_KEYWORD("repeatable", REPEATABLE, UNRESERVED_KEYWORD)
PG_KEYWORD("replace", REPLACE, UNRESERVED_KEYWORD)
PG_KEYWORD("replica", REPLICA, UNRESERVED_KEYWORD)
+#ifdef PGXC
+PG_KEYWORD("replication", REPLICATION, UNRESERVED_KEYWORD)
+#endif
PG_KEYWORD("reset", RESET, UNRESERVED_KEYWORD)
PG_KEYWORD("restart", RESTART, UNRESERVED_KEYWORD)
PG_KEYWORD("restrict", RESTRICT, UNRESERVED_KEYWORD)
@@ -315,8 +328,14 @@ PG_KEYWORD("returning", RETURNING, RESERVED_KEYWORD)
PG_KEYWORD("returns", RETURNS, UNRESERVED_KEYWORD)
PG_KEYWORD("revoke", REVOKE, UNRESERVED_KEYWORD)
PG_KEYWORD("right", RIGHT, TYPE_FUNC_NAME_KEYWORD)
+#ifdef PGXC
+PG_KEYWORD("robin", ROBIN, UNRESERVED_KEYWORD)
+#endif
PG_KEYWORD("role", ROLE, UNRESERVED_KEYWORD)
PG_KEYWORD("rollback", ROLLBACK, UNRESERVED_KEYWORD)
+#ifdef PGXC
+PG_KEYWORD("round", ROUND, UNRESERVED_KEYWORD)
+#endif
PG_KEYWORD("row", ROW, COL_NAME_KEYWORD)
PG_KEYWORD("rows", ROWS, UNRESERVED_KEYWORD)
PG_KEYWORD("rule", RULE, UNRESERVED_KEYWORD)
diff --git a/src/include/parser/parse_utilcmd.h b/src/include/parser/parse_utilcmd.h
index 089c907c0e..319699381d 100644
--- a/src/include/parser/parse_utilcmd.h
+++ b/src/include/parser/parse_utilcmd.h
@@ -6,6 +6,7 @@
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
*
* $PostgreSQL: pgsql/src/include/parser/parse_utilcmd.h,v 1.4 2009/01/01 17:24:00 momjian Exp $
*
@@ -24,5 +25,8 @@ extern IndexStmt *transformIndexStmt(IndexStmt *stmt, const char *queryString);
extern void transformRuleStmt(RuleStmt *stmt, const char *queryString,
List **actions, Node **whereClause);
extern List *transformCreateSchemaStmt(CreateSchemaStmt *stmt);
+#ifdef PGXC
+extern bool CheckLocalIndexColumn (char loctype, char *partcolname, char *indexcolname);
+#endif
#endif /* PARSE_UTILCMD_H */
diff --git a/src/include/pgxc/combiner.h b/src/include/pgxc/combiner.h
new file mode 100644
index 0000000000..8c02627b57
--- /dev/null
+++ b/src/include/pgxc/combiner.h
@@ -0,0 +1,63 @@
+/*-------------------------------------------------------------------------
+ *
+ * combiner.h
+ *
+ * Combine responses from multiple Data Nodes
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group ?
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * IDENTIFICATION
+ * $$
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef COMBINER_H
+#define COMBINER_H
+
+#include "postgres.h"
+#include "tcop/dest.h"
+
+typedef enum
+{
+ COMBINE_TYPE_NONE, /* it is known that no row count, do not parse */
+ COMBINE_TYPE_SUM, /* sum row counts (partitioned, round robin) */
+ COMBINE_TYPE_AVG /* calculate average (replicated) */
+} CombineType;
+
+typedef enum
+{
+ REQUEST_TYPE_NOT_DEFINED, /* not determined yet */
+ REQUEST_TYPE_COMMAND, /* OK or row count response */
+ REQUEST_TYPE_QUERY, /* Row description response */
+ REQUEST_TYPE_COPY_IN, /* Copy In response */
+ REQUEST_TYPE_COPY_OUT /* Copy Out response */
+} RequestType;
+
+
+typedef struct
+{
+ int node_count;
+ CombineType combine_type;
+ CommandDest dest;
+ int command_complete_count;
+ int row_count;
+ RequestType request_type;
+ int description_count;
+ List *simple_aggregates;
+} ResponseCombinerData;
+
+
+typedef ResponseCombinerData *ResponseCombiner;
+
+extern ResponseCombiner CreateResponseCombiner(int node_count,
+ CombineType combine_type, CommandDest dest);
+extern int CombineResponse(ResponseCombiner combiner, char msg_type,
+ char *msg_body, size_t len);
+extern bool ValidateAndCloseCombiner(ResponseCombiner combiner);
+extern bool ValidateAndResetCombiner(ResponseCombiner combiner);
+extern void AssignCombinerAggregates(ResponseCombiner combiner, List *simple_aggregates);
+
+#endif /* COMBINER_H */
diff --git a/src/include/pgxc/datanode.h b/src/include/pgxc/datanode.h
new file mode 100644
index 0000000000..e140445a28
--- /dev/null
+++ b/src/include/pgxc/datanode.h
@@ -0,0 +1,76 @@
+/*-------------------------------------------------------------------------
+ *
+ * datanode.h
+ *
+ * Utility functions to communicate to Data Node
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group ?
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * IDENTIFICATION
+ * $$
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef DATANODE_H
+#define DATANODE_H
+#include "combiner.h"
+#include "nodes/pg_list.h"
+#include "utils/snapshot.h"
+#include <unistd.h>
+
+/* Connection to data node maintained by Pool Manager */
+typedef struct PGconn NODE_CONNECTION;
+
+/* Helper structure to access data node from Session */
+typedef enum
+{
+ DN_CONNECTION_STATE_IDLE,
+ DN_CONNECTION_STATE_BUSY,
+ DN_CONNECTION_STATE_COMPLETED,
+ DN_CONNECTION_STATE_ERROR
+
+} DNConnectionState;
+
+struct data_node_handle
+{
+ /* fd of the connection */
+ int sock;
+ /* Connection state */
+ char transaction_status;
+ DNConnectionState state;
+ char *error;
+ /* Output buffer */
+ char *outBuffer;
+ size_t outSize;
+ size_t outEnd;
+ /* Input buffer */
+ char *inBuffer;
+ size_t inSize;
+ size_t inStart;
+ size_t inEnd;
+ size_t inCursor;
+};
+typedef struct data_node_handle DataNodeHandle;
+
+extern void InitMultinodeExecutor(void);
+
+/* Open/close connection routines (invoked from Pool Manager) */
+extern char *DataNodeConnStr(char *host, char *port, char *dbname, char *user,
+ char *password);
+extern NODE_CONNECTION *DataNodeConnect(char *connstr);
+extern void DataNodeClose(NODE_CONNECTION * conn);
+extern int DataNodeConnected(NODE_CONNECTION * conn);
+extern int DataNodeConnClean(NODE_CONNECTION * conn);
+extern void DataNodeCleanAndRelease(int code, Datum arg);
+
+/* Multinode Executor */
+extern void DataNodeBegin(void);
+extern int DataNodeCommit(CommandDest dest);
+extern int DataNodeRollback(CommandDest dest);
+
+extern int DataNodeExec(const char *query, List *nodelist, CommandDest dest, Snapshot snapshot, bool force_autocommit, List *simple_aggregates, bool is_read_only);
+
+#endif
diff --git a/src/include/pgxc/locator.h b/src/include/pgxc/locator.h
new file mode 100644
index 0000000000..1320b3c6f6
--- /dev/null
+++ b/src/include/pgxc/locator.h
@@ -0,0 +1,66 @@
+/*-------------------------------------------------------------------------
+ *
+ * locator.h
+ * Externally declared locator functions
+ *
+ *
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ *
+ * IDENTIFICATION
+ * $$
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef LOCATOR_H
+#define LOCATOR_H
+
+#define LOCATOR_TYPE_REPLICATED 'R'
+#define LOCATOR_TYPE_HASH 'H'
+#define LOCATOR_TYPE_RANGE 'G'
+#define LOCATOR_TYPE_SINGLE 'S'
+#define LOCATOR_TYPE_RROBIN 'N'
+#define LOCATOR_TYPE_CUSTOM 'C'
+
+#define HASH_SIZE 4096
+#define HASH_MASK 0x00000FFF;
+
+#include "utils/relcache.h"
+
+
+typedef int PartAttrNumber;
+
+typedef struct
+{
+ Oid relid;
+ char locatorType;
+ PartAttrNumber partAttrNum; /* if partitioned */
+ char *partAttrName; /* if partitioned */
+ int nodeCount;
+ List *nodeList;
+ ListCell *roundRobinNode; /* points to next one to use */
+} RelationLocInfo;
+
+
+extern char *PreferredDataNodes;
+
+extern void InitRelationLocInfo();
+extern char GetLocatorType(Oid relid);
+extern char ConvertToLocatorType(int disttype);
+
+extern char *GetRelationHashColumn(RelationLocInfo * rel_loc_info);
+extern RelationLocInfo *GetRelationLocInfo(Oid relid);
+extern RelationLocInfo *CopyRelationLocInfo(RelationLocInfo * src_info);
+extern List *GetRelationNodes(RelationLocInfo * rel_loc_info, long *partValue,
+ int isRead);
+extern bool IsHashColumn(RelationLocInfo * rel_loc_info, char *part_col_name);
+extern bool IsHashColumnForRelId(Oid relid, char *part_col_name);
+extern int GetRoundRobinNode(Oid relid);
+
+extern bool IsHashDistributable(Oid col_type);
+extern List *GetAllNodes(void);
+extern int GetAnyDataNode(void);
+extern void RelationBuildLocator(Relation rel);
+extern void FreeRelationLocInfo(RelationLocInfo * relationLocInfo);
+
+#endif /* LOCATOR_H */
diff --git a/src/include/pgxc/pgxc.h b/src/include/pgxc/pgxc.h
new file mode 100644
index 0000000000..09ff2c0ada
--- /dev/null
+++ b/src/include/pgxc/pgxc.h
@@ -0,0 +1,23 @@
+/*-------------------------------------------------------------------------
+ *
+ * pgxc.h
+ * PG-XC
+ *
+ *
+ * Portions Copyright (c) 1996-2010 PostgreSQL Global Development Group
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * IDENTIFICATION
+ * $$
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifdef PGXC
+
+extern bool isPGXCCoordinator;
+extern bool isPGXCDataNode;
+
+#define IS_PGXC_COORDINATOR isPGXCCoordinator
+#define IS_PGXC_DATANODE isPGXCDataNode
+
+#endif /* PGXC */
diff --git a/src/include/pgxc/planner.h b/src/include/pgxc/planner.h
new file mode 100644
index 0000000000..eda25a72bb
--- /dev/null
+++ b/src/include/pgxc/planner.h
@@ -0,0 +1,86 @@
+/*-------------------------------------------------------------------------
+ *
+ * planner.h
+ * Externally declared locator functions
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group ?
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * IDENTIFICATION
+ * $$
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PGXCPLANNER_H
+#define PGXCPLANNER_H
+
+/* for Query_Plan.exec_loc_type can have these OR'ed*/
+#define EXEC_ON_COORD 0x1
+#define EXEC_ON_DATA_NODES 0x2
+
+/* Contains instructions on processing a step of a query.
+ * In the prototype this will be simple, but it will eventually
+ * evolve into a GridSQL-style QueryStep.
+ */
+typedef struct
+{
+ char *sql_statement;
+ List *nodelist;
+ List *simple_aggregates; /* simple aggregate to combine on this
+ * step */
+} Query_Step;
+
+
+/*
+ * The PGXC plan to execute.
+ * In the prototype this will be simple, and queryStepList will
+ * contain just one step.
+ */
+typedef struct
+{
+ int exec_loc_type;
+ bool force_autocommit; /* For CREATE DATABASE */
+ List *query_step_list; /* List of QuerySteps */
+} Query_Plan;
+
+
+/* For handling simple aggregates (no group by present)
+ * For now, only MAX will be supported.
+ */
+typedef enum
+{
+ AGG_TYPE_MAX,
+ AGG_TYPE_MIN,
+ AGG_TYPE_COUNT,
+ AGG_TYPE_SUM,
+ AGG_TYPE_AVG
+} SimpleAggType;
+
+
+/* For handling simple aggregates */
+/* For now, only support int/long types */
+typedef struct
+{
+ int agg_type; /* SimpleAggType enum */
+ int column_pos; /* Only use 1 for now */
+ unsigned long ulong_value;
+ /* Datum agg_value; PGXCTODO - use Datum, support more types */
+ int data_len;
+ int agg_data_type;
+ int response_count;
+} SimpleAgg;
+
+/* forbid SQL if unsafe, useful to turn off for development */
+extern bool StrictStatementChecking;
+
+/* forbid SELECT even multi-node ORDER BY */
+extern bool StrictSelectChecking;
+
+extern Query_Plan *
+ GetQueryPlan(Node *parsetree, const char *sql_statement, List *querytree_list);
+extern void
+ FreeQueryPlan(Query_Plan * query_plan);
+extern bool IsHashDistributable(Oid col_type);
+
+#endif /* PGXCPLANNER_H */
diff --git a/src/include/pgxc/poolcomm.h b/src/include/pgxc/poolcomm.h
new file mode 100644
index 0000000000..3c62f0662e
--- /dev/null
+++ b/src/include/pgxc/poolcomm.h
@@ -0,0 +1,49 @@
+/*-------------------------------------------------------------------------
+ *
+ * poolcomm.h
+ *
+ * Definitions for the Pooler-Seesion communications.
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * IDENTIFICATION
+ * $$
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef POOLCOMM_H
+#define POOLCOMM_H
+
+#include "lib/stringinfo.h"
+
+#define POOL_BUFFER_SIZE 1024
+#define Socket(port) (port).fdsock
+
+typedef struct
+{
+ /* file descriptors */
+ int fdsock;
+ /* receive buffer */
+ int RecvLength;
+ int RecvPointer;
+ char RecvBuffer[POOL_BUFFER_SIZE];
+ /* send buffer */
+ int SendPointer;
+ char SendBuffer[POOL_BUFFER_SIZE];
+} PoolPort;
+
+extern int pool_listen(unsigned short port, const char *unixSocketName);
+extern int pool_connect(unsigned short port, const char *unixSocketName);
+extern int pool_getbyte(PoolPort * port);
+extern int pool_pollbyte(PoolPort * port);
+extern int pool_getmessage(PoolPort * port, StringInfo s, int maxlen);
+extern int pool_getbytes(PoolPort * port, char *s, size_t len);
+extern int pool_putmessage(PoolPort * port, char msgtype, const char *s, size_t len);
+extern int pool_putbytes(PoolPort * port, const char *s, size_t len);
+extern int pool_flush(PoolPort * port);
+extern int pool_sendfds(PoolPort * port, int *fds, int count);
+extern int pool_recvfds(PoolPort * port, int *fds, int count);
+
+#endif /* POOLCOMM_H */
diff --git a/src/include/pgxc/poolmgr.h b/src/include/pgxc/poolmgr.h
new file mode 100644
index 0000000000..6e88fca3bc
--- /dev/null
+++ b/src/include/pgxc/poolmgr.h
@@ -0,0 +1,130 @@
+/*-------------------------------------------------------------------------
+ *
+ * poolmgr.h
+ *
+ * Definitions for the data nodes connection pool.
+ *
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
+ *
+ * IDENTIFICATION
+ * $$
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef POOLMGR_H
+#define POOLMGR_H
+#include <sys/time.h>
+#include "datanode.h"
+#include "poolcomm.h"
+#include "storage/pmsignal.h"
+
+#define MAX_IDLE_TIME 60
+
+/* TODO move? */
+typedef struct
+{
+ char *host;
+ char *port;
+ char *uname;
+ char *password;
+} DataNodeConnectionInfo;
+
+/* Connection pool entry */
+typedef struct
+{
+ struct timeval released;
+ NODE_CONNECTION *conn;
+} DataNodePoolSlot;
+
+/* Pool of connections to specified data nodes */
+typedef struct
+{
+ char *connstr;
+ int freeSize; /* available connections */
+ int size; /* total pool size */
+ DataNodePoolSlot **slot;
+} DataNodePool;
+
+/* All pools for specified database */
+typedef struct databasepool
+{
+ Oid databaseId;
+ char *database;
+ DataNodePool **nodePools; /* one for each data node */
+ struct databasepool *next;
+} DatabasePool;
+
+/* Agent of client session (Pool Manager side)
+ * Acts as a session manager, grouping connections together
+ */
+typedef struct
+{
+ /* communication channel */
+ PoolPort port;
+ DatabasePool *pool;
+ DataNodePoolSlot **connections; /* one for each data node */
+} PoolAgent;
+
+/* Handle to the pool manager (Session's side) */
+typedef struct
+{
+ /* communication channel */
+ PoolPort port;
+} PoolHandle;
+
+extern int NumDataNodes;
+extern int MinPoolSize;
+extern int MaxPoolSize;
+extern int PoolerPort;
+
+extern bool PersistentConnections;
+
+extern char *DataNodeHosts;
+extern char *DataNodePorts;
+extern char *DataNodeUsers;
+extern char *DataNodePwds;
+
+/* Initialize internal structures */
+extern int PoolManagerInit(void);
+
+/* Destroy internal structures */
+extern int PoolManagerDestroy(void);
+
+/*
+ * Get handle to pool manager. This function should be called just before
+ * forking off new session. It creates PoolHandle, PoolAgent and a pipe between
+ * them. PoolAgent is stored within Postmaster's memory context and Session
+ * closes it later. PoolHandle is returned and should be store in a local
+ * variable. After forking off it can be stored in global memory, so it will
+ * only be accessible by the process running the session.
+ */
+extern PoolHandle *GetPoolManagerHandle(void);
+
+/*
+ * Called from Postmaster(Coordinator) after fork. Close one end of the pipe and
+ * free memory occupied by PoolHandler
+ */
+extern void PoolManagerCloseHandle(PoolHandle * handle);
+
+/*
+ * Gracefully close connection to the PoolManager
+ */
+extern void PoolManagerDisconnect(PoolHandle * handle);
+
+/*
+ * Called from Session process after fork(). Associate handle with session
+ * for subsequent calls. Associate session with specified database and
+ * initialize respective connection pool
+ */
+extern void PoolManagerConnect(PoolHandle * handle, const char *database, List *nodes);
+
+/* Get pooled connections */
+extern int *PoolManagerGetConnections(List *nodelist);
+
+/* Retun connections back to the pool */
+extern void PoolManagerReleaseConnections(void);
+
+#endif
diff --git a/src/include/postgres.h b/src/include/postgres.h
index c1e4f77386..e8bfd5a391 100644
--- a/src/include/postgres.h
+++ b/src/include/postgres.h
@@ -9,6 +9,7 @@
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1995, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
*
* $PostgreSQL: pgsql/src/include/postgres.h,v 1.92 2009/01/01 17:23:55 momjian Exp $
*
@@ -693,4 +694,7 @@ extern int ExceptionalCondition(const char *conditionName,
const char *errorType,
const char *fileName, int lineNumber);
+//#define PGXC_COORD // for PGXC coordinator compiling
+//#define PGXC_DATANODE // for PGXC data node compiling
+
#endif /* POSTGRES_H */
diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h
index 3175487af3..952291bcb0 100644
--- a/src/include/postmaster/autovacuum.h
+++ b/src/include/postmaster/autovacuum.h
@@ -6,6 +6,7 @@
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
*
* $PostgreSQL: pgsql/src/include/postmaster/autovacuum.h,v 1.15 2009/01/01 17:24:01 momjian Exp $
*
@@ -60,4 +61,8 @@ extern void AutovacuumLauncherIAm(void);
extern Size AutoVacuumShmemSize(void);
extern void AutoVacuumShmemInit(void);
+#ifdef PGXC /* PGXC_DATANODE */
+bool IsAutoVacuumWorkerProcess(void);
+#endif
+
#endif /* AUTOVACUUM_H */
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index b250d3f0f2..66a920ded0 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -143,8 +143,9 @@ typedef struct PROC_HDR
* normal operation. Startup process also consumes one slot, but WAL
* writer and autovacuum launcher are launched only after it has
* exited.
+ * Also pool manager process is added
*/
-#define NUM_AUXILIARY_PROCS 3
+#define NUM_AUXILIARY_PROCS 4
/* configurable options */
diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h
index fab84ee1a0..4431e1bc54 100644
--- a/src/include/storage/procarray.h
+++ b/src/include/storage/procarray.h
@@ -6,6 +6,7 @@
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
*
* $PostgreSQL: pgsql/src/include/storage/procarray.h,v 1.26 2009/06/11 14:49:12 momjian Exp $
*
@@ -26,6 +27,10 @@ extern void ProcArrayRemove(PGPROC *proc, TransactionId latestXid);
extern void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid);
extern void ProcArrayClearTransaction(PGPROC *proc);
+#ifdef PGXC /* PGXC_DATANODE */
+extern void SetGlobalSnapshotData(int xmin, int xmax, int xcnt, int *xip);
+extern void UnsetGlobalSnapshotData(void);
+#endif /* PGXC */
extern Snapshot GetSnapshotData(Snapshot snapshot);
extern bool TransactionIdIsInProgress(TransactionId xid);
diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h
index b50944a547..9c87386288 100644
--- a/src/include/utils/guc_tables.h
+++ b/src/include/utils/guc_tables.h
@@ -76,7 +76,9 @@ enum config_group
COMPAT_OPTIONS_CLIENT,
PRESET_OPTIONS,
CUSTOM_OPTIONS,
- DEVELOPER_OPTIONS
+ DEVELOPER_OPTIONS,
+ DATA_NODES,
+ GTM
};
/*
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index ca9913bda3..5f3a482877 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -6,6 +6,7 @@
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
*
* $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.114 2009/06/11 14:49:13 momjian Exp $
*
@@ -20,6 +21,9 @@
#include "catalog/pg_index.h"
#include "fmgr.h"
#include "nodes/bitmapset.h"
+#ifdef PGXC
+#include "pgxc/locator.h"
+#endif
#include "rewrite/prs2lock.h"
#include "storage/block.h"
#include "storage/relfilenode.h"
@@ -205,6 +209,9 @@ typedef struct RelationData
/* use "struct" here to avoid needing to include pgstat.h: */
struct PgStat_TableStatus *pgstat_info; /* statistics collection area */
+#ifdef PGXC
+ RelationLocInfo *rd_locator_info;
+#endif
} RelationData;
/*
diff --git a/src/include/utils/snapshot.h b/src/include/utils/snapshot.h
index e5003b669a..835ba95291 100644
--- a/src/include/utils/snapshot.h
+++ b/src/include/utils/snapshot.h
@@ -5,6 +5,7 @@
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
*
* $PostgreSQL: pgsql/src/include/utils/snapshot.h,v 1.5 2009/06/11 14:49:13 momjian Exp $
*
@@ -46,7 +47,11 @@ typedef struct SnapshotData
*/
TransactionId xmin; /* all XID < xmin are visible to me */
TransactionId xmax; /* all XID >= xmax are invisible to me */
+ TransactionId recent_global_xmin;
uint32 xcnt; /* # of xact ids in xip[] */
+#ifdef PGXC /* PGXC_COORD */
+ uint32 max_xcnt; /* Max # of xact in xip[] */
+#endif
TransactionId *xip; /* array of xact IDs in progress */
/* note: all ids in xip[] satisfy xmin <= xip[i] < xmax */
int32 subxcnt; /* # of xact ids in subxip[], -1 if overflow */
diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
index 1428b28d15..e038041519 100644
--- a/src/include/utils/syscache.h
+++ b/src/include/utils/syscache.h
@@ -8,6 +8,7 @@
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 2010 Nippon Telegraph and Telephone Corporation
*
* $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.74 2009/01/01 17:24:02 momjian Exp $
*
@@ -64,6 +65,9 @@ enum SysCacheIdentifier
OPEROID,
OPFAMILYAMNAMENSP,
OPFAMILYOID,
+#ifdef PGXC
+ PGXCCLASSRELID,
+#endif
PROCNAMEARGSNSP,
PROCOID,
RELNAMENSP,