diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..553bce4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +CMakeCache.txt +CMakeFiles/ +Makefile +cmake_install.cmake +install_manifest.txt +mini/CMakeFiles/ +mini/Makefile +mini/cmake_install.cmake +mini/libmini.so +pgquarrel +.vscode/ +pg.ini +todo.md \ No newline at end of file diff --git a/src/common.h b/src/common.h index 693e98a..45ed272 100644 --- a/src/common.h +++ b/src/common.h @@ -89,6 +89,7 @@ typedef struct QuarrelGeneralOptions bool statistics; bool subscription; bool table; + bool tablepartition; bool textsearch; bool transform; bool trigger; diff --git a/src/index.c b/src/index.c index 3dd4740..796f13c 100644 --- a/src/index.c +++ b/src/index.c @@ -34,7 +34,13 @@ getIndexes(PGconn *c, int *n) logNoise("index: server version: %d", PQserverVersion(c)); - query = psprintf("SELECT c.oid, n.nspname, c.relname, t.spcname AS tablespacename, pg_get_indexdef(c.oid) AS indexdef, array_to_string(c.reloptions, ', ') AS reloptions, obj_description(c.oid, 'pg_class') AS description FROM pg_class c INNER JOIN pg_namespace n ON (c.relnamespace = n.oid) INNER JOIN pg_index i ON (i.indexrelid = c.oid) LEFT JOIN pg_tablespace t ON (c.reltablespace = t.oid) WHERE relkind = 'i' AND nspname !~ '^pg_' AND nspname <> 'information_schema' %s%s AND NOT indisprimary ORDER BY nspname, relname", include_schema_str, exclude_schema_str); + if (PQserverVersion(c) >= 100000 && !options.tablepartition){ + // THIS QUERY IS OPTIMIZED ONLY FOR DISCOVERING INDEXES WHICH DOES NOT BELONG PARTITIONS + query = psprintf("SELECT c.oid, n.nspname, c.relname, t.spcname AS tablespacename, pg_get_indexdef(c.oid) AS indexdef, array_to_string(c.reloptions, ', ') AS reloptions, obj_description(c.oid, 'pg_class') AS description FROM pg_class c INNER JOIN pg_namespace n ON (c.relnamespace = n.oid) INNER JOIN pg_index i ON (i.indexrelid = c.oid) LEFT JOIN pg_tablespace t ON (c.reltablespace = t.oid) LEFT JOIN pg_class pt ON NOT c.relispartition AND i.indrelid=pt.oid WHERE c.relkind = 'i' AND NOT c.relispartition AND NOT pt.relispartition AND nspname !~ '^pg_' AND nspname <> 'information_schema' %s%s AND NOT indisprimary ORDER BY nspname, c.relname", include_schema_str, exclude_schema_str); + } + else { + query = psprintf("SELECT c.oid, n.nspname, c.relname, t.spcname AS tablespacename, pg_get_indexdef(c.oid) AS indexdef, array_to_string(c.reloptions, ', ') AS reloptions, obj_description(c.oid, 'pg_class') AS description FROM pg_class c INNER JOIN pg_namespace n ON (c.relnamespace = n.oid) INNER JOIN pg_index i ON (i.indexrelid = c.oid) LEFT JOIN pg_tablespace t ON (c.reltablespace = t.oid) WHERE relkind = 'i' AND nspname !~ '^pg_' AND nspname <> 'information_schema' %s%s AND NOT indisprimary ORDER BY nspname, relname", include_schema_str, exclude_schema_str); + } res = PQexec(c, query); diff --git a/src/quarrel.c b/src/quarrel.c index 738a76e..8bf7b0e 100644 --- a/src/quarrel.c +++ b/src/quarrel.c @@ -289,6 +289,8 @@ help(void) (opts.general.subscription) ? "true" : "false"); printf(" --table=BOOL table (default: %s)\n", (opts.general.table) ? "true" : "false"); + printf(" --table-partition=BOOL table partition (default: %s)\n", + (opts.general.tablepartition) ? "true" : "false"); printf(" --text-search=BOOL text search (default: %s)\n", (opts.general.textsearch) ? "true" : "false"); printf(" --transform=BOOL transform (default: %s)\n", @@ -365,6 +367,7 @@ loadConfig(const char *cf, QuarrelOptions *options) options->general.statistics = false; /* general - statistics */ options->general.subscription = false; /* general - subscription */ options->general.table = true; /* general - table */ + options->general.tablepartition = true; /* general - table-partition */ options->general.textsearch = false; /* general - text-search */ options->general.transform = false; /* general - transform */ options->general.trigger = true; /* general - trigger */ @@ -592,6 +595,10 @@ loadConfig(const char *cf, QuarrelOptions *options) options->general.table = parseBoolean("table", mini_file_get_value(config, "general", "table")); + if (mini_file_get_value(config, "general", "table-partition") != NULL) + options->general.tablepartition = parseBoolean("table-partition", mini_file_get_value(config, + "general", "table-partition")); + if (mini_file_get_value(config, "general", "text-search") != NULL) options->general.textsearch = parseBoolean("text-search", mini_file_get_value(config, @@ -4671,6 +4678,7 @@ int main(int argc, char *argv[]) {"temp-directory", required_argument, NULL, 37}, {"include-schema", required_argument, NULL, 45}, {"exclude-schema", required_argument, NULL, 46}, + {"table-partition", required_argument, NULL, 47}, {NULL, 0, NULL, 0} }; @@ -4862,6 +4870,10 @@ int main(int argc, char *argv[]) gopts.table = parseBoolean("table", optarg); gopts_given.table = true; break; + case 47: + gopts.tablepartition = parseBoolean("table-partition", optarg); + gopts_given.tablepartition = true; + break; case 32: gopts.textsearch = parseBoolean("text-search", optarg); gopts_given.textsearch = true; @@ -5007,6 +5019,8 @@ int main(int argc, char *argv[]) options.subscription = gopts.subscription; if (gopts_given.table) options.table = gopts.table; + if (gopts_given.tablepartition) + options.tablepartition = gopts.tablepartition; if (gopts_given.textsearch) options.textsearch = gopts.textsearch; if (gopts_given.transform) diff --git a/src/table.c b/src/table.c index f98395d..61274a8 100644 --- a/src/table.c +++ b/src/table.c @@ -112,7 +112,7 @@ getTables(PGconn *c, int *n, char k) { if (PGQ_IS_REGULAR_OR_PARTITIONED_TABLE(k)) { - query = psprintf("SELECT c.oid, n.nspname, c.relname, c.relkind, t.spcname AS tablespacename, c.relpersistence, array_to_string(c.reloptions, ', ') AS reloptions, obj_description(c.oid, 'pg_class') AS description, pg_get_userbyid(c.relowner) AS relowner, relacl, relreplident, reloftype, o.nspname AS typnspname, y.typname, c.relispartition, pg_get_partkeydef(c.oid) AS partitionkeydef, pg_get_expr(c.relpartbound, c.oid) AS partitionbound, c.relhassubclass FROM pg_class c INNER JOIN pg_namespace n ON (c.relnamespace = n.oid) LEFT JOIN pg_tablespace t ON (c.reltablespace = t.oid) LEFT JOIN (pg_type y INNER JOIN pg_namespace o ON (y.typnamespace = o.oid)) ON (c.reloftype = y.oid) WHERE relkind IN ('r', 'p') AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema' %s%s AND NOT EXISTS(SELECT 1 FROM pg_depend d WHERE t.oid = d.objid AND d.deptype = 'e') ORDER BY n.nspname, relname", include_schema_str, exclude_schema_str); + query = psprintf("SELECT c.oid, n.nspname, c.relname, c.relkind, t.spcname AS tablespacename, c.relpersistence, array_to_string(c.reloptions, ', ') AS reloptions, obj_description(c.oid, 'pg_class') AS description, pg_get_userbyid(c.relowner) AS relowner, relacl, relreplident, reloftype, o.nspname AS typnspname, y.typname, c.relispartition, pg_get_partkeydef(c.oid) AS partitionkeydef, pg_get_expr(c.relpartbound, c.oid) AS partitionbound, c.relhassubclass FROM pg_class c INNER JOIN pg_namespace n ON (c.relnamespace = n.oid) LEFT JOIN pg_tablespace t ON (c.reltablespace = t.oid) LEFT JOIN (pg_type y INNER JOIN pg_namespace o ON (y.typnamespace = o.oid)) ON (c.reloftype = y.oid) WHERE relkind IN ('r', 'p') AND c.relispartition=%s AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema' %s%s AND NOT EXISTS(SELECT 1 FROM pg_depend d WHERE t.oid = d.objid AND d.deptype = 'e') ORDER BY n.nspname, relname", options.tablepartition? "TRUE":"FALSE", include_schema_str, exclude_schema_str); } else if (PGQ_IS_FOREIGN_TABLE(k)) { @@ -1345,10 +1345,10 @@ dumpCreateTable(FILE *output, FILE *output2, PQLTable *t) /* print foreign key constraints */ for (i = 0; i < t->nfk; i++) { - fprintf(output, "\n\n"); - fprintf(output, "ALTER TABLE ONLY %s.%s\n", schema, tabname); - fprintf(output, "\tADD CONSTRAINT %s %s", t->fk[i].conname, t->fk[i].condef); - fprintf(output, ";"); + fprintf(output2, "\n\n"); + fprintf(output2, "ALTER TABLE ONLY %s.%s\n", schema, tabname); + fprintf(output2, "\tADD CONSTRAINT %s %s", t->fk[i].conname, t->fk[i].condef); + fprintf(output2, ";"); } /* XXX Should it belong to sequence.c? */