>From d5668f66fccf5118793717a85bd55dd416ede023 Mon Sep 17 00:00:00 2001
From: Alvaro Herrera <alvherre@alvh.no-ip.org>
Date: Mon, 23 Mar 2015 19:40:17 -0300
Subject: [PATCH 33/37] deparse: infrastructure for ALTER TEXT SEARCH CONFIG
 support

---
 src/backend/commands/event_trigger.c | 34 +++++++++++++++++++++++++++++++++-
 src/backend/commands/tsearchcmds.c   |  5 +++++
 src/backend/nodes/copyfuncs.c        |  1 +
 src/backend/nodes/equalfuncs.c       |  1 +
 src/backend/parser/gram.y            |  6 ++++++
 src/backend/tcop/deparse_utility.c   |  3 +++
 src/include/commands/event_trigger.h |  2 ++
 src/include/nodes/parsenodes.h       | 10 ++++++++++
 src/include/tcop/deparse_utility.h   | 11 ++++++++++-
 9 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
index ba97550..a01b90b 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -24,6 +24,7 @@
 #include "catalog/pg_opfamily.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_trigger.h"
+#include "catalog/pg_ts_config.h"
 #include "catalog/pg_type.h"
 #include "commands/dbcommands.h"
 #include "commands/event_trigger.h"
@@ -1914,6 +1915,32 @@ EventTriggerStashCreateOpClass(CreateOpClassStmt *stmt, Oid opcoid,
 	MemoryContextSwitchTo(oldcxt);
 }
 
+void
+EventTriggerStashAlterTSConfig(AlterTSConfigurationStmt *stmt, Oid cfgId,
+							   Oid *dictIds, int ndicts)
+{
+	MemoryContext	oldcxt;
+	StashedCommand *stashed;
+
+	if (currentEventTriggerState->commandCollectionInhibited)
+		return;
+
+	oldcxt = MemoryContextSwitchTo(currentEventTriggerState->cxt);
+
+	stashed = palloc0(sizeof(StashedCommand));
+	stashed->type = SCT_AlterTSConfig;
+	stashed->in_extension = creating_extension;
+	stashed->d.atscfg.tscfgOid = cfgId;
+	stashed->d.atscfg.dictIds = palloc(sizeof(Oid) * ndicts);
+	memcpy(stashed->d.atscfg.dictIds, dictIds, sizeof(Oid) * ndicts);
+	stashed->d.atscfg.ndicts = ndicts;
+	stashed->parsetree = copyObject(stmt);
+
+	currentEventTriggerState->stash = lappend(currentEventTriggerState->stash,
+											  stashed);
+
+	MemoryContextSwitchTo(oldcxt);
+}
 
 /*
  * EventTriggerStashAlterDefPrivs
@@ -2042,7 +2069,8 @@ pg_event_trigger_get_creation_commands(PG_FUNCTION_ARGS)
 		if (cmd->type == SCT_Simple ||
 			cmd->type == SCT_AlterTable ||
 			cmd->type == SCT_AlterOpFamily ||
-			cmd->type == SCT_CreateOpClass)
+			cmd->type == SCT_CreateOpClass ||
+			cmd->type == SCT_AlterTSConfig)
 		{
 			const char *tag;
 			char	   *identity;
@@ -2063,6 +2091,10 @@ pg_event_trigger_get_creation_commands(PG_FUNCTION_ARGS)
 				ObjectAddressSet(addr,
 								 OperatorClassRelationId,
 								 cmd->d.createopc.opcOid);
+			else if (cmd->type == SCT_AlterTSConfig)
+				ObjectAddressSet(addr,
+								 TSConfigRelationId,
+								 cmd->d.atscfg.tscfgOid);
 
 			tag = CreateCommandTag(cmd->parsetree);
 
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 4c404e7..13eff3d 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -34,6 +34,7 @@
 #include "catalog/pg_type.h"
 #include "commands/alter.h"
 #include "commands/defrem.h"
+#include "commands/event_trigger.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "parser/parse_func.h"
@@ -1442,6 +1443,8 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
 			}
 		}
 	}
+
+	EventTriggerStashAlterTSConfig(stmt, cfgId, dictIds, ndict);
 }
 
 /*
@@ -1509,6 +1512,8 @@ DropConfigurationMapping(AlterTSConfigurationStmt *stmt,
 
 		i++;
 	}
+
+	EventTriggerStashAlterTSConfig(stmt, cfgId, NULL, 0);
 }
 
 
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 029761e..457735e 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -3879,6 +3879,7 @@ _copyAlterTSConfigurationStmt(const AlterTSConfigurationStmt *from)
 {
 	AlterTSConfigurationStmt *newnode = makeNode(AlterTSConfigurationStmt);
 
+	COPY_SCALAR_FIELD(kind);
 	COPY_NODE_FIELD(cfgname);
 	COPY_NODE_FIELD(tokentype);
 	COPY_NODE_FIELD(dicts);
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 190e50a..d830c4c 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1993,6 +1993,7 @@ static bool
 _equalAlterTSConfigurationStmt(const AlterTSConfigurationStmt *a,
 							   const AlterTSConfigurationStmt *b)
 {
+	COMPARE_SCALAR_FIELD(kind);
 	COMPARE_NODE_FIELD(cfgname);
 	COMPARE_NODE_FIELD(tokentype);
 	COMPARE_NODE_FIELD(dicts);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 3aa9e42..3a77120 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -8918,6 +8918,7 @@ AlterTSConfigurationStmt:
 			ALTER TEXT_P SEARCH CONFIGURATION any_name ADD_P MAPPING FOR name_list any_with any_name_list
 				{
 					AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
+					n->kind = ALTER_TSCONFIG_ADD_MAPPING;
 					n->cfgname = $5;
 					n->tokentype = $9;
 					n->dicts = $11;
@@ -8928,6 +8929,7 @@ AlterTSConfigurationStmt:
 			| ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list any_with any_name_list
 				{
 					AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
+					n->kind = ALTER_TSCONFIG_ALTER_MAPPING_FOR_TOKEN;
 					n->cfgname = $5;
 					n->tokentype = $9;
 					n->dicts = $11;
@@ -8938,6 +8940,7 @@ AlterTSConfigurationStmt:
 			| ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING REPLACE any_name any_with any_name
 				{
 					AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
+					n->kind = ALTER_TSCONFIG_REPLACE_DICT;
 					n->cfgname = $5;
 					n->tokentype = NIL;
 					n->dicts = list_make2($9,$11);
@@ -8948,6 +8951,7 @@ AlterTSConfigurationStmt:
 			| ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list REPLACE any_name any_with any_name
 				{
 					AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
+					n->kind = ALTER_TSCONFIG_REPLACE_DICT_FOR_TOKEN;
 					n->cfgname = $5;
 					n->tokentype = $9;
 					n->dicts = list_make2($11,$13);
@@ -8958,6 +8962,7 @@ AlterTSConfigurationStmt:
 			| ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING FOR name_list
 				{
 					AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
+					n->kind = ALTER_TSCONFIG_DROP_MAPPING;
 					n->cfgname = $5;
 					n->tokentype = $9;
 					n->missing_ok = false;
@@ -8966,6 +8971,7 @@ AlterTSConfigurationStmt:
 			| ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING IF_P EXISTS FOR name_list
 				{
 					AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
+					n->kind = ALTER_TSCONFIG_DROP_MAPPING;
 					n->cfgname = $5;
 					n->tokentype = $11;
 					n->missing_ok = true;
diff --git a/src/backend/tcop/deparse_utility.c b/src/backend/tcop/deparse_utility.c
index 9a36894..b362adf 100644
--- a/src/backend/tcop/deparse_utility.c
+++ b/src/backend/tcop/deparse_utility.c
@@ -6903,6 +6903,9 @@ deparse_utility_command(StashedCommand *cmd)
 		case SCT_AlterDefaultPrivileges:
 			tree = deparse_AlterDefaultPrivilegesStmt(cmd);
 			break;
+		case SCT_AlterTSConfig:
+			tree = deparse_AlterTSConfigurationStmt(cmd);
+			break;
 		default:
 			elog(ERROR, "unexpected deparse node type %d", cmd->type);
 	}
diff --git a/src/include/commands/event_trigger.h b/src/include/commands/event_trigger.h
index 8d53e8b..b732fd9 100644
--- a/src/include/commands/event_trigger.h
+++ b/src/include/commands/event_trigger.h
@@ -78,6 +78,8 @@ extern void EventTriggerStashAlterOpFam(AlterOpFamilyStmt *stmt, Oid opfamoid,
 							List *operators, List *procedures);
 extern void EventTriggerStashCreateOpClass(CreateOpClassStmt *stmt, Oid opcoid,
 							   List *operators, List *procedures);
+extern void EventTriggerStashAlterTSConfig(AlterTSConfigurationStmt *stmt,
+							   Oid cfgId, Oid *dicts, int ndicts);
 extern void EventTriggerStashAlterDefPrivs(AlterDefaultPrivilegesStmt *stmt);
 
 #endif   /* EVENT_TRIGGER_H */
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 3ecfbac..3739eca 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -2851,9 +2851,19 @@ typedef struct AlterTSDictionaryStmt
 /*
  * TS Configuration stmts: DefineStmt, RenameStmt and DropStmt are default
  */
+typedef enum AlterTSConfigType
+{
+	ALTER_TSCONFIG_ADD_MAPPING,
+	ALTER_TSCONFIG_ALTER_MAPPING_FOR_TOKEN,
+	ALTER_TSCONFIG_REPLACE_DICT,
+	ALTER_TSCONFIG_REPLACE_DICT_FOR_TOKEN,
+	ALTER_TSCONFIG_DROP_MAPPING
+} AlterTSConfigType;
+
 typedef struct AlterTSConfigurationStmt
 {
 	NodeTag		type;
+	AlterTSConfigType	kind;	/* ALTER_TSCONFIG_ADD_MAPPING, etc */
 	List	   *cfgname;		/* qualified name (list of Value strings) */
 
 	/*
diff --git a/src/include/tcop/deparse_utility.h b/src/include/tcop/deparse_utility.h
index 6ee3ce2..0e80266 100644
--- a/src/include/tcop/deparse_utility.h
+++ b/src/include/tcop/deparse_utility.h
@@ -32,7 +32,8 @@ typedef enum StashedCommandType
 	SCT_Grant,
 	SCT_AlterOpFamily,
 	SCT_AlterDefaultPrivileges,
-	SCT_CreateOpClass
+	SCT_CreateOpClass,
+	SCT_AlterTSConfig
 } StashedCommandType;
 
 /*
@@ -91,6 +92,14 @@ typedef struct StashedCommand
 			List   *procedures;
 		} createopc;
 
+		/* ALTER TEXT SEARCH CONFIGURATION ADD/ALTER/DROP MAPPING */
+		struct
+		{
+			Oid		tscfgOid;
+			Oid	   *dictIds;
+			int		ndicts;
+		} atscfg;
+
 		/* ALTER DEFAULT PRIVILEGES */
 		struct
 		{
-- 
2.1.4

