summaryrefslogtreecommitdiff
path: root/src/backend/commands/variable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/variable.c')
-rw-r--r--src/backend/commands/variable.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index f8f456e0e5..717bc39c01 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -4,6 +4,7 @@
* Routines for handling specialized SET variables.
*
*
+ * Portions Copyright (c) 2012-2014, TransLattice, Inc.
* Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
@@ -23,6 +24,9 @@
#include "access/xact.h"
#include "access/xlog.h"
#include "catalog/pg_authid.h"
+#ifdef XCP
+#include "catalog/pgxc_node.h"
+#endif
#include "commands/variable.h"
#include "miscadmin.h"
#include "utils/acl.h"
@@ -528,7 +532,14 @@ check_XactIsoLevel(char **newval, void **extra, GucSource source)
if (strcmp(*newval, "serializable") == 0)
{
+#ifdef PGXC
+ /*
+ * PGXCTODO - PGXC does not support 9.1 serializable transactions yet
+ */
+ newXactIsoLevel = XACT_REPEATABLE_READ;
+#else
newXactIsoLevel = XACT_SERIALIZABLE;
+#endif
}
else if (strcmp(*newval, "repeatable read") == 0)
{
@@ -586,6 +597,13 @@ void
assign_XactIsoLevel(const char *newval, void *extra)
{
XactIsoLevel = *((int *) extra);
+#ifdef PGXC
+ /*
+ * PGXCTODO - PGXC does not support 9.1 serializable transactions yet
+ */
+ if (XactIsoLevel == XACT_SERIALIZABLE)
+ XactIsoLevel = XACT_REPEATABLE_READ;
+#endif
}
const char *
@@ -852,6 +870,135 @@ assign_session_authorization(const char *newval, void *extra)
}
+#ifdef XCP
+
+/*
+ * SET GLOBAL SESSION
+ */
+
+typedef struct
+{
+ /* This is the "extra" state for GLOBAL SESSION */
+ Oid coordid;
+ int coordpid;
+} global_session_extra;
+
+
+bool
+check_global_session(char **newval, void **extra, GucSource source)
+{
+ HeapTuple coordTup;
+ Oid coordid;
+ char *separatorPos;
+ int coordpid;
+ global_session_extra *myextra;
+
+ /* Do nothing for the boot_val default of NULL */
+ if (*newval == NULL)
+ return true;
+
+ if (strcmp(*newval, "none") == 0)
+ {
+ /* hardwired translation */
+ coordid = InvalidOid;
+ coordpid = 0;
+ }
+ else
+ {
+ if (!IsTransactionState())
+ {
+ /*
+ * Can't do catalog lookups, so fail. The result of this is that
+ * global_session cannot be set in postgresql.conf, which seems
+ * like a good thing anyway, so we don't work hard to avoid it.
+ */
+ return false;
+ }
+
+ /*
+ * Get pointer on '_' character separating coordinator name from pid in the
+ * global session identifier
+ */
+ separatorPos = strrchr(*newval, '_');
+ if (separatorPos == NULL)
+ {
+ GUC_check_errmsg("malformed Global Session identifier: \"%s\"", *newval);
+ return false;
+ }
+
+ /*
+ * The pid is written immediately after the separator
+ */
+ coordpid = atoi(separatorPos + 1);
+ if (coordpid <= 0)
+ {
+ GUC_check_errmsg("malformed Global Session identifier: \"%s\"", *newval);
+ return false;
+ }
+
+
+ /*
+ * Temporary truncate the Global Session identifier to extract session name
+ */
+ *separatorPos = '\0';
+ /* Look up the nodename */
+ coordTup = SearchSysCache1(PGXCNODENAME, PointerGetDatum(*newval));
+ if (!HeapTupleIsValid(coordTup))
+ {
+ *separatorPos = '_';
+ GUC_check_errmsg("node \"%s\" does not exist", *newval);
+ return false;
+ }
+
+ if (((Form_pgxc_node) GETSTRUCT(coordTup))->node_type != PGXC_NODE_COORDINATOR)
+ {
+ ReleaseSysCache(coordTup);
+ *separatorPos = '_';
+ GUC_check_errmsg("node \"%s\" is not a coordinator", *newval);
+ return false;
+ }
+
+ coordid = HeapTupleGetOid(coordTup);
+
+ /*
+ * Save the coordinator name is a global variable so that we don't need
+ * to do catalog lookups later, especially if we running outside a
+ * transaction block or in an aborted transaction
+ */
+ if (OidIsValid(coordid))
+ strncpy(MyCoordName, *newval, NAMEDATALEN);
+
+ *separatorPos = '_';
+ ReleaseSysCache(coordTup);
+ }
+
+ /* Set up "extra" struct for assign_session_authorization to use */
+ myextra = (global_session_extra *) malloc(sizeof(global_session_extra));
+ if (!myextra)
+ return false;
+
+ myextra->coordid = coordid;
+ myextra->coordpid = coordpid;
+ *extra = (void *) myextra;
+
+ return true;
+}
+
+
+void
+assign_global_session(const char *newval, void *extra)
+{
+ global_session_extra *myextra = (global_session_extra *) extra;
+
+ /* Do nothing for the boot_val default of NULL */
+ if (!myextra)
+ return;
+
+ SetGlobalSession(myextra->coordid, myextra->coordpid);
+}
+#endif
+
+
/*
* SET ROLE
*