>From b96f59cca4d2f172c579185add9516c18054aff0 Mon Sep 17 00:00:00 2001
From: Kouhei Sutou <kou@clear-code.com>
Date: Fri, 1 Jan 2016 16:54:50 +0900
Subject: [PATCH] Support dumping string index parameters of amindex extension

BUG #13840

pg_dump dumps string index parameters of amindex extension without
quote like:

    CREATE INDEX pgroonga_index ON t USING pgroonga (c) WITH (normalizer=none);

"normalizer=none" is syntax error because "none" isn't one of the
reserved keywords. pg_dump should dump "none" with quote like:

    CREATE INDEX pgroonga_index ON t USING pgroonga (c) WITH (normalizer='none');

This change quotes index parameter value when the value may be a string
value.
---
 src/backend/utils/adt/ruleutils.c | 63 ++++++++++++++++++++++++++++++++-------
 1 file changed, 52 insertions(+), 11 deletions(-)

diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 280808a..e9ece0f 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -56,6 +56,7 @@
 #include "utils/array.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
+#include "utils/guc.h"
 #include "utils/hsearch.h"
 #include "utils/lsyscache.h"
 #include "utils/rel.h"
@@ -9858,18 +9859,58 @@ flatten_reloptions(Oid relid)
 								 Anum_pg_class_reloptions, &isnull);
 	if (!isnull)
 	{
-		Datum		sep,
-					txt;
+		StringInfoData	buf;
+		Datum		   *options;
+		int				i;
+		int				noptions;
 
-		/*
-		 * We want to use array_to_text(reloptions, ', ') --- but
-		 * DirectFunctionCall2(array_to_text) does not work, because
-		 * array_to_text() relies on flinfo to be valid.  So use
-		 * OidFunctionCall2.
-		 */
-		sep = CStringGetTextDatum(", ");
-		txt = OidFunctionCall2(F_ARRAY_TO_TEXT, reloptions, sep);
-		result = TextDatumGetCString(txt);
+		initStringInfo(&buf);
+
+		deconstruct_array(DatumGetArrayTypeP(reloptions),
+						  TEXTOID, -1, false, 'i',
+						  &options, NULL, &noptions);
+
+		for (i = 0; i < noptions; i++)
+		{
+			char   *option;
+			char   *name;
+			char   *separator;
+			char   *value;
+
+			option = TextDatumGetCString(options[i]);
+			name = option;
+			separator = strchr(name, '=');
+			*separator = '\0';
+			value = separator + 1;
+
+			if (i > 0)
+				appendStringInfoString(&buf, ", ");
+
+			appendStringInfo(&buf, "%s=",  name);
+			if (parse_bool(value, NULL) ||
+				parse_int(value, NULL, 0, NULL) ||
+				parse_real(value, NULL))
+			{
+				appendStringInfoString(&buf, value);
+			}
+			else
+			{
+				char *v;
+				appendStringInfoString(&buf, "'");
+				for (v = value; *v != '\0'; v++)
+				{
+					if (*v == '\'')
+						appendStringInfo(&buf, "'%c", *v);
+					else
+						appendStringInfo(&buf, "%c", *v);
+				}
+				appendStringInfoString(&buf, "'");
+			}
+
+			pfree(option);
+		}
+
+		result = buf.data;
 	}
 
 	ReleaseSysCache(tuple);
-- 
2.6.4

