+
+ if (schemaList != NULL && g_fout->remoteVersion < 70300)
+ {
+ write_msg(NULL, "Postgres must be at least version 7.3 to use schema switches\n");
+ exit_nicely();
+ }
+
+ /* Check schema selection flags */
+ resetPQExpBuffer(query);
+ switch_include_exclude = true;
+
+ for (this_obj_name = schemaList; this_obj_name; this_obj_name = this_obj_name->next)
+ {
+ if (switch_include_exclude)
+ {
+ /* Special case for when -N is the first argument */
+ if (this_obj_name == schemaList && !this_obj_name->is_include)
+ appendPQExpBuffer(query,
+ "SELECT oid FROM pg_catalog.pg_namespace "
+ "WHERE nspname NOT LIKE 'pg_%%' AND "
+ " nspname != 'information_schema' EXCEPT\n");
+
+ appendPQExpBuffer(query, "SELECT oid FROM pg_catalog.pg_namespace WHERE");
+ }
+
+ appendPQExpBuffer(query, "%s nspname %c ", switch_include_exclude ? "" : " OR",
+ /* any meta-characters? */
+ strpbrk(this_obj_name->name,"([{\\.?+") == NULL ? '=' : '~');
+ appendStringLiteralAH(query, this_obj_name->name, g_fout);
+
+ if (this_obj_name->next && this_obj_name->next->is_include == this_obj_name->is_include)
+ switch_include_exclude = false;
+ else
+ {
+ switch_include_exclude = true;
+
+ /* Add the joiner if needed */
+ if (this_obj_name->next)
+ appendPQExpBuffer(query, "\n%s\n",
+ this_obj_name->next->is_include ? "UNION" : "EXCEPT");
+ }
+ }
+
+ /* Construct OID list of matching schemas */
+ if (schemaList)
+ {
+ int len;
+
+ res = PQexec(g_conn, query->data);
+ check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+ if (PQntuples(res) == 0)
+ {
+ write_msg(NULL, "No matching schemas were found\n");
+ exit_nicely();
+ }
+
+ for (i = 0, len = strlen(" "); i < PQntuples(res); i++)
+ len += strlen(PQgetvalue(res, i, 0)) + 1;
+
+ /*
+ * Need to use comma separators so it can be used by IN. zero
+ * is a dummy placeholder. Format is " oid oid oid ".
+ */
+ matchingSchemas = malloc(len + 1);
+ strcpy(matchingSchemas, " ");
+ for (i = 0; i < PQntuples(res); i++)
+ {
+ strcat(matchingSchemas, PQgetvalue(res, i, 0));
+ strcat(matchingSchemas, " ");
+ }
+ }
+
+ /* Check table selection flags */
+ resetPQExpBuffer(query);
+ switch_include_exclude = true;
+
+ for (this_obj_name = tableList; this_obj_name; this_obj_name = this_obj_name->next)
+ {
+ if (switch_include_exclude)
+ {
+ /* Special case for when -T is the first argument */
+ if (this_obj_name == tableList && !this_obj_name->is_include && !strlen(query->data))
+ appendPQExpBuffer(query,
+ "SELECT pg_class.oid FROM pg_catalog.pg_class, pg_catalog.pg_namespace "
+ "WHERE relkind='r' AND "
+ " relnamespace = pg_namespace.oid AND "
+ " nspname NOT LIKE 'pg_%%' AND "
+ " nspname != 'information_schema' EXCEPT\n");
+
+ appendPQExpBuffer(query, "SELECT oid FROM pg_catalog.pg_class WHERE relkind='r' AND (");
+ }
+
+ appendPQExpBuffer(query, "%srelname %c ", switch_include_exclude ? "" : " OR ",
+ /* any meta-characters? */
+ strpbrk(this_obj_name->name,"([{\\.?+") == NULL ? '=' : '~');
+ appendStringLiteralAH(query, this_obj_name->name, g_fout);
+
+ if (this_obj_name->next && this_obj_name->next->is_include == this_obj_name->is_include)
+ switch_include_exclude = false;
+ else
+ {
+ switch_include_exclude = true;
+ appendPQExpBuffer(query, ")");
+
+ /* Add the joiner if needed */
+ if (this_obj_name->next)
+ appendPQExpBuffer(query, "\n%s\n", this_obj_name->next->is_include ?
+ "UNION" : "EXCEPT");
+ }
+ }
+
+ /* Construct OID list of matching tables */
+ if (tableList)
+ {
+ int len;
+
+ /* Restrict by schema? */
+ if (matchingSchemas != NULL)
+ {
+ char *matchingSchemas_commas = strdup(matchingSchemas), *p;
+
+ /* Construct "IN" SQL string by adding commas, " oid, oid, oid " */
+ for (p = matchingSchemas_commas; *p; p++)
+ {
+ /* No commas for first/last characters */
+ if (*p == ' ' && p != matchingSchemas_commas && *(p+1))
+ *p = ',';
+ }
+
+ appendPQExpBuffer(query,
+ "\nINTERSECT\nSELECT oid FROM pg_catalog.pg_class WHERE relkind='r' AND relnamespace IN (%s)\n",
+ matchingSchemas_commas);
+ }
+
+ res = PQexec(g_conn, query->data);
+ check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+ if (PQntuples(res) == 0)
+ {
+ write_msg(NULL, "No matching tables were found\n");
+ exit_nicely();
+ }
+
+ for (i = 0, len = strlen(" "); i < PQntuples(res); i++)
+ len += strlen(PQgetvalue(res, i, 0)) + 1;
+
+ matchingTables = malloc(len + 1);
+ strcpy(matchingTables, " ");
+ for (i = 0; i < PQntuples(res); i++)
+ {
+ strcat(matchingTables, PQgetvalue(res, i, 0));
+ strcat(matchingTables, " ");
+ }
+ }
+
+ destroyPQExpBuffer(query);
+