mirror of
https://github.com/postgres/postgres.git
synced 2025-06-04 00:02:37 -04:00
Dump privileges on functions, aggregates, languages.
This commit is contained in:
parent
dd9af92c41
commit
c88540fb0e
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.262 2002/05/18 13:48:00 petere Exp $
|
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.263 2002/05/19 10:08:25 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -99,11 +99,19 @@ static void dumpOneTable(Archive *fout, TableInfo *tbinfo,
|
|||||||
TableInfo *g_tblinfo);
|
TableInfo *g_tblinfo);
|
||||||
static void dumpOneSequence(Archive *fout, TableInfo *tbinfo,
|
static void dumpOneSequence(Archive *fout, TableInfo *tbinfo,
|
||||||
const bool schemaOnly, const bool dataOnly);
|
const bool schemaOnly, const bool dataOnly);
|
||||||
static void dumpACL(Archive *fout, TableInfo *tbinfo);
|
|
||||||
|
static void dumpTableACL(Archive *fout, TableInfo *tbinfo);
|
||||||
|
static void dumpFuncACL(Archive *fout, FuncInfo *finfo);
|
||||||
|
static void dumpAggACL(Archive *fout, AggInfo *finfo);
|
||||||
|
static void dumpACL(Archive *fout, const char *type, const char *name,
|
||||||
|
const char *nspname, const char *usename,
|
||||||
|
const char *acl, const char *objoid);
|
||||||
|
|
||||||
static void dumpTriggers(Archive *fout, TableInfo *tblinfo, int numTables);
|
static void dumpTriggers(Archive *fout, TableInfo *tblinfo, int numTables);
|
||||||
static void dumpRules(Archive *fout, TableInfo *tblinfo, int numTables);
|
static void dumpRules(Archive *fout, TableInfo *tblinfo, int numTables);
|
||||||
static void formatStringLiteral(PQExpBuffer buf, const char *str,
|
static void formatStringLiteral(PQExpBuffer buf, const char *str,
|
||||||
const formatLiteralOptions opts);
|
const formatLiteralOptions opts);
|
||||||
|
static char *format_function_signature(FuncInfo *finfo);
|
||||||
static void dumpOneFunc(Archive *fout, FuncInfo *finfo);
|
static void dumpOneFunc(Archive *fout, FuncInfo *finfo);
|
||||||
static void dumpOneOpr(Archive *fout, OprInfo *oprinfo,
|
static void dumpOneOpr(Archive *fout, OprInfo *oprinfo,
|
||||||
OprInfo *g_oprinfo, int numOperators);
|
OprInfo *g_oprinfo, int numOperators);
|
||||||
@ -120,7 +128,7 @@ static char *myFormatType(const char *typname, int32 typmod);
|
|||||||
static const char *fmtQualifiedId(const char *schema, const char *id);
|
static const char *fmtQualifiedId(const char *schema, const char *id);
|
||||||
|
|
||||||
static void AddAcl(char *aclbuf, const char *keyword);
|
static void AddAcl(char *aclbuf, const char *keyword);
|
||||||
static char *GetPrivileges(Archive *AH, const char *s);
|
static char *GetPrivileges(Archive *AH, const char *s, const char *type);
|
||||||
|
|
||||||
static int dumpBlobs(Archive *AH, char *, void *);
|
static int dumpBlobs(Archive *AH, char *, void *);
|
||||||
static int dumpDatabase(Archive *AH);
|
static int dumpDatabase(Archive *AH);
|
||||||
@ -1758,7 +1766,9 @@ getAggregates(int *numAggs)
|
|||||||
int i_oid;
|
int i_oid;
|
||||||
int i_aggname;
|
int i_aggname;
|
||||||
int i_aggnamespace;
|
int i_aggnamespace;
|
||||||
|
int i_aggbasetype;
|
||||||
int i_usename;
|
int i_usename;
|
||||||
|
int i_aggacl;
|
||||||
|
|
||||||
/* Make sure we are in proper schema */
|
/* Make sure we are in proper schema */
|
||||||
selectSourceSchema("pg_catalog");
|
selectSourceSchema("pg_catalog");
|
||||||
@ -1769,7 +1779,9 @@ getAggregates(int *numAggs)
|
|||||||
{
|
{
|
||||||
appendPQExpBuffer(query, "SELECT pg_proc.oid, proname as aggname, "
|
appendPQExpBuffer(query, "SELECT pg_proc.oid, proname as aggname, "
|
||||||
"pronamespace as aggnamespace, "
|
"pronamespace as aggnamespace, "
|
||||||
"(select usename from pg_user where proowner = usesysid) as usename "
|
"proargtypes[0]::regtype as aggbasetype, "
|
||||||
|
"(select usename from pg_user where proowner = usesysid) as usename, "
|
||||||
|
"proacl as aggacl "
|
||||||
"FROM pg_proc "
|
"FROM pg_proc "
|
||||||
"WHERE proisagg "
|
"WHERE proisagg "
|
||||||
"AND pronamespace != "
|
"AND pronamespace != "
|
||||||
@ -1779,7 +1791,10 @@ getAggregates(int *numAggs)
|
|||||||
{
|
{
|
||||||
appendPQExpBuffer(query, "SELECT pg_aggregate.oid, aggname, "
|
appendPQExpBuffer(query, "SELECT pg_aggregate.oid, aggname, "
|
||||||
"0::oid as aggnamespace, "
|
"0::oid as aggnamespace, "
|
||||||
"(select usename from pg_user where aggowner = usesysid) as usename "
|
"CASE WHEN aggbasetype = 0 THEN '-' "
|
||||||
|
"ELSE format_type(aggbasetype, NULL) END as aggbasetype, "
|
||||||
|
"(select usename from pg_user where aggowner = usesysid) as usename, "
|
||||||
|
"cast('{=X}' as aclitem[]) as aggacl "
|
||||||
"from pg_aggregate "
|
"from pg_aggregate "
|
||||||
"where oid > '%u'::oid",
|
"where oid > '%u'::oid",
|
||||||
g_last_builtin_oid);
|
g_last_builtin_oid);
|
||||||
@ -1802,7 +1817,9 @@ getAggregates(int *numAggs)
|
|||||||
i_oid = PQfnumber(res, "oid");
|
i_oid = PQfnumber(res, "oid");
|
||||||
i_aggname = PQfnumber(res, "aggname");
|
i_aggname = PQfnumber(res, "aggname");
|
||||||
i_aggnamespace = PQfnumber(res, "aggnamespace");
|
i_aggnamespace = PQfnumber(res, "aggnamespace");
|
||||||
|
i_aggbasetype = PQfnumber(res, "aggbasetype");
|
||||||
i_usename = PQfnumber(res, "usename");
|
i_usename = PQfnumber(res, "usename");
|
||||||
|
i_aggacl = PQfnumber(res, "aggacl");
|
||||||
|
|
||||||
for (i = 0; i < ntups; i++)
|
for (i = 0; i < ntups; i++)
|
||||||
{
|
{
|
||||||
@ -1810,10 +1827,12 @@ getAggregates(int *numAggs)
|
|||||||
agginfo[i].aggname = strdup(PQgetvalue(res, i, i_aggname));
|
agginfo[i].aggname = strdup(PQgetvalue(res, i, i_aggname));
|
||||||
agginfo[i].aggnamespace = findNamespace(PQgetvalue(res, i, i_aggnamespace),
|
agginfo[i].aggnamespace = findNamespace(PQgetvalue(res, i, i_aggnamespace),
|
||||||
agginfo[i].oid);
|
agginfo[i].oid);
|
||||||
|
agginfo[i].aggbasetype = strdup(PQgetvalue(res, i, i_aggbasetype));
|
||||||
agginfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
|
agginfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
|
||||||
if (strlen(agginfo[i].usename) == 0)
|
if (strlen(agginfo[i].usename) == 0)
|
||||||
write_msg(NULL, "WARNING: owner of aggregate function \"%s\" appears to be invalid\n",
|
write_msg(NULL, "WARNING: owner of aggregate function \"%s\" appears to be invalid\n",
|
||||||
agginfo[i].aggname);
|
agginfo[i].aggname);
|
||||||
|
agginfo[i].aggacl = strdup(PQgetvalue(res, i, i_aggacl));
|
||||||
}
|
}
|
||||||
|
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
@ -1847,6 +1866,7 @@ getFuncs(int *numFuncs)
|
|||||||
int i_pronargs;
|
int i_pronargs;
|
||||||
int i_proargtypes;
|
int i_proargtypes;
|
||||||
int i_prorettype;
|
int i_prorettype;
|
||||||
|
int i_proacl;
|
||||||
|
|
||||||
/* Make sure we are in proper schema */
|
/* Make sure we are in proper schema */
|
||||||
selectSourceSchema("pg_catalog");
|
selectSourceSchema("pg_catalog");
|
||||||
@ -1857,7 +1877,7 @@ getFuncs(int *numFuncs)
|
|||||||
{
|
{
|
||||||
appendPQExpBuffer(query,
|
appendPQExpBuffer(query,
|
||||||
"SELECT pg_proc.oid, proname, prolang, "
|
"SELECT pg_proc.oid, proname, prolang, "
|
||||||
"pronargs, proargtypes, prorettype, "
|
"pronargs, proargtypes, prorettype, proacl, "
|
||||||
"pronamespace, "
|
"pronamespace, "
|
||||||
"(select usename from pg_user where proowner = usesysid) as usename "
|
"(select usename from pg_user where proowner = usesysid) as usename "
|
||||||
"FROM pg_proc "
|
"FROM pg_proc "
|
||||||
@ -1870,6 +1890,7 @@ getFuncs(int *numFuncs)
|
|||||||
appendPQExpBuffer(query,
|
appendPQExpBuffer(query,
|
||||||
"SELECT pg_proc.oid, proname, prolang, "
|
"SELECT pg_proc.oid, proname, prolang, "
|
||||||
"pronargs, proargtypes, prorettype, "
|
"pronargs, proargtypes, prorettype, "
|
||||||
|
"cast('{=X}' as aclitem[]) as proacl, "
|
||||||
"0::oid as pronamespace, "
|
"0::oid as pronamespace, "
|
||||||
"(select usename from pg_user where proowner = usesysid) as usename "
|
"(select usename from pg_user where proowner = usesysid) as usename "
|
||||||
"FROM pg_proc "
|
"FROM pg_proc "
|
||||||
@ -1902,6 +1923,7 @@ getFuncs(int *numFuncs)
|
|||||||
i_pronargs = PQfnumber(res, "pronargs");
|
i_pronargs = PQfnumber(res, "pronargs");
|
||||||
i_proargtypes = PQfnumber(res, "proargtypes");
|
i_proargtypes = PQfnumber(res, "proargtypes");
|
||||||
i_prorettype = PQfnumber(res, "prorettype");
|
i_prorettype = PQfnumber(res, "prorettype");
|
||||||
|
i_proacl = PQfnumber(res, "proacl");
|
||||||
|
|
||||||
for (i = 0; i < ntups; i++)
|
for (i = 0; i < ntups; i++)
|
||||||
{
|
{
|
||||||
@ -1912,6 +1934,7 @@ getFuncs(int *numFuncs)
|
|||||||
finfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
|
finfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
|
||||||
finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
|
finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
|
||||||
finfo[i].prorettype = strdup(PQgetvalue(res, i, i_prorettype));
|
finfo[i].prorettype = strdup(PQgetvalue(res, i, i_prorettype));
|
||||||
|
finfo[i].proacl = strdup(PQgetvalue(res, i, i_proacl));
|
||||||
finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
|
finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
|
||||||
if (finfo[i].nargs == 0)
|
if (finfo[i].nargs == 0)
|
||||||
finfo[i].argtypes = NULL;
|
finfo[i].argtypes = NULL;
|
||||||
@ -3074,7 +3097,7 @@ dumpTypes(Archive *fout, FuncInfo *finfo, int numFuncs,
|
|||||||
* writes out to fout the queries to recreate user-defined procedural languages
|
* writes out to fout the queries to recreate user-defined procedural languages
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
dumpProcLangs(Archive *fout, FuncInfo *finfo, int numFuncs)
|
dumpProcLangs(Archive *fout, FuncInfo finfo[], int numFuncs)
|
||||||
{
|
{
|
||||||
PGresult *res;
|
PGresult *res;
|
||||||
PQExpBuffer query = createPQExpBuffer();
|
PQExpBuffer query = createPQExpBuffer();
|
||||||
@ -3086,9 +3109,11 @@ dumpProcLangs(Archive *fout, FuncInfo *finfo, int numFuncs)
|
|||||||
int i_lanpltrusted;
|
int i_lanpltrusted;
|
||||||
int i_lanplcallfoid;
|
int i_lanplcallfoid;
|
||||||
int i_lancompiler;
|
int i_lancompiler;
|
||||||
|
int i_lanacl = -1;
|
||||||
char *lanoid;
|
char *lanoid;
|
||||||
char *lanname;
|
char *lanname;
|
||||||
char *lancompiler;
|
char *lancompiler;
|
||||||
|
char *lanacl;
|
||||||
const char *lanplcallfoid;
|
const char *lanplcallfoid;
|
||||||
const char *((*deps)[]);
|
const char *((*deps)[]);
|
||||||
int depIdx;
|
int depIdx;
|
||||||
@ -3116,6 +3141,8 @@ dumpProcLangs(Archive *fout, FuncInfo *finfo, int numFuncs)
|
|||||||
i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
|
i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
|
||||||
i_lancompiler = PQfnumber(res, "lancompiler");
|
i_lancompiler = PQfnumber(res, "lancompiler");
|
||||||
i_oid = PQfnumber(res, "oid");
|
i_oid = PQfnumber(res, "oid");
|
||||||
|
if (fout->remoteVersion >= 70300)
|
||||||
|
i_lanacl = PQfnumber(res, "lanacl");
|
||||||
|
|
||||||
for (i = 0; i < ntups; i++)
|
for (i = 0; i < ntups; i++)
|
||||||
{
|
{
|
||||||
@ -3123,6 +3150,10 @@ dumpProcLangs(Archive *fout, FuncInfo *finfo, int numFuncs)
|
|||||||
lanplcallfoid = PQgetvalue(res, i, i_lanplcallfoid);
|
lanplcallfoid = PQgetvalue(res, i, i_lanplcallfoid);
|
||||||
lanname = PQgetvalue(res, i, i_lanname);
|
lanname = PQgetvalue(res, i, i_lanname);
|
||||||
lancompiler = PQgetvalue(res, i, i_lancompiler);
|
lancompiler = PQgetvalue(res, i, i_lancompiler);
|
||||||
|
if (fout->remoteVersion >= 70300)
|
||||||
|
lanacl = PQgetvalue(res, i, i_lanacl);
|
||||||
|
else
|
||||||
|
lanacl = "{=U}";
|
||||||
|
|
||||||
fidx = findFuncByOid(finfo, numFuncs, lanplcallfoid);
|
fidx = findFuncByOid(finfo, numFuncs, lanplcallfoid);
|
||||||
if (fidx < 0)
|
if (fidx < 0)
|
||||||
@ -3167,6 +3198,14 @@ dumpProcLangs(Archive *fout, FuncInfo *finfo, int numFuncs)
|
|||||||
finfo[fidx].pronamespace->nspname, "",
|
finfo[fidx].pronamespace->nspname, "",
|
||||||
"PROCEDURAL LANGUAGE", deps,
|
"PROCEDURAL LANGUAGE", deps,
|
||||||
defqry->data, delqry->data, NULL, NULL, NULL);
|
defqry->data, delqry->data, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
if (!aclsSkip)
|
||||||
|
{
|
||||||
|
char * tmp = strdup(fmtId(lanname, force_quotes));
|
||||||
|
dumpACL(fout, "LANGUAGE", tmp, finfo[fidx].pronamespace->nspname,
|
||||||
|
NULL, lanacl, lanoid);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
@ -3181,7 +3220,7 @@ dumpProcLangs(Archive *fout, FuncInfo *finfo, int numFuncs)
|
|||||||
* writes out to fout the queries to recreate all the user-defined functions
|
* writes out to fout the queries to recreate all the user-defined functions
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
dumpFuncs(Archive *fout, FuncInfo *finfo, int numFuncs)
|
dumpFuncs(Archive *fout, FuncInfo finfo[], int numFuncs)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -3192,9 +3231,47 @@ dumpFuncs(Archive *fout, FuncInfo *finfo, int numFuncs)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
dumpOneFunc(fout, &finfo[i]);
|
dumpOneFunc(fout, &finfo[i]);
|
||||||
|
if (!aclsSkip)
|
||||||
|
dumpFuncACL(fout, &finfo[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
format_function_signature(FuncInfo *finfo)
|
||||||
|
{
|
||||||
|
PQExpBufferData fn;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
initPQExpBuffer(&fn);
|
||||||
|
appendPQExpBuffer(&fn, "%s (", fmtId(finfo->proname, force_quotes));
|
||||||
|
for (j = 0; j < finfo->nargs; j++)
|
||||||
|
{
|
||||||
|
char *typname;
|
||||||
|
|
||||||
|
typname = getFormattedTypeName(finfo->argtypes[j], zeroAsOpaque);
|
||||||
|
appendPQExpBuffer(&fn, "%s%s",
|
||||||
|
(j > 0) ? "," : "",
|
||||||
|
typname);
|
||||||
|
free(typname);
|
||||||
|
}
|
||||||
|
appendPQExpBuffer(&fn, ")");
|
||||||
|
return fn.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
dumpFuncACL(Archive *fout, FuncInfo *finfo)
|
||||||
|
{
|
||||||
|
char *funcsig;
|
||||||
|
|
||||||
|
funcsig = format_function_signature(finfo);
|
||||||
|
dumpACL(fout, "FUNCTION", funcsig, finfo->pronamespace->nspname,
|
||||||
|
finfo->usename, finfo->proacl, finfo->oid);
|
||||||
|
free(funcsig);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dumpOneFunc:
|
* dumpOneFunc:
|
||||||
* dump out only one function
|
* dump out only one function
|
||||||
@ -3204,12 +3281,11 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
|||||||
{
|
{
|
||||||
PQExpBuffer query = createPQExpBuffer();
|
PQExpBuffer query = createPQExpBuffer();
|
||||||
PQExpBuffer q = createPQExpBuffer();
|
PQExpBuffer q = createPQExpBuffer();
|
||||||
PQExpBuffer fn = createPQExpBuffer();
|
|
||||||
PQExpBuffer delqry = createPQExpBuffer();
|
PQExpBuffer delqry = createPQExpBuffer();
|
||||||
PQExpBuffer asPart = createPQExpBuffer();
|
PQExpBuffer asPart = createPQExpBuffer();
|
||||||
PGresult *res = NULL;
|
PGresult *res = NULL;
|
||||||
|
char *funcsig = NULL;
|
||||||
int ntups;
|
int ntups;
|
||||||
int j;
|
|
||||||
char *proretset;
|
char *proretset;
|
||||||
char *prosrc;
|
char *prosrc;
|
||||||
char *probin;
|
char *probin;
|
||||||
@ -3316,24 +3392,13 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
appendPQExpBuffer(fn, "%s (", fmtId(finfo->proname, force_quotes));
|
funcsig = format_function_signature(finfo);
|
||||||
for (j = 0; j < finfo->nargs; j++)
|
|
||||||
{
|
|
||||||
char *typname;
|
|
||||||
|
|
||||||
typname = getFormattedTypeName(finfo->argtypes[j], zeroAsOpaque);
|
appendPQExpBuffer(delqry, "DROP FUNCTION %s;\n", funcsig);
|
||||||
appendPQExpBuffer(fn, "%s%s",
|
|
||||||
(j > 0) ? "," : "",
|
|
||||||
typname);
|
|
||||||
free(typname);
|
|
||||||
}
|
|
||||||
appendPQExpBuffer(fn, ")");
|
|
||||||
|
|
||||||
appendPQExpBuffer(delqry, "DROP FUNCTION %s;\n", fn->data);
|
|
||||||
|
|
||||||
rettypename = getFormattedTypeName(finfo->prorettype, zeroAsOpaque);
|
rettypename = getFormattedTypeName(finfo->prorettype, zeroAsOpaque);
|
||||||
|
|
||||||
appendPQExpBuffer(q, "CREATE FUNCTION %s ", fn->data);
|
appendPQExpBuffer(q, "CREATE FUNCTION %s ", funcsig);
|
||||||
appendPQExpBuffer(q, "RETURNS %s%s %s LANGUAGE %s",
|
appendPQExpBuffer(q, "RETURNS %s%s %s LANGUAGE %s",
|
||||||
(proretset[0] == 't') ? "SETOF " : "",
|
(proretset[0] == 't') ? "SETOF " : "",
|
||||||
rettypename,
|
rettypename,
|
||||||
@ -3367,7 +3432,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
|||||||
|
|
||||||
appendPQExpBuffer(q, ";\n");
|
appendPQExpBuffer(q, ";\n");
|
||||||
|
|
||||||
ArchiveEntry(fout, finfo->oid, fn->data, finfo->pronamespace->nspname,
|
ArchiveEntry(fout, finfo->oid, funcsig, finfo->pronamespace->nspname,
|
||||||
finfo->usename, "FUNCTION", NULL,
|
finfo->usename, "FUNCTION", NULL,
|
||||||
q->data, delqry->data,
|
q->data, delqry->data,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
@ -3375,7 +3440,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
|||||||
/*** Dump Function Comments ***/
|
/*** Dump Function Comments ***/
|
||||||
|
|
||||||
resetPQExpBuffer(q);
|
resetPQExpBuffer(q);
|
||||||
appendPQExpBuffer(q, "FUNCTION %s", fn->data);
|
appendPQExpBuffer(q, "FUNCTION %s", funcsig);
|
||||||
dumpComment(fout, q->data,
|
dumpComment(fout, q->data,
|
||||||
finfo->pronamespace->nspname, finfo->usename,
|
finfo->pronamespace->nspname, finfo->usename,
|
||||||
finfo->oid, "pg_proc", 0, NULL);
|
finfo->oid, "pg_proc", 0, NULL);
|
||||||
@ -3385,9 +3450,9 @@ done:
|
|||||||
|
|
||||||
destroyPQExpBuffer(query);
|
destroyPQExpBuffer(query);
|
||||||
destroyPQExpBuffer(q);
|
destroyPQExpBuffer(q);
|
||||||
destroyPQExpBuffer(fn);
|
|
||||||
destroyPQExpBuffer(delqry);
|
destroyPQExpBuffer(delqry);
|
||||||
destroyPQExpBuffer(asPart);
|
destroyPQExpBuffer(asPart);
|
||||||
|
free(funcsig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3744,7 +3809,7 @@ convertOperatorReference(const char *opr,
|
|||||||
* writes out to fout the queries to create all the user-defined aggregates
|
* writes out to fout the queries to create all the user-defined aggregates
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
dumpAggs(Archive *fout, AggInfo *agginfo, int numAggs)
|
dumpAggs(Archive *fout, AggInfo agginfo[], int numAggs)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -3755,9 +3820,57 @@ dumpAggs(Archive *fout, AggInfo *agginfo, int numAggs)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
dumpOneAgg(fout, &agginfo[i]);
|
dumpOneAgg(fout, &agginfo[i]);
|
||||||
|
if (!aclsSkip)
|
||||||
|
dumpAggACL(fout, &agginfo[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
format_aggregate_signature(AggInfo *agginfo, Archive *fout)
|
||||||
|
{
|
||||||
|
PQExpBufferData buf;
|
||||||
|
bool anybasetype;
|
||||||
|
|
||||||
|
initPQExpBuffer(&buf);
|
||||||
|
appendPQExpBuffer(&buf, "%s",
|
||||||
|
fmtId(agginfo->aggname, force_quotes));
|
||||||
|
|
||||||
|
anybasetype = (strcmp(agginfo->aggbasetype, "-") == 0);
|
||||||
|
|
||||||
|
/* If using regtype or format_type, name is already quoted */
|
||||||
|
if (fout->remoteVersion >= 70100)
|
||||||
|
{
|
||||||
|
if (anybasetype)
|
||||||
|
appendPQExpBuffer(&buf, "(*)");
|
||||||
|
else
|
||||||
|
appendPQExpBuffer(&buf, "(%s)", agginfo->aggbasetype);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (anybasetype)
|
||||||
|
appendPQExpBuffer(&buf, "(*)");
|
||||||
|
else
|
||||||
|
appendPQExpBuffer(&buf, "(%s)",
|
||||||
|
fmtId(agginfo->aggbasetype, force_quotes));
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
dumpAggACL(Archive *fout, AggInfo *finfo)
|
||||||
|
{
|
||||||
|
char *aggsig;
|
||||||
|
|
||||||
|
aggsig = format_aggregate_signature(finfo, fout);
|
||||||
|
dumpACL(fout, "FUNCTION", aggsig, finfo->aggnamespace->nspname,
|
||||||
|
finfo->usename, finfo->aggacl, finfo->oid);
|
||||||
|
free(aggsig);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dumpOneAgg
|
* dumpOneAgg
|
||||||
* write out a single aggregate definition
|
* write out a single aggregate definition
|
||||||
@ -3768,20 +3881,18 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
|||||||
PQExpBuffer query = createPQExpBuffer();
|
PQExpBuffer query = createPQExpBuffer();
|
||||||
PQExpBuffer q = createPQExpBuffer();
|
PQExpBuffer q = createPQExpBuffer();
|
||||||
PQExpBuffer delq = createPQExpBuffer();
|
PQExpBuffer delq = createPQExpBuffer();
|
||||||
PQExpBuffer aggSig = createPQExpBuffer();
|
|
||||||
PQExpBuffer details = createPQExpBuffer();
|
PQExpBuffer details = createPQExpBuffer();
|
||||||
|
char *aggSig;
|
||||||
PGresult *res;
|
PGresult *res;
|
||||||
int ntups;
|
int ntups;
|
||||||
int i_aggtransfn;
|
int i_aggtransfn;
|
||||||
int i_aggfinalfn;
|
int i_aggfinalfn;
|
||||||
int i_aggtranstype;
|
int i_aggtranstype;
|
||||||
int i_aggbasetype;
|
|
||||||
int i_agginitval;
|
int i_agginitval;
|
||||||
int i_convertok;
|
int i_convertok;
|
||||||
const char *aggtransfn;
|
const char *aggtransfn;
|
||||||
const char *aggfinalfn;
|
const char *aggfinalfn;
|
||||||
const char *aggtranstype;
|
const char *aggtranstype;
|
||||||
const char *aggbasetype;
|
|
||||||
const char *agginitval;
|
const char *agginitval;
|
||||||
bool convertok;
|
bool convertok;
|
||||||
bool anybasetype;
|
bool anybasetype;
|
||||||
@ -3794,7 +3905,6 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
|||||||
{
|
{
|
||||||
appendPQExpBuffer(query, "SELECT aggtransfn, "
|
appendPQExpBuffer(query, "SELECT aggtransfn, "
|
||||||
"aggfinalfn, aggtranstype::regtype, "
|
"aggfinalfn, aggtranstype::regtype, "
|
||||||
"proargtypes[0]::regtype as aggbasetype, "
|
|
||||||
"agginitval, "
|
"agginitval, "
|
||||||
"'t'::boolean as convertok "
|
"'t'::boolean as convertok "
|
||||||
"from pg_aggregate a, pg_proc p "
|
"from pg_aggregate a, pg_proc p "
|
||||||
@ -3806,8 +3916,6 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
|||||||
{
|
{
|
||||||
appendPQExpBuffer(query, "SELECT aggtransfn, aggfinalfn, "
|
appendPQExpBuffer(query, "SELECT aggtransfn, aggfinalfn, "
|
||||||
"format_type(aggtranstype, NULL) as aggtranstype, "
|
"format_type(aggtranstype, NULL) as aggtranstype, "
|
||||||
"CASE WHEN aggbasetype = 0 THEN '-' "
|
|
||||||
"ELSE format_type(aggbasetype, NULL) END as aggbasetype, "
|
|
||||||
"agginitval, 't'::boolean as convertok "
|
"agginitval, 't'::boolean as convertok "
|
||||||
"from pg_aggregate "
|
"from pg_aggregate "
|
||||||
"where oid = '%s'::oid",
|
"where oid = '%s'::oid",
|
||||||
@ -3818,8 +3926,6 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
|||||||
appendPQExpBuffer(query, "SELECT aggtransfn1 as aggtransfn, "
|
appendPQExpBuffer(query, "SELECT aggtransfn1 as aggtransfn, "
|
||||||
"aggfinalfn, "
|
"aggfinalfn, "
|
||||||
"(select typname from pg_type where oid = aggtranstype1) as aggtranstype, "
|
"(select typname from pg_type where oid = aggtranstype1) as aggtranstype, "
|
||||||
"CASE WHEN aggbasetype = 0 THEN '-'::name "
|
|
||||||
"ELSE (select typname from pg_type where oid = aggbasetype) END as aggbasetype, "
|
|
||||||
"agginitval1 as agginitval, "
|
"agginitval1 as agginitval, "
|
||||||
"(aggtransfn2 = 0 and aggtranstype2 = 0 and agginitval2 is null) as convertok "
|
"(aggtransfn2 = 0 and aggtranstype2 = 0 and agginitval2 is null) as convertok "
|
||||||
"from pg_aggregate "
|
"from pg_aggregate "
|
||||||
@ -3848,47 +3954,25 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
|||||||
i_aggtransfn = PQfnumber(res, "aggtransfn");
|
i_aggtransfn = PQfnumber(res, "aggtransfn");
|
||||||
i_aggfinalfn = PQfnumber(res, "aggfinalfn");
|
i_aggfinalfn = PQfnumber(res, "aggfinalfn");
|
||||||
i_aggtranstype = PQfnumber(res, "aggtranstype");
|
i_aggtranstype = PQfnumber(res, "aggtranstype");
|
||||||
i_aggbasetype = PQfnumber(res, "aggbasetype");
|
|
||||||
i_agginitval = PQfnumber(res, "agginitval");
|
i_agginitval = PQfnumber(res, "agginitval");
|
||||||
i_convertok = PQfnumber(res, "convertok");
|
i_convertok = PQfnumber(res, "convertok");
|
||||||
|
|
||||||
aggtransfn = PQgetvalue(res, 0, i_aggtransfn);
|
aggtransfn = PQgetvalue(res, 0, i_aggtransfn);
|
||||||
aggfinalfn = PQgetvalue(res, 0, i_aggfinalfn);
|
aggfinalfn = PQgetvalue(res, 0, i_aggfinalfn);
|
||||||
aggtranstype = PQgetvalue(res, 0, i_aggtranstype);
|
aggtranstype = PQgetvalue(res, 0, i_aggtranstype);
|
||||||
aggbasetype = PQgetvalue(res, 0, i_aggbasetype);
|
|
||||||
agginitval = PQgetvalue(res, 0, i_agginitval);
|
agginitval = PQgetvalue(res, 0, i_agginitval);
|
||||||
convertok = (PQgetvalue(res, 0, i_convertok)[0] == 't');
|
convertok = (PQgetvalue(res, 0, i_convertok)[0] == 't');
|
||||||
|
|
||||||
anybasetype = (strcmp(aggbasetype, "-") == 0);
|
aggSig = format_aggregate_signature(agginfo, g_fout);
|
||||||
|
|
||||||
appendPQExpBuffer(aggSig, "%s",
|
|
||||||
fmtId(agginfo->aggname, force_quotes));
|
|
||||||
|
|
||||||
/* If using regtype or format_type, name is already quoted */
|
|
||||||
if (g_fout->remoteVersion >= 70100)
|
|
||||||
{
|
|
||||||
if (anybasetype)
|
|
||||||
appendPQExpBuffer(aggSig, "(*)");
|
|
||||||
else
|
|
||||||
appendPQExpBuffer(aggSig, "(%s)", aggbasetype);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (anybasetype)
|
|
||||||
appendPQExpBuffer(aggSig, "(*)");
|
|
||||||
else
|
|
||||||
appendPQExpBuffer(aggSig, "(%s)",
|
|
||||||
fmtId(aggbasetype, force_quotes));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!convertok)
|
if (!convertok)
|
||||||
{
|
{
|
||||||
write_msg(NULL, "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n",
|
write_msg(NULL, "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n",
|
||||||
aggSig->data);
|
aggSig);
|
||||||
|
|
||||||
appendPQExpBuffer(q, "-- WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n",
|
appendPQExpBuffer(q, "-- WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n",
|
||||||
aggSig->data);
|
aggSig);
|
||||||
ArchiveEntry(fout, agginfo->oid, aggSig->data,
|
ArchiveEntry(fout, agginfo->oid, aggSig,
|
||||||
agginfo->aggnamespace->nspname, agginfo->usename,
|
agginfo->aggnamespace->nspname, agginfo->usename,
|
||||||
"WARNING", NULL,
|
"WARNING", NULL,
|
||||||
q->data, "" /* Del */ ,
|
q->data, "" /* Del */ ,
|
||||||
@ -3896,11 +3980,13 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
anybasetype = (strcmp(agginfo->aggbasetype, "-") == 0);
|
||||||
|
|
||||||
if (g_fout->remoteVersion >= 70300)
|
if (g_fout->remoteVersion >= 70300)
|
||||||
{
|
{
|
||||||
/* If using 7.3's regproc or regtype, data is already quoted */
|
/* If using 7.3's regproc or regtype, data is already quoted */
|
||||||
appendPQExpBuffer(details, "BASETYPE = %s, SFUNC = %s, STYPE = %s",
|
appendPQExpBuffer(details, "BASETYPE = %s, SFUNC = %s, STYPE = %s",
|
||||||
anybasetype ? "'any'" : aggbasetype,
|
anybasetype ? "'any'" : agginfo->aggbasetype,
|
||||||
aggtransfn,
|
aggtransfn,
|
||||||
aggtranstype);
|
aggtranstype);
|
||||||
}
|
}
|
||||||
@ -3908,7 +3994,7 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
|||||||
{
|
{
|
||||||
/* format_type quotes, regproc does not */
|
/* format_type quotes, regproc does not */
|
||||||
appendPQExpBuffer(details, "BASETYPE = %s, SFUNC = %s, STYPE = %s",
|
appendPQExpBuffer(details, "BASETYPE = %s, SFUNC = %s, STYPE = %s",
|
||||||
anybasetype ? "'any'" : aggbasetype,
|
anybasetype ? "'any'" : agginfo->aggbasetype,
|
||||||
fmtId(aggtransfn, force_quotes),
|
fmtId(aggtransfn, force_quotes),
|
||||||
aggtranstype);
|
aggtranstype);
|
||||||
}
|
}
|
||||||
@ -3917,7 +4003,7 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
|||||||
/* need quotes all around */
|
/* need quotes all around */
|
||||||
appendPQExpBuffer(details, "BASETYPE = %s, ",
|
appendPQExpBuffer(details, "BASETYPE = %s, ",
|
||||||
anybasetype ? "'any'" :
|
anybasetype ? "'any'" :
|
||||||
fmtId(aggbasetype, force_quotes));
|
fmtId(agginfo->aggbasetype, force_quotes));
|
||||||
appendPQExpBuffer(details, "SFUNC = %s, ",
|
appendPQExpBuffer(details, "SFUNC = %s, ",
|
||||||
fmtId(aggtransfn, force_quotes));
|
fmtId(aggtransfn, force_quotes));
|
||||||
appendPQExpBuffer(details, "STYPE = %s",
|
appendPQExpBuffer(details, "STYPE = %s",
|
||||||
@ -3936,13 +4022,13 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
|||||||
aggfinalfn);
|
aggfinalfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
appendPQExpBuffer(delq, "DROP AGGREGATE %s;\n", aggSig->data);
|
appendPQExpBuffer(delq, "DROP AGGREGATE %s;\n", aggSig);
|
||||||
|
|
||||||
appendPQExpBuffer(q, "CREATE AGGREGATE %s ( %s );\n",
|
appendPQExpBuffer(q, "CREATE AGGREGATE %s ( %s );\n",
|
||||||
fmtId(agginfo->aggname, force_quotes),
|
fmtId(agginfo->aggname, force_quotes),
|
||||||
details->data);
|
details->data);
|
||||||
|
|
||||||
ArchiveEntry(fout, agginfo->oid, aggSig->data,
|
ArchiveEntry(fout, agginfo->oid, aggSig,
|
||||||
agginfo->aggnamespace->nspname, agginfo->usename,
|
agginfo->aggnamespace->nspname, agginfo->usename,
|
||||||
"AGGREGATE", NULL,
|
"AGGREGATE", NULL,
|
||||||
q->data, delq->data,
|
q->data, delq->data,
|
||||||
@ -3951,7 +4037,7 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
|||||||
/*** Dump Aggregate Comments ***/
|
/*** Dump Aggregate Comments ***/
|
||||||
|
|
||||||
resetPQExpBuffer(q);
|
resetPQExpBuffer(q);
|
||||||
appendPQExpBuffer(q, "AGGREGATE %s", aggSig->data);
|
appendPQExpBuffer(q, "AGGREGATE %s", aggSig);
|
||||||
if (g_fout->remoteVersion >= 70300)
|
if (g_fout->remoteVersion >= 70300)
|
||||||
dumpComment(fout, q->data,
|
dumpComment(fout, q->data,
|
||||||
agginfo->aggnamespace->nspname, agginfo->usename,
|
agginfo->aggnamespace->nspname, agginfo->usename,
|
||||||
@ -3966,8 +4052,8 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
|||||||
destroyPQExpBuffer(query);
|
destroyPQExpBuffer(query);
|
||||||
destroyPQExpBuffer(q);
|
destroyPQExpBuffer(q);
|
||||||
destroyPQExpBuffer(delq);
|
destroyPQExpBuffer(delq);
|
||||||
destroyPQExpBuffer(aggSig);
|
|
||||||
destroyPQExpBuffer(details);
|
destroyPQExpBuffer(details);
|
||||||
|
free(aggSig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3996,7 +4082,7 @@ AddAcl(char *aclbuf, const char *keyword)
|
|||||||
* appropriate.
|
* appropriate.
|
||||||
*/
|
*/
|
||||||
static char *
|
static char *
|
||||||
GetPrivileges(Archive *AH, const char *s)
|
GetPrivileges(Archive *AH, const char *s, const char *type)
|
||||||
{
|
{
|
||||||
char aclbuf[100];
|
char aclbuf[100];
|
||||||
bool all = true;
|
bool all = true;
|
||||||
@ -4009,6 +4095,8 @@ GetPrivileges(Archive *AH, const char *s)
|
|||||||
else \
|
else \
|
||||||
all = false
|
all = false
|
||||||
|
|
||||||
|
if (strcmp(type, "TABLE")==0)
|
||||||
|
{
|
||||||
CONVERT_PRIV('a', "INSERT");
|
CONVERT_PRIV('a', "INSERT");
|
||||||
CONVERT_PRIV('r', "SELECT");
|
CONVERT_PRIV('r', "SELECT");
|
||||||
CONVERT_PRIV('R', "RULE");
|
CONVERT_PRIV('R', "RULE");
|
||||||
@ -4025,6 +4113,17 @@ GetPrivileges(Archive *AH, const char *s)
|
|||||||
/* 7.0 and 7.1 have a simpler worldview */
|
/* 7.0 and 7.1 have a simpler worldview */
|
||||||
CONVERT_PRIV('w', "UPDATE,DELETE");
|
CONVERT_PRIV('w', "UPDATE,DELETE");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "FUNCTION")==0)
|
||||||
|
{
|
||||||
|
CONVERT_PRIV('X', "EXECUTE");
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "LANGUAGE")==0)
|
||||||
|
{
|
||||||
|
CONVERT_PRIV('U', "USAGE");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
abort();
|
||||||
|
|
||||||
#undef CONVERT_PRIV
|
#undef CONVERT_PRIV
|
||||||
|
|
||||||
@ -4036,18 +4135,25 @@ GetPrivileges(Archive *AH, const char *s)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dumpACL:
|
* Write out grant/revoke information
|
||||||
* Write out grant/revoke information for a table, view or sequence
|
*
|
||||||
|
* 'type' must be TABLE, FUNCTION, or LANGUAGE. 'name' is the
|
||||||
|
* formatted name of the object. Must be quoted etc. already.
|
||||||
|
* 'nspname' is the namespace the object is in. 'usename' is the
|
||||||
|
* owner, NULL if there is no owner (for languages). 'acls' is the
|
||||||
|
* string read out of the fooacl system catalog field; it will be
|
||||||
|
* parsed here. 'objoid' is the OID of the object for purposes of
|
||||||
|
* ordering.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
dumpACL(Archive *fout, TableInfo *tbinfo)
|
dumpACL(Archive *fout, const char *type, const char *name,
|
||||||
|
const char *nspname, const char *usename,
|
||||||
|
const char *acls, const char *objoid)
|
||||||
{
|
{
|
||||||
const char *acls = tbinfo->relacl;
|
|
||||||
char *aclbuf,
|
char *aclbuf,
|
||||||
*tok,
|
*tok,
|
||||||
*eqpos,
|
*eqpos,
|
||||||
*priv;
|
*priv;
|
||||||
char *objoid;
|
|
||||||
PQExpBuffer sql;
|
PQExpBuffer sql;
|
||||||
bool found_owner_privs = false;
|
bool found_owner_privs = false;
|
||||||
|
|
||||||
@ -4075,8 +4181,8 @@ dumpACL(Archive *fout, TableInfo *tbinfo)
|
|||||||
eqpos = strchr(tok, '=');
|
eqpos = strchr(tok, '=');
|
||||||
if (!eqpos)
|
if (!eqpos)
|
||||||
{
|
{
|
||||||
write_msg(NULL, "could not parse ACL list ('%s') for relation %s\n",
|
write_msg(NULL, "could not parse ACL list ('%s') for %s %s\n",
|
||||||
acls, tbinfo->relname);
|
acls, type, name);
|
||||||
exit_nicely();
|
exit_nicely();
|
||||||
}
|
}
|
||||||
*eqpos = '\0'; /* it's ok to clobber aclbuf */
|
*eqpos = '\0'; /* it's ok to clobber aclbuf */
|
||||||
@ -4085,10 +4191,11 @@ dumpACL(Archive *fout, TableInfo *tbinfo)
|
|||||||
* Parse the privileges (right-hand side). Skip if there are
|
* Parse the privileges (right-hand side). Skip if there are
|
||||||
* none.
|
* none.
|
||||||
*/
|
*/
|
||||||
priv = GetPrivileges(fout, eqpos + 1);
|
priv = GetPrivileges(fout, eqpos + 1, type);
|
||||||
|
|
||||||
if (*priv)
|
if (*priv)
|
||||||
{
|
{
|
||||||
if (strcmp(tok, tbinfo->usename) == 0)
|
if (usename && strcmp(tok, usename) == 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* For the owner, the default privilege level is ALL.
|
* For the owner, the default privilege level is ALL.
|
||||||
@ -4097,12 +4204,11 @@ dumpACL(Archive *fout, TableInfo *tbinfo)
|
|||||||
if (strcmp(priv, "ALL") != 0)
|
if (strcmp(priv, "ALL") != 0)
|
||||||
{
|
{
|
||||||
/* NB: only one fmtId per appendPQExpBuffer! */
|
/* NB: only one fmtId per appendPQExpBuffer! */
|
||||||
appendPQExpBuffer(sql, "REVOKE ALL ON %s FROM ",
|
appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM ",
|
||||||
fmtId(tbinfo->relname, force_quotes));
|
type, name);
|
||||||
appendPQExpBuffer(sql, "%s;\n", fmtId(tok, force_quotes));
|
appendPQExpBuffer(sql, "%s;\n", fmtId(tok, force_quotes));
|
||||||
appendPQExpBuffer(sql, "GRANT %s ON %s TO ",
|
appendPQExpBuffer(sql, "GRANT %s ON %s %s TO ",
|
||||||
priv,
|
priv, type, name);
|
||||||
fmtId(tbinfo->relname, force_quotes));
|
|
||||||
appendPQExpBuffer(sql, "%s;\n", fmtId(tok, force_quotes));
|
appendPQExpBuffer(sql, "%s;\n", fmtId(tok, force_quotes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4111,9 +4217,8 @@ dumpACL(Archive *fout, TableInfo *tbinfo)
|
|||||||
/*
|
/*
|
||||||
* Otherwise can assume we are starting from no privs.
|
* Otherwise can assume we are starting from no privs.
|
||||||
*/
|
*/
|
||||||
appendPQExpBuffer(sql, "GRANT %s ON %s TO ",
|
appendPQExpBuffer(sql, "GRANT %s ON %s %s TO ",
|
||||||
priv,
|
priv, type, name);
|
||||||
fmtId(tbinfo->relname, force_quotes));
|
|
||||||
if (eqpos == tok)
|
if (eqpos == tok)
|
||||||
{
|
{
|
||||||
/* Empty left-hand side means "PUBLIC" */
|
/* Empty left-hand side means "PUBLIC" */
|
||||||
@ -4133,34 +4238,39 @@ dumpACL(Archive *fout, TableInfo *tbinfo)
|
|||||||
/*
|
/*
|
||||||
* If we didn't find any owner privs, the owner must have revoked 'em all
|
* If we didn't find any owner privs, the owner must have revoked 'em all
|
||||||
*/
|
*/
|
||||||
if (!found_owner_privs && *tbinfo->usename)
|
if (!found_owner_privs && usename)
|
||||||
{
|
{
|
||||||
appendPQExpBuffer(sql, "REVOKE ALL ON %s FROM ",
|
appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM ",
|
||||||
fmtId(tbinfo->relname, force_quotes));
|
type, name);
|
||||||
appendPQExpBuffer(sql, "%s;\n", fmtId(tbinfo->usename, force_quotes));
|
appendPQExpBuffer(sql, "%s;\n", fmtId(usename, force_quotes));
|
||||||
}
|
}
|
||||||
|
|
||||||
free(aclbuf);
|
free(aclbuf);
|
||||||
|
|
||||||
if (tbinfo->viewoid != NULL)
|
ArchiveEntry(fout, objoid, name, nspname, usename ? usename : "",
|
||||||
objoid = tbinfo->viewoid;
|
"ACL", NULL, sql->data, "", NULL, NULL, NULL);
|
||||||
else
|
|
||||||
objoid = tbinfo->oid;
|
|
||||||
|
|
||||||
ArchiveEntry(fout, objoid, tbinfo->relname,
|
|
||||||
tbinfo->relnamespace->nspname,
|
|
||||||
tbinfo->usename, "ACL", NULL,
|
|
||||||
sql->data, "", NULL, NULL, NULL);
|
|
||||||
|
|
||||||
destroyPQExpBuffer(sql);
|
destroyPQExpBuffer(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
dumpTableACL(Archive *fout, TableInfo *tbinfo)
|
||||||
|
{
|
||||||
|
char * tmp = strdup( fmtId(tbinfo->relname, force_quotes) );
|
||||||
|
dumpACL(fout, "TABLE", tmp, tbinfo->relnamespace->nspname,
|
||||||
|
tbinfo->usename, tbinfo->relacl,
|
||||||
|
tbinfo->viewoid != NULL ? tbinfo->viewoid : tbinfo->oid);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dumpTables:
|
* dumpTables:
|
||||||
* write out to fout the declarations (not data) of all user-defined tables
|
* write out to fout the declarations (not data) of all user-defined tables
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
|
dumpTables(Archive *fout, TableInfo tblinfo[], int numTables,
|
||||||
const bool aclsSkip, const bool schemaOnly, const bool dataOnly)
|
const bool aclsSkip, const bool schemaOnly, const bool dataOnly)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -4176,7 +4286,7 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
|
|||||||
{
|
{
|
||||||
dumpOneSequence(fout, tbinfo, schemaOnly, dataOnly);
|
dumpOneSequence(fout, tbinfo, schemaOnly, dataOnly);
|
||||||
if (!dataOnly && !aclsSkip)
|
if (!dataOnly && !aclsSkip)
|
||||||
dumpACL(fout, tbinfo);
|
dumpTableACL(fout, tbinfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4193,7 +4303,7 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
|
|||||||
{
|
{
|
||||||
dumpOneTable(fout, tbinfo, tblinfo);
|
dumpOneTable(fout, tbinfo, tblinfo);
|
||||||
if (!aclsSkip)
|
if (!aclsSkip)
|
||||||
dumpACL(fout, tbinfo);
|
dumpTableACL(fout, tbinfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_dump.h,v 1.85 2002/05/10 22:36:27 tgl Exp $
|
* $Id: pg_dump.h,v 1.86 2002/05/19 10:08:25 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -62,6 +62,7 @@ typedef struct _funcInfo
|
|||||||
int nargs;
|
int nargs;
|
||||||
char **argtypes; /* OIDs */
|
char **argtypes; /* OIDs */
|
||||||
char *prorettype; /* OID */
|
char *prorettype; /* OID */
|
||||||
|
char *proacl;
|
||||||
bool dumped; /* true if already dumped */
|
bool dumped; /* true if already dumped */
|
||||||
} FuncInfo;
|
} FuncInfo;
|
||||||
|
|
||||||
@ -69,8 +70,10 @@ typedef struct _aggInfo
|
|||||||
{
|
{
|
||||||
char *oid;
|
char *oid;
|
||||||
char *aggname;
|
char *aggname;
|
||||||
|
char *aggbasetype;
|
||||||
NamespaceInfo *aggnamespace; /* link to containing namespace */
|
NamespaceInfo *aggnamespace; /* link to containing namespace */
|
||||||
char *usename;
|
char *usename;
|
||||||
|
char *aggacl;
|
||||||
} AggInfo;
|
} AggInfo;
|
||||||
|
|
||||||
typedef struct _oprInfo
|
typedef struct _oprInfo
|
||||||
@ -201,11 +204,11 @@ extern void dumpNamespaces(Archive *fout,
|
|||||||
NamespaceInfo *nsinfo, int numNamespaces);
|
NamespaceInfo *nsinfo, int numNamespaces);
|
||||||
extern void dumpTypes(Archive *fout, FuncInfo *finfo, int numFuncs,
|
extern void dumpTypes(Archive *fout, FuncInfo *finfo, int numFuncs,
|
||||||
TypeInfo *tinfo, int numTypes);
|
TypeInfo *tinfo, int numTypes);
|
||||||
extern void dumpProcLangs(Archive *fout, FuncInfo *finfo, int numFuncs);
|
extern void dumpProcLangs(Archive *fout, FuncInfo finfo[], int numFuncs);
|
||||||
extern void dumpFuncs(Archive *fout, FuncInfo *finfo, int numFuncs);
|
extern void dumpFuncs(Archive *fout, FuncInfo finfo[], int numFuncs);
|
||||||
extern void dumpAggs(Archive *fout, AggInfo *agginfo, int numAggregates);
|
extern void dumpAggs(Archive *fout, AggInfo agginfo[], int numAggregates);
|
||||||
extern void dumpOprs(Archive *fout, OprInfo *oprinfo, int numOperators);
|
extern void dumpOprs(Archive *fout, OprInfo *oprinfo, int numOperators);
|
||||||
extern void dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
|
extern void dumpTables(Archive *fout, TableInfo tblinfo[], int numTables,
|
||||||
const bool aclsSkip,
|
const bool aclsSkip,
|
||||||
const bool schemaOnly, const bool dataOnly);
|
const bool schemaOnly, const bool dataOnly);
|
||||||
extern void dumpIndexes(Archive *fout, TableInfo *tbinfo, int numTables);
|
extern void dumpIndexes(Archive *fout, TableInfo *tbinfo, int numTables);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user