Skip to content

Commit db086aa

Browse files
committed
Make pg_dumplo schema-aware. Karel Zak
1 parent 839484f commit db086aa

File tree

4 files changed

+106
-54
lines changed

4 files changed

+106
-54
lines changed

contrib/pg_dumplo/lo_export.c

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/* -------------------------------------------------------------------------
22
* pg_dumplo
33
*
4-
* $PostgreSQL: pgsql/contrib/pg_dumplo/lo_export.c,v 1.12 2003/11/29 19:51:35 pgsql Exp $
4+
* $PostgreSQL: pgsql/contrib/pg_dumplo/lo_export.c,v 1.13 2004/11/28 23:49:49 tgl Exp $
55
*
6-
* Karel Zak 1999-2000
6+
* Karel Zak 1999-2004
77
* -------------------------------------------------------------------------
88
*/
99

@@ -29,7 +29,7 @@ load_lolist(LODumpMaster * pgLO)
2929
LOlist *ll;
3030
int i;
3131
int n;
32-
32+
3333
/*
3434
* Now find any candidate tables who have columns of type oid.
3535
*
@@ -39,15 +39,16 @@ load_lolist(LODumpMaster * pgLO)
3939
* NOTE: the system oid column is ignored, as it has attnum < 1. This
4040
* shouldn't matter for correctness, but it saves time.
4141
*/
42-
pgLO->res = PQexec(pgLO->conn,
43-
"SELECT c.relname, a.attname "
44-
"FROM pg_class c, pg_attribute a, pg_type t "
42+
pgLO->res = PQexec(pgLO->conn, "SELECT c.relname, a.attname, n.nspname "
43+
"FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a, "
44+
" pg_catalog.pg_type t, pg_catalog.pg_namespace n "
4545
"WHERE a.attnum > 0 "
4646
" AND a.attrelid = c.oid "
4747
" AND a.atttypid = t.oid "
4848
" AND t.typname = 'oid' "
4949
" AND c.relkind = 'r' "
50-
" AND c.relname NOT LIKE 'pg_%'");
50+
" AND c.relname NOT LIKE 'pg_%' "
51+
" AND n.oid = c.relnamespace");
5152

5253
if (PQresultStatus(pgLO->res) != PGRES_TUPLES_OK)
5354
{
@@ -63,6 +64,7 @@ load_lolist(LODumpMaster * pgLO)
6364
}
6465

6566
pgLO->lolist = (LOlist *) malloc((n + 1) * sizeof(LOlist));
67+
memset(pgLO->lolist, 0, (n + 1) * sizeof(LOlist));
6668

6769
if (!pgLO->lolist)
6870
{
@@ -74,8 +76,8 @@ load_lolist(LODumpMaster * pgLO)
7476
{
7577
ll->lo_table = strdup(PQgetvalue(pgLO->res, i, 0));
7678
ll->lo_attr = strdup(PQgetvalue(pgLO->res, i, 1));
79+
ll->lo_schema = strdup(PQgetvalue(pgLO->res, i, 2));
7780
}
78-
ll->lo_table = ll->lo_attr = (char *) NULL;
7981

8082
PQclear(pgLO->res);
8183
}
@@ -98,7 +100,7 @@ pglo_export(LODumpMaster * pgLO)
98100
fprintf(pgLO->index, "#\tHost: %s\n", pgLO->host);
99101
fprintf(pgLO->index, "#\tDatabase: %s\n", pgLO->db);
100102
fprintf(pgLO->index, "#\tUser: %s\n", pgLO->user);
101-
fprintf(pgLO->index, "#\n# oid\ttable\tattribut\tinfile\n#\n");
103+
fprintf(pgLO->index, "#\n# oid\ttable\tattribut\tinfile\tschema\n#\n");
102104
}
103105

104106
pgLO->counter = 0;
@@ -109,8 +111,9 @@ pglo_export(LODumpMaster * pgLO)
109111
* Query: find the LOs referenced by this column
110112
*/
111113
snprintf(Qbuff, QUERY_BUFSIZ,
112-
"SELECT DISTINCT l.loid FROM \"%s\" x, pg_largeobject l WHERE x.\"%s\" = l.loid",
113-
ll->lo_table, ll->lo_attr);
114+
"SELECT DISTINCT l.loid FROM \"%s\".\"%s\" x, pg_catalog.pg_largeobject l "
115+
"WHERE x.\"%s\" = l.loid",
116+
ll->lo_schema, ll->lo_table, ll->lo_attr);
114117

115118
/* puts(Qbuff); */
116119

@@ -124,8 +127,8 @@ pglo_export(LODumpMaster * pgLO)
124127
else if ((tuples = PQntuples(pgLO->res)) == 0)
125128
{
126129
if (!pgLO->quiet && pgLO->action == ACTION_EXPORT_ATTR)
127-
printf("%s: no large objects in \"%s\".\"%s\"\n",
128-
progname, ll->lo_table, ll->lo_attr);
130+
printf("%s: no large objects in \"%s\".\"%s\".\"%s\"\n",
131+
progname, ll->lo_schema, ll->lo_table, ll->lo_attr);
129132
}
130133
else
131134
{
@@ -140,7 +143,7 @@ pglo_export(LODumpMaster * pgLO)
140143
{
141144

142145
snprintf(path, BUFSIZ, "%s/%s/%s", pgLO->space, pgLO->db,
143-
ll->lo_table);
146+
ll->lo_schema);
144147

145148
if (mkdir(path, DIR_UMASK) == -1)
146149
{
@@ -150,9 +153,21 @@ pglo_export(LODumpMaster * pgLO)
150153
exit(RE_ERROR);
151154
}
152155
}
153-
156+
154157
snprintf(path, BUFSIZ, "%s/%s/%s/%s", pgLO->space, pgLO->db,
155-
ll->lo_table, ll->lo_attr);
158+
ll->lo_schema, ll->lo_table);
159+
160+
if (mkdir(path, DIR_UMASK) == -1)
161+
{
162+
if (errno != EEXIST)
163+
{
164+
perror(path);
165+
exit(RE_ERROR);
166+
}
167+
}
168+
169+
snprintf(path, BUFSIZ, "%s/%s/%s/%s/%s", pgLO->space, pgLO->db,
170+
ll->lo_schema, ll->lo_table, ll->lo_attr);
156171

157172
if (mkdir(path, DIR_UMASK) == -1)
158173
{
@@ -164,8 +179,8 @@ pglo_export(LODumpMaster * pgLO)
164179
}
165180

166181
if (!pgLO->quiet)
167-
printf("dump %s.%s (%d large obj)\n",
168-
ll->lo_table, ll->lo_attr, tuples);
182+
printf("dump %s.%s.%s (%d large obj)\n",
183+
ll->lo_schema, ll->lo_table, ll->lo_attr, tuples);
169184
}
170185

171186
pgLO->counter += tuples;
@@ -180,20 +195,22 @@ pglo_export(LODumpMaster * pgLO)
180195

181196
if (pgLO->action == ACTION_SHOW)
182197
{
183-
printf("%s.%s: %u\n", ll->lo_table, ll->lo_attr, lo);
198+
printf("%s.%s.%s: %u\n", ll->lo_schema, ll->lo_table, ll->lo_attr, lo);
184199
continue;
185200
}
186201

187-
snprintf(path, BUFSIZ, "%s/%s/%s/%s/%s", pgLO->space,
188-
pgLO->db, ll->lo_table, ll->lo_attr, val);
202+
snprintf(path, BUFSIZ, "%s/%s/%s/%s/%s/%s", pgLO->space,
203+
pgLO->db, ll->lo_schema, ll->lo_table, ll->lo_attr, val);
189204

190205
if (lo_export(pgLO->conn, lo, path) < 0)
191206
fprintf(stderr, "%s: lo_export failed:\n%s", progname,
192207
PQerrorMessage(pgLO->conn));
193208

194209
else
195-
fprintf(pgLO->index, "%s\t%s\t%s\t%s/%s/%s/%s\n", val,
196-
ll->lo_table, ll->lo_attr, pgLO->db, ll->lo_table, ll->lo_attr, val);
210+
fprintf(pgLO->index, "%s\t%s\t%s\t%s/%s/%s/%s/%s\t%s\n",
211+
val, ll->lo_table, ll->lo_attr, pgLO->db,
212+
ll->lo_schema, ll->lo_table, ll->lo_attr,
213+
val, ll->lo_schema);
197214
}
198215
}
199216

contrib/pg_dumplo/lo_import.c

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/* -------------------------------------------------------------------------
22
* pg_dumplo
33
*
4-
* $PostgreSQL: pgsql/contrib/pg_dumplo/lo_import.c,v 1.10 2003/11/29 19:51:35 pgsql Exp $
4+
* $PostgreSQL: pgsql/contrib/pg_dumplo/lo_import.c,v 1.11 2004/11/28 23:49:49 tgl Exp $
55
*
6-
* Karel Zak 1999-2000
6+
* Karel Zak 1999-2004
77
* -------------------------------------------------------------------------
88
*/
99

@@ -27,26 +27,47 @@ pglo_import(LODumpMaster * pgLO)
2727
{
2828
LOlist loa;
2929
Oid new_oid;
30+
int ret, line=0;
3031
char tab[MAX_TABLE_NAME],
3132
attr[MAX_ATTR_NAME],
33+
sch[MAX_SCHEMA_NAME],
3234
path[BUFSIZ],
3335
lo_path[BUFSIZ],
3436
Qbuff[QUERY_BUFSIZ];
3537

3638
while (fgets(Qbuff, QUERY_BUFSIZ, pgLO->index))
3739
{
38-
40+
line++;
41+
3942
if (*Qbuff == '#')
4043
continue;
4144

4245
if (!pgLO->remove && !pgLO->quiet)
4346
printf(Qbuff);
4447

45-
sscanf(Qbuff, "%u\t%s\t%s\t%s\n", &loa.lo_oid, tab, attr, path);
48+
if ((ret=sscanf(Qbuff, "%u\t%s\t%s\t%s\t%s\n", &loa.lo_oid, tab, attr, path, sch)) < 5)
49+
{
50+
/* backward compatible mode */
51+
ret = sscanf(Qbuff, "%u\t%s\t%s\t%s\n", &loa.lo_oid, tab, attr, path);
52+
strcpy(sch, "public");
53+
}
54+
if (ret < 4)
55+
{
56+
fprintf(stderr, "%s: index file reading failed at line %d\n", progname, line);
57+
PQexec(pgLO->conn, "ROLLBACK");
58+
fprintf(stderr, "\n%s: ROLLBACK\n", progname);
59+
exit(RE_ERROR);
60+
}
61+
62+
loa.lo_schema = sch;
4663
loa.lo_table = tab;
4764
loa.lo_attr = attr;
4865

49-
snprintf(lo_path, BUFSIZ, "%s/%s", pgLO->space, path);
66+
if (path && *path=='/')
67+
/* absolute path */
68+
snprintf(lo_path, BUFSIZ, "%s", path);
69+
else
70+
snprintf(lo_path, BUFSIZ, "%s/%s", pgLO->space, path);
5071

5172
/*
5273
* Import LO
@@ -80,10 +101,10 @@ pglo_import(LODumpMaster * pgLO)
80101
* UPDATE oid in tab
81102
*/
82103
snprintf(Qbuff, QUERY_BUFSIZ,
83-
"UPDATE \"%s\" SET \"%s\"=%u WHERE \"%s\"=%u",
84-
loa.lo_table, loa.lo_attr, new_oid, loa.lo_attr, loa.lo_oid);
104+
"UPDATE \"%s\".\"%s\" SET \"%s\"=%u WHERE \"%s\"=%u",
105+
loa.lo_schema, loa.lo_table, loa.lo_attr, new_oid, loa.lo_attr, loa.lo_oid);
85106

86-
/* fprintf(stderr, Qbuff); */
107+
/*fprintf(stderr, Qbuff);*/
87108

88109
pgLO->res = PQexec(pgLO->conn, Qbuff);
89110

contrib/pg_dumplo/main.c

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* -------------------------------------------------------------------------
22
* pg_dumplo
33
*
4-
* $PostgreSQL: pgsql/contrib/pg_dumplo/main.c,v 1.21 2004/11/27 18:51:04 tgl Exp $
4+
* $PostgreSQL: pgsql/contrib/pg_dumplo/main.c,v 1.22 2004/11/28 23:49:49 tgl Exp $
55
*
66
* Karel Zak 1999-2000
77
* -------------------------------------------------------------------------
@@ -150,13 +150,10 @@ main(int argc, char **argv)
150150
/*
151151
* Check space
152152
*/
153-
if (!pgLO->space && !pgLO->action == ACTION_SHOW)
153+
if (pgLO->space==NULL && pgLO->action != ACTION_SHOW)
154154
{
155155
if (!(pgLO->space = getenv("PWD")))
156-
{
157-
fprintf(stderr, "%s: not set space for dump-tree (option '-s' or $PWD).\n", progname);
158-
exit(RE_ERROR);
159-
}
156+
pgLO->space = ".";
160157
}
161158

162159
if (!pgLO->action)
@@ -230,9 +227,8 @@ static void
230227
parse_lolist(LODumpMaster * pgLO)
231228
{
232229
LOlist *ll;
233-
char **d,
234-
*loc,
235-
buff[MAX_TABLE_NAME + MAX_ATTR_NAME + 1];
230+
char **d, *loc, *loc2,
231+
buff[MAX_SCHEMA_NAME + MAX_TABLE_NAME + MAX_ATTR_NAME + 3];
236232

237233
pgLO->lolist = (LOlist *) malloc(pgLO->argc * sizeof(LOlist));
238234

@@ -247,16 +243,31 @@ parse_lolist(LODumpMaster * pgLO)
247243
d++, ll++)
248244
{
249245

250-
strncpy(buff, *d, MAX_TABLE_NAME + MAX_ATTR_NAME);
246+
strncpy(buff, *d, MAX_SCHEMA_NAME + MAX_TABLE_NAME + MAX_ATTR_NAME + 2);
251247

252-
if ((loc = strchr(buff, '.')) == NULL)
248+
if ((loc = strchr(buff, '.')) == NULL || *(loc+1)=='\0')
253249
{
254-
fprintf(stderr, "%s: '%s' is bad 'table.attr'\n", progname, buff);
250+
fprintf(stderr, "%s: '%s' is bad 'table.attr' or 'schema.table.attr'\n", progname, buff);
255251
exit(RE_ERROR);
256252
}
253+
loc2 = strchr(loc+1, '.');
257254
*loc = '\0';
258-
ll->lo_table = strdup(buff);
259-
ll->lo_attr = strdup(++loc);
255+
256+
if (loc2)
257+
{
258+
/* "schema.table.attr"
259+
*/
260+
*loc2 = '\0';
261+
ll->lo_schema = strdup(buff);
262+
ll->lo_table = strdup(loc+1);
263+
ll->lo_attr = strdup(loc2+1);
264+
}
265+
else
266+
{
267+
ll->lo_schema = strdup("public");
268+
ll->lo_table = strdup(buff);
269+
ll->lo_attr = strdup(loc+1);
270+
}
260271
}
261272
ll++;
262273
ll->lo_table = ll->lo_attr = (char *) NULL;
@@ -277,7 +288,7 @@ usage(void)
277288
"-s --space=<dir> directory with dump tree (for export/import)\n"
278289
"-i --import import large obj dump tree to DB\n"
279290
"-e --export export (dump) large obj to dump tree\n"
280-
"-l <table.attr ...> dump attribute (columns) with LO to dump tree\n"
291+
"-l <schema.table.attr ...> dump attribute (columns) with LO to dump tree\n"
281292
"-a --all dump all LO in DB (default)\n"
282293
"-r --remove if is set '-i' try remove old LO\n"
283294
"-q --quiet run quietly\n"
@@ -288,8 +299,9 @@ usage(void)
288299
"Example (import): pg_dumplo -i -d my_db -s /my_dump/dir\n"
289300
"Example (show): pg_dumplo -w -d my_db\n\n"
290301
"Note: * option '-l' must be last option!\n"
291-
" * option '-i' without option '-r' make new large obj in DB\n"
302+
" * default schema is \"public\"\n"
303+
" * option '-i' without option '-r' make new large obj in DB\n"
292304
" not rewrite old, the '-i' UPDATE oid numbers in table.attr only!\n"
293-
" * if option -s is not set, pg_dumplo uses $PWD\n"
305+
" * if option -s is not set, pg_dumplo uses $PWD or \".\"\n"
294306
); /* puts() */
295307
}

contrib/pg_dumplo/pg_dumplo.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/* -------------------------------------------------------------------------
22
* pg_dumplo.h
33
*
4-
* $PostgreSQL: pgsql/contrib/pg_dumplo/pg_dumplo.h,v 1.10 2003/11/29 19:51:35 pgsql Exp $
4+
* $PostgreSQL: pgsql/contrib/pg_dumplo/pg_dumplo.h,v 1.11 2004/11/28 23:49:49 tgl Exp $
55
*
6-
* Karel Zak 1999-2000
6+
* Karel Zak 1999-2004
77
* -------------------------------------------------------------------------
88
*/
99

@@ -25,6 +25,7 @@
2525
#define RE_OK 0
2626
#define RE_ERROR 1
2727

28+
#define MAX_SCHEMA_NAME 128
2829
#define MAX_TABLE_NAME 128
2930
#define MAX_ATTR_NAME 128
3031

@@ -36,10 +37,11 @@
3637
*/
3738
typedef struct
3839
{
39-
char *lo_table,
40-
*lo_attr;
41-
Oid lo_oid;
42-
} LOlist;
40+
char *lo_schema,
41+
*lo_table,
42+
*lo_attr;
43+
Oid lo_oid;
44+
} LOlist;
4345

4446
typedef struct
4547
{

0 commit comments

Comments
 (0)