On Fri, Mar 29, 2013 at 07:03:05PM -0400, Tom Lane wrote: > Andres Freund <and...@2ndquadrant.com> writes: > > Those columns cannot be NULL, so using IS DISTINCT FROM seems a bit > > clumsy. > > That was what I started to write, too, but actually I think the IS > DISTINCT is correct and the RIGHT JOIN should be a LEFT JOIN. Note > that the query appears to be intended to collect regular tables as > well as indexes. (As patched, that's totally broken, so I infer > Bruce hasn't tested it yet.)
Yes, I only ran my simple tests so far --- I wanted to at least get some eyes on it. I was wondering if we ever need to use parentheses for queries that mix normal and outer joins? I am unclear on that. Attached is a fixed patch that uses LEFT JOIN. I went back and looked at the patch that added this test and I think the patch is now complete. I would like to apply it tomorrow/Saturday so it will be ready for Monday's packaging, and get some buildfarm time on it. -- Bruce Momjian <br...@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. +
diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c new file mode 100644 index 65fb548..35783d0 *** a/contrib/pg_upgrade/check.c --- b/contrib/pg_upgrade/check.c *************** static void check_is_super_user(ClusterI *** 20,26 **** static void check_for_prepared_transactions(ClusterInfo *cluster); static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster); static void check_for_reg_data_type_usage(ClusterInfo *cluster); - static void check_for_invalid_indexes(ClusterInfo *cluster); static void get_bin_version(ClusterInfo *cluster); static char *get_canonical_locale_name(int category, const char *locale); --- 20,25 ---- *************** check_and_dump_old_cluster(bool live_che *** 97,103 **** check_is_super_user(&old_cluster); check_for_prepared_transactions(&old_cluster); check_for_reg_data_type_usage(&old_cluster); - check_for_invalid_indexes(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); /* old = PG 8.3 checks? */ --- 96,101 ---- *************** check_for_reg_data_type_usage(ClusterInf *** 952,1046 **** " %s\n\n", output_path); } else - check_ok(); - } - - - /* - * check_for_invalid_indexes() - * - * CREATE INDEX CONCURRENTLY can create invalid indexes if the index build - * fails. These are dumped as valid indexes by pg_dump, but the - * underlying files are still invalid indexes. This checks to make sure - * no invalid indexes exist, either failed index builds or concurrent - * indexes in the process of being created. - */ - static void - check_for_invalid_indexes(ClusterInfo *cluster) - { - int dbnum; - FILE *script = NULL; - bool found = false; - char output_path[MAXPGPATH]; - - prep_status("Checking for invalid indexes from concurrent index builds"); - - snprintf(output_path, sizeof(output_path), "invalid_indexes.txt"); - - for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) - { - PGresult *res; - bool db_used = false; - int ntups; - int rowno; - int i_nspname, - i_relname; - DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(cluster, active_db->db_name); - - res = executeQueryOrDie(conn, - "SELECT n.nspname, c.relname " - "FROM pg_catalog.pg_class c, " - " pg_catalog.pg_namespace n, " - " pg_catalog.pg_index i " - "WHERE (i.indisvalid = false OR " - " i.indisready = false) AND " - " i.indexrelid = c.oid AND " - " c.relnamespace = n.oid AND " - /* we do not migrate these, so skip them */ - " n.nspname != 'pg_catalog' AND " - " n.nspname != 'information_schema' AND " - /* indexes do not have toast tables */ - " n.nspname != 'pg_toast'"); - - ntups = PQntuples(res); - i_nspname = PQfnumber(res, "nspname"); - i_relname = PQfnumber(res, "relname"); - for (rowno = 0; rowno < ntups; rowno++) - { - found = true; - if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL) - pg_log(PG_FATAL, "Could not open file \"%s\": %s\n", - output_path, getErrorText(errno)); - if (!db_used) - { - fprintf(script, "Database: %s\n", active_db->db_name); - db_used = true; - } - fprintf(script, " %s.%s\n", - PQgetvalue(res, rowno, i_nspname), - PQgetvalue(res, rowno, i_relname)); - } - - PQclear(res); - - PQfinish(conn); - } - - if (script) - fclose(script); - - if (found) - { - pg_log(PG_REPORT, "fatal\n"); - pg_log(PG_FATAL, - "Your installation contains invalid indexes due to failed or\n" - "currently running CREATE INDEX CONCURRENTLY operations. You\n" - "cannot upgrade until these indexes are valid or removed. A\n" - "list of the problem indexes is in the file:\n" - " %s\n\n", output_path); - } - else check_ok(); } --- 950,955 ---- diff --git a/contrib/pg_upgrade/info.c b/contrib/pg_upgrade/info.c new file mode 100644 index a5aa40f..c5c3698 *** a/contrib/pg_upgrade/info.c --- b/contrib/pg_upgrade/info.c *************** get_rel_infos(ClusterInfo *cluster, DbIn *** 282,288 **** --- 282,294 ---- "CREATE TEMPORARY TABLE info_rels (reloid) AS SELECT c.oid " "FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n " " ON c.relnamespace = n.oid " + "LEFT OUTER JOIN pg_catalog.pg_index i " + " ON c.oid = i.indexrelid " "WHERE relkind IN ('r', 'm', 'i'%s) AND " + /* pg_dump only dumps valid indexes; testing indisready is + * necessary in 9.2, and harmless in earlier/later versions. */ + " i.indisvalid IS DISTINCT FROM false AND " + " i.indisready IS DISTINCT FROM false AND " /* exclude possible orphaned temp tables */ " ((n.nspname !~ '^pg_temp_' AND " " n.nspname !~ '^pg_toast_temp_' AND "
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers