mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Teach pg_dump to quote reloption values safely.
Commit c7e27becd2 fixed this on the backend side, but we neglected
the fact that several code paths in pg_dump were printing reloptions
values that had not gotten massaged by ruleutils.  Apply essentially the
same quoting logic in those places, too.
			
			
This commit is contained in:
		@@ -265,6 +265,9 @@ static void binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
 | 
				
			|||||||
								const char *objlabel);
 | 
													const char *objlabel);
 | 
				
			||||||
static const char *getAttrName(int attrnum, TableInfo *tblInfo);
 | 
					static const char *getAttrName(int attrnum, TableInfo *tblInfo);
 | 
				
			||||||
static const char *fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer);
 | 
					static const char *fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer);
 | 
				
			||||||
 | 
					static bool nonemptyReloptions(const char *reloptions);
 | 
				
			||||||
 | 
					static void fmtReloptionsArray(Archive *fout, PQExpBuffer buffer,
 | 
				
			||||||
 | 
									   const char *reloptions, const char *prefix);
 | 
				
			||||||
static char *get_synchronized_snapshot(Archive *fout);
 | 
					static char *get_synchronized_snapshot(Archive *fout);
 | 
				
			||||||
static PGresult *ExecuteSqlQueryForSingleRow(Archive *fout, char *query);
 | 
					static PGresult *ExecuteSqlQueryForSingleRow(Archive *fout, char *query);
 | 
				
			||||||
static void setupDumpWorker(Archive *AHX, RestoreOptions *ropt);
 | 
					static void setupDumpWorker(Archive *AHX, RestoreOptions *ropt);
 | 
				
			||||||
@@ -4295,8 +4298,8 @@ getTables(Archive *fout, int *numTables)
 | 
				
			|||||||
						  "d.refobjid AS owning_tab, "
 | 
											  "d.refobjid AS owning_tab, "
 | 
				
			||||||
						  "d.refobjsubid AS owning_col, "
 | 
											  "d.refobjsubid AS owning_col, "
 | 
				
			||||||
						  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
 | 
											  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
 | 
				
			||||||
						"array_to_string(c.reloptions, ', ') AS reloptions, "
 | 
											  "c.reloptions AS reloptions, "
 | 
				
			||||||
						  "array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
 | 
											  "tc.reloptions AS toast_reloptions "
 | 
				
			||||||
						  "FROM pg_class c "
 | 
											  "FROM pg_class c "
 | 
				
			||||||
						  "LEFT JOIN pg_depend d ON "
 | 
											  "LEFT JOIN pg_depend d ON "
 | 
				
			||||||
						  "(c.relkind = '%c' AND "
 | 
											  "(c.relkind = '%c' AND "
 | 
				
			||||||
@@ -4333,8 +4336,8 @@ getTables(Archive *fout, int *numTables)
 | 
				
			|||||||
						  "d.refobjid AS owning_tab, "
 | 
											  "d.refobjid AS owning_tab, "
 | 
				
			||||||
						  "d.refobjsubid AS owning_col, "
 | 
											  "d.refobjsubid AS owning_col, "
 | 
				
			||||||
						  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
 | 
											  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
 | 
				
			||||||
						"array_to_string(c.reloptions, ', ') AS reloptions, "
 | 
											  "c.reloptions AS reloptions, "
 | 
				
			||||||
						  "array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
 | 
											  "tc.reloptions AS toast_reloptions "
 | 
				
			||||||
						  "FROM pg_class c "
 | 
											  "FROM pg_class c "
 | 
				
			||||||
						  "LEFT JOIN pg_depend d ON "
 | 
											  "LEFT JOIN pg_depend d ON "
 | 
				
			||||||
						  "(c.relkind = '%c' AND "
 | 
											  "(c.relkind = '%c' AND "
 | 
				
			||||||
@@ -4371,8 +4374,8 @@ getTables(Archive *fout, int *numTables)
 | 
				
			|||||||
						  "d.refobjid AS owning_tab, "
 | 
											  "d.refobjid AS owning_tab, "
 | 
				
			||||||
						  "d.refobjsubid AS owning_col, "
 | 
											  "d.refobjsubid AS owning_col, "
 | 
				
			||||||
						  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
 | 
											  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
 | 
				
			||||||
						"array_to_string(c.reloptions, ', ') AS reloptions, "
 | 
											  "c.reloptions AS reloptions, "
 | 
				
			||||||
						  "array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
 | 
											  "tc.reloptions AS toast_reloptions "
 | 
				
			||||||
						  "FROM pg_class c "
 | 
											  "FROM pg_class c "
 | 
				
			||||||
						  "LEFT JOIN pg_depend d ON "
 | 
											  "LEFT JOIN pg_depend d ON "
 | 
				
			||||||
						  "(c.relkind = '%c' AND "
 | 
											  "(c.relkind = '%c' AND "
 | 
				
			||||||
@@ -4408,8 +4411,8 @@ getTables(Archive *fout, int *numTables)
 | 
				
			|||||||
						  "d.refobjid AS owning_tab, "
 | 
											  "d.refobjid AS owning_tab, "
 | 
				
			||||||
						  "d.refobjsubid AS owning_col, "
 | 
											  "d.refobjsubid AS owning_col, "
 | 
				
			||||||
						  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
 | 
											  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
 | 
				
			||||||
						"array_to_string(c.reloptions, ', ') AS reloptions, "
 | 
											  "c.reloptions AS reloptions, "
 | 
				
			||||||
						  "array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
 | 
											  "tc.reloptions AS toast_reloptions "
 | 
				
			||||||
						  "FROM pg_class c "
 | 
											  "FROM pg_class c "
 | 
				
			||||||
						  "LEFT JOIN pg_depend d ON "
 | 
											  "LEFT JOIN pg_depend d ON "
 | 
				
			||||||
						  "(c.relkind = '%c' AND "
 | 
											  "(c.relkind = '%c' AND "
 | 
				
			||||||
@@ -4445,7 +4448,7 @@ getTables(Archive *fout, int *numTables)
 | 
				
			|||||||
						  "d.refobjid AS owning_tab, "
 | 
											  "d.refobjid AS owning_tab, "
 | 
				
			||||||
						  "d.refobjsubid AS owning_col, "
 | 
											  "d.refobjsubid AS owning_col, "
 | 
				
			||||||
						  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
 | 
											  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
 | 
				
			||||||
						"array_to_string(c.reloptions, ', ') AS reloptions, "
 | 
											  "c.reloptions AS reloptions, "
 | 
				
			||||||
						  "NULL AS toast_reloptions "
 | 
											  "NULL AS toast_reloptions "
 | 
				
			||||||
						  "FROM pg_class c "
 | 
											  "FROM pg_class c "
 | 
				
			||||||
						  "LEFT JOIN pg_depend d ON "
 | 
											  "LEFT JOIN pg_depend d ON "
 | 
				
			||||||
@@ -4896,7 +4899,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
 | 
				
			|||||||
				i_conoid,
 | 
									i_conoid,
 | 
				
			||||||
				i_condef,
 | 
									i_condef,
 | 
				
			||||||
				i_tablespace,
 | 
									i_tablespace,
 | 
				
			||||||
				i_options,
 | 
									i_indreloptions,
 | 
				
			||||||
				i_relpages;
 | 
									i_relpages;
 | 
				
			||||||
	int			ntups;
 | 
						int			ntups;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -4953,7 +4956,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
 | 
				
			|||||||
							  "c.oid AS conoid, "
 | 
												  "c.oid AS conoid, "
 | 
				
			||||||
				  "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
 | 
									  "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
 | 
				
			||||||
							  "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
 | 
												  "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
 | 
				
			||||||
							"array_to_string(t.reloptions, ', ') AS options "
 | 
												  "t.reloptions AS indreloptions "
 | 
				
			||||||
							  "FROM pg_catalog.pg_index i "
 | 
												  "FROM pg_catalog.pg_index i "
 | 
				
			||||||
					  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
 | 
										  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
 | 
				
			||||||
							  "LEFT JOIN pg_catalog.pg_constraint c "
 | 
												  "LEFT JOIN pg_catalog.pg_constraint c "
 | 
				
			||||||
@@ -4980,7 +4983,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
 | 
				
			|||||||
							  "c.oid AS conoid, "
 | 
												  "c.oid AS conoid, "
 | 
				
			||||||
							  "null AS condef, "
 | 
												  "null AS condef, "
 | 
				
			||||||
							  "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
 | 
												  "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
 | 
				
			||||||
							"array_to_string(t.reloptions, ', ') AS options "
 | 
												  "t.reloptions AS indreloptions "
 | 
				
			||||||
							  "FROM pg_catalog.pg_index i "
 | 
												  "FROM pg_catalog.pg_index i "
 | 
				
			||||||
					  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
 | 
										  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
 | 
				
			||||||
							  "LEFT JOIN pg_catalog.pg_depend d "
 | 
												  "LEFT JOIN pg_catalog.pg_depend d "
 | 
				
			||||||
@@ -5010,7 +5013,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
 | 
				
			|||||||
							  "c.oid AS conoid, "
 | 
												  "c.oid AS conoid, "
 | 
				
			||||||
							  "null AS condef, "
 | 
												  "null AS condef, "
 | 
				
			||||||
							  "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
 | 
												  "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
 | 
				
			||||||
							  "null AS options "
 | 
												  "null AS indreloptions "
 | 
				
			||||||
							  "FROM pg_catalog.pg_index i "
 | 
												  "FROM pg_catalog.pg_index i "
 | 
				
			||||||
					  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
 | 
										  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
 | 
				
			||||||
							  "LEFT JOIN pg_catalog.pg_depend d "
 | 
												  "LEFT JOIN pg_catalog.pg_depend d "
 | 
				
			||||||
@@ -5039,7 +5042,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
 | 
				
			|||||||
							  "c.oid AS conoid, "
 | 
												  "c.oid AS conoid, "
 | 
				
			||||||
							  "null AS condef, "
 | 
												  "null AS condef, "
 | 
				
			||||||
							  "NULL AS tablespace, "
 | 
												  "NULL AS tablespace, "
 | 
				
			||||||
							  "null AS options "
 | 
												  "null AS indreloptions "
 | 
				
			||||||
							  "FROM pg_catalog.pg_index i "
 | 
												  "FROM pg_catalog.pg_index i "
 | 
				
			||||||
					  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
 | 
										  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
 | 
				
			||||||
							  "LEFT JOIN pg_catalog.pg_depend d "
 | 
												  "LEFT JOIN pg_catalog.pg_depend d "
 | 
				
			||||||
@@ -5071,7 +5074,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
 | 
				
			|||||||
							  "t.oid AS conoid, "
 | 
												  "t.oid AS conoid, "
 | 
				
			||||||
							  "null AS condef, "
 | 
												  "null AS condef, "
 | 
				
			||||||
							  "NULL AS tablespace, "
 | 
												  "NULL AS tablespace, "
 | 
				
			||||||
							  "null AS options "
 | 
												  "null AS indreloptions "
 | 
				
			||||||
							  "FROM pg_index i, pg_class t "
 | 
												  "FROM pg_index i, pg_class t "
 | 
				
			||||||
							  "WHERE t.oid = i.indexrelid "
 | 
												  "WHERE t.oid = i.indexrelid "
 | 
				
			||||||
							  "AND i.indrelid = '%u'::oid "
 | 
												  "AND i.indrelid = '%u'::oid "
 | 
				
			||||||
@@ -5098,7 +5101,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
 | 
				
			|||||||
							  "t.oid AS conoid, "
 | 
												  "t.oid AS conoid, "
 | 
				
			||||||
							  "null AS condef, "
 | 
												  "null AS condef, "
 | 
				
			||||||
							  "NULL AS tablespace, "
 | 
												  "NULL AS tablespace, "
 | 
				
			||||||
							  "null AS options "
 | 
												  "null AS indreloptions "
 | 
				
			||||||
							  "FROM pg_index i, pg_class t "
 | 
												  "FROM pg_index i, pg_class t "
 | 
				
			||||||
							  "WHERE t.oid = i.indexrelid "
 | 
												  "WHERE t.oid = i.indexrelid "
 | 
				
			||||||
							  "AND i.indrelid = '%u'::oid "
 | 
												  "AND i.indrelid = '%u'::oid "
 | 
				
			||||||
@@ -5126,7 +5129,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
 | 
				
			|||||||
		i_conoid = PQfnumber(res, "conoid");
 | 
							i_conoid = PQfnumber(res, "conoid");
 | 
				
			||||||
		i_condef = PQfnumber(res, "condef");
 | 
							i_condef = PQfnumber(res, "condef");
 | 
				
			||||||
		i_tablespace = PQfnumber(res, "tablespace");
 | 
							i_tablespace = PQfnumber(res, "tablespace");
 | 
				
			||||||
		i_options = PQfnumber(res, "options");
 | 
							i_indreloptions = PQfnumber(res, "indreloptions");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		indxinfo = (IndxInfo *) pg_malloc(ntups * sizeof(IndxInfo));
 | 
							indxinfo = (IndxInfo *) pg_malloc(ntups * sizeof(IndxInfo));
 | 
				
			||||||
		constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
 | 
							constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
 | 
				
			||||||
@@ -5145,7 +5148,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
 | 
				
			|||||||
			indxinfo[j].indexdef = pg_strdup(PQgetvalue(res, j, i_indexdef));
 | 
								indxinfo[j].indexdef = pg_strdup(PQgetvalue(res, j, i_indexdef));
 | 
				
			||||||
			indxinfo[j].indnkeys = atoi(PQgetvalue(res, j, i_indnkeys));
 | 
								indxinfo[j].indnkeys = atoi(PQgetvalue(res, j, i_indnkeys));
 | 
				
			||||||
			indxinfo[j].tablespace = pg_strdup(PQgetvalue(res, j, i_tablespace));
 | 
								indxinfo[j].tablespace = pg_strdup(PQgetvalue(res, j, i_tablespace));
 | 
				
			||||||
			indxinfo[j].options = pg_strdup(PQgetvalue(res, j, i_options));
 | 
								indxinfo[j].indreloptions = pg_strdup(PQgetvalue(res, j, i_indreloptions));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/*
 | 
								/*
 | 
				
			||||||
			 * In pre-7.4 releases, indkeys may contain more entries than
 | 
								 * In pre-7.4 releases, indkeys may contain more entries than
 | 
				
			||||||
@@ -12896,8 +12899,12 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 | 
				
			|||||||
											 tbinfo->dobj.catId.oid, false);
 | 
																 tbinfo->dobj.catId.oid, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		appendPQExpBuffer(q, "CREATE VIEW %s", fmtId(tbinfo->dobj.name));
 | 
							appendPQExpBuffer(q, "CREATE VIEW %s", fmtId(tbinfo->dobj.name));
 | 
				
			||||||
		if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0)
 | 
							if (nonemptyReloptions(tbinfo->reloptions))
 | 
				
			||||||
			appendPQExpBuffer(q, " WITH (%s)", tbinfo->reloptions);
 | 
							{
 | 
				
			||||||
 | 
								appendPQExpBufferStr(q, " WITH (");
 | 
				
			||||||
 | 
								fmtReloptionsArray(fout, q, tbinfo->reloptions, "");
 | 
				
			||||||
 | 
								appendPQExpBufferChar(q, ')');
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		result = createViewAsClause(fout, tbinfo);
 | 
							result = createViewAsClause(fout, tbinfo);
 | 
				
			||||||
		appendPQExpBuffer(q, " AS\n%s;\n", result->data);
 | 
							appendPQExpBuffer(q, " AS\n%s;\n", result->data);
 | 
				
			||||||
		destroyPQExpBuffer(result);
 | 
							destroyPQExpBuffer(result);
 | 
				
			||||||
@@ -13140,23 +13147,24 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 | 
				
			|||||||
				appendPQExpBuffer(q, "\nSERVER %s", fmtId(srvname));
 | 
									appendPQExpBuffer(q, "\nSERVER %s", fmtId(srvname));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ((tbinfo->reloptions && strlen(tbinfo->reloptions) > 0) ||
 | 
							if (nonemptyReloptions(tbinfo->reloptions) ||
 | 
				
			||||||
		  (tbinfo->toast_reloptions && strlen(tbinfo->toast_reloptions) > 0))
 | 
								nonemptyReloptions(tbinfo->toast_reloptions))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			bool		addcomma = false;
 | 
								bool		addcomma = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			appendPQExpBuffer(q, "\nWITH (");
 | 
								appendPQExpBufferStr(q, "\nWITH (");
 | 
				
			||||||
			if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0)
 | 
								if (nonemptyReloptions(tbinfo->reloptions))
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				addcomma = true;
 | 
									addcomma = true;
 | 
				
			||||||
				appendPQExpBuffer(q, "%s", tbinfo->reloptions);
 | 
									fmtReloptionsArray(fout, q, tbinfo->reloptions, "");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (tbinfo->toast_reloptions && strlen(tbinfo->toast_reloptions) > 0)
 | 
								if (nonemptyReloptions(tbinfo->toast_reloptions))
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				appendPQExpBuffer(q, "%s%s", addcomma ? ", " : "",
 | 
									if (addcomma)
 | 
				
			||||||
								  tbinfo->toast_reloptions);
 | 
										appendPQExpBufferStr(q, ", ");
 | 
				
			||||||
 | 
									fmtReloptionsArray(fout, q, tbinfo->toast_reloptions, "toast.");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			appendPQExpBuffer(q, ")");
 | 
								appendPQExpBufferChar(q, ')');
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Dump generic options if any */
 | 
							/* Dump generic options if any */
 | 
				
			||||||
@@ -13697,8 +13705,12 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			appendPQExpBuffer(q, ")");
 | 
								appendPQExpBuffer(q, ")");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (indxinfo->options && strlen(indxinfo->options) > 0)
 | 
								if (nonemptyReloptions(indxinfo->indreloptions))
 | 
				
			||||||
				appendPQExpBuffer(q, " WITH (%s)", indxinfo->options);
 | 
								{
 | 
				
			||||||
 | 
									appendPQExpBufferStr(q, " WITH (");
 | 
				
			||||||
 | 
									fmtReloptionsArray(fout, q, indxinfo->indreloptions, "");
 | 
				
			||||||
 | 
									appendPQExpBufferChar(q, ')');
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (coninfo->condeferrable)
 | 
								if (coninfo->condeferrable)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
@@ -14558,11 +14570,12 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
 | 
				
			|||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Apply view's reloptions when its ON SELECT rule is separate.
 | 
						 * Apply view's reloptions when its ON SELECT rule is separate.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (rinfo->reloptions && strlen(rinfo->reloptions) > 0)
 | 
						if (nonemptyReloptions(rinfo->reloptions))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		appendPQExpBuffer(cmd, "ALTER VIEW %s SET (%s);\n",
 | 
							appendPQExpBuffer(cmd, "ALTER VIEW %s SET (",
 | 
				
			||||||
						  fmtId(tbinfo->dobj.name),
 | 
											  fmtId(tbinfo->dobj.name));
 | 
				
			||||||
						  rinfo->reloptions);
 | 
							fmtReloptionsArray(fout, cmd, rinfo->reloptions, "");
 | 
				
			||||||
 | 
							appendPQExpBufferStr(cmd, ");\n");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
@@ -15432,6 +15445,83 @@ fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer)
 | 
				
			|||||||
	return buffer->data;
 | 
						return buffer->data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Check if a reloptions array is nonempty.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static bool
 | 
				
			||||||
 | 
					nonemptyReloptions(const char *reloptions)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* Don't want to print it if it's just "{}" */
 | 
				
			||||||
 | 
						return (reloptions != NULL && strlen(reloptions) > 2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Format a reloptions array and append it to the given buffer.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * "prefix" is prepended to the option names; typically it's "" or "toast.".
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Note: this logic should generally match the backend's flatten_reloptions()
 | 
				
			||||||
 | 
					 * (in adt/ruleutils.c).
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					fmtReloptionsArray(Archive *fout, PQExpBuffer buffer, const char *reloptions,
 | 
				
			||||||
 | 
									   const char *prefix)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char	  **options;
 | 
				
			||||||
 | 
						int			noptions;
 | 
				
			||||||
 | 
						int			i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!parsePGArray(reloptions, &options, &noptions))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							write_msg(NULL, "WARNING: could not parse reloptions array\n");
 | 
				
			||||||
 | 
							if (options)
 | 
				
			||||||
 | 
								free(options);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < noptions; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							char	   *option = options[i];
 | 
				
			||||||
 | 
							char	   *name;
 | 
				
			||||||
 | 
							char	   *separator;
 | 
				
			||||||
 | 
							char	   *value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Each array element should have the form name=value.  If the "=" is
 | 
				
			||||||
 | 
							 * missing for some reason, treat it like an empty value.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							name = option;
 | 
				
			||||||
 | 
							separator = strchr(option, '=');
 | 
				
			||||||
 | 
							if (separator)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*separator = '\0';
 | 
				
			||||||
 | 
								value = separator + 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								value = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (i > 0)
 | 
				
			||||||
 | 
								appendPQExpBufferStr(buffer, ", ");
 | 
				
			||||||
 | 
							appendPQExpBuffer(buffer, "%s%s=", prefix, fmtId(name));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * In general we need to quote the value; but to avoid unnecessary
 | 
				
			||||||
 | 
							 * clutter, do not quote if it is an identifier that would not need
 | 
				
			||||||
 | 
							 * quoting.  (We could also allow numbers, but that is a bit trickier
 | 
				
			||||||
 | 
							 * than it looks --- for example, are leading zeroes significant?  We
 | 
				
			||||||
 | 
							 * don't want to assume very much here about what custom reloptions
 | 
				
			||||||
 | 
							 * might mean.)
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (strcmp(fmtId(value), value) == 0)
 | 
				
			||||||
 | 
								appendPQExpBufferStr(buffer, value);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								appendStringLiteralAH(buffer, value, fout);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (options)
 | 
				
			||||||
 | 
							free(options);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Execute an SQL query and verify that we got exactly one row back.
 | 
					 * Execute an SQL query and verify that we got exactly one row back.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -312,7 +312,7 @@ typedef struct _indxInfo
 | 
				
			|||||||
	TableInfo  *indextable;		/* link to table the index is for */
 | 
						TableInfo  *indextable;		/* link to table the index is for */
 | 
				
			||||||
	char	   *indexdef;
 | 
						char	   *indexdef;
 | 
				
			||||||
	char	   *tablespace;		/* tablespace in which index is stored */
 | 
						char	   *tablespace;		/* tablespace in which index is stored */
 | 
				
			||||||
	char	   *options;		/* options specified by WITH (...) */
 | 
						char	   *indreloptions;	/* options specified by WITH (...) */
 | 
				
			||||||
	int			indnkeys;
 | 
						int			indnkeys;
 | 
				
			||||||
	Oid		   *indkeys;
 | 
						Oid		   *indkeys;
 | 
				
			||||||
	bool		indisclustered;
 | 
						bool		indisclustered;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user