Add a developer GUC "enable_datanode_row_triggers" to allow ROW TRIGGERS to be
authorPavan Deolasee <[email protected]>
Tue, 15 Dec 2015 08:17:32 +0000 (13:47 +0530)
committerPavan Deolasee <[email protected]>
Tue, 15 Dec 2015 08:17:32 +0000 (13:47 +0530)
executed on the datanodes.

This must be used with caution. Postgres-XL does not officially support
triggers yet. One of the reasons for not supporting triggers is that a trigger
function executed on a datanode may not have access to all the required data
since the data may not reside on the datanode. But if users are confident that
the triggers can be safely executed on the datanode, they may turn this GUC on.
Still since the feature is not well tested, we don't recommend users to use
this without thorough testing and knowing consequences.

src/backend/commands/trigger.c
src/backend/tcop/utility.c
src/backend/utils/misc/guc.c
src/include/commands/trigger.h
src/pl/plpgsql/src/pl_exec.c

index e1081b09736b95a2805baec057c8907f2fcbf240..60399283674ccbf93e068262ec17d90adf6e5670 100644 (file)
@@ -106,6 +106,9 @@ static void AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo,
                                          List *recheckIndexes, Bitmapset *modifiedCols);
 static void AfterTriggerEnlargeQueryState(void);
 
+#ifdef XCP
+bool enable_datanode_row_triggers;
+#endif
 
 /*
  * Create a trigger.  Returns the address of the created trigger.
index 90a68c7e648bf0ed533ae22ba3236f9c298a848e..79d2b922be844b9d59a18212fe0c849896de3112 100644 (file)
@@ -2273,11 +2273,30 @@ ProcessUtilitySlow(Node *parsetree,
 
                        case T_CreateTrigStmt:
 #ifdef PGXC
-                               /* Postgres-XC does not support yet triggers */
-                               ereport(ERROR,
-                                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                                errmsg("Postgres-XL does not support TRIGGER yet"),
-                                                errdetail("The feature is not currently supported")));
+                               if (!enable_datanode_row_triggers)
+                               {
+                                       /* Postgres-XC does not support yet triggers */
+                                       ereport(ERROR,
+                                                       (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                                                        errmsg("Postgres-XL does not support TRIGGER yet"),
+                                                        errdetail("The feature is not currently supported")));
+                               }
+                               else
+                               {
+                                       if (!((CreateTrigStmt *) parsetree)->row)
+                                               ereport(ERROR,
+                                                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                                                                errmsg("STATEMENT triggers not supported"),
+                                                                errhint("Though enable_datanode_row_triggers "
+                                                                        "is ON, Postgres-XL only supports ROW "
+                                                                        "triggers")));
+                                       else
+                                               elog(WARNING, "Developer option "
+                                                               "enable_datanode_row_triggers is ON. "
+                                                               "Triggers will be executed on the datanodes "
+                                                               "and must not require access to other nodes. "
+                                                               "Use with caution");
+                               }
 
                                if (IS_PGXC_LOCAL_COORDINATOR)
                                        ExecUtilityStmtOnNodes(queryString, NULL, sentToRemote, false, EXEC_ON_ALL_NODES, false);
index e735c0ac17f6c47ac3e0b6c7cce9e8f0e7248533..ad4a28bdffe1fe57c830f2b8405614bb825b51c7 100644 (file)
@@ -64,6 +64,7 @@
 #include "pgstat.h"
 #ifdef PGXC
 #include "commands/tablecmds.h"
+#include "commands/trigger.h"
 #include "nodes/nodes.h"
 #include "pgxc/execRemote.h"
 #include "pgxc/locator.h"
@@ -961,6 +962,15 @@ static struct config_bool ConfigureNamesBool[] =
                false,
                NULL, NULL, NULL
        },
+       {
+               {"enable_datanode_row_triggers", PGC_POSTMASTER, DEVELOPER_OPTIONS,
+                       gettext_noop("Enables datanode-only ROW triggers"),
+                       NULL
+               },
+               &enable_datanode_row_triggers,
+               false,
+               NULL, NULL, NULL
+       },
 #endif
        {
                {"geqo", PGC_USERSET, QUERY_TUNING_GEQO,
index 72a6b4a31bbb4cc996cc677a44a7221e7d44a1ee..f14507d337c41c6787764f80f100deb6b1d8da96 100644 (file)
@@ -100,6 +100,10 @@ typedef struct TriggerData
 #define SESSION_REPLICATION_ROLE_LOCAL         2
 extern PGDLLIMPORT int SessionReplicationRole;
 
+#ifdef XCP
+extern bool enable_datanode_row_triggers;
+#endif
+
 /*
  * States at which a trigger can be fired. These are the
  * possible values for pg_trigger.tgenabled.
index 71b01c2570dde330c2c6ff53227adabda4a1848b..87c2d1da79baee3908419949366102483346180e 100644 (file)
@@ -3537,7 +3537,7 @@ exec_stmt_execsql(PLpgSQL_execstate *estate,
                                        /* PGXCTODO: Support a better parameter interface for XC with DMLs */
                                        if
 #ifdef XCP
-                                          (IS_PGXC_DATANODE &&
+                                          (IS_PGXC_DATANODE && !enable_datanode_row_triggers &&
 #endif
                                                (q->commandType == CMD_INSERT ||
                                                 q->commandType == CMD_UPDATE ||