Commit db086aa9 authored by Tom Lane's avatar Tom Lane

Make pg_dumplo schema-aware. Karel Zak

parent 839484f9
/* ------------------------------------------------------------------------- /* -------------------------------------------------------------------------
* pg_dumplo * pg_dumplo
* *
* $PostgreSQL: pgsql/contrib/pg_dumplo/lo_export.c,v 1.12 2003/11/29 19:51:35 pgsql Exp $ * $PostgreSQL: pgsql/contrib/pg_dumplo/lo_export.c,v 1.13 2004/11/28 23:49:49 tgl Exp $
* *
* Karel Zak 1999-2000 * Karel Zak 1999-2004
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
*/ */
...@@ -29,7 +29,7 @@ load_lolist(LODumpMaster * pgLO) ...@@ -29,7 +29,7 @@ load_lolist(LODumpMaster * pgLO)
LOlist *ll; LOlist *ll;
int i; int i;
int n; int n;
/* /*
* Now find any candidate tables who have columns of type oid. * Now find any candidate tables who have columns of type oid.
* *
...@@ -39,15 +39,16 @@ load_lolist(LODumpMaster * pgLO) ...@@ -39,15 +39,16 @@ load_lolist(LODumpMaster * pgLO)
* NOTE: the system oid column is ignored, as it has attnum < 1. This * NOTE: the system oid column is ignored, as it has attnum < 1. This
* shouldn't matter for correctness, but it saves time. * shouldn't matter for correctness, but it saves time.
*/ */
pgLO->res = PQexec(pgLO->conn, pgLO->res = PQexec(pgLO->conn, "SELECT c.relname, a.attname, n.nspname "
"SELECT c.relname, a.attname " "FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a, "
"FROM pg_class c, pg_attribute a, pg_type t " " pg_catalog.pg_type t, pg_catalog.pg_namespace n "
"WHERE a.attnum > 0 " "WHERE a.attnum > 0 "
" AND a.attrelid = c.oid " " AND a.attrelid = c.oid "
" AND a.atttypid = t.oid " " AND a.atttypid = t.oid "
" AND t.typname = 'oid' " " AND t.typname = 'oid' "
" AND c.relkind = 'r' " " AND c.relkind = 'r' "
" AND c.relname NOT LIKE 'pg_%'"); " AND c.relname NOT LIKE 'pg_%' "
" AND n.oid = c.relnamespace");
if (PQresultStatus(pgLO->res) != PGRES_TUPLES_OK) if (PQresultStatus(pgLO->res) != PGRES_TUPLES_OK)
{ {
...@@ -63,6 +64,7 @@ load_lolist(LODumpMaster * pgLO) ...@@ -63,6 +64,7 @@ load_lolist(LODumpMaster * pgLO)
} }
pgLO->lolist = (LOlist *) malloc((n + 1) * sizeof(LOlist)); pgLO->lolist = (LOlist *) malloc((n + 1) * sizeof(LOlist));
memset(pgLO->lolist, 0, (n + 1) * sizeof(LOlist));
if (!pgLO->lolist) if (!pgLO->lolist)
{ {
...@@ -74,8 +76,8 @@ load_lolist(LODumpMaster * pgLO) ...@@ -74,8 +76,8 @@ load_lolist(LODumpMaster * pgLO)
{ {
ll->lo_table = strdup(PQgetvalue(pgLO->res, i, 0)); ll->lo_table = strdup(PQgetvalue(pgLO->res, i, 0));
ll->lo_attr = strdup(PQgetvalue(pgLO->res, i, 1)); ll->lo_attr = strdup(PQgetvalue(pgLO->res, i, 1));
ll->lo_schema = strdup(PQgetvalue(pgLO->res, i, 2));
} }
ll->lo_table = ll->lo_attr = (char *) NULL;
PQclear(pgLO->res); PQclear(pgLO->res);
} }
...@@ -98,7 +100,7 @@ pglo_export(LODumpMaster * pgLO) ...@@ -98,7 +100,7 @@ pglo_export(LODumpMaster * pgLO)
fprintf(pgLO->index, "#\tHost: %s\n", pgLO->host); fprintf(pgLO->index, "#\tHost: %s\n", pgLO->host);
fprintf(pgLO->index, "#\tDatabase: %s\n", pgLO->db); fprintf(pgLO->index, "#\tDatabase: %s\n", pgLO->db);
fprintf(pgLO->index, "#\tUser: %s\n", pgLO->user); fprintf(pgLO->index, "#\tUser: %s\n", pgLO->user);
fprintf(pgLO->index, "#\n# oid\ttable\tattribut\tinfile\n#\n"); fprintf(pgLO->index, "#\n# oid\ttable\tattribut\tinfile\tschema\n#\n");
} }
pgLO->counter = 0; pgLO->counter = 0;
...@@ -109,8 +111,9 @@ pglo_export(LODumpMaster * pgLO) ...@@ -109,8 +111,9 @@ pglo_export(LODumpMaster * pgLO)
* Query: find the LOs referenced by this column * Query: find the LOs referenced by this column
*/ */
snprintf(Qbuff, QUERY_BUFSIZ, snprintf(Qbuff, QUERY_BUFSIZ,
"SELECT DISTINCT l.loid FROM \"%s\" x, pg_largeobject l WHERE x.\"%s\" = l.loid", "SELECT DISTINCT l.loid FROM \"%s\".\"%s\" x, pg_catalog.pg_largeobject l "
ll->lo_table, ll->lo_attr); "WHERE x.\"%s\" = l.loid",
ll->lo_schema, ll->lo_table, ll->lo_attr);
/* puts(Qbuff); */ /* puts(Qbuff); */
...@@ -124,8 +127,8 @@ pglo_export(LODumpMaster * pgLO) ...@@ -124,8 +127,8 @@ pglo_export(LODumpMaster * pgLO)
else if ((tuples = PQntuples(pgLO->res)) == 0) else if ((tuples = PQntuples(pgLO->res)) == 0)
{ {
if (!pgLO->quiet && pgLO->action == ACTION_EXPORT_ATTR) if (!pgLO->quiet && pgLO->action == ACTION_EXPORT_ATTR)
printf("%s: no large objects in \"%s\".\"%s\"\n", printf("%s: no large objects in \"%s\".\"%s\".\"%s\"\n",
progname, ll->lo_table, ll->lo_attr); progname, ll->lo_schema, ll->lo_table, ll->lo_attr);
} }
else else
{ {
...@@ -140,7 +143,7 @@ pglo_export(LODumpMaster * pgLO) ...@@ -140,7 +143,7 @@ pglo_export(LODumpMaster * pgLO)
{ {
snprintf(path, BUFSIZ, "%s/%s/%s", pgLO->space, pgLO->db, snprintf(path, BUFSIZ, "%s/%s/%s", pgLO->space, pgLO->db,
ll->lo_table); ll->lo_schema);
if (mkdir(path, DIR_UMASK) == -1) if (mkdir(path, DIR_UMASK) == -1)
{ {
...@@ -150,9 +153,21 @@ pglo_export(LODumpMaster * pgLO) ...@@ -150,9 +153,21 @@ pglo_export(LODumpMaster * pgLO)
exit(RE_ERROR); exit(RE_ERROR);
} }
} }
snprintf(path, BUFSIZ, "%s/%s/%s/%s", pgLO->space, pgLO->db, snprintf(path, BUFSIZ, "%s/%s/%s/%s", pgLO->space, pgLO->db,
ll->lo_table, ll->lo_attr); ll->lo_schema, ll->lo_table);
if (mkdir(path, DIR_UMASK) == -1)
{
if (errno != EEXIST)
{
perror(path);
exit(RE_ERROR);
}
}
snprintf(path, BUFSIZ, "%s/%s/%s/%s/%s", pgLO->space, pgLO->db,
ll->lo_schema, ll->lo_table, ll->lo_attr);
if (mkdir(path, DIR_UMASK) == -1) if (mkdir(path, DIR_UMASK) == -1)
{ {
...@@ -164,8 +179,8 @@ pglo_export(LODumpMaster * pgLO) ...@@ -164,8 +179,8 @@ pglo_export(LODumpMaster * pgLO)
} }
if (!pgLO->quiet) if (!pgLO->quiet)
printf("dump %s.%s (%d large obj)\n", printf("dump %s.%s.%s (%d large obj)\n",
ll->lo_table, ll->lo_attr, tuples); ll->lo_schema, ll->lo_table, ll->lo_attr, tuples);
} }
pgLO->counter += tuples; pgLO->counter += tuples;
...@@ -180,20 +195,22 @@ pglo_export(LODumpMaster * pgLO) ...@@ -180,20 +195,22 @@ pglo_export(LODumpMaster * pgLO)
if (pgLO->action == ACTION_SHOW) if (pgLO->action == ACTION_SHOW)
{ {
printf("%s.%s: %u\n", ll->lo_table, ll->lo_attr, lo); printf("%s.%s.%s: %u\n", ll->lo_schema, ll->lo_table, ll->lo_attr, lo);
continue; continue;
} }
snprintf(path, BUFSIZ, "%s/%s/%s/%s/%s", pgLO->space, snprintf(path, BUFSIZ, "%s/%s/%s/%s/%s/%s", pgLO->space,
pgLO->db, ll->lo_table, ll->lo_attr, val); pgLO->db, ll->lo_schema, ll->lo_table, ll->lo_attr, val);
if (lo_export(pgLO->conn, lo, path) < 0) if (lo_export(pgLO->conn, lo, path) < 0)
fprintf(stderr, "%s: lo_export failed:\n%s", progname, fprintf(stderr, "%s: lo_export failed:\n%s", progname,
PQerrorMessage(pgLO->conn)); PQerrorMessage(pgLO->conn));
else else
fprintf(pgLO->index, "%s\t%s\t%s\t%s/%s/%s/%s\n", val, fprintf(pgLO->index, "%s\t%s\t%s\t%s/%s/%s/%s/%s\t%s\n",
ll->lo_table, ll->lo_attr, pgLO->db, ll->lo_table, ll->lo_attr, val); val, ll->lo_table, ll->lo_attr, pgLO->db,
ll->lo_schema, ll->lo_table, ll->lo_attr,
val, ll->lo_schema);
} }
} }
......
/* ------------------------------------------------------------------------- /* -------------------------------------------------------------------------
* pg_dumplo * pg_dumplo
* *
* $PostgreSQL: pgsql/contrib/pg_dumplo/lo_import.c,v 1.10 2003/11/29 19:51:35 pgsql Exp $ * $PostgreSQL: pgsql/contrib/pg_dumplo/lo_import.c,v 1.11 2004/11/28 23:49:49 tgl Exp $
* *
* Karel Zak 1999-2000 * Karel Zak 1999-2004
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
*/ */
...@@ -27,26 +27,47 @@ pglo_import(LODumpMaster * pgLO) ...@@ -27,26 +27,47 @@ pglo_import(LODumpMaster * pgLO)
{ {
LOlist loa; LOlist loa;
Oid new_oid; Oid new_oid;
int ret, line=0;
char tab[MAX_TABLE_NAME], char tab[MAX_TABLE_NAME],
attr[MAX_ATTR_NAME], attr[MAX_ATTR_NAME],
sch[MAX_SCHEMA_NAME],
path[BUFSIZ], path[BUFSIZ],
lo_path[BUFSIZ], lo_path[BUFSIZ],
Qbuff[QUERY_BUFSIZ]; Qbuff[QUERY_BUFSIZ];
while (fgets(Qbuff, QUERY_BUFSIZ, pgLO->index)) while (fgets(Qbuff, QUERY_BUFSIZ, pgLO->index))
{ {
line++;
if (*Qbuff == '#') if (*Qbuff == '#')
continue; continue;
if (!pgLO->remove && !pgLO->quiet) if (!pgLO->remove && !pgLO->quiet)
printf(Qbuff); printf(Qbuff);
sscanf(Qbuff, "%u\t%s\t%s\t%s\n", &loa.lo_oid, tab, attr, path); if ((ret=sscanf(Qbuff, "%u\t%s\t%s\t%s\t%s\n", &loa.lo_oid, tab, attr, path, sch)) < 5)
{
/* backward compatible mode */
ret = sscanf(Qbuff, "%u\t%s\t%s\t%s\n", &loa.lo_oid, tab, attr, path);
strcpy(sch, "public");
}
if (ret < 4)
{
fprintf(stderr, "%s: index file reading failed at line %d\n", progname, line);
PQexec(pgLO->conn, "ROLLBACK");
fprintf(stderr, "\n%s: ROLLBACK\n", progname);
exit(RE_ERROR);
}
loa.lo_schema = sch;
loa.lo_table = tab; loa.lo_table = tab;
loa.lo_attr = attr; loa.lo_attr = attr;
snprintf(lo_path, BUFSIZ, "%s/%s", pgLO->space, path); if (path && *path=='/')
/* absolute path */
snprintf(lo_path, BUFSIZ, "%s", path);
else
snprintf(lo_path, BUFSIZ, "%s/%s", pgLO->space, path);
/* /*
* Import LO * Import LO
...@@ -80,10 +101,10 @@ pglo_import(LODumpMaster * pgLO) ...@@ -80,10 +101,10 @@ pglo_import(LODumpMaster * pgLO)
* UPDATE oid in tab * UPDATE oid in tab
*/ */
snprintf(Qbuff, QUERY_BUFSIZ, snprintf(Qbuff, QUERY_BUFSIZ,
"UPDATE \"%s\" SET \"%s\"=%u WHERE \"%s\"=%u", "UPDATE \"%s\".\"%s\" SET \"%s\"=%u WHERE \"%s\"=%u",
loa.lo_table, loa.lo_attr, new_oid, loa.lo_attr, loa.lo_oid); loa.lo_schema, loa.lo_table, loa.lo_attr, new_oid, loa.lo_attr, loa.lo_oid);
/* fprintf(stderr, Qbuff); */ /*fprintf(stderr, Qbuff);*/
pgLO->res = PQexec(pgLO->conn, Qbuff); pgLO->res = PQexec(pgLO->conn, Qbuff);
......
/* ------------------------------------------------------------------------- /* -------------------------------------------------------------------------
* pg_dumplo * pg_dumplo
* *
* $PostgreSQL: pgsql/contrib/pg_dumplo/main.c,v 1.21 2004/11/27 18:51:04 tgl Exp $ * $PostgreSQL: pgsql/contrib/pg_dumplo/main.c,v 1.22 2004/11/28 23:49:49 tgl Exp $
* *
* Karel Zak 1999-2000 * Karel Zak 1999-2000
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
...@@ -150,13 +150,10 @@ main(int argc, char **argv) ...@@ -150,13 +150,10 @@ main(int argc, char **argv)
/* /*
* Check space * Check space
*/ */
if (!pgLO->space && !pgLO->action == ACTION_SHOW) if (pgLO->space==NULL && pgLO->action != ACTION_SHOW)
{ {
if (!(pgLO->space = getenv("PWD"))) if (!(pgLO->space = getenv("PWD")))
{ pgLO->space = ".";
fprintf(stderr, "%s: not set space for dump-tree (option '-s' or $PWD).\n", progname);
exit(RE_ERROR);
}
} }
if (!pgLO->action) if (!pgLO->action)
...@@ -230,9 +227,8 @@ static void ...@@ -230,9 +227,8 @@ static void
parse_lolist(LODumpMaster * pgLO) parse_lolist(LODumpMaster * pgLO)
{ {
LOlist *ll; LOlist *ll;
char **d, char **d, *loc, *loc2,
*loc, buff[MAX_SCHEMA_NAME + MAX_TABLE_NAME + MAX_ATTR_NAME + 3];
buff[MAX_TABLE_NAME + MAX_ATTR_NAME + 1];
pgLO->lolist = (LOlist *) malloc(pgLO->argc * sizeof(LOlist)); pgLO->lolist = (LOlist *) malloc(pgLO->argc * sizeof(LOlist));
...@@ -247,16 +243,31 @@ parse_lolist(LODumpMaster * pgLO) ...@@ -247,16 +243,31 @@ parse_lolist(LODumpMaster * pgLO)
d++, ll++) d++, ll++)
{ {
strncpy(buff, *d, MAX_TABLE_NAME + MAX_ATTR_NAME); strncpy(buff, *d, MAX_SCHEMA_NAME + MAX_TABLE_NAME + MAX_ATTR_NAME + 2);
if ((loc = strchr(buff, '.')) == NULL) if ((loc = strchr(buff, '.')) == NULL || *(loc+1)=='\0')
{ {
fprintf(stderr, "%s: '%s' is bad 'table.attr'\n", progname, buff); fprintf(stderr, "%s: '%s' is bad 'table.attr' or 'schema.table.attr'\n", progname, buff);
exit(RE_ERROR); exit(RE_ERROR);
} }
loc2 = strchr(loc+1, '.');
*loc = '\0'; *loc = '\0';
ll->lo_table = strdup(buff);
ll->lo_attr = strdup(++loc); if (loc2)
{
/* "schema.table.attr"
*/
*loc2 = '\0';
ll->lo_schema = strdup(buff);
ll->lo_table = strdup(loc+1);
ll->lo_attr = strdup(loc2+1);
}
else
{
ll->lo_schema = strdup("public");
ll->lo_table = strdup(buff);
ll->lo_attr = strdup(loc+1);
}
} }
ll++; ll++;
ll->lo_table = ll->lo_attr = (char *) NULL; ll->lo_table = ll->lo_attr = (char *) NULL;
...@@ -277,7 +288,7 @@ usage(void) ...@@ -277,7 +288,7 @@ usage(void)
"-s --space=<dir> directory with dump tree (for export/import)\n" "-s --space=<dir> directory with dump tree (for export/import)\n"
"-i --import import large obj dump tree to DB\n" "-i --import import large obj dump tree to DB\n"
"-e --export export (dump) large obj to dump tree\n" "-e --export export (dump) large obj to dump tree\n"
"-l <table.attr ...> dump attribute (columns) with LO to dump tree\n" "-l <schema.table.attr ...> dump attribute (columns) with LO to dump tree\n"
"-a --all dump all LO in DB (default)\n" "-a --all dump all LO in DB (default)\n"
"-r --remove if is set '-i' try remove old LO\n" "-r --remove if is set '-i' try remove old LO\n"
"-q --quiet run quietly\n" "-q --quiet run quietly\n"
...@@ -288,8 +299,9 @@ usage(void) ...@@ -288,8 +299,9 @@ usage(void)
"Example (import): pg_dumplo -i -d my_db -s /my_dump/dir\n" "Example (import): pg_dumplo -i -d my_db -s /my_dump/dir\n"
"Example (show): pg_dumplo -w -d my_db\n\n" "Example (show): pg_dumplo -w -d my_db\n\n"
"Note: * option '-l' must be last option!\n" "Note: * option '-l' must be last option!\n"
" * option '-i' without option '-r' make new large obj in DB\n" " * default schema is \"public\"\n"
" * option '-i' without option '-r' make new large obj in DB\n"
" not rewrite old, the '-i' UPDATE oid numbers in table.attr only!\n" " not rewrite old, the '-i' UPDATE oid numbers in table.attr only!\n"
" * if option -s is not set, pg_dumplo uses $PWD\n" " * if option -s is not set, pg_dumplo uses $PWD or \".\"\n"
); /* puts() */ ); /* puts() */
} }
/* ------------------------------------------------------------------------- /* -------------------------------------------------------------------------
* pg_dumplo.h * pg_dumplo.h
* *
* $PostgreSQL: pgsql/contrib/pg_dumplo/pg_dumplo.h,v 1.10 2003/11/29 19:51:35 pgsql Exp $ * $PostgreSQL: pgsql/contrib/pg_dumplo/pg_dumplo.h,v 1.11 2004/11/28 23:49:49 tgl Exp $
* *
* Karel Zak 1999-2000 * Karel Zak 1999-2004
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
*/ */
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define RE_OK 0 #define RE_OK 0
#define RE_ERROR 1 #define RE_ERROR 1
#define MAX_SCHEMA_NAME 128
#define MAX_TABLE_NAME 128 #define MAX_TABLE_NAME 128
#define MAX_ATTR_NAME 128 #define MAX_ATTR_NAME 128
...@@ -36,10 +37,11 @@ ...@@ -36,10 +37,11 @@
*/ */
typedef struct typedef struct
{ {
char *lo_table, char *lo_schema,
*lo_attr; *lo_table,
Oid lo_oid; *lo_attr;
} LOlist; Oid lo_oid;
} LOlist;
typedef struct typedef struct
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment