diff --git a/src/bin/pgcopydb/catalog.c b/src/bin/pgcopydb/catalog.c index ab012c866..1ea178612 100644 --- a/src/bin/pgcopydb/catalog.c +++ b/src/bin/pgcopydb/catalog.c @@ -189,14 +189,14 @@ static char *filterDBcreateDDLs[] = { "create table s_coll(" " oid integer primary key, collname text, description text, " - " restore_list_name text" + " datname text, restore_list_name text" ")", "create unique index s_coll_rlname on s_coll(restore_list_name)", "create table s_extension(" " oid integer primary key, extname text, extnamespace text, " - " extrelocatable integer " + " datname text, extrelocatable integer " ")", "create table s_extension_config(" @@ -214,7 +214,8 @@ static char *filterDBcreateDDLs[] = { ")", "create table s_namespace(" - " oid integer primary key, nspname text, restore_list_name text " + " oid integer primary key, nspname text, restore_list_name text, " + " datname text" ")", "create index s_n_rlname on s_namespace(restore_list_name)", @@ -324,7 +325,8 @@ static char *targetDBcreateDDLs[] = { ")", "create table s_namespace(" - " nspname text primary key, restore_list_name text" + " oid integer primary key, nspname text, restore_list_name text, " + " datname text" ")", "create index s_n_rlname on s_namespace(restore_list_name)", @@ -1632,9 +1634,9 @@ catalog_add_s_table(DatabaseCatalog *catalog, SourceTable *table) char *sql = "insert into s_table(" - " oid, qname, nspname, relname, amname, restore_list_name, " + " oid, qname, nspname, relname, datname, amname, restore_list_name, " " relpages, reltuples, bytes, bytes_pretty, exclude_data, part_key) " - "values($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)"; + "values($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)"; SQLiteQuery query = { 0 }; @@ -1650,6 +1652,7 @@ catalog_add_s_table(DatabaseCatalog *catalog, SourceTable *table) { BIND_PARAMETER_TYPE_TEXT, "qname", 0, table->qname }, { BIND_PARAMETER_TYPE_TEXT, "nspname", 0, table->nspname }, { BIND_PARAMETER_TYPE_TEXT, "relname", 0, table->relname }, + { BIND_PARAMETER_TYPE_TEXT, "datname", 0, table->datname }, { BIND_PARAMETER_TYPE_TEXT, "amname", 0, table->amname }, { BIND_PARAMETER_TYPE_TEXT, "restore_list_name", 0, @@ -2174,7 +2177,8 @@ catalog_lookup_s_table(DatabaseCatalog *catalog, if (partNumber > 0) { char *sql = - " select t.oid, qname, nspname, relname, amname, restore_list_name, " + " select t.oid, qname, nspname, relname, " + " datname, amname, restore_list_name, " " relpages, reltuples, bytes, bytes_pretty, " " exclude_data, part_key, " " p.partcount as partcount, p.partnum, p.min, p.max " @@ -2270,7 +2274,8 @@ catalog_lookup_s_table_by_name(DatabaseCatalog *catalog, } char *sql = - " select t.oid, qname, nspname, relname, amname, restore_list_name, " + " select t.oid, qname, nspname, relname, " + " datname, amname, restore_list_name, " " relpages, reltuples, bytes, bytes_pretty, " " exclude_data, part_key, " " p.partcount, 0 as partnum, 0 as min, 0 as max " @@ -2574,7 +2579,8 @@ catalog_iter_s_table_init(SourceTableIterator *iter) if (iter->splitTableLargerThanBytes > 0) { sql = - " select t.oid, qname, nspname, relname, amname, restore_list_name, " + " select t.oid, qname, nspname, relname, " + " datname, amname, restore_list_name, " " relpages, reltuples, bytes, bytes_pretty, " " exclude_data, part_key, " " count(p.oid), 0 as partnum, 0 as min, 0 as max, " @@ -2589,7 +2595,8 @@ catalog_iter_s_table_init(SourceTableIterator *iter) else { sql = - " select t.oid, qname, nspname, relname, amname, restore_list_name, " + " select t.oid, qname, nspname, relname " + " datname, amname, restore_list_name, " " relpages, reltuples, t.bytes, t.bytes_pretty, " " exclude_data, part_key, " " coalesce(p.partcount, 0) as partcount, " @@ -2661,7 +2668,8 @@ catalog_iter_s_table_nopk_init(SourceTableIterator *iter) } char *sql = - " select t.oid, qname, nspname, relname, amname, restore_list_name, " + " select t.oid, qname, nspname, relname, " + " datname, amname, restore_list_name, " " relpages, reltuples, bytes, bytes_pretty, " " exclude_data, part_key, " " (select count(1) from s_table_part p where p.oid = t.oid) " @@ -2740,35 +2748,39 @@ catalog_s_table_fetch(SQLiteQuery *query) (char *) sqlite3_column_text(query->ppStmt, 3), sizeof(table->relname)); - strlcpy(table->amname, + strlcpy(table->datname, (char *) sqlite3_column_text(query->ppStmt, 4), + sizeof(table->datname)); + + strlcpy(table->amname, + (char *) sqlite3_column_text(query->ppStmt, 5), sizeof(table->amname)); strlcpy(table->restoreListName, - (char *) sqlite3_column_text(query->ppStmt, 5), + (char *) sqlite3_column_text(query->ppStmt, 6), sizeof(table->restoreListName)); - table->relpages = sqlite3_column_int64(query->ppStmt, 6); - table->reltuples = sqlite3_column_int64(query->ppStmt, 7); - table->bytes = sqlite3_column_int64(query->ppStmt, 8); + table->relpages = sqlite3_column_int64(query->ppStmt, 7); + table->reltuples = sqlite3_column_int64(query->ppStmt, 8); + table->bytes = sqlite3_column_int64(query->ppStmt, 9); - if (sqlite3_column_type(query->ppStmt, 9) != SQLITE_NULL) + if (sqlite3_column_type(query->ppStmt, 10) != SQLITE_NULL) { strlcpy(table->bytesPretty, - (char *) sqlite3_column_text(query->ppStmt, 9), + (char *) sqlite3_column_text(query->ppStmt, 10), sizeof(table->bytesPretty)); } - table->excludeData = sqlite3_column_int64(query->ppStmt, 10) == 1; + table->excludeData = sqlite3_column_int64(query->ppStmt, 11) == 1; - if (sqlite3_column_type(query->ppStmt, 11) != SQLITE_NULL) + if (sqlite3_column_type(query->ppStmt, 12) != SQLITE_NULL) { strlcpy(table->partKey, - (char *) sqlite3_column_text(query->ppStmt, 11), + (char *) sqlite3_column_text(query->ppStmt, 12), sizeof(table->partKey)); } - table->partition.partCount = sqlite3_column_int64(query->ppStmt, 12); + table->partition.partCount = sqlite3_column_int64(query->ppStmt, 13); /* * The main iterator query returns partition count, whereas the catalog @@ -2778,42 +2790,42 @@ catalog_s_table_fetch(SQLiteQuery *query) int cols = sqlite3_column_count(query->ppStmt); /* partition information from s_table_part */ - if (cols >= 16) + if (cols >= 17) { - table->partition.partNumber = sqlite3_column_int64(query->ppStmt, 13); - table->partition.min = sqlite3_column_int64(query->ppStmt, 14); - table->partition.max = sqlite3_column_int64(query->ppStmt, 15); + table->partition.partNumber = sqlite3_column_int64(query->ppStmt, 14); + table->partition.min = sqlite3_column_int64(query->ppStmt, 15); + table->partition.max = sqlite3_column_int64(query->ppStmt, 16); } /* checksum information from s_table_chksum */ - if (cols >= 20) + if (cols >= 21) { table->sourceChecksum.rowcount = - sqlite3_column_int64(query->ppStmt, 16); + sqlite3_column_int64(query->ppStmt, 17); - if (sqlite3_column_type(query->ppStmt, 17) != SQLITE_NULL) + if (sqlite3_column_type(query->ppStmt, 18) != SQLITE_NULL) { strlcpy(table->sourceChecksum.checksum, - (char *) sqlite3_column_text(query->ppStmt, 17), + (char *) sqlite3_column_text(query->ppStmt, 18), sizeof(table->sourceChecksum.checksum)); } table->targetChecksum.rowcount = - sqlite3_column_int64(query->ppStmt, 18); + sqlite3_column_int64(query->ppStmt, 19); - if (sqlite3_column_type(query->ppStmt, 19) != SQLITE_NULL) + if (sqlite3_column_type(query->ppStmt, 20) != SQLITE_NULL) { strlcpy(table->targetChecksum.checksum, - (char *) sqlite3_column_text(query->ppStmt, 19), + (char *) sqlite3_column_text(query->ppStmt, 20), sizeof(table->targetChecksum.checksum)); } } /* summary information from s_table_parts_done */ - if (cols == 22) + if (cols == 23) { - table->durationMs = sqlite3_column_int64(query->ppStmt, 20); - table->bytesTransmitted = sqlite3_column_int64(query->ppStmt, 21); + table->durationMs = sqlite3_column_int64(query->ppStmt, 21); + table->bytesTransmitted = sqlite3_column_int64(query->ppStmt, 22); } return true; @@ -4214,8 +4226,8 @@ catalog_add_s_seq(DatabaseCatalog *catalog, SourceSequence *seq) char *sql = "insert into s_seq(" " oid, ownedby, attrelid, attroid, " - " qname, nspname, relname, restore_list_name)" - "values($1, $2, $3, $4, $5, $6, $7, $8)"; + " datname, qname, nspname, relname, restore_list_name)" + "values($1, $2, $3, $4, $5, $6, $7, $8, $9)"; SQLiteQuery query = { 0 }; @@ -4232,6 +4244,7 @@ catalog_add_s_seq(DatabaseCatalog *catalog, SourceSequence *seq) { BIND_PARAMETER_TYPE_INT64, "attrelid", seq->attrelid, NULL }, { BIND_PARAMETER_TYPE_INT64, "attroid", seq->attroid, NULL }, + { BIND_PARAMETER_TYPE_TEXT, "datname", 0, seq->datname }, { BIND_PARAMETER_TYPE_TEXT, "qname", 0, seq->qname }, { BIND_PARAMETER_TYPE_TEXT, "nspname", 0, seq->nspname }, { BIND_PARAMETER_TYPE_TEXT, "relname", 0, seq->relname }, @@ -4333,7 +4346,7 @@ catalog_lookup_s_seq_by_name(DatabaseCatalog *catalog, char *sql = " select oid, ownedby, attrelid, attroid, " - " qname, nspname, relname, restore_list_name, " + " datname, qname, nspname, relname, restore_list_name, " " last_value, isCalled " " from s_seq " " where nspname = $1 and relname = $2 "; @@ -4457,7 +4470,7 @@ catalog_iter_s_seq_init(SourceSeqIterator *iter) char *sql = " select oid, ownedby, attrelid, attroid, " - " qname, nspname, relname, restore_list_name, " + " datname, qname, nspname, relname, restore_list_name, " " last_value, isCalled " " from s_seq " "order by nspname, relname"; @@ -4523,24 +4536,28 @@ catalog_s_seq_fetch(SQLiteQuery *query) seq->attrelid = sqlite3_column_int64(query->ppStmt, 2); seq->attroid = sqlite3_column_int64(query->ppStmt, 3); - strlcpy(seq->qname, + strlcpy(seq->datname, (char *) sqlite3_column_text(query->ppStmt, 4), + sizeof(seq->datname)); + + strlcpy(seq->qname, + (char *) sqlite3_column_text(query->ppStmt, 5), sizeof(seq->qname)); strlcpy(seq->nspname, - (char *) sqlite3_column_text(query->ppStmt, 5), + (char *) sqlite3_column_text(query->ppStmt, 6), sizeof(seq->nspname)); strlcpy(seq->relname, - (char *) sqlite3_column_text(query->ppStmt, 6), + (char *) sqlite3_column_text(query->ppStmt, 7), sizeof(seq->relname)); strlcpy(seq->restoreListName, - (char *) sqlite3_column_text(query->ppStmt, 7), + (char *) sqlite3_column_text(query->ppStmt, 8), sizeof(seq->restoreListName)); - seq->lastValue = sqlite3_column_int64(query->ppStmt, 8); - seq->isCalled = sqlite3_column_int(query->ppStmt, 9); + seq->lastValue = sqlite3_column_int64(query->ppStmt, 9); + seq->isCalled = sqlite3_column_int(query->ppStmt, 10); return true; } @@ -5392,8 +5409,9 @@ catalog_add_s_coll(DatabaseCatalog *catalog, SourceCollation *coll) } char *sql = - "insert into s_coll(oid, collname, description, restore_list_name) " - "values($1, $2, $3, $4)"; + "insert into s_coll" + "(oid, collname, description, datname, restore_list_name) " + "values($1, $2, $3, $4, $5)"; SQLiteQuery query = { 0 }; @@ -5408,6 +5426,7 @@ catalog_add_s_coll(DatabaseCatalog *catalog, SourceCollation *coll) { BIND_PARAMETER_TYPE_INT64, "oid", coll->oid, NULL }, { BIND_PARAMETER_TYPE_TEXT, "nspname", 0, coll->collname }, { BIND_PARAMETER_TYPE_TEXT, "description", 0, coll->desc }, + { BIND_PARAMETER_TYPE_TEXT, "datname", 0, coll->datname }, { BIND_PARAMETER_TYPE_TEXT, "restore_list_name", 0, coll->restoreListName } @@ -5514,7 +5533,7 @@ catalog_iter_s_coll_init(SourceCollationIterator *iter) } char *sql = - " select oid, collname, description, restore_list_name" + " select oid, collname, description, datname, restore_list_name" " from s_coll " "order by oid"; @@ -5601,8 +5620,12 @@ catalog_s_coll_fetch(SQLiteQuery *query) bytes); } - strlcpy(coll->restoreListName, + strlcpy(coll->datname, (char *) sqlite3_column_text(query->ppStmt, 3), + sizeof(coll->datname)); + + strlcpy(coll->restoreListName, + (char *) sqlite3_column_text(query->ppStmt, 4), sizeof(coll->restoreListName)); return true; @@ -5652,8 +5675,8 @@ catalog_add_s_namespace(DatabaseCatalog *catalog, SourceSchema *namespace) } char *sql = - "insert into s_namespace(oid, nspname, restore_list_name) " - "values($1, $2, $3)"; + "insert into s_namespace(oid, nspname, restore_list_name, datname) " + "values($1, $2, $3, $4)"; SQLiteQuery query = { 0 }; @@ -5669,7 +5692,9 @@ catalog_add_s_namespace(DatabaseCatalog *catalog, SourceSchema *namespace) { BIND_PARAMETER_TYPE_TEXT, "nspname", 0, namespace->nspname }, { BIND_PARAMETER_TYPE_TEXT, "restore_list_name", 0, - namespace->restoreListName } + namespace->restoreListName }, + + { BIND_PARAMETER_TYPE_TEXT, "datname", 0, namespace->datname }, }; int count = sizeof(params) / sizeof(params[0]); @@ -5788,8 +5813,9 @@ catalog_add_s_extension(DatabaseCatalog *catalog, SourceExtension *extension) } char *sql = - "insert into s_extension(oid, extname, extnamespace, extrelocatable) " - "values($1, $2, $3, $4)"; + "insert into s_extension" + "(oid, extname, extnamespace, datname, extrelocatable) " + "values($1, $2, $3, $4, $5)"; SQLiteQuery query = { 0 }; @@ -5804,6 +5830,7 @@ catalog_add_s_extension(DatabaseCatalog *catalog, SourceExtension *extension) { BIND_PARAMETER_TYPE_INT64, "oid", extension->oid, NULL }, { BIND_PARAMETER_TYPE_TEXT, "extname", 0, extension->extname }, { BIND_PARAMETER_TYPE_TEXT, "extnamespace", 0, extension->extnamespace }, + { BIND_PARAMETER_TYPE_TEXT, "datname", 0, extension->datname }, { BIND_PARAMETER_TYPE_INT, "extrelocatable", extension->extrelocatable ? 1 : 0, NULL } @@ -5969,7 +5996,7 @@ catalog_iter_s_extension_init(SourceExtensionIterator *iter) } char *sql = - " select oid, extname, extnamespace, extrelocatable " + " select oid, extname, extnamespace, datname, extrelocatable " " from s_extension " "order by extname"; @@ -6040,7 +6067,11 @@ catalog_s_extension_fetch(SQLiteQuery *query) (char *) sqlite3_column_text(query->ppStmt, 2), sizeof(ext->extnamespace)); - ext->extrelocatable = sqlite3_column_int(query->ppStmt, 3) == 1; + strlcpy(ext->datname, + (char *) sqlite3_column_text(query->ppStmt, 3), + sizeof(ext->datname)); + + ext->extrelocatable = sqlite3_column_int(query->ppStmt, 4) == 1; return true; } @@ -6894,7 +6925,8 @@ catalog_iter_s_table_in_copy_init(SourceTableIterator *iter) } char *sql = - " select t.oid, qname, nspname, relname, amname, restore_list_name, " + " select t.oid, qname, nspname, relname, " + " datname, amname, restore_list_name, " " relpages, reltuples, t.bytes, t.bytes_pretty, " " exclude_data, part_key, " " part.partcount, s.partnum, part.min, part.max, " diff --git a/src/bin/pgcopydb/schema.c b/src/bin/pgcopydb/schema.c index 1067e0aee..e6ed5ef9e 100644 --- a/src/bin/pgcopydb/schema.c +++ b/src/bin/pgcopydb/schema.c @@ -334,10 +334,11 @@ schema_list_schemas(PGSQL *pgsql, DatabaseCatalog *catalog) SourceSchemaArrayContext parseContext = { { 0 }, catalog, false }; char *sql = - "select n.oid, n.nspname, " + "select n.oid, format('%I', n.nspname) as nspname, " " format('- %s %s', " " regexp_replace(n.nspname, '[\\n\\r]', ' '), " - " regexp_replace(auth.rolname, '[\\n\\r]', ' ')) " + " regexp_replace(auth.rolname, '[\\n\\r]', ' ')), " + " format('%I', current_database()) as datname" " from pg_namespace n " " join pg_roles auth ON auth.oid = n.nspowner " " where nspname <> 'information_schema' and nspname !~ '^pg_'"; @@ -402,7 +403,9 @@ schema_list_extensions(PGSQL *pgsql, DatabaseCatalog *catalog) SourceExtensionArrayContext parseContext = { { 0 }, catalog, false }; char *sql = - "select e.oid, extname, extnamespace::regnamespace, extrelocatable, " + "select e.oid, extname, extnamespace::regnamespace, " + " format('%I', current_database()) as datname, " + " extrelocatable, " " 0 as count, null as n, " " null as extconfig, null as nspname, null as relname, " " null as extcondition, " @@ -412,7 +415,9 @@ schema_list_extensions(PGSQL *pgsql, DatabaseCatalog *catalog) " UNION ALL " - " select e.oid, extname, extnamespace::regnamespace, extrelocatable, " + " select e.oid, extname, extnamespace::regnamespace, " + " format('%I', current_database()) as datname, " + " extrelocatable, " " array_length(e.extconfig, 1) as count, " " extconfig.n, " " extconfig.extconfig, " @@ -457,10 +462,11 @@ schema_list_ext_schemas(PGSQL *pgsql, DatabaseCatalog *catalog) SourceSchemaArrayContext parseContext = { { 0 }, catalog, false }; char *sql = - "select n.oid, n.nspname, " + "select n.oid, format('%I', n.nspname) as nspname, " " format('- %s %s', " " regexp_replace(n.nspname, '[\\n\\r]', ' '), " - " regexp_replace(auth.rolname, '[\\n\\r]', ' ')) " + " regexp_replace(auth.rolname, '[\\n\\r]', ' ')), " + " format('%I', current_database()) as datname" " from pg_namespace n " " join pg_roles auth ON auth.oid = n.nspowner " " join pg_depend d " @@ -568,6 +574,7 @@ schema_list_collations(PGSQL *pgsql, DatabaseCatalog *catalog) " ) " "select colloid, collname, " " pg_describe_object('pg_class'::regclass, indexrelid, 0), " + " format('%I', current_database()) as datname, " " format('%s %s %s', " " regexp_replace(n.nspname, '[\\n\\r]', ' '), " " regexp_replace(c.collname, '[\\n\\r]', ' '), " @@ -582,7 +589,8 @@ schema_list_collations(PGSQL *pgsql, DatabaseCatalog *catalog) "union " "select c.oid as colloid, c.collname, " - " format('database %s', d.datname) as desc, " + " format('database %I', current_database()) as desc, " + " format('%I', current_database()) as datname, " " format('%s %s %s', " " regexp_replace(n.nspname, '[\\n\\r]', ' '), " " regexp_replace(c.collname, '[\\n\\r]', ' '), " @@ -597,6 +605,7 @@ schema_list_collations(PGSQL *pgsql, DatabaseCatalog *catalog) "select coll.oid as colloid, coll.collname, " " pg_describe_object('pg_class'::regclass, attrelid, attnum), " + " format('%I', current_database()) as datname, " " format('%s %s %s', " " regexp_replace(cn.nspname, '[\\n\\r]', ' '), " " regexp_replace(coll.collname, '[\\n\\r]', ' '), " @@ -971,6 +980,7 @@ struct FilteringQueries listSourceTablesSQL[] = { " select c.oid, " " format('%I', n.nspname) as nspname, " " format('%I', c.relname) as relname, " + " format('%I', current_database()) as datname, " " pg_am.amname, " " c.relpages, c.reltuples::bigint, " " ts.bytes as bytes, " @@ -1056,6 +1066,7 @@ struct FilteringQueries listSourceTablesSQL[] = { " select c.oid, " " format('%I', n.nspname) as nspname, " " format('%I', c.relname) as relname, " + " format('%I', current_database()) as datname, " " pg_am.amname, " " c.relpages, c.reltuples::bigint, " " ts.bytes as bytes, " @@ -1149,6 +1160,7 @@ struct FilteringQueries listSourceTablesSQL[] = { " select c.oid, " " format('%I', n.nspname) as nspname, " " format('%I', c.relname) as relname, " + " format('%I', current_database()) as datname, " " pg_am.amname, " " c.relpages, c.reltuples::bigint, " " ts.bytes as bytes, " @@ -1253,6 +1265,7 @@ struct FilteringQueries listSourceTablesSQL[] = { " select c.oid, " " format('%I', n.nspname) as nspname, " " format('%I', c.relname) as relname, " + " format('%I', current_database()) as datname, " " pg_am.amname, " " c.relpages, c.reltuples::bigint, " " ts.bytes as bytes, " @@ -1346,6 +1359,7 @@ struct FilteringQueries listSourceTablesSQL[] = { " select c.oid, " " format('%I', n.nspname) as nspname, " " format('%I', c.relname) as relname, " + " format('%I', current_database()) as datname, " " pg_am.amname, " " c.relpages, c.reltuples::bigint, " " ts.bytes as bytes, " @@ -1455,6 +1469,7 @@ schema_list_table(PGSQL *pgsql, " select c.oid, " " format('%I', n.nspname) as nspname, " " format('%I', c.relname) as relname, " + " format('%I', current_database()) as datname, " " pg_am.amname, " " c.relpages, c.reltuples::bigint, " " null as bytes, " @@ -1608,6 +1623,7 @@ struct FilteringQueries listSourceTablesNoPKSQL[] = { " select c.oid, " " format('%I', n.nspname) as nspname, " " format('%I', c.relname) as relname, " + " format('%I', current_database()) as datname, " " pg_am.amname, " " c.relpages, c.reltuples::bigint, " " ts.bytes as bytes, " @@ -1655,6 +1671,7 @@ struct FilteringQueries listSourceTablesNoPKSQL[] = { " select c.oid, " " format('%I', n.nspname) as nspname, " " format('%I', c.relname) as relname, " + " format('%I', current_database()) as datname, " " pg_am.amname, " " c.relpages, c.reltuples::bigint, " " ts.bytes as bytes, " @@ -1707,6 +1724,7 @@ struct FilteringQueries listSourceTablesNoPKSQL[] = { " select c.oid, " " format('%I', n.nspname) as nspname, " " format('%I', c.relname) as relname, " + " format('%I', current_database()) as datname, " " pg_am.amname, " " c.relpages, c.reltuples::bigint, " " ts.bytes as bytes, " @@ -1773,6 +1791,7 @@ struct FilteringQueries listSourceTablesNoPKSQL[] = { " select c.oid, " " format('%I', n.nspname) as nspname, " " format('%I', c.relname) as relname, " + " format('%I', current_database()) as datname, " " pg_am.amname, " " c.relpages, c.reltuples::bigint, " " ts.bytes as bytes, " @@ -1828,6 +1847,7 @@ struct FilteringQueries listSourceTablesNoPKSQL[] = { " select c.oid, " " format('%I', n.nspname) as nspname, " " format('%I', c.relname) as relname, " + " format('%I', current_database()) as datname, " " pg_am.amname, " " c.relpages, c.reltuples::bigint, " " ts.bytes as bytes, " @@ -1975,6 +1995,7 @@ struct FilteringQueries listSourceSequencesSQL[] = { " regexp_replace(n.nspname, '[\\n\\r]', ' '), " " regexp_replace(c.relname, '[\\n\\r]', ' '), " " regexp_replace(auth.rolname, '[\\n\\r]', ' ')), " + " format('%I', current_database()) as datname, " " NULL as ownedby, " " NULL as attrelid, " " NULL as attroid " @@ -2040,6 +2061,7 @@ struct FilteringQueries listSourceSequencesSQL[] = { * by using a DEFAULT value. */ " select s.seqoid, s.nspname, s.relname, s.restore_list_name, " + " format('%I', current_database()) as datname, " " r1.oid as ownedby, " " r2.oid as attrelid, " " a.oid as attroid " @@ -2119,6 +2141,7 @@ struct FilteringQueries listSourceSequencesSQL[] = { * by using a DEFAULT value. */ " select s.seqoid, s.nspname, s.relname, s.restore_list_name, " + " format('%I', current_database()) as datname, " " r1.oid as ownedby, " " r2.oid as attrelid, " " a.oid as attroid " @@ -2222,6 +2245,7 @@ struct FilteringQueries listSourceSequencesSQL[] = { * by using a DEFAULT value. */ " select s.seqoid, s.nspname, s.relname, s.restore_list_name, " + " format('%I', current_database()) as datname, " " r1.oid as ownedby, " " r2.oid as attrelid, " " a.oid as attroid " @@ -2301,6 +2325,7 @@ struct FilteringQueries listSourceSequencesSQL[] = { * by using a DEFAULT value. */ " select s.seqoid, s.nspname, s.relname, s.restore_list_name, " + " format('%I', current_database()) as datname, " " r1.oid as ownedby, " " r2.oid as attrelid, " " a.oid as attroid " @@ -2426,6 +2451,7 @@ schema_list_sequences(PGSQL *pgsql, " format('%%I', nspname) as nspname, " " format('%%I', relname) as relname, " " restore_list_name, " + " format('%%I', current_database()) as datname, " " ownedby, attrelid, attroid " " from (%s) as exclude " " where not exists " @@ -3868,11 +3894,9 @@ getSchemaList(void *ctx, PGresult *result) SourceSchemaArrayContext *context = (SourceSchemaArrayContext *) ctx; int nTuples = PQntuples(result); - log_debug("getSchemaList: %d", nTuples); - - if (PQnfields(result) != 3) + if (PQnfields(result) != 4) { - log_error("Query returned %d columns, expected 3", PQnfields(result)); + log_error("Query returned %d columns, expected 4", PQnfields(result)); context->parsedOk = false; return; } @@ -3923,6 +3947,18 @@ getSchemaList(void *ctx, PGresult *result) ++errors; } + /* 4. datname */ + value = PQgetvalue(result, rowNumber, 3); + length = strlcpy(schema->datname, value, PG_NAMEDATALEN); + + if (length >= PG_NAMEDATALEN) + { + log_error("Schema datname \"%s\" is %d bytes long, " + "the maximum expected is %d (PG_NAMEDATALEN - 1)", + value, length, PG_NAMEDATALEN - 1); + ++errors; + } + log_trace("getSchemaList: %u \"%s\" %s", schema->oid, schema->nspname, @@ -4281,9 +4317,9 @@ getExtensionList(void *ctx, PGresult *result) log_debug("getExtensionList: %d", nTuples); - if (PQnfields(result) != 11) + if (PQnfields(result) != 12) { - log_error("Query returned %d columns, expected 10", PQnfields(result)); + log_error("Query returned %d columns, expected 12", PQnfields(result)); context->parsedOk = false; return; } @@ -4438,18 +4474,30 @@ parseCurrentExtension(PGresult *result, ++errors; } - /* 4. extrelocatable */ + /* 4. datname */ value = PQgetvalue(result, rowNumber, 3); + length = strlcpy(extension->datname, value, PG_NAMEDATALEN); + + if (length >= PG_NAMEDATALEN) + { + log_error("Extension datname \"%s\" is %d bytes long, " + "the maximum expected is %d (PG_NAMEDATALEN - 1)", + value, length, PG_NAMEDATALEN - 1); + ++errors; + } + + /* 5. extrelocatable */ + value = PQgetvalue(result, rowNumber, 4); extension->extrelocatable = (*value) == 't'; - /* 5. array_length(extconfig), or NULL */ - if (PQgetisnull(result, rowNumber, 4)) + /* 6. array_length(extconfig), or NULL */ + if (PQgetisnull(result, rowNumber, 5)) { extension->config.count = 0; } else { - value = PQgetvalue(result, rowNumber, 4); + value = PQgetvalue(result, rowNumber, 5); if (!stringToInt(value, &(extension->config.count))) { @@ -4458,14 +4506,14 @@ parseCurrentExtension(PGresult *result, } } - /* 6. n (position over count), or NULL */ - if (PQgetisnull(result, rowNumber, 5)) + /* 7. n (position over count), or NULL */ + if (PQgetisnull(result, rowNumber, 6)) { *confIndex = 0; } else { - value = PQgetvalue(result, rowNumber, 5); + value = PQgetvalue(result, rowNumber, 6); if (!stringToInt(value, confIndex)) { @@ -4490,8 +4538,8 @@ parseCurrentExtensionConfig(PGresult *result, { int errors = 0; - /* 7. extconfig (pg_class oid) */ - char *value = PQgetvalue(result, rowNumber, 6); + /* 8. extconfig (pg_class oid) */ + char *value = PQgetvalue(result, rowNumber, 7); if (!stringToUInt32(value, &(extConfig->reloid))) { @@ -4499,8 +4547,8 @@ parseCurrentExtensionConfig(PGresult *result, ++errors; } - /* 8. n.nspname */ - value = PQgetvalue(result, rowNumber, 7); + /* 9. n.nspname */ + value = PQgetvalue(result, rowNumber, 8); int length = strlcpy(extConfig->nspname, value, PG_NAMEDATALEN); if (length >= PG_NAMEDATALEN) @@ -4511,8 +4559,8 @@ parseCurrentExtensionConfig(PGresult *result, ++errors; } - /* 9. c.relname */ - value = PQgetvalue(result, rowNumber, 8); + /* 10. c.relname */ + value = PQgetvalue(result, rowNumber, 9); length = strlcpy(extConfig->relname, value, PG_NAMEDATALEN); if (length >= PG_NAMEDATALEN) @@ -4523,8 +4571,8 @@ parseCurrentExtensionConfig(PGresult *result, ++errors; } - /* 10. extcondition */ - value = PQgetvalue(result, rowNumber, 9); + /* 11. extcondition */ + value = PQgetvalue(result, rowNumber, 10); extConfig->condition = strdup(value); if (extConfig->condition == NULL) @@ -4533,8 +4581,8 @@ parseCurrentExtensionConfig(PGresult *result, ++errors; } - /* 11. relkind */ - value = PQgetvalue(result, rowNumber, 10); + /* 12. relkind */ + value = PQgetvalue(result, rowNumber, 11); extConfig->relkind = value[0]; if (extConfig->relkind == 0) @@ -4662,9 +4710,9 @@ getCollationList(void *ctx, PGresult *result) log_debug("getCollationList: %d", nTuples); - if (PQnfields(result) != 4) + if (PQnfields(result) != 5) { - log_error("Query returned %d columns, expected 4", PQnfields(result)); + log_error("Query returned %d columns, expected 5", PQnfields(result)); context->parsedOk = false; return; } @@ -4717,8 +4765,20 @@ getCollationList(void *ctx, PGresult *result) strlcpy(collation->desc, value, length); - /* 4. restoreListName */ + /* 4. datname */ value = PQgetvalue(result, rowNumber, 3); + length = strlcpy(collation->datname, value, PG_NAMEDATALEN); + + if (length >= PG_NAMEDATALEN) + { + log_error("Collation datname \"%s\" is %d bytes long, " + "the maximum expected is %d (PG_NAMEDATALEN - 1)", + value, length, PG_NAMEDATALEN - 1); + ++errors; + } + + /* 5. restoreListName */ + value = PQgetvalue(result, rowNumber, 4); length = strlcpy(collation->restoreListName, value, @@ -4760,9 +4820,9 @@ getTableArray(void *ctx, PGresult *result) SourceTableArrayContext *context = (SourceTableArrayContext *) ctx; int nTuples = PQntuples(result); - if (PQnfields(result) != 12) + if (PQnfields(result) != 13) { - log_error("Query returned %d columns, expected 12", PQnfields(result)); + log_error("Query returned %d columns, expected 13", PQnfields(result)); context->parsedOk = false; return; } @@ -4810,6 +4870,7 @@ parseCurrentSourceTable(PGresult *result, int rowNumber, SourceTable *table) int fnoid = PQfnumber(result, "oid"); int fnnspname = PQfnumber(result, "nspname"); int fnrelname = PQfnumber(result, "relname"); + int fndatname = PQfnumber(result, "datname"); int fnamname = PQfnumber(result, "amname"); int fnrelpages = PQfnumber(result, "relpages"); int fnreltuples = PQfnumber(result, "reltuples"); @@ -4869,6 +4930,18 @@ parseCurrentSourceTable(PGresult *result, int rowNumber, SourceTable *table) ++errors; } + /* datname */ + value = PQgetvalue(result, rowNumber, fndatname); + length = strlcpy(table->datname, value, PG_NAMEDATALEN); + + if (length >= PG_NAMEDATALEN) + { + log_error("Table datname \"%s\" is %d bytes long, " + "the maximum expected is %d (PG_NAMEDATALEN - 1)", + value, length, PG_NAMEDATALEN - 1); + ++errors; + } + /* pgam_amname */ if (PQgetisnull(result, rowNumber, fnamname)) { @@ -5083,9 +5156,9 @@ getSequenceArray(void *ctx, PGresult *result) SourceSequenceArrayContext *context = (SourceSequenceArrayContext *) ctx; int nTuples = PQntuples(result); - if (PQnfields(result) != 7) + if (PQnfields(result) != 8) { - log_error("Query returned %d columns, expected 7", PQnfields(result)); + log_error("Query returned %d columns, expected 8", PQnfields(result)); context->parsedOk = false; return; } @@ -5186,20 +5259,32 @@ parseCurrentSourceSequence(PGresult *result, int rowNumber, SourceSequence *seq) if (length >= RESTORE_LIST_NAMEDATALEN) { - log_error("Table restore list name \"%s\" is %d bytes long, " + log_error("Sequence restore list name \"%s\" is %d bytes long, " "the maximum expected is %d (RESTORE_LIST_NAMEDATALEN - 1)", value, length, RESTORE_LIST_NAMEDATALEN - 1); ++errors; } - /* 5. ownedby */ - if (PQgetisnull(result, rowNumber, 4)) + /* 5. datname */ + value = PQgetvalue(result, rowNumber, 4); + length = strlcpy(seq->datname, value, PG_NAMEDATALEN); + + if (length >= PG_NAMEDATALEN) + { + log_error("Sequence datname \"%s\" is %d bytes long, " + "the maximum expected is %d (RESTORE_LIST_NAMEDATALEN - 1)", + value, length, RESTORE_LIST_NAMEDATALEN - 1); + ++errors; + } + + /* 6. ownedby */ + if (PQgetisnull(result, rowNumber, 5)) { seq->ownedby = 0; } else { - value = PQgetvalue(result, rowNumber, 4); + value = PQgetvalue(result, rowNumber, 5); if (!stringToUInt32(value, &(seq->ownedby)) || seq->ownedby == 0) { @@ -5208,14 +5293,14 @@ parseCurrentSourceSequence(PGresult *result, int rowNumber, SourceSequence *seq) } } - /* 6. attrelid */ - if (PQgetisnull(result, rowNumber, 5)) + /* 7. attrelid */ + if (PQgetisnull(result, rowNumber, 6)) { seq->attrelid = 0; } else { - value = PQgetvalue(result, rowNumber, 5); + value = PQgetvalue(result, rowNumber, 6); if (!stringToUInt32(value, &(seq->attrelid)) || seq->attrelid == 0) { @@ -5224,14 +5309,14 @@ parseCurrentSourceSequence(PGresult *result, int rowNumber, SourceSequence *seq) } } - /* 6. attroid */ - if (PQgetisnull(result, rowNumber, 6)) + /* 8. attroid */ + if (PQgetisnull(result, rowNumber, 7)) { seq->attroid = 0; } else { - value = PQgetvalue(result, rowNumber, 6); + value = PQgetvalue(result, rowNumber, 7); if (!stringToUInt32(value, &(seq->attroid)) || seq->attroid == 0) { diff --git a/src/bin/pgcopydb/schema.h b/src/bin/pgcopydb/schema.h index a34800aee..2c50d3cb7 100644 --- a/src/bin/pgcopydb/schema.h +++ b/src/bin/pgcopydb/schema.h @@ -45,6 +45,7 @@ typedef struct SourceSchema uint32_t oid; char nspname[PG_NAMEDATALEN]; char restoreListName[RESTORE_LIST_NAMEDATALEN]; + char datname[PG_NAMEDATALEN]; } SourceSchema; @@ -75,6 +76,7 @@ typedef struct SourceExtension uint32_t oid; char extname[PG_NAMEDATALEN]; char extnamespace[PG_NAMEDATALEN]; + char datname[PG_NAMEDATALEN]; bool extrelocatable; SourceExtensionConfigArray config; } SourceExtension; @@ -101,6 +103,7 @@ typedef struct SourceCollation char collname[PG_NAMEDATALEN]; char *desc; /* malloc'ed area */ char restoreListName[RESTORE_LIST_NAMEDATALEN]; + char datname[PG_NAMEDATALEN]; } SourceCollation; @@ -154,6 +157,7 @@ typedef struct SourceTable char qname[PG_NAMEDATALEN_FQ]; char nspname[PG_NAMEDATALEN]; char relname[PG_NAMEDATALEN]; + char datname[PG_NAMEDATALEN]; char amname[PG_NAMEDATALEN]; char restoreListName[RESTORE_LIST_NAMEDATALEN]; @@ -202,6 +206,7 @@ typedef struct SourceSequence char qname[PG_NAMEDATALEN_FQ]; char nspname[PG_NAMEDATALEN]; char relname[PG_NAMEDATALEN]; + char datname[PG_NAMEDATALEN]; int64_t lastValue; bool isCalled;