diff --git a/src/aggregate.c b/src/aggregate.c index 71999bf..6076d28 100644 --- a/src/aggregate.c +++ b/src/aggregate.c @@ -511,7 +511,7 @@ dumpAlterAggregate(FILE *output, PQLAggregate *a, PQLAggregate *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER AGGREGATE %s.%s(%s) OWNER TO %s;", + fprintf(output, "ALTER AGGREGATE %s.%s(%s) OWNER TO \"%s\";", schema2, aggname2, b->arguments, diff --git a/src/am.c b/src/am.c index 1b7a10b..e5b0f7f 100644 --- a/src/am.c +++ b/src/am.c @@ -33,7 +33,7 @@ getAccessMethods(PGconn *c, int *n) return NULL; } - res = PQexec(c, "SELECT a.oid, a.amname, a.amtype, a.amhandler AS handleroid, n.nspname AS handlernspname, p.proname AS handlername, obj_description(a.oid, 'pg_am') AS description FROM pg_am a INNER JOIN pg_proc p ON (a.amhandler = p.oid) INNER JON pg_namespace n ON (p.pronamespace = n.oid) ORDER BY a.amname"); + res = PQexec(c, "SELECT a.oid, a.amname, a.amtype, a.amhandler AS handleroid, n.nspname AS handlernspname, p.proname AS handlername, obj_description(a.oid, 'pg_am') AS description FROM pg_am a INNER JOIN pg_proc p ON (a.amhandler = p.oid) INNER JOIN pg_namespace n ON (p.pronamespace = n.oid) ORDER BY a.amname"); if (PQresultStatus(res) != PGRES_TUPLES_OK) { diff --git a/src/collation.c b/src/collation.c index 91fd7a8..ed1a178 100644 --- a/src/collation.c +++ b/src/collation.c @@ -195,7 +195,7 @@ dumpCreateCollation(FILE *output, PQLCollation *c) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER COLLATION %s.%s OWNER TO %s;", + fprintf(output, "ALTER COLLATION %s.%s OWNER TO \"%s\";", schema, collname, c->owner); @@ -253,7 +253,7 @@ dumpAlterCollation(FILE *output, PQLCollation *a, PQLCollation *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER COLLATION %s.%s OWNER TO %s;", + fprintf(output, "ALTER COLLATION %s.%s OWNER TO \"%s\";", schema2, collname2, b->owner); diff --git a/src/conversion.c b/src/conversion.c index 095a058..a00ff29 100644 --- a/src/conversion.c +++ b/src/conversion.c @@ -156,7 +156,7 @@ dumpCreateConversion(FILE *output, PQLConversion *c) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER CONVERSION %s.%s OWNER TO %s;", + fprintf(output, "ALTER CONVERSION %s.%s OWNER TO \"%s\";", schema, convname, c->owner); @@ -193,7 +193,7 @@ dumpAlterConversion(FILE *output, PQLConversion *a, PQLConversion *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER CONVERSION %s.%s OWNER TO %s;", + fprintf(output, "ALTER CONVERSION %s.%s OWNER TO \"%s\";", schema2, convname2, b->owner); diff --git a/src/domain.c b/src/domain.c index 8f79251..8e090f7 100644 --- a/src/domain.c +++ b/src/domain.c @@ -357,7 +357,7 @@ dumpCreateDomain(FILE *output, PQLDomain *d) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER DOMAIN %s.%s OWNER TO %s;", + fprintf(output, "ALTER DOMAIN %s.%s OWNER TO \"%s\";", schema, domname, d->owner); @@ -544,7 +544,7 @@ dumpAlterDomain(FILE *output, PQLDomain *a, PQLDomain *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER DOMAIN %s.%s OWNER TO %s;", + fprintf(output, "ALTER DOMAIN %s.%s OWNER TO \"%s\";", schema2, domname2, b->owner); diff --git a/src/eventtrigger.c b/src/eventtrigger.c index f92395c..0fec4db 100644 --- a/src/eventtrigger.c +++ b/src/eventtrigger.c @@ -236,7 +236,7 @@ dumpCreateEventTrigger(FILE *output, PQLEventTrigger *e) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER EVENT TRIGGER %s OWNER TO %s;", + fprintf(output, "ALTER EVENT TRIGGER %s OWNER TO \"%s\";", evtname, e->owner); } @@ -398,7 +398,7 @@ dumpAlterEventTrigger(FILE *output, PQLEventTrigger *a, PQLEventTrigger *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER EVENT TRIGGER %s OWNER TO %s;", + fprintf(output, "ALTER EVENT TRIGGER %s OWNER TO \"%s\";", evtname2, b->owner); } diff --git a/src/fdw.c b/src/fdw.c index 6a4455f..46c9928 100644 --- a/src/fdw.c +++ b/src/fdw.c @@ -210,7 +210,7 @@ dumpCreateForeignDataWrapper(FILE *output, PQLForeignDataWrapper *f) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER FOREIGN DATA WRAPPER %s OWNER TO %s;", fdwname, + fprintf(output, "ALTER FOREIGN DATA WRAPPER %s OWNER TO \"%s\";", fdwname, f->owner); } @@ -452,7 +452,7 @@ dumpAlterForeignDataWrapper(FILE *output, PQLForeignDataWrapper *a, if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER FOREIGN DATA WRAPPER %s OWNER TO %s;", fdwname2, + fprintf(output, "ALTER FOREIGN DATA WRAPPER %s OWNER TO \"%s\";", fdwname2, b->owner); } } diff --git a/src/function.c b/src/function.c index e7c2fc5..d235321 100644 --- a/src/function.c +++ b/src/function.c @@ -370,7 +370,7 @@ dumpCreateFunction(FILE *output, PQLFunction *f, bool orreplace) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER FUNCTION %s.%s(%s) OWNER TO %s;", + fprintf(output, "ALTER FUNCTION %s.%s(%s) OWNER TO \"%s\";", schema, funcname, f->iarguments, @@ -766,7 +766,7 @@ dumpAlterFunction(FILE *output, PQLFunction *a, PQLFunction *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER FUNCTION %s.%s(%s) OWNER TO %s;", + fprintf(output, "ALTER FUNCTION %s.%s(%s) OWNER TO \"%s\";", schema2, funcname2, b->iarguments, b->owner); } } diff --git a/src/language.c b/src/language.c index f6d8b88..9359ea3 100644 --- a/src/language.c +++ b/src/language.c @@ -237,7 +237,7 @@ dumpCreateLanguage(FILE *output, PQLLanguage *l) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER LANGUAGE %s OWNER TO %s;", + fprintf(output, "ALTER LANGUAGE %s OWNER TO \"%s\";", langname, l->owner); } @@ -378,7 +378,7 @@ dumpAlterLanguage(FILE *output, PQLLanguage *a, PQLLanguage *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER LANGUAGE %s OWNER TO %s;", + fprintf(output, "ALTER LANGUAGE %s OWNER TO \"%s\";", langname2, b->owner); } diff --git a/src/matview.c b/src/matview.c index b255e5b..a8de00f 100644 --- a/src/matview.c +++ b/src/matview.c @@ -35,6 +35,25 @@ static void dumpAlterColumnSetStorage(FILE *output, PQLMaterializedView *a, static void dumpAlterColumnSetOptions(FILE *output, PQLMaterializedView *a, PQLMaterializedView *b, int i); +int +compareMaterializedViews(PQLMaterializedView *a, PQLMaterializedView *b) +{ + int c; + + c = strcmp(a->obj.schemaname, b->obj.schemaname); + + /* compare relation names iif schema names are equal */ + if (c == 0) { + c = strcmp((a->obj.objectname != NULL)?a->obj.objectname:"", (b->obj.objectname != NULL)?b->obj.objectname:""); + + if (c == 0) { + c = strcmp((a->viewdef != NULL)?a->viewdef:"", (b->viewdef != NULL)?b->viewdef:""); + } + } + + return c; +} + PQLMaterializedView * getMaterializedViews(PGconn *c, int *n) { @@ -402,7 +421,7 @@ dumpCreateMaterializedView(FILE *output, PQLMaterializedView *v) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER MATERIALIZED VIEW %s.%s OWNER TO %s;", schema, matvname, + fprintf(output, "ALTER MATERIALIZED VIEW %s.%s OWNER TO \"%s\";", schema, matvname, v->owner); } @@ -809,7 +828,7 @@ dumpAlterMaterializedView(FILE *output, PQLMaterializedView *a, if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER MATERIALIZED VIEW %s.%s OWNER TO %s;", + fprintf(output, "ALTER MATERIALIZED VIEW %s.%s OWNER TO \"%s\";", schema2, matvname2, b->owner); diff --git a/src/matview.h b/src/matview.h index 07cc8cd..9f341fc 100644 --- a/src/matview.h +++ b/src/matview.h @@ -33,6 +33,7 @@ typedef struct PQLMaterializedView } PQLMaterializedView; PQLMaterializedView *getMaterializedViews(PGconn *c, int *n); +int compareMaterializedViews(PQLMaterializedView *a, PQLMaterializedView *b); void getMaterializedViewAttributes(PGconn *c, PQLMaterializedView *v); void getMaterializedViewSecurityLabels(PGconn *c, PQLMaterializedView *v); diff --git a/src/operator.c b/src/operator.c index 02543b5..230f668 100644 --- a/src/operator.c +++ b/src/operator.c @@ -668,7 +668,7 @@ dumpCreateOperator(FILE *output, PQLOperator *o) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER OPERATOR %s.%s(%s,%s) OWNER TO %s;", + fprintf(output, "ALTER OPERATOR %s.%s(%s,%s) OWNER TO \"%s\";", schema, oprname, (o->lefttype) ? o->lefttype : "NONE", (o->righttype) ? o->righttype : "NONE", @@ -763,7 +763,7 @@ dumpCreateOperatorClass(FILE *output, PQLOperatorClass *c) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER OPERATOR CLASS %s.%s USING %s OWNER TO %s;", + fprintf(output, "ALTER OPERATOR CLASS %s.%s USING %s OWNER TO \"%s\";", schema, opcname, c->accessmethod, c->owner); @@ -804,7 +804,7 @@ dumpCreateOperatorFamily(FILE *output, PQLOperatorFamily *f) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER OPERATOR FAMILY %s.%s USING %s OWNER TO %s;", + fprintf(output, "ALTER OPERATOR FAMILY %s.%s USING %s OWNER TO \"%s\";", schema, opfname, f->accessmethod, f->owner); @@ -892,7 +892,7 @@ dumpAlterOperator(FILE *output, PQLOperator *a, PQLOperator *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER OPERATOR %s.%s(%s,%s) OWNER TO %s;", + fprintf(output, "ALTER OPERATOR %s.%s(%s,%s) OWNER TO \"%s\";", schema2, oprname2, (b->lefttype) ? b->lefttype : "NONE", @@ -1018,7 +1018,7 @@ dumpAlterOperatorClass(FILE *output, PQLOperatorClass *a, PQLOperatorClass *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER OPERATOR CLASS %s.%s USING %s OWNER TO %s;", + fprintf(output, "ALTER OPERATOR CLASS %s.%s USING %s OWNER TO \"%s\";", schema2, opcname2, b->accessmethod, @@ -1172,7 +1172,7 @@ dumpAlterOperatorFamily(FILE *output, PQLOperatorFamily *a, if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER OPERATOR CLASS %s.%s USING %s OWNER TO %s;", + fprintf(output, "ALTER OPERATOR CLASS %s.%s USING %s OWNER TO \"%s\";", schema2, opfname2, b->accessmethod, diff --git a/src/privileges.c b/src/privileges.c index a7a9582..7cf87b2 100644 --- a/src/privileges.c +++ b/src/privileges.c @@ -482,6 +482,9 @@ dumpGrant(FILE *output, int objecttype, PQLObject *a, char *privs, case PGQ_TYPE: fprintf(output, "TYPE"); break; + case PGQ_VIEW: + fprintf(output, "TABLE"); + break; } /* function arguments? */ @@ -490,29 +493,51 @@ dumpGrant(FILE *output, int objecttype, PQLObject *a, char *privs, /* there are some objects that are not schema-qualified */ schema = formatObjectIdentifier(a->schemaname); - fprintf(output, " %s.%s(%s) TO %s;", + if (strcmp(grantee, "PUBLIC") == 0 || strcmp(grantee, "public") == 0) + { + fprintf(output, " %s.%s(%s) TO %s;", + schema, + objname, + args, + grantee); + } else { + fprintf(output, " %s.%s(%s) TO \"%s\";", schema, objname, args, grantee); + } } else if (objecttype == PGQ_DATABASE || objecttype == PGQ_FOREIGN_DATA_WRAPPER || objecttype == PGQ_FOREIGN_SERVER || objecttype == PGQ_LANGUAGE || objecttype == PGQ_SCHEMA || objecttype == PGQ_TABLESPACE) { - /* there are some objects that are not schema-qualified */ - fprintf(output, " %s TO %s;", + /* there are some objects that are not schema-qualified */ + if (strcmp(grantee, "PUBLIC") == 0 || strcmp(grantee, "public") == 0) { + fprintf(output, " %s TO %s;", + objname, + grantee); + } else { + fprintf(output, " %s TO \"%s\";", objname, grantee); + } } else { schema = formatObjectIdentifier(a->schemaname); - fprintf(output, " %s.%s TO %s;", + if (strcmp(grantee, "PUBLIC") == 0 || strcmp(grantee, "public") == 0) { + fprintf(output, " %s.%s TO %s;", + schema, + objname, + grantee); + } else { + fprintf(output, " %s.%s TO \"%s\";", schema, objname, grantee); + } } free(p); @@ -579,6 +604,9 @@ dumpRevoke(FILE *output, int objecttype, PQLObject *a, char *privs, case PGQ_TYPE: fprintf(output, "TYPE"); break; + case PGQ_VIEW: + fprintf(output, "TABLE"); + break; } /* function arguments? */ @@ -587,29 +615,50 @@ dumpRevoke(FILE *output, int objecttype, PQLObject *a, char *privs, /* there are some objects that are not schema-qualified */ schema = formatObjectIdentifier(a->schemaname); - fprintf(output, " %s.%s(%s) FROM %s;", + if (strcmp(grantee, "PUBLIC") == 0 || strcmp(grantee, "public") == 0) { + fprintf(output, " %s.%s(%s) FROM %s;", + schema, + objname, + args, + grantee); + } else { + fprintf(output, " %s.%s(%s) FROM \"%s\";", schema, objname, args, grantee); + } } else if (objecttype == PGQ_DATABASE || objecttype == PGQ_FOREIGN_DATA_WRAPPER || objecttype == PGQ_FOREIGN_SERVER || objecttype == PGQ_LANGUAGE || objecttype == PGQ_SCHEMA || objecttype == PGQ_TABLESPACE) { /* there are some objects that are not schema-qualified */ - fprintf(output, " %s FROM %s;", + if (strcmp(grantee, "PUBLIC") == 0 || strcmp(grantee, "public") == 0) { + fprintf(output, " %s FROM %s;", objname, grantee); + } else { + fprintf(output, " %s FROM \"%s\";", + objname, + grantee); + } } else { schema = formatObjectIdentifier(a->schemaname); - fprintf(output, " %s.%s FROM %s;", + if (strcmp(grantee, "PUBLIC") == 0 || strcmp(grantee, "public") == 0) { + fprintf(output, " %s.%s FROM %s;", schema, objname, grantee); + } else { + fprintf(output, " %s.%s FROM \"%s\";", + schema, + objname, + grantee); + } } free(p); @@ -641,7 +690,7 @@ dumpGrantAndRevoke(FILE *output, int objecttype, PQLObject *a, PQLObject *b, /* End of aclList ala. Print GRANT for aclList alb until its end. */ if (tmpa == NULL) { - logDebug("grant to %s: server2 (end)", tmpb->grantee); + logDebug("grant to \"%s\": server2 (end)", tmpb->grantee); dumpGrant(output, objecttype, b, tmpb->privileges, tmpb->grantee, ((objecttype == PGQ_FUNCTION) ? args : NULL), cols); @@ -687,7 +736,7 @@ dumpGrantAndRevoke(FILE *output, int objecttype, PQLObject *a, PQLObject *b, } else if (strcmp(tmpa->grantee, tmpb->grantee) > 0) { - logDebug("grant to %s: server2", tmpb->grantee); + logDebug("grant to \"%s\": server2", tmpb->grantee); dumpGrant(output, objecttype, b, tmpb->privileges, tmpb->grantee, ((objecttype == PGQ_FUNCTION) ? args : NULL), cols); diff --git a/src/privileges.h b/src/privileges.h index 7c10bc1..d90af3d 100644 --- a/src/privileges.h +++ b/src/privileges.h @@ -37,7 +37,8 @@ enum PQLObjectType PGQ_TYPE = 7, PGQ_LANGUAGE = 8, PGQ_FOREIGN_DATA_WRAPPER = 9, - PGQ_FOREIGN_SERVER = 10 + PGQ_FOREIGN_SERVER = 10, + PGQ_VIEW = 11 }; diff --git a/src/quarrel.c b/src/quarrel.c index 21eb17f..aae8a78 100644 --- a/src/quarrel.c +++ b/src/quarrel.c @@ -42,6 +42,7 @@ * UNSUPPORTED * ~~~~~~~~~~~~~ * foreign table + * policy * procedure * publication * subscription @@ -1991,6 +1992,12 @@ quarrelMaterializedViews() getMaterializedViewSecurityLabels(conn2, &matviews2[j]); } + if (compareMaterializedViews(&matviews1[i], &matviews2[j]) != 0) + { + dumpDropMaterializedView(fpre, &matviews2[j]); + dumpCreateMaterializedView(fpre, &matviews2[j]); + } + dumpAlterMaterializedView(fpre, &matviews1[i], &matviews2[j]); i++; @@ -3822,6 +3829,7 @@ quarrelViews() logNoise("server2: %s.%s", views2[i].obj.schemaname, views2[i].obj.objectname); + /* * We have two sorted lists. Let's figure out which elements are not in the * other list. @@ -3840,7 +3848,7 @@ quarrelViews() if (options.securitylabels) getViewSecurityLabels(conn2, &views2[j]); - dumpCreateView(fpre, &views2[j]); + dumpCreateView(fpre, &views2[j], false); j++; qstat.viewadded++; @@ -3867,6 +3875,9 @@ quarrelViews() getViewSecurityLabels(conn2, &views2[j]); } + if (compareViews(&views1[i], &views2[j]) != 0) + dumpCreateView(fpre, &views2[j], true); + dumpAlterView(fpre, &views1[i], &views2[j]); i++; @@ -3890,7 +3901,7 @@ quarrelViews() if (options.securitylabels) getViewSecurityLabels(conn2, &views2[j]); - dumpCreateView(fpre, &views2[j]); + dumpCreateView(fpre, &views2[j], false); j++; qstat.viewadded++; @@ -4023,13 +4034,69 @@ isEmptyFile(char *p) static void printSummary(void) { - fprintf(stderr, "%d table(s) added, %d table(s) removed\n", qstat.tableadded, + if (qstat.schemaadded > 0 || qstat.schemaremoved > 0) + fprintf(stderr, "%d schema(0 ) added, %d schema(s) removed\n", qstat.schemaadded, + qstat.schemaremoved); + + if (qstat.tableadded > 0 || qstat.tableremoved > 0) + fprintf(stderr, "%d table(s) added, %d table(s) removed\n", qstat.tableadded, qstat.tableremoved); - fprintf(stderr, "%d sequence(s) added, %d sequence(s) removed\n", - qstat.seqadded, + + if (qstat.seqadded > 0 || qstat.seqremoved > 0) + fprintf(stderr, "%d sequence(s) added, %d sequence(s) removed\n", qstat.seqadded, qstat.seqremoved); - fprintf(stderr, "%d index(es) added, %d index(es) removed\n", qstat.indexadded, + + if (qstat.indexadded > 0 || qstat.indexremoved > 0) + fprintf(stderr, "%d index(es) added, %d index(es) removed\n", qstat.indexadded, qstat.indexremoved); + + if (qstat.viewadded > 0 || qstat.viewremoved > 0) + fprintf(stderr, "%d view(s) added, %d view(s) removed\n", qstat.viewadded, + qstat.viewremoved); + + if (qstat.matviewadded > 0 || qstat.matviewremoved > 0) + fprintf(stderr, "%d materialized view(s) added, %d materialized view(s) removed\n", qstat.matviewadded, + qstat.matviewremoved); + + if (qstat.operatoradded > 0 || qstat.operatorremoved > 0) + fprintf(stderr, "%d operator(s) added, %d operator(s) removed\n", qstat.operatoradded, + qstat.operatorremoved); + + if (qstat.languageadded > 0 || qstat.languageremoved > 0) + fprintf(stderr, "%d language(s) added, %d language(s) removed\n", qstat.languageadded, + qstat.languageremoved); + + if (qstat.collationadded > 0 || qstat.collationremoved > 0) + fprintf(stderr, "%d collation(s) added, %d collation(s) removed\n", qstat.collationadded, + qstat.collationremoved); + + if (qstat.conversionadded > 0 || qstat.conversionremoved > 0) + fprintf(stderr, "%d conversion(s) added, %d conversion(s) removed\n", qstat.conversionadded, + qstat.conversionremoved); + + if (qstat.domainadded > 0 || qstat.domainremoved > 0) + fprintf(stderr, "%d domain(s) added, %d domain(s) removed\n", qstat.domainadded, + qstat.domainremoved); + + if (qstat.evttrgadded > 0 || qstat.evttrgremoved > 0) + fprintf(stderr, "%d eventtrigger(s) added, %d eventtrigger(s) removed\n", qstat.evttrgadded, + qstat.evttrgremoved); + + if (qstat.extensionadded > 0 || qstat.extensionremoved > 0) + fprintf(stderr, "%d extension(s) added, %d extension(s) removed\n", qstat.extensionadded, + qstat.extensionremoved); + + if (qstat.functionadded > 0 || qstat.functionremoved > 0) + fprintf(stderr, "%d function(s) added, %d function(s) removed\n", qstat.functionadded, + qstat.functionremoved); + + if (qstat.ruleadded > 0 || qstat.ruleremoved > 0) + fprintf(stderr, "%d rule(s) added, %d rule(s) removed\n", qstat.ruleadded, + qstat.ruleremoved); + + if (qstat.serveradded > 0 || qstat.serverremoved > 0) + fprintf(stderr, "%d server(s) added, %d server(s) removed\n", qstat.serveradded, + qstat.serverremoved); } int main(int argc, char *argv[]) diff --git a/src/schema.c b/src/schema.c index 36c73a7..b688a2a 100644 --- a/src/schema.c +++ b/src/schema.c @@ -216,7 +216,7 @@ dumpCreateSchema(FILE *output, PQLSchema *s) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER SCHEMA %s OWNER TO %s;", schemaname, s->owner); + fprintf(output, "ALTER SCHEMA %s OWNER TO \"%s\";", schemaname, s->owner); } /* privileges */ @@ -359,7 +359,8 @@ dumpAlterSchema(FILE *output, PQLSchema *a, PQLSchema *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER SCHEMA %s OWNER TO %s;", schemaname2, b->owner); + fprintf(output, "ALTER SCHEMA %s OWNER TO \"%s\";", schemaname2, b->owner); + } } diff --git a/src/sequence.c b/src/sequence.c index e3e95fd..c7c8cac 100644 --- a/src/sequence.c +++ b/src/sequence.c @@ -407,7 +407,7 @@ dumpCreateSequence(FILE *output, PQLSequence *s) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER SEQUENCE %s.%s OWNER TO %s;", schema, seqname, s->owner); + fprintf(output, "ALTER SEQUENCE %s.%s OWNER TO \"%s\";", schema, seqname, s->owner); } /* privileges */ @@ -637,7 +637,7 @@ dumpAlterSequence(FILE *output, PQLSequence *a, PQLSequence *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER SEQUENCE %s.%s OWNER TO %s;", schema2, seqname2, + fprintf(output, "ALTER SEQUENCE %s.%s OWNER TO \"%s\";", schema2, seqname2, b->owner); } } diff --git a/src/server.c b/src/server.c index eab9ec1..298a8f7 100644 --- a/src/server.c +++ b/src/server.c @@ -196,7 +196,7 @@ dumpCreateForeignServer(FILE *output, PQLForeignServer *s) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER SERVER %s OWNER TO %s;", srvname, s->owner); + fprintf(output, "ALTER SERVER %s OWNER TO \"%s\";", srvname, s->owner); } /* privileges */ @@ -414,7 +414,7 @@ dumpAlterForeignServer(FILE *output, PQLForeignServer *a, PQLForeignServer *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER SERVER %s OWNER TO %s;", srvname2, b->owner); + fprintf(output, "ALTER SERVER %s OWNER TO \"%s\";", srvname2, b->owner); } } diff --git a/src/statistics.c b/src/statistics.c index e504482..524cc09 100644 --- a/src/statistics.c +++ b/src/statistics.c @@ -122,7 +122,7 @@ dumpCreateStatistics(FILE *output, PQLStatistics *s) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER STATISTICS %s.%s OWNER TO %s;", schema, stxname, + fprintf(output, "ALTER STATISTICS %s.%s OWNER TO \"%s\";", schema, stxname, s->owner); } @@ -175,7 +175,7 @@ dumpAlterStatistics(FILE *output, PQLStatistics *a, PQLStatistics *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER STATISTICS %s.%s OWNER TO %s;", schema2, stxname2, + fprintf(output, "ALTER STATISTICS %s.%s OWNER TO \"%s\";", schema2, stxname2, b->owner); } } diff --git a/src/table.c b/src/table.c index 72062bb..910271e 100644 --- a/src/table.c +++ b/src/table.c @@ -469,13 +469,14 @@ getTableAttributes(PGconn *c, PQLTable *t) { /* determine how many characters will be written by snprintf */ nquery = snprintf(query, nquery, - "SELECT a.attnum, a.attname, a.attnotnull, pg_catalog.format_type(t.oid, a.atttypmod) as atttypname, pg_get_expr(d.adbin, a.attrelid) as attdefexpr, CASE WHEN a.attcollation <> t.typcollation THEN c.collname ELSE NULL END AS attcollation, col_description(a.attrelid, a.attnum) AS description, a.attstattarget, a.attstorage, CASE WHEN t.typstorage <> a.attstorage THEN FALSE ELSE TRUE END AS defstorage, array_to_string(attoptions, ', ') AS attoptions, attacl FROM pg_attribute a LEFT JOIN pg_type t ON (a.atttypid = t.oid) LEFT JOIN pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) LEFT JOIN pg_collation c ON (a.attcollation = c.oid) WHERE a.attrelid = %u AND a.attnum > 0 AND attisdropped IS FALSE ORDER BY a.attname", + "SELECT a.attnum, a.attname, a.attnotnull, pg_catalog.format_type(t.oid, a.atttypmod) as atttypname, pg_get_expr(d.adbin, a.attrelid) as attdefexpr, CASE WHEN a.attcollation <> t.typcollation THEN c.collname ELSE NULL END AS attcollation, col_description(a.attrelid, a.attnum) AS description, a.attstattarget, a.attstorage, CASE WHEN t.typstorage <> a.attstorage THEN FALSE ELSE TRUE END AS defstorage, array_to_string(attoptions, ', ') AS attoptions, attacl FROM pg_attribute a LEFT JOIN pg_type t ON (a.atttypid = t.oid) LEFT JOIN pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) LEFT JOIN pg_collation c ON (a.attcollation = c.oid) WHERE a.attrelid = %u AND a.attnum > 0 AND attisdropped IS FALSE ORDER BY a.attnum", t->obj.oid); nquery++; query = (char *) malloc(nquery * sizeof(char)); /* make enough room for query */ snprintf(query, nquery, - "SELECT a.attnum, a.attname, a.attnotnull, pg_catalog.format_type(t.oid, a.atttypmod) as atttypname, pg_get_expr(d.adbin, a.attrelid) as attdefexpr, CASE WHEN a.attcollation <> t.typcollation THEN c.collname ELSE NULL END AS attcollation, col_description(a.attrelid, a.attnum) AS description, a.attstattarget, a.attstorage, CASE WHEN t.typstorage <> a.attstorage THEN FALSE ELSE TRUE END AS defstorage, array_to_string(attoptions, ', ') AS attoptions, attacl FROM pg_attribute a LEFT JOIN pg_type t ON (a.atttypid = t.oid) LEFT JOIN pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) LEFT JOIN pg_collation c ON (a.attcollation = c.oid) WHERE a.attrelid = %u AND a.attnum > 0 AND attisdropped IS FALSE ORDER BY a.attname", + "SELECT a.attnum, a.attname, a.attnotnull, pg_catalog.format_type(t.oid, a.atttypmod) as atttypname, pg_get_expr(d.adbin, a.attrelid) as attdefexpr, CASE WHEN a.attcollation <> t.typcollation THEN c.collname ELSE NULL END AS attcollation, col_description(a.attrelid, a.attnum) AS description, a.attstattarget, a.attstorage, CASE WHEN t.typstorage <> a.attstorage THEN FALSE ELSE TRUE END AS defstorage, array_to_string(attoptions, ', ') AS attoptions, attacl FROM pg_attribute a LEFT JOIN pg_type t ON (a.atttypid = t.oid) LEFT JOIN pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) LEFT JOIN pg_collation c ON (a.attcollation = c.oid) WHERE a.attrelid = %u AND a.attnum > 0 AND attisdropped IS FALSE ORDER BY a.attnum", + t->obj.oid); logNoise("table: query size: %d ; query: %s", nquery, query); @@ -484,13 +485,14 @@ getTableAttributes(PGconn *c, PQLTable *t) { /* determine how many characters will be written by snprintf */ nquery = snprintf(query, nquery, - "SELECT a.attnum, a.attname, a.attnotnull, pg_catalog.format_type(t.oid, a.atttypmod) as atttypname, pg_get_expr(d.adbin, a.attrelid) as attdefexpr, NULL AS attcollation, col_description(a.attrelid, a.attnum) AS description, a.attstattarget, a.attstorage, CASE WHEN t.typstorage <> a.attstorage THEN FALSE ELSE TRUE END AS defstorage, array_to_string(attoptions, ', ') AS attoptions, attacl FROM pg_attribute a LEFT JOIN pg_type t ON (a.atttypid = t.oid) LEFT JOIN pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) WHERE a.attrelid = %u AND a.attnum > 0 AND attisdropped IS FALSE ORDER BY a.attname", + "SELECT a.attnum, a.attname, a.attnotnull, pg_catalog.format_type(t.oid, a.atttypmod) as atttypname, pg_get_expr(d.adbin, a.attrelid) as attdefexpr, NULL AS attcollation, col_description(a.attrelid, a.attnum) AS description, a.attstattarget, a.attstorage, CASE WHEN t.typstorage <> a.attstorage THEN FALSE ELSE TRUE END AS defstorage, array_to_string(attoptions, ', ') AS attoptions, attacl FROM pg_attribute a LEFT JOIN pg_type t ON (a.atttypid = t.oid) LEFT JOIN pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) WHERE a.attrelid = %u AND a.attnum > 0 AND attisdropped IS FALSE ORDER BY a.attnum", + t->obj.oid); nquery++; query = (char *) malloc(nquery * sizeof(char)); /* make enough room for query */ snprintf(query, nquery, - "SELECT a.attnum, a.attname, a.attnotnull, pg_catalog.format_type(t.oid, a.atttypmod) as atttypname, pg_get_expr(d.adbin, a.attrelid) as attdefexpr, NULL AS attcollation, col_description(a.attrelid, a.attnum) AS description, a.attstattarget, a.attstorage, CASE WHEN t.typstorage <> a.attstorage THEN FALSE ELSE TRUE END AS defstorage, array_to_string(attoptions, ', ') AS attoptions, attacl FROM pg_attribute a LEFT JOIN pg_type t ON (a.atttypid = t.oid) LEFT JOIN pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) WHERE a.attrelid = %u AND a.attnum > 0 AND attisdropped IS FALSE ORDER BY a.attname", + "SELECT a.attnum, a.attname, a.attnotnull, pg_catalog.format_type(t.oid, a.atttypmod) as atttypname, pg_get_expr(d.adbin, a.attrelid) as attdefexpr, NULL AS attcollation, col_description(a.attrelid, a.attnum) AS description, a.attstattarget, a.attstorage, CASE WHEN t.typstorage <> a.attstorage THEN FALSE ELSE TRUE END AS defstorage, array_to_string(attoptions, ', ') AS attoptions, attacl FROM pg_attribute a LEFT JOIN pg_type t ON (a.atttypid = t.oid) LEFT JOIN pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) WHERE a.attrelid = %u AND a.attnum > 0 AND attisdropped IS FALSE ORDER BY a.attnum", t->obj.oid); logNoise("table: query size: %d ; query: %s", nquery, query); @@ -1011,7 +1013,7 @@ dumpCreateTable(FILE *output, FILE *output2, PQLTable *t) hasatts = true; /* attribute name and type */ - fprintf(output, "%s %s", t->attributes[i].attname, t->attributes[i].atttypname); + fprintf(output, "\t%s %s", t->attributes[i].attname, t->attributes[i].atttypname); /* collate */ /* XXX schema-qualified? */ @@ -1117,6 +1119,7 @@ dumpCreateTable(FILE *output, FILE *output2, PQLTable *t) fprintf(output, ";"); } + /* XXX Should it belong to sequence.c? */ /* print owned by sequences */ for (i = 0; i < t->nownedby; i++) @@ -1134,6 +1137,7 @@ dumpCreateTable(FILE *output, FILE *output2, PQLTable *t) free(attname); } + /* comment */ if (options.comment) { @@ -1257,7 +1261,24 @@ dumpCreateTable(FILE *output, FILE *output2, PQLTable *t) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER TABLE %s.%s OWNER TO %s;", schema, tabname, t->owner); + fprintf(output, "ALTER TABLE %s.%s OWNER TO \"%s\";", schema, tabname, t->owner); + } + + /* XXX Should it belong to sequence.c? */ + /* print owned by sequences */ + for (i = 0; i < t->nownedby; i++) + { + char *seqschema = formatObjectIdentifier(t->seqownedby[i].schemaname); + char *seqname = formatObjectIdentifier(t->seqownedby[i].objectname); + char *attname = formatObjectIdentifier(t->attownedby[i]); + + fprintf(output, "\n\n"); + fprintf(output, "ALTER SEQUENCE %s.%s OWNED BY %s.%s.%s;", seqschema, seqname, + seqschema, tabname, attname); + + free(seqschema); + free(seqname); + free(attname); } /* privileges */ @@ -2327,7 +2348,7 @@ dumpAlterTable(FILE *output, PQLTable *a, PQLTable *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER TABLE %s.%s OWNER TO %s;", schema2, tabname2, b->owner); + fprintf(output, "ALTER TABLE %s.%s OWNER TO \"%s\";", schema2, tabname2, b->owner); } } diff --git a/src/textsearch.c b/src/textsearch.c index d4b2350..fbd7936 100644 --- a/src/textsearch.c +++ b/src/textsearch.c @@ -598,7 +598,7 @@ dumpAlterTextSearchConfig(FILE *output, PQLTextSearchConfig *a, if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER TEXT SEARCH CONFIGURATION %s.%s OWNER TO %s;", + fprintf(output, "ALTER TEXT SEARCH CONFIGURATION %s.%s OWNER TO \"%s\";", schema2, cfgname2, b->owner); @@ -804,7 +804,8 @@ void dumpAlterTextSearchDict(FILE *output, PQLTextSearchDict *a, if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER TEXT SEARCH DICTIONARY %s.%s OWNER TO %s;", + fprintf(output, "ALTER TEXT SEARCH DICTIONARY %s.%s OWNER TO \"%s\";", + schema2, dictname2, b->owner); diff --git a/src/type.c b/src/type.c index d482ba8..e2f90f6 100644 --- a/src/type.c +++ b/src/type.c @@ -997,7 +997,7 @@ dumpCreateBaseType(FILE *output, PQLBaseType *t) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER TYPE %s.%s OWNER TO %s;", schema, typname, t->owner); + fprintf(output, "ALTER TYPE %s.%s OWNER TO \"%s\";", schema, typname, t->owner); } /* privileges */ @@ -1067,7 +1067,7 @@ dumpCreateCompositeType(FILE *output, PQLCompositeType *t) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER TYPE %s.%s OWNER TO %s;", schema, typname, t->owner); + fprintf(output, "ALTER TYPE %s.%s OWNER TO \"%s\";", schema, typname, t->owner); } /* privileges */ @@ -1125,7 +1125,8 @@ dumpCreateEnumType(FILE *output, PQLEnumType *t) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER TYPE %s.%s OWNER TO %s;", schema, typname, t->owner); + fprintf(output, "ALTER TYPE %s.%s OWNER TO \"%s\";", schema, typname, t->owner); + } /* privileges */ @@ -1207,7 +1208,7 @@ dumpCreateRangeType(FILE *output, PQLRangeType *t) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER TYPE %s.%s OWNER TO %s;", schema, typname, t->owner); + fprintf(output, "ALTER TYPE %s.%s OWNER TO \"%s\";", schema, typname, t->owner); } /* privileges */ @@ -1397,7 +1398,8 @@ dumpAlterBaseType(FILE *output, PQLBaseType *a, PQLBaseType *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER TYPE %s.%s OWNER TO %s;", schema2, typname2, b->owner); + fprintf(output, "ALTER TYPE %s.%s OWNER TO \"%s\";", schema2, typname2, b->owner); + } } @@ -1540,7 +1542,8 @@ dumpAlterCompositeType(FILE *output, PQLCompositeType *a, PQLCompositeType *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER TYPE %s.%s OWNER TO %s;", schema2, typname2, b->owner); + fprintf(output, "ALTER TYPE %s.%s OWNER TO \"%s\";", schema2, typname2, b->owner); + } } @@ -1683,7 +1686,7 @@ dumpAlterEnumType(FILE *output, PQLEnumType *a, PQLEnumType *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER TYPE %s.%s OWNER TO %s;", schema2, typname2, b->owner); + fprintf(output, "ALTER TYPE %s.%s OWNER TO \"%s\";", schema2, typname2, b->owner); } } @@ -1826,7 +1829,7 @@ dumpAlterRangeType(FILE *output, PQLRangeType *a, PQLRangeType *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER TYPE %s.%s OWNER TO %s;", schema2, typname2, b->owner); + fprintf(output, "ALTER TYPE %s.%s OWNER TO \"%s\";", schema2, typname2, b->owner); } } diff --git a/src/view.c b/src/view.c index 166dc4f..b1fb252 100644 --- a/src/view.c +++ b/src/view.c @@ -25,6 +25,26 @@ #include "view.h" +int +compareViews(PQLView *a, PQLView *b) +{ + int c; + + c = strcmp(a->obj.schemaname, b->obj.schemaname); + + /* compare relation names iif schema names are equal */ + if (c == 0) { + c = strcmp((a->obj.objectname != NULL)?a->obj.objectname:"", (b->obj.objectname != NULL)?b->obj.objectname:""); + + if (c == 0) { + c = strcmp((a->viewdef != NULL)?a->viewdef:"", (b->viewdef != NULL)?b->viewdef:""); + } + } + + return c; +} + + PQLView * getViews(PGconn *c, int *n) { @@ -42,17 +62,17 @@ getViews(PGconn *c, int *n) if (PQserverVersion(c) >= 90300) { res = PQexec(c, - "SELECT c.oid, n.nspname, c.relname, pg_get_viewdef(c.oid) AS viewdef, array_to_string(array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded'), ', ') AS reloptions, CASE WHEN 'check_option=local' = ANY(c.reloptions) THEN 'LOCAL'::text WHEN 'check_option=cascaded' = ANY(c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, obj_description(c.oid, 'pg_class') AS description, pg_get_userbyid(c.relowner) AS relowner FROM pg_class c INNER JOIN pg_namespace n ON (c.relnamespace = n.oid) WHERE relkind = 'v' AND nspname !~ '^pg_' AND nspname <> 'information_schema' AND NOT EXISTS(SELECT 1 FROM pg_depend d WHERE c.oid = d.objid AND d.deptype = 'e') ORDER BY nspname, relname"); + "SELECT c.oid, n.nspname, c.relname, pg_get_viewdef(c.oid) AS viewdef, array_to_string(array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded'), ', ') AS reloptions, CASE WHEN 'check_option=local' = ANY(c.reloptions) THEN 'LOCAL'::text WHEN 'check_option=cascaded' = ANY(c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, obj_description(c.oid, 'pg_class') AS description, pg_get_userbyid(c.relowner) AS relowner, relacl FROM pg_class c INNER JOIN pg_namespace n ON (c.relnamespace = n.oid) WHERE relkind = 'v' AND nspname !~ '^pg_' AND nspname <> 'information_schema' AND NOT EXISTS(SELECT 1 FROM pg_depend d WHERE c.oid = d.objid AND d.deptype = 'e') ORDER BY nspname, relname"); } else if (PQserverVersion(c) >= 90100) /* extension support */ { res = PQexec(c, - "SELECT c.oid, n.nspname, c.relname, pg_get_viewdef(c.oid) AS viewdef, array_to_string(c.reloptions, ', ') AS reloptions, CASE WHEN 'check_option=local' = ANY(c.reloptions) THEN 'LOCAL'::text WHEN 'check_option=cascaded' = ANY(c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, obj_description(c.oid, 'pg_class') AS description, pg_get_userbyid(c.relowner) AS relowner FROM pg_class c INNER JOIN pg_namespace n ON (c.relnamespace = n.oid) WHERE relkind = 'v' AND nspname !~ '^pg_' AND nspname <> 'information_schema' AND NOT EXISTS(SELECT 1 FROM pg_depend d WHERE c.oid = d.objid AND d.deptype = 'e') ORDER BY nspname, relname"); + "SELECT c.oid, n.nspname, c.relname, pg_get_viewdef(c.oid) AS viewdef, array_to_string(c.reloptions, ', ') AS reloptions, CASE WHEN 'check_option=local' = ANY(c.reloptions) THEN 'LOCAL'::text WHEN 'check_option=cascaded' = ANY(c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, obj_description(c.oid, 'pg_class') AS description, pg_get_userbyid(c.relowner) AS relowner, relacl FROM pg_class c INNER JOIN pg_namespace n ON (c.relnamespace = n.oid) WHERE relkind = 'v' AND nspname !~ '^pg_' AND nspname <> 'information_schema' AND NOT EXISTS(SELECT 1 FROM pg_depend d WHERE c.oid = d.objid AND d.deptype = 'e') ORDER BY nspname, relname"); } else { res = PQexec(c, - "SELECT c.oid, n.nspname, c.relname, pg_get_viewdef(c.oid) AS viewdef, array_to_string(c.reloptions, ', ') AS reloptions, CASE WHEN 'check_option=local' = ANY(c.reloptions) THEN 'LOCAL'::text WHEN 'check_option=cascaded' = ANY(c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, obj_description(c.oid, 'pg_class') AS description, pg_get_userbyid(c.relowner) AS relowner FROM pg_class c INNER JOIN pg_namespace n ON (c.relnamespace = n.oid) WHERE relkind = 'v' AND nspname !~ '^pg_' AND nspname <> 'information_schema' ORDER BY nspname, relname"); + "SELECT c.oid, n.nspname, c.relname, pg_get_viewdef(c.oid) AS viewdef, array_to_string(c.reloptions, ', ') AS reloptions, CASE WHEN 'check_option=local' = ANY(c.reloptions) THEN 'LOCAL'::text WHEN 'check_option=cascaded' = ANY(c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, obj_description(c.oid, 'pg_class') AS description, pg_get_userbyid(c.relowner) AS relowner, relacl FROM pg_class c INNER JOIN pg_namespace n ON (c.relnamespace = n.oid) WHERE relkind = 'v' AND nspname !~ '^pg_' AND nspname <> 'information_schema' ORDER BY nspname, relname"); } if (PQresultStatus(res) != PGRES_TUPLES_OK) @@ -94,6 +114,11 @@ getViews(PGconn *c, int *n) v[i].owner = strdup(PQgetvalue(res, i, PQfnumber(res, "relowner"))); + if (PQgetisnull(res, i, PQfnumber(res, "relacl"))) + v[i].acl = NULL; + else + v[i].acl = strdup(PQgetvalue(res, i, PQfnumber(res, "relacl"))); + /* * Security labels are not assigned here (see getViewSecurityLabels), * but default values are essential to avoid having trouble in @@ -208,13 +233,13 @@ dumpDropView(FILE *output, PQLView *v) } void -dumpCreateView(FILE *output, PQLView *v) +dumpCreateView(FILE *output, PQLView *v, bool orreplace) { char *schema = formatObjectIdentifier(v->obj.schemaname); char *viewname = formatObjectIdentifier(v->obj.objectname); fprintf(output, "\n\n"); - fprintf(output, "CREATE VIEW %s.%s", schema, viewname); + fprintf(output, "CREATE %sVIEW %s.%s", orreplace ? "OR REPLACE " : "", schema, viewname); /* reloptions */ if (v->reloptions != NULL) @@ -254,9 +279,12 @@ dumpCreateView(FILE *output, PQLView *v) if (options.owner) { fprintf(output, "\n\n"); - fprintf(output, "ALTER VIEW %s.%s OWNER TO %s;", schema, viewname, v->owner); + fprintf(output, "ALTER VIEW %s.%s OWNER TO \"%s\";", schema, viewname, v->owner); } + if (options.privileges) + dumpGrantAndRevoke(output, PGQ_VIEW, &v->obj, &v->obj, NULL, v->acl, NULL, NULL); + free(schema); free(viewname); } @@ -486,10 +514,13 @@ dumpAlterView(FILE *output, PQLView *a, PQLView *b) if (strcmp(a->owner, b->owner) != 0) { fprintf(output, "\n\n"); - fprintf(output, "ALTER VIEW %s.%s OWNER TO %s;", schema2, viewname2, b->owner); + fprintf(output, "ALTER VIEW %s.%s OWNER TO \"%s\";", schema2, viewname2, b->owner); } } + if (options.privileges) + dumpGrantAndRevoke(output, PGQ_VIEW, &a->obj, &b->obj, a->acl, b->acl, NULL, NULL); + free(schema1); free(viewname1); free(schema2); diff --git a/src/view.h b/src/view.h index e193be9..c99890f 100644 --- a/src/view.h +++ b/src/view.h @@ -10,6 +10,7 @@ #define VIEW_H #include "common.h" +#include "privileges.h" typedef struct PQLView { @@ -21,6 +22,7 @@ typedef struct PQLView char *reloptions; char *comment; char *owner; + char *acl; /* security labels */ PQLSecLabel *seclabels; @@ -29,9 +31,10 @@ typedef struct PQLView PQLView *getViews(PGconn *c, int *n); void getViewSecurityLabels(PGconn *c, PQLView *v); +int compareViews(PQLView *a, PQLView *b); void dumpDropView(FILE *output, PQLView *v); -void dumpCreateView(FILE *output, PQLView *v); +void dumpCreateView(FILE *output, PQLView *v, bool orreplace); void dumpAlterView(FILE *output, PQLView *a, PQLView *b); void freeViews(PQLView *v, int n);