|
|
|
@ -22,7 +22,7 @@ |
|
|
|
|
* |
|
|
|
|
* |
|
|
|
|
* IDENTIFICATION |
|
|
|
|
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.286 2002/08/18 21:05:32 tgl Exp $ |
|
|
|
|
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.287 2002/08/19 19:33:35 tgl Exp $ |
|
|
|
|
* |
|
|
|
|
*------------------------------------------------------------------------- |
|
|
|
|
*/ |
|
|
|
@ -2056,6 +2056,8 @@ getTables(int *numTables) |
|
|
|
|
int i_relhasindex; |
|
|
|
|
int i_relhasrules; |
|
|
|
|
int i_relhasoids; |
|
|
|
|
int i_owning_tab; |
|
|
|
|
int i_owning_col; |
|
|
|
|
|
|
|
|
|
/* Make sure we are in proper schema */ |
|
|
|
|
selectSourceSchema("pg_catalog"); |
|
|
|
@ -2071,20 +2073,34 @@ getTables(int *numTables) |
|
|
|
|
* |
|
|
|
|
* Note: in this phase we should collect only a minimal amount of |
|
|
|
|
* information about each table, basically just enough to decide if |
|
|
|
|
* it is interesting. |
|
|
|
|
* it is interesting. We must fetch all tables in this phase because |
|
|
|
|
* otherwise we cannot correctly identify inherited columns, serial |
|
|
|
|
* columns, etc. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
if (g_fout->remoteVersion >= 70300) |
|
|
|
|
{ |
|
|
|
|
/*
|
|
|
|
|
* Left join to pick up dependency info linking sequences to their |
|
|
|
|
* serial column, if any |
|
|
|
|
*/ |
|
|
|
|
appendPQExpBuffer(query, |
|
|
|
|
"SELECT pg_class.oid, relname, relacl, relkind, " |
|
|
|
|
"SELECT c.oid, relname, relacl, relkind, " |
|
|
|
|
"relnamespace, " |
|
|
|
|
"(select usename from pg_user where relowner = usesysid) as usename, " |
|
|
|
|
"relchecks, reltriggers, " |
|
|
|
|
"relhasindex, relhasrules, relhasoids " |
|
|
|
|
"from pg_class " |
|
|
|
|
"relhasindex, relhasrules, relhasoids, " |
|
|
|
|
"d.refobjid as owning_tab, " |
|
|
|
|
"d.refobjsubid as owning_col " |
|
|
|
|
"from pg_class c " |
|
|
|
|
"left join pg_depend d on " |
|
|
|
|
"(c.relkind = '%c' and " |
|
|
|
|
"d.classid = c.tableoid and d.objid = c.oid and " |
|
|
|
|
"d.objsubid = 0 and " |
|
|
|
|
"d.refclassid = c.tableoid and d.deptype = 'i') " |
|
|
|
|
"where relkind in ('%c', '%c', '%c') " |
|
|
|
|
"order by oid", |
|
|
|
|
"order by c.oid", |
|
|
|
|
RELKIND_SEQUENCE, |
|
|
|
|
RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW); |
|
|
|
|
} |
|
|
|
|
else if (g_fout->remoteVersion >= 70200) |
|
|
|
@ -2095,7 +2111,9 @@ getTables(int *numTables) |
|
|
|
|
"0::oid as relnamespace, " |
|
|
|
|
"(select usename from pg_user where relowner = usesysid) as usename, " |
|
|
|
|
"relchecks, reltriggers, " |
|
|
|
|
"relhasindex, relhasrules, relhasoids " |
|
|
|
|
"relhasindex, relhasrules, relhasoids, " |
|
|
|
|
"NULL::oid as owning_tab, " |
|
|
|
|
"NULL::int4 as owning_col " |
|
|
|
|
"from pg_class " |
|
|
|
|
"where relkind in ('%c', '%c', '%c') " |
|
|
|
|
"order by oid", |
|
|
|
@ -2109,7 +2127,10 @@ getTables(int *numTables) |
|
|
|
|
"0::oid as relnamespace, " |
|
|
|
|
"(select usename from pg_user where relowner = usesysid) as usename, " |
|
|
|
|
"relchecks, reltriggers, " |
|
|
|
|
"relhasindex, relhasrules, 't'::bool as relhasoids " |
|
|
|
|
"relhasindex, relhasrules, " |
|
|
|
|
"'t'::bool as relhasoids, " |
|
|
|
|
"NULL::oid as owning_tab, " |
|
|
|
|
"NULL::int4 as owning_col " |
|
|
|
|
"from pg_class " |
|
|
|
|
"where relkind in ('%c', '%c', '%c') " |
|
|
|
|
"order by oid", |
|
|
|
@ -2131,7 +2152,10 @@ getTables(int *numTables) |
|
|
|
|
"0::oid as relnamespace, " |
|
|
|
|
"(select usename from pg_user where relowner = usesysid) as usename, " |
|
|
|
|
"relchecks, reltriggers, " |
|
|
|
|
"relhasindex, relhasrules, 't'::bool as relhasoids " |
|
|
|
|
"relhasindex, relhasrules, " |
|
|
|
|
"'t'::bool as relhasoids, " |
|
|
|
|
"NULL::oid as owning_tab, " |
|
|
|
|
"NULL::int4 as owning_col " |
|
|
|
|
"from pg_class c " |
|
|
|
|
"where relkind in ('%c', '%c') " |
|
|
|
|
"order by oid", |
|
|
|
@ -2175,6 +2199,8 @@ getTables(int *numTables) |
|
|
|
|
i_relhasindex = PQfnumber(res, "relhasindex"); |
|
|
|
|
i_relhasrules = PQfnumber(res, "relhasrules"); |
|
|
|
|
i_relhasoids = PQfnumber(res, "relhasoids"); |
|
|
|
|
i_owning_tab = PQfnumber(res, "owning_tab"); |
|
|
|
|
i_owning_col = PQfnumber(res, "owning_col"); |
|
|
|
|
|
|
|
|
|
for (i = 0; i < ntups; i++) |
|
|
|
|
{ |
|
|
|
@ -2190,13 +2216,28 @@ getTables(int *numTables) |
|
|
|
|
tblinfo[i].hasoids = (strcmp(PQgetvalue(res, i, i_relhasoids), "t") == 0); |
|
|
|
|
tblinfo[i].ncheck = atoi(PQgetvalue(res, i, i_relchecks)); |
|
|
|
|
tblinfo[i].ntrig = atoi(PQgetvalue(res, i, i_reltriggers)); |
|
|
|
|
if (PQgetisnull(res, i, i_owning_tab)) |
|
|
|
|
{ |
|
|
|
|
tblinfo[i].owning_tab = NULL; |
|
|
|
|
tblinfo[i].owning_col = 0; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
tblinfo[i].owning_tab = strdup(PQgetvalue(res, i, i_owning_tab)); |
|
|
|
|
tblinfo[i].owning_col = atoi(PQgetvalue(res, i, i_owning_col)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* other fields were zeroed above */ |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Decide whether we want to dump this table. |
|
|
|
|
* Decide whether we want to dump this table. Sequences owned |
|
|
|
|
* by serial columns are never dumpable on their own; we will |
|
|
|
|
* transpose their owning table's dump flag to them below. |
|
|
|
|
*/ |
|
|
|
|
if (tblinfo[i].owning_tab == NULL) |
|
|
|
|
selectDumpableTable(&tblinfo[i]); |
|
|
|
|
else |
|
|
|
|
tblinfo[i].dump = false; |
|
|
|
|
tblinfo[i].interesting = tblinfo[i].dump; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -2314,7 +2355,8 @@ void |
|
|
|
|
getTableAttrs(TableInfo *tblinfo, int numTables) |
|
|
|
|
{ |
|
|
|
|
int i, |
|
|
|
|
j; |
|
|
|
|
j, |
|
|
|
|
k; |
|
|
|
|
PQExpBuffer q = createPQExpBuffer(); |
|
|
|
|
int i_attname; |
|
|
|
|
int i_atttypname; |
|
|
|
@ -2329,23 +2371,25 @@ getTableAttrs(TableInfo *tblinfo, int numTables) |
|
|
|
|
|
|
|
|
|
for (i = 0; i < numTables; i++) |
|
|
|
|
{ |
|
|
|
|
TableInfo *tbinfo = &tblinfo[i]; |
|
|
|
|
|
|
|
|
|
/* Don't bother to collect info for sequences */ |
|
|
|
|
if (tblinfo[i].relkind == RELKIND_SEQUENCE) |
|
|
|
|
if (tbinfo->relkind == RELKIND_SEQUENCE) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
/* Don't bother to collect info for type relations */ |
|
|
|
|
if (tblinfo[i].relkind == RELKIND_COMPOSITE_TYPE) |
|
|
|
|
if (tbinfo->relkind == RELKIND_COMPOSITE_TYPE) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
/* Don't bother with uninteresting tables, either */ |
|
|
|
|
if (!tblinfo[i].interesting) |
|
|
|
|
if (!tbinfo->interesting) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Make sure we are in proper schema for this table; this allows |
|
|
|
|
* correct retrieval of formatted type names and default exprs |
|
|
|
|
*/ |
|
|
|
|
selectSourceSchema(tblinfo[i].relnamespace->nspname); |
|
|
|
|
selectSourceSchema(tbinfo->relnamespace->nspname); |
|
|
|
|
|
|
|
|
|
/* find all the user attributes and their types */ |
|
|
|
|
|
|
|
|
@ -2359,7 +2403,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables) |
|
|
|
|
*/ |
|
|
|
|
if (g_verbose) |
|
|
|
|
write_msg(NULL, "finding the columns and types for table %s\n", |
|
|
|
|
tblinfo[i].relname); |
|
|
|
|
tbinfo->relname); |
|
|
|
|
|
|
|
|
|
resetPQExpBuffer(q); |
|
|
|
|
|
|
|
|
@ -2372,7 +2416,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables) |
|
|
|
|
"where attrelid = '%s'::pg_catalog.oid " |
|
|
|
|
"and attnum > 0::pg_catalog.int2 " |
|
|
|
|
"order by attrelid, attnum", |
|
|
|
|
tblinfo[i].oid); |
|
|
|
|
tbinfo->oid); |
|
|
|
|
} |
|
|
|
|
else if (g_fout->remoteVersion >= 70100) |
|
|
|
|
{ |
|
|
|
@ -2388,7 +2432,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables) |
|
|
|
|
"where attrelid = '%s'::oid " |
|
|
|
|
"and attnum > 0::int2 " |
|
|
|
|
"order by attrelid, attnum", |
|
|
|
|
tblinfo[i].oid); |
|
|
|
|
tbinfo->oid); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
@ -2400,7 +2444,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables) |
|
|
|
|
"where attrelid = '%s'::oid " |
|
|
|
|
"and attnum > 0::int2 " |
|
|
|
|
"order by attrelid, attnum", |
|
|
|
|
tblinfo[i].oid); |
|
|
|
|
tbinfo->oid); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
res = PQexec(g_conn, q->data); |
|
|
|
@ -2421,34 +2465,36 @@ getTableAttrs(TableInfo *tblinfo, int numTables) |
|
|
|
|
i_atthasdef = PQfnumber(res, "atthasdef"); |
|
|
|
|
i_attisdropped = PQfnumber(res, "attisdropped"); |
|
|
|
|
|
|
|
|
|
tblinfo[i].numatts = ntups; |
|
|
|
|
tblinfo[i].attnames = (char **) malloc(ntups * sizeof(char *)); |
|
|
|
|
tblinfo[i].atttypnames = (char **) malloc(ntups * sizeof(char *)); |
|
|
|
|
tblinfo[i].atttypmod = (int *) malloc(ntups * sizeof(int)); |
|
|
|
|
tblinfo[i].attstattarget = (int *) malloc(ntups * sizeof(int)); |
|
|
|
|
tblinfo[i].attisdropped = (bool *) malloc(ntups * sizeof(bool)); |
|
|
|
|
tblinfo[i].notnull = (bool *) malloc(ntups * sizeof(bool)); |
|
|
|
|
tblinfo[i].adef_expr = (char **) malloc(ntups * sizeof(char *)); |
|
|
|
|
tblinfo[i].inhAttrs = (bool *) malloc(ntups * sizeof(bool)); |
|
|
|
|
tblinfo[i].inhAttrDef = (bool *) malloc(ntups * sizeof(bool)); |
|
|
|
|
tblinfo[i].inhNotNull = (bool *) malloc(ntups * sizeof(bool)); |
|
|
|
|
tbinfo->numatts = ntups; |
|
|
|
|
tbinfo->attnames = (char **) malloc(ntups * sizeof(char *)); |
|
|
|
|
tbinfo->atttypnames = (char **) malloc(ntups * sizeof(char *)); |
|
|
|
|
tbinfo->atttypmod = (int *) malloc(ntups * sizeof(int)); |
|
|
|
|
tbinfo->attstattarget = (int *) malloc(ntups * sizeof(int)); |
|
|
|
|
tbinfo->attisdropped = (bool *) malloc(ntups * sizeof(bool)); |
|
|
|
|
tbinfo->attisserial = (bool *) malloc(ntups * sizeof(bool)); |
|
|
|
|
tbinfo->notnull = (bool *) malloc(ntups * sizeof(bool)); |
|
|
|
|
tbinfo->adef_expr = (char **) malloc(ntups * sizeof(char *)); |
|
|
|
|
tbinfo->inhAttrs = (bool *) malloc(ntups * sizeof(bool)); |
|
|
|
|
tbinfo->inhAttrDef = (bool *) malloc(ntups * sizeof(bool)); |
|
|
|
|
tbinfo->inhNotNull = (bool *) malloc(ntups * sizeof(bool)); |
|
|
|
|
hasdefaults = false; |
|
|
|
|
|
|
|
|
|
for (j = 0; j < ntups; j++) |
|
|
|
|
{ |
|
|
|
|
tblinfo[i].attnames[j] = strdup(PQgetvalue(res, j, i_attname)); |
|
|
|
|
tblinfo[i].atttypnames[j] = strdup(PQgetvalue(res, j, i_atttypname)); |
|
|
|
|
tblinfo[i].atttypmod[j] = atoi(PQgetvalue(res, j, i_atttypmod)); |
|
|
|
|
tblinfo[i].attstattarget[j] = atoi(PQgetvalue(res, j, i_attstattarget)); |
|
|
|
|
tblinfo[i].attisdropped[j] = (PQgetvalue(res, j, i_attisdropped)[0] == 't'); |
|
|
|
|
tblinfo[i].notnull[j] = (PQgetvalue(res, j, i_attnotnull)[0] == 't'); |
|
|
|
|
tblinfo[i].adef_expr[j] = NULL; /* fix below */ |
|
|
|
|
tbinfo->attnames[j] = strdup(PQgetvalue(res, j, i_attname)); |
|
|
|
|
tbinfo->atttypnames[j] = strdup(PQgetvalue(res, j, i_atttypname)); |
|
|
|
|
tbinfo->atttypmod[j] = atoi(PQgetvalue(res, j, i_atttypmod)); |
|
|
|
|
tbinfo->attstattarget[j] = atoi(PQgetvalue(res, j, i_attstattarget)); |
|
|
|
|
tbinfo->attisdropped[j] = (PQgetvalue(res, j, i_attisdropped)[0] == 't'); |
|
|
|
|
tbinfo->attisserial[j] = false; /* fix below */ |
|
|
|
|
tbinfo->notnull[j] = (PQgetvalue(res, j, i_attnotnull)[0] == 't'); |
|
|
|
|
tbinfo->adef_expr[j] = NULL; /* fix below */ |
|
|
|
|
if (PQgetvalue(res, j, i_atthasdef)[0] == 't') |
|
|
|
|
hasdefaults = true; |
|
|
|
|
/* these flags will be set in flagInhAttrs() */ |
|
|
|
|
tblinfo[i].inhAttrs[j] = false; |
|
|
|
|
tblinfo[i].inhAttrDef[j] = false; |
|
|
|
|
tblinfo[i].inhNotNull[j] = false; |
|
|
|
|
tbinfo->inhAttrs[j] = false; |
|
|
|
|
tbinfo->inhAttrDef[j] = false; |
|
|
|
|
tbinfo->inhNotNull[j] = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PQclear(res); |
|
|
|
@ -2459,7 +2505,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables) |
|
|
|
|
|
|
|
|
|
if (g_verbose) |
|
|
|
|
write_msg(NULL, "finding DEFAULT expressions for table %s\n", |
|
|
|
|
tblinfo[i].relname); |
|
|
|
|
tbinfo->relname); |
|
|
|
|
|
|
|
|
|
resetPQExpBuffer(q); |
|
|
|
|
if (g_fout->remoteVersion >= 70300) |
|
|
|
@ -2468,7 +2514,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables) |
|
|
|
|
"pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc " |
|
|
|
|
"FROM pg_catalog.pg_attrdef " |
|
|
|
|
"WHERE adrelid = '%s'::pg_catalog.oid", |
|
|
|
|
tblinfo[i].oid); |
|
|
|
|
tbinfo->oid); |
|
|
|
|
} |
|
|
|
|
else if (g_fout->remoteVersion >= 70200) |
|
|
|
|
{ |
|
|
|
@ -2476,14 +2522,14 @@ getTableAttrs(TableInfo *tblinfo, int numTables) |
|
|
|
|
"pg_get_expr(adbin, adrelid) AS adsrc " |
|
|
|
|
"FROM pg_attrdef " |
|
|
|
|
"WHERE adrelid = '%s'::oid", |
|
|
|
|
tblinfo[i].oid); |
|
|
|
|
tbinfo->oid); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
/* no pg_get_expr, so must rely on adsrc */ |
|
|
|
|
appendPQExpBuffer(q, "SELECT adnum, adsrc FROM pg_attrdef " |
|
|
|
|
"WHERE adrelid = '%s'::oid", |
|
|
|
|
tblinfo[i].oid); |
|
|
|
|
tbinfo->oid); |
|
|
|
|
} |
|
|
|
|
res = PQexec(g_conn, q->data); |
|
|
|
|
if (!res || |
|
|
|
@ -2502,13 +2548,51 @@ getTableAttrs(TableInfo *tblinfo, int numTables) |
|
|
|
|
if (adnum <= 0 || adnum > ntups) |
|
|
|
|
{ |
|
|
|
|
write_msg(NULL, "bogus adnum value %d for table %s\n", |
|
|
|
|
adnum, tblinfo[i].relname); |
|
|
|
|
adnum, tbinfo->relname); |
|
|
|
|
exit_nicely(); |
|
|
|
|
} |
|
|
|
|
tblinfo[i].adef_expr[adnum-1] = strdup(PQgetvalue(res, j, 1)); |
|
|
|
|
tbinfo->adef_expr[adnum-1] = strdup(PQgetvalue(res, j, 1)); |
|
|
|
|
} |
|
|
|
|
PQclear(res); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Check to see if any columns are serial columns. Our first quick |
|
|
|
|
* filter is that it must be integer or bigint with a default. If |
|
|
|
|
* so, we scan to see if we found a sequence linked to this column. |
|
|
|
|
* If we did, mark the column and sequence appropriately. |
|
|
|
|
*/ |
|
|
|
|
for (j = 0; j < ntups; j++) |
|
|
|
|
{ |
|
|
|
|
/*
|
|
|
|
|
* Note assumption that format_type will show these types as |
|
|
|
|
* exactly "integer" and "bigint" regardless of schema path. |
|
|
|
|
* This is correct in 7.3 but needs to be watched. |
|
|
|
|
*/ |
|
|
|
|
if (strcmp(tbinfo->atttypnames[j], "integer") != 0 && |
|
|
|
|
strcmp(tbinfo->atttypnames[j], "bigint") != 0) |
|
|
|
|
continue; |
|
|
|
|
if (tbinfo->adef_expr[j] == NULL) |
|
|
|
|
continue; |
|
|
|
|
for (k = 0; k < numTables; k++) |
|
|
|
|
{ |
|
|
|
|
TableInfo *seqinfo = &tblinfo[k]; |
|
|
|
|
|
|
|
|
|
if (seqinfo->owning_tab != NULL && |
|
|
|
|
strcmp(seqinfo->owning_tab, tbinfo->oid) == 0 && |
|
|
|
|
seqinfo->owning_col == j+1) |
|
|
|
|
{ |
|
|
|
|
/*
|
|
|
|
|
* Found a match. Copy the table's interesting and |
|
|
|
|
* dumpable flags to the sequence. |
|
|
|
|
*/ |
|
|
|
|
tbinfo->attisserial[j] = true; |
|
|
|
|
seqinfo->interesting = tbinfo->interesting; |
|
|
|
|
seqinfo->dump = tbinfo->dump; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
destroyPQExpBuffer(q); |
|
|
|
@ -4884,11 +4968,26 @@ dumpACL(Archive *fout, const char *type, const char *name, |
|
|
|
|
static void |
|
|
|
|
dumpTableACL(Archive *fout, TableInfo *tbinfo) |
|
|
|
|
{ |
|
|
|
|
char *tmp = strdup(fmtId(tbinfo->relname)); |
|
|
|
|
dumpACL(fout, "TABLE", tmp, tbinfo->relname, |
|
|
|
|
char *namecopy = strdup(fmtId(tbinfo->relname)); |
|
|
|
|
char *dumpoid; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Choose OID to use for sorting ACL into position. For a view, sort |
|
|
|
|
* by the view OID; for a serial sequence, sort by the owning table's |
|
|
|
|
* OID; otherwise use the table's own OID. |
|
|
|
|
*/ |
|
|
|
|
if (tbinfo->viewoid != NULL) |
|
|
|
|
dumpoid = tbinfo->viewoid; |
|
|
|
|
else if (tbinfo->owning_tab != NULL) |
|
|
|
|
dumpoid = tbinfo->owning_tab; |
|
|
|
|
else |
|
|
|
|
dumpoid = tbinfo->oid; |
|
|
|
|
|
|
|
|
|
dumpACL(fout, "TABLE", namecopy, tbinfo->relname, |
|
|
|
|
tbinfo->relnamespace->nspname, tbinfo->usename, tbinfo->relacl, |
|
|
|
|
tbinfo->viewoid != NULL ? tbinfo->viewoid : tbinfo->oid); |
|
|
|
|
free(tmp); |
|
|
|
|
dumpoid); |
|
|
|
|
|
|
|
|
|
free(namecopy); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -4902,7 +5001,10 @@ dumpTables(Archive *fout, TableInfo tblinfo[], int numTables, |
|
|
|
|
{ |
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
/* Dump sequences first, in case they are referenced in table defn's */ |
|
|
|
|
/*
|
|
|
|
|
* Dump non-serial sequences first, in case they are referenced in |
|
|
|
|
* table defn's |
|
|
|
|
*/ |
|
|
|
|
for (i = 0; i < numTables; i++) |
|
|
|
|
{ |
|
|
|
|
TableInfo *tbinfo = &tblinfo[i]; |
|
|
|
@ -4910,7 +5012,7 @@ dumpTables(Archive *fout, TableInfo tblinfo[], int numTables, |
|
|
|
|
if (tbinfo->relkind != RELKIND_SEQUENCE) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (tbinfo->dump) |
|
|
|
|
if (tbinfo->dump && tbinfo->owning_tab == NULL) |
|
|
|
|
{ |
|
|
|
|
dumpOneSequence(fout, tbinfo, schemaOnly, dataOnly); |
|
|
|
|
if (!dataOnly && !aclsSkip) |
|
|
|
@ -4937,6 +5039,25 @@ dumpTables(Archive *fout, TableInfo tblinfo[], int numTables, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Dump serial sequences last (we will not emit any CREATE commands, |
|
|
|
|
* but we do have to think about ACLs and setval operations). |
|
|
|
|
*/ |
|
|
|
|
for (i = 0; i < numTables; i++) |
|
|
|
|
{ |
|
|
|
|
TableInfo *tbinfo = &tblinfo[i]; |
|
|
|
|
|
|
|
|
|
if (tbinfo->relkind != RELKIND_SEQUENCE) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (tbinfo->dump && tbinfo->owning_tab != NULL) |
|
|
|
|
{ |
|
|
|
|
dumpOneSequence(fout, tbinfo, schemaOnly, dataOnly); |
|
|
|
|
if (!dataOnly && !aclsSkip) |
|
|
|
|
dumpTableACL(fout, tbinfo); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -5089,24 +5210,48 @@ dumpOneTable(Archive *fout, TableInfo *tbinfo, TableInfo *g_tblinfo) |
|
|
|
|
appendPQExpBuffer(q, ","); |
|
|
|
|
appendPQExpBuffer(q, "\n "); |
|
|
|
|
|
|
|
|
|
/* Attr name & type */ |
|
|
|
|
/* Attribute name */ |
|
|
|
|
appendPQExpBuffer(q, "%s ", |
|
|
|
|
fmtId(tbinfo->attnames[j])); |
|
|
|
|
|
|
|
|
|
/* If no format_type, fake it */ |
|
|
|
|
/* Attribute type */ |
|
|
|
|
if (g_fout->remoteVersion >= 70100) |
|
|
|
|
appendPQExpBuffer(q, "%s", tbinfo->atttypnames[j]); |
|
|
|
|
{ |
|
|
|
|
char *typname = tbinfo->atttypnames[j]; |
|
|
|
|
|
|
|
|
|
if (tbinfo->attisserial[j]) |
|
|
|
|
{ |
|
|
|
|
if (strcmp(typname, "integer") == 0) |
|
|
|
|
typname = "serial"; |
|
|
|
|
else if (strcmp(typname, "bigint") == 0) |
|
|
|
|
typname = "bigserial"; |
|
|
|
|
} |
|
|
|
|
appendPQExpBuffer(q, "%s", typname); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
/* If no format_type, fake it */ |
|
|
|
|
appendPQExpBuffer(q, "%s", |
|
|
|
|
myFormatType(tbinfo->atttypnames[j], |
|
|
|
|
tbinfo->atttypmod[j])); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Default value */ |
|
|
|
|
if (tbinfo->adef_expr[j] != NULL && !tbinfo->inhAttrDef[j]) |
|
|
|
|
/* Default value --- suppress if inherited or serial */ |
|
|
|
|
if (tbinfo->adef_expr[j] != NULL && |
|
|
|
|
!tbinfo->inhAttrDef[j] && |
|
|
|
|
!tbinfo->attisserial[j]) |
|
|
|
|
appendPQExpBuffer(q, " DEFAULT %s", |
|
|
|
|
tbinfo->adef_expr[j]); |
|
|
|
|
|
|
|
|
|
/* Not Null constraint */ |
|
|
|
|
/*
|
|
|
|
|
* Not Null constraint --- suppress if inherited |
|
|
|
|
* |
|
|
|
|
* Note: we could suppress this for serial columns since |
|
|
|
|
* SERIAL implies NOT NULL. We choose not to for forward |
|
|
|
|
* compatibility, since there has been some talk of making |
|
|
|
|
* SERIAL not imply NOT NULL, in which case the explicit |
|
|
|
|
* specification would be needed. |
|
|
|
|
*/ |
|
|
|
|
if (tbinfo->notnull[j] && !tbinfo->inhNotNull[j]) |
|
|
|
|
appendPQExpBuffer(q, " NOT NULL"); |
|
|
|
|
|
|
|
|
@ -5708,15 +5853,17 @@ dumpOneSequence(Archive *fout, TableInfo *tbinfo, |
|
|
|
|
called = (strcmp(PQgetvalue(res, 0, 7), "t") == 0); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The logic we use for restoring sequences is as follows: - Add a |
|
|
|
|
* basic CREATE SEQUENCE statement (use last_val for start if called |
|
|
|
|
* is false, else use min_val for start_val). |
|
|
|
|
* The logic we use for restoring sequences is as follows: |
|
|
|
|
* |
|
|
|
|
* Add a basic CREATE SEQUENCE statement (use last_val for start if |
|
|
|
|
* called is false, else use min_val for start_val). Skip this if the |
|
|
|
|
* sequence came from a SERIAL column. |
|
|
|
|
* |
|
|
|
|
* Add a 'SETVAL(seq, last_val, iscalled)' at restore-time iff we load |
|
|
|
|
* data |
|
|
|
|
* data. We do this for serial sequences too. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
if (!dataOnly) |
|
|
|
|
if (!dataOnly && tbinfo->owning_tab == NULL) |
|
|
|
|
{ |
|
|
|
|
resetPQExpBuffer(delqry); |
|
|
|
|
|
|
|
|
|