diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index 64d46efa40..b20b6f69d3 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.22 1998/10/02 16:27:46 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.23 1998/10/06 22:14:14 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -243,6 +243,7 @@ DefineQueryRewrite(RuleStmt *stmt) Form_pg_attribute attr; char *attname; int i; + char expected_name[NAMEDATALEN + 5]; /* * So there cannot be INSTEAD NOTHING, ... @@ -269,7 +270,7 @@ DefineQueryRewrite(RuleStmt *stmt) /* * ... the targetlist of the SELECT action must - * exactly match the event relation ... + * exactly match the event relation, ... */ event_relation = heap_openr(event_obj->relname); if (event_relation == NULL) @@ -295,8 +296,8 @@ DefineQueryRewrite(RuleStmt *stmt) } /* - * ... and final there must not be another ON SELECT - * rule already. + * ... there must not be another ON SELECT + * rule already ... */ if (event_relation->rd_rules != NULL) { for (i = 0; i < event_relation->rd_rules->numLocks; i++) { @@ -309,6 +310,15 @@ DefineQueryRewrite(RuleStmt *stmt) } heap_close(event_relation); + + /* + * ... and finally the rule must be named _RETviewname. + */ + sprintf(expected_name, "_RET%s", event_obj->relname); + if (strcmp(expected_name, stmt->rulename) != 0) { + elog(ERROR, "view rule for %s must be named %s", + event_obj->relname, expected_name); + } } /* diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index b3a1db8c06..8bde27bcd0 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -3,7 +3,7 @@ * out of it's tuple * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.4 1998/10/02 16:27:51 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.5 1998/10/06 22:14:16 momjian Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -415,7 +415,7 @@ pg_get_indexdef(Oid indexrelid) * Start the index definition * ---------- */ - sprintf(buf, "CREATE %sINDEX %s ON %s USING %s (", + sprintf(buf, "CREATE %sINDEX \"%s\" ON \"%s\" USING %s (", idxrec->indisunique ? "UNIQUE " : "", nameout(&(idxrelrec->relname)), nameout(&(indrelrec->relname)), @@ -439,11 +439,13 @@ pg_get_indexdef(Oid indexrelid) * Add the indexed field name * ---------- */ + strcat(keybuf, "\""); if (idxrec->indkey[keyno] == ObjectIdAttributeNumber - 1) strcat(keybuf, "oid"); else strcat(keybuf, get_attribute_name(idxrec->indrelid, idxrec->indkey[keyno])); + strcat(keybuf, "\""); /* ---------- * If not a functional index, add the operator class name @@ -462,8 +464,9 @@ pg_get_indexdef(Oid indexrelid) spi_tup = SPI_tuptable->vals[0]; spi_ttc = SPI_tuptable->tupdesc; spi_fno = SPI_fnumber(spi_ttc, "opcname"); - strcat(keybuf, " "); + strcat(keybuf, " \""); strcat(keybuf, SPI_getvalue(spi_tup, spi_ttc, spi_fno)); + strcat(keybuf, "\""); } } @@ -482,8 +485,9 @@ pg_get_indexdef(Oid indexrelid) elog(ERROR, "cache lookup for proc %d failed", idxrec->indproc); procStruct = (Form_pg_proc) GETSTRUCT(proctup); + strcat(buf, "\""); strcat(buf, nameout(&(procStruct->proname))); - strcat(buf, " ("); + strcat(buf, "\" ("); strcat(buf, keybuf); strcat(buf, ") "); @@ -498,7 +502,9 @@ pg_get_indexdef(Oid indexrelid) spi_tup = SPI_tuptable->vals[0]; spi_ttc = SPI_tuptable->tupdesc; spi_fno = SPI_fnumber(spi_ttc, "opcname"); + strcat(buf, "\""); strcat(buf, SPI_getvalue(spi_tup, spi_ttc, spi_fno)); + strcat(buf, "\""); } else /* ---------- @@ -628,29 +634,29 @@ make_ruledef(HeapTuple ruletup, TupleDesc rulettc) * Build the rules definition text * ---------- */ - strcpy(buf, "CREATE RULE "); + strcpy(buf, "CREATE RULE \""); /* The rule name */ strcat(buf, rulename); - strcat(buf, " AS ON "); + strcat(buf, "\" AS ON "); /* The event the rule is fired for */ switch (ev_type) { case '1': - strcat(buf, "SELECT TO "); + strcat(buf, "SELECT TO \""); break; case '2': - strcat(buf, "UPDATE TO "); + strcat(buf, "UPDATE TO \""); break; case '3': - strcat(buf, "INSERT TO "); + strcat(buf, "INSERT TO \""); break; case '4': - strcat(buf, "DELETE TO "); + strcat(buf, "DELETE TO \""); break; default: @@ -661,10 +667,12 @@ make_ruledef(HeapTuple ruletup, TupleDesc rulettc) /* The relation the rule is fired on */ strcat(buf, get_relation_name(ev_class)); + strcat(buf, "\""); if (ev_attr > 0) { - strcat(buf, "."); + strcat(buf, ".\""); strcat(buf, get_attribute_name(ev_class, ev_attr)); + strcat(buf, "\""); } /* If the rule has an event qualification, add it */ @@ -941,8 +949,9 @@ get_select_query_def(Query *query, QryHier *qh) /* and do if so */ if (tell_as) { - strcat(buf, " AS "); + strcat(buf, " AS \""); strcat(buf, tle->resdom->resname); + strcat(buf, "\""); } } @@ -967,11 +976,14 @@ get_select_query_def(Query *query, QryHier *qh) strcat(buf, sep); sep = ", "; + strcat(buf, "\""); strcat(buf, rte->relname); + strcat(buf, "\""); if (strcmp(rte->relname, rte->refname) != 0) { - strcat(buf, " "); + strcat(buf, " \""); strcat(buf, rte->refname); + strcat(buf, "\""); } } } @@ -1071,8 +1083,9 @@ get_insert_query_def(Query *query, QryHier *qh) * ---------- */ rte = (RangeTblEntry *) nth(query->resultRelation - 1, query->rtable); - strcpy(buf, "INSERT INTO "); + strcpy(buf, "INSERT INTO \""); strcat(buf, rte->relname); + strcat(buf, "\""); /* Add the target list */ sep = " ("; @@ -1082,7 +1095,9 @@ get_insert_query_def(Query *query, QryHier *qh) strcat(buf, sep); sep = ", "; + strcat(buf, "\""); strcat(buf, tle->resdom->resname); + strcat(buf, "\""); } strcat(buf, ") "); @@ -1142,8 +1157,9 @@ get_update_query_def(Query *query, QryHier *qh) strcat(buf, sep); sep = ", "; + strcat(buf, "\""); strcat(buf, tle->resdom->resname); - strcat(buf, " = "); + strcat(buf, "\" = "); strcat(buf, get_tle_expr(qh, query->resultRelation, tle, TRUE)); } @@ -1179,8 +1195,9 @@ get_delete_query_def(Query *query, QryHier *qh) * ---------- */ rte = (RangeTblEntry *) nth(query->resultRelation - 1, query->rtable); - strcpy(buf, "DELETE FROM "); + strcpy(buf, "DELETE FROM \""); strcat(buf, rte->relname); + strcat(buf, "\""); /* Add a WHERE clause if given */ if (query->qual != NULL) @@ -1232,8 +1249,9 @@ get_rule_expr(QryHier *qh, int rt_index, Node *node, bool varprefix) { Aggreg *agg = (Aggreg *) node; + strcat(buf, "\""); strcat(buf, agg->aggname); - strcat(buf, "("); + strcat(buf, "\"("); strcat(buf, get_rule_expr(qh, rt_index, (Node *) (agg->target), varprefix)); strcat(buf, ")"); @@ -1328,10 +1346,8 @@ get_rule_expr(QryHier *qh, int rt_index, Node *node, bool varprefix) int sup = var->varlevelsup; while(sup-- > 0) qh = qh->parent; - rte = (RangeTblEntry *) nth(var->varno - 1, qh->query->rtable); - if (qh->parent == NULL && var->varlevelsup > 0) - rte = (RangeTblEntry *) nth(var->varno + 1, qh->query->rtable); + rte = (RangeTblEntry *) nth(var->varno - 1, qh->query->rtable); if (!strcmp(rte->refname, "*NEW*")) strcat(buf, "new."); @@ -1343,12 +1359,15 @@ get_rule_expr(QryHier *qh, int rt_index, Node *node, bool varprefix) { if (strcmp(rte->relname, rte->refname) != 0) { + strcat(buf, "\""); strcat(buf, rte->refname); - strcat(buf, "."); + strcat(buf, "\"."); } } } + strcat(buf, "\""); strcat(buf, get_attribute_name(rte->relid, var->varattno)); + strcat(buf, "\""); return pstrdup(buf); } @@ -1433,8 +1452,9 @@ get_func_expr(QryHier *qh, int rt_index, Expr *expr, bool varprefix) * Build a string of proname(args) * ---------- */ - strcpy(buf, proname); - strcat(buf, "("); + strcpy(buf, "\""); + strcat(buf, proname); + strcat(buf, "\"("); sep = ""; foreach(l, expr->args) { @@ -1561,7 +1581,7 @@ get_const_expr(Const *constval) extval = (char *) (*fmgr_faddr(&finfo_output)) (constval->constvalue, &isnull, -1); - sprintf(namebuf, "::%s", nameout(&(typeStruct->typname))); + sprintf(namebuf, "::\"%s\"", nameout(&(typeStruct->typname))); if (strcmp(namebuf, "::unknown") == 0) namebuf[0] = '\0'; sprintf(buf, "'%s'%s", extval, namebuf); diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c index 7974a9db6d..ea1f63feaa 100644 --- a/src/bin/pg_dump/common.c +++ b/src/bin/pg_dump/common.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.26 1998/10/02 16:43:38 thomas Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.27 1998/10/06 22:14:17 momjian Exp $ * * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2 * @@ -304,6 +304,14 @@ dumpSchema(FILE *fout, tinfo, numTypes, tablename, acls); } + if (!tablename && fout) + { + if (g_verbose) + fprintf(stderr, "%s dumping out user-defined procedural languages %s\n", + g_comment_start, g_comment_end); + dumpProcLangs(fout, finfo, numFuncs, tinfo, numTypes); + } + if (!tablename && fout) { if (g_verbose) @@ -315,7 +323,7 @@ dumpSchema(FILE *fout, if (!tablename && fout) { if (g_verbose) - fprintf(stderr, "%s dumping out user-defined functions %s\n", + fprintf(stderr, "%s dumping out user-defined aggregates %s\n", g_comment_start, g_comment_end); dumpAggs(fout, agginfo, numAggregates, tinfo, numTypes); } diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 604a29ccdf..6151d2d1c7 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -21,7 +21,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.90 1998/10/06 05:35:42 thomas Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.91 1998/10/06 22:14:19 momjian Exp $ * * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb * @@ -82,6 +82,8 @@ static void dumpSequence(FILE *fout, TableInfo tbinfo); static void dumpACL(FILE *fout, TableInfo tbinfo); static void dumpTriggers(FILE *fout, const char *tablename, TableInfo *tblinfo, int numTables); +static void dumpRules(FILE *fout, const char *tablename, + TableInfo *tblinfo, int numTables); static char *checkForQuote(const char *s); static void clearTableInfo(TableInfo *, int); static void dumpOneFunc(FILE *fout, FuncInfo *finfo, int i, @@ -190,6 +192,7 @@ isViewRule(char *relname) sprintf(query, "select relname from pg_class, pg_rewrite " "where pg_class.oid = ev_class " + "and pg_rewrite.ev_type = '1' " "and rulename = '_RET%s'", relname); res = PQexec(g_conn, query); @@ -698,6 +701,7 @@ main(int argc, char **argv) { dumpSchemaIdx(g_fout, tablename, tblinfo, numTables); dumpTriggers(g_fout, tablename, tblinfo, numTables); + dumpRules(g_fout, tablename, tblinfo, numTables); } fflush(g_fout); @@ -1384,7 +1388,7 @@ getFuncs(int *numFuncs) TableInfo * getTables(int *numTables, FuncInfo *finfo, int numFuncs) { - PGresult *res, *viewres; + PGresult *res; int ntups; int i; char query[MAXQUERYLEN]; @@ -1415,8 +1419,6 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs) } PQclear(res); -/* NOTE, when outer joins are here, change this query to get the -view definition all in one go. */ sprintf(query, "SELECT pg_class.oid, relname, relkind, relacl, usename, " "relchecks, reltriggers " @@ -1457,39 +1459,6 @@ view definition all in one go. */ tblinfo[i].ncheck = atoi(PQgetvalue(res, i, i_relchecks)); tblinfo[i].ntrig = atoi(PQgetvalue(res, i, i_reltriggers)); - /* NOTE that at such time as left outer joins become avaliable, - then this will no longer be needed, and can be done in the - above query. */ - - sprintf(query, - "select definition from pg_views where viewname = '%s';", - tblinfo[i].relname); - - viewres = PQexec(g_conn, query); - if (!viewres || - PQresultStatus(res) != PGRES_TUPLES_OK) - { - fprintf(stderr, "getTables(): SELECT for views failed\n"); - exit_nicely(g_conn); - } - - /* NOTE: Tryed to use isViewRule here, but it does it's own - BEGIN and END so messed things up. - This also needs redone should we ever get outer joins. - */ - if ( PQntuples(viewres) > 0 ) - { - if ( PQntuples(viewres) != 1 ) - { - fprintf(stderr, "getTables(): failed to get view definition.\n"); - exit_nicely(g_conn); - } - - tblinfo[i].viewdef = strdup(PQgetvalue(viewres, 0, 0)); - } - - PQclear(viewres); - /* Get CHECK constraints */ if (tblinfo[i].ncheck > 0) { @@ -1596,7 +1565,6 @@ view definition all in one go. */ for (findx = 0; findx < numFuncs; findx++) { if (strcmp(finfo[findx].oid, tgfunc) == 0 && - finfo[findx].lang == ClanguageId && finfo[findx].nargs == 0 && strcmp(finfo[findx].prorettype, "0") == 0) break; @@ -2035,6 +2003,88 @@ dumpTypes(FILE *fout, FuncInfo *finfo, int numFuncs, } } +/* + * dumpProcLangs + * writes out to fout the queries to recreate user-defined procedural languages + * + */ +void +dumpProcLangs(FILE *fout, FuncInfo *finfo, int numFuncs, + TypeInfo *tinfo, int numTypes) +{ + PGresult *res; + char query[MAXQUERYLEN]; + int ntups; + int i_lanname; + int i_lanpltrusted; + int i_lanplcallfoid; + int i_lancompiler; + char *lanname; + char *lancompiler; + char *lanplcallfoid; + int i, + fidx; + + res = PQexec(g_conn, "begin"); + if (!res || + PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "BEGIN command failed\n"); + exit_nicely(g_conn); + } + + sprintf(query, "SELECT * FROM pg_language " + "WHERE lanispl " + "ORDER BY oid"); + res = PQexec(g_conn, query); + if (!res || + PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "dumpProcLangs(): SELECT failed\n"); + exit_nicely(g_conn); + } + ntups = PQntuples(res); + + i_lanname = PQfnumber(res, "lanname"); + i_lanpltrusted = PQfnumber(res, "lanpltrusted"); + i_lanplcallfoid = PQfnumber(res, "lanplcallfoid"); + i_lancompiler = PQfnumber(res, "lancompiler"); + + for (i = 0; i < ntups; i++) { + lanplcallfoid = PQgetvalue(res, i, i_lanplcallfoid); + for (fidx = 0; fidx < numFuncs; fidx++) + { + if (!strcmp(finfo[fidx].oid, lanplcallfoid)) + break; + } + if (fidx >= numFuncs) + { + fprintf(stderr, "dumpProcLangs(): handler procedure for language %s not found\n", PQgetvalue(res, i, i_lanname)); + exit_nicely(g_conn); + } + + dumpOneFunc(fout, finfo, fidx, tinfo, numTypes); + + lanname = checkForQuote(PQgetvalue(res, i, i_lanname)); + lancompiler = checkForQuote(PQgetvalue(res, i, i_lancompiler)); + + fprintf(fout, "CREATE %sPROCEDURAL LANGUAGE '%s' " + "HANDLER %s LANCOMPILER '%s';\n", + (PQgetvalue(res, i, i_lanpltrusted)[0] == 't') ? "TRUSTED " : "", + lanname, + fmtId(finfo[fidx].proname), + lancompiler); + + free(lanname); + free(lancompiler); + } + + PQclear(res); + + res = PQexec(g_conn, "end"); + PQclear(res); +} + /* * dumpFuncs * writes out to fout the queries to recreate all the user-defined functions @@ -2063,6 +2113,8 @@ dumpOneFunc(FILE *fout, FuncInfo *finfo, int i, { char q[MAXQUERYLEN]; int j; + char *func_def; + char func_lang[NAMEDATALEN + 1]; if (finfo[i].dumped) return; @@ -2071,6 +2123,66 @@ dumpOneFunc(FILE *fout, FuncInfo *finfo, int i, becomeUser(fout, finfo[i].usename); + if (finfo[i].lang == INTERNALlanguageId) + { + func_def = finfo[i].prosrc; + strcpy(func_lang, "INTERNAL"); + } + else if (finfo[i].lang == ClanguageId) + { + func_def = finfo[i].probin; + strcpy(func_lang, "C"); + } + else if (finfo[i].lang == SQLlanguageId) + { + func_def = finfo[i].prosrc; + strcpy(func_lang, "SQL"); + } + else + { + PGresult *res; + int nlangs; + int i_lanname; + char query[256]; + + res = PQexec(g_conn, "begin"); + if (!res || + PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "dumpOneFunc(): BEGIN command failed\n"); + exit_nicely(g_conn); + } + PQclear(res); + + sprintf(query, "SELECT lanname FROM pg_language " + "WHERE oid = %d", + finfo[i].lang); + res = PQexec(g_conn, query); + if (!res || + PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "dumpOneFunc(): SELECT for procedural language failed\n"); + exit_nicely(g_conn); + } + nlangs = PQntuples(res); + + if (nlangs != 1) + { + fprintf(stderr, "dumpOneFunc(): procedural language for function %s not found\n", finfo[i].proname); + exit_nicely(g_conn); + } + + i_lanname = PQfnumber(res, "lanname"); + + func_def = finfo[i].prosrc; + strcpy(func_lang, PQgetvalue(res, 0, i_lanname)); + + PQclear(res); + + res = PQexec(g_conn, "end"); + PQclear(res); + } + sprintf(q, "CREATE FUNCTION %s (", fmtId(finfo[i].proname)); for (j = 0; j < finfo[i].nargs; j++) { @@ -2086,12 +2198,7 @@ dumpOneFunc(FILE *fout, FuncInfo *finfo, int i, q, (finfo[i].retset) ? " SETOF " : "", fmtId(findTypeByOid(tinfo, numTypes, finfo[i].prorettype)), - (finfo[i].lang == INTERNALlanguageId) ? finfo[i].prosrc : - (finfo[i].lang == ClanguageId) ? finfo[i].probin : - (finfo[i].lang == SQLlanguageId) ? finfo[i].prosrc : "unknown", - (finfo[i].lang == INTERNALlanguageId) ? "INTERNAL" : - (finfo[i].lang == ClanguageId) ? "C" : - (finfo[i].lang == SQLlanguageId) ? "SQL" : "unknown"); + func_def, func_lang); fputs(q, fout); @@ -2504,102 +2611,97 @@ dumpTables(FILE *fout, TableInfo *tblinfo, int numTables, if (!tablename || (!strcmp(tblinfo[i].relname, tablename))) { - /* Dump VIEW relations also !-) */ + /* Skip VIEW relations */ + /* if (isViewRule(tblinfo[i].relname)) + continue; + */ + + parentRels = tblinfo[i].parentRels; + numParents = tblinfo[i].numParents; + + becomeUser(fout, tblinfo[i].usename); + + sprintf(q, "CREATE TABLE %s (", fmtId(tblinfo[i].relname)); + actual_atts = 0; + for (j = 0; j < tblinfo[i].numatts; j++) { - becomeUser(fout, tblinfo[i].usename); - - sprintf(q, "CREATE VIEW %s AS %s\n", - fmtId(tblinfo[i].relname), - tblinfo[i].viewdef); - } - else - { - parentRels = tblinfo[i].parentRels; - numParents = tblinfo[i].numParents; - - becomeUser(fout, tblinfo[i].usename); - - sprintf(q, "CREATE TABLE %s (", fmtId(tblinfo[i].relname)); - actual_atts = 0; - for (j = 0; j < tblinfo[i].numatts; j++) + if (tblinfo[i].inhAttrs[j] == 0) { - if (tblinfo[i].inhAttrs[j] == 0) + + /* Show lengths on bpchar and varchar */ + if (!strcmp(tblinfo[i].typnames[j], "bpchar")) { - - /* Show lengths on bpchar and varchar */ - if (!strcmp(tblinfo[i].typnames[j], "bpchar")) - { - sprintf(q, "%s%s%s char", - q, - (actual_atts > 0) ? ", " : "", - fmtId(tblinfo[i].attnames[j])); - - sprintf(q, "%s(%d)", - q, - tblinfo[i].atttypmod[j] - VARHDRSZ); - actual_atts++; - } - else if (!strcmp(tblinfo[i].typnames[j], "varchar")) - { - sprintf(q, "%s%s%s %s", - q, - (actual_atts > 0) ? ", " : "", - fmtId(tblinfo[i].attnames[j]), - tblinfo[i].typnames[j]); - - sprintf(q, "%s(%d)", - q, - tblinfo[i].atttypmod[j] - VARHDRSZ); - actual_atts++; - } - else - { - strcpy(id1, fmtId(tblinfo[i].attnames[j])); - strcpy(id2, fmtId(tblinfo[i].typnames[j])); - sprintf(q, "%s%s%s %s", - q, - (actual_atts > 0) ? ", " : "", - id1, - id2); - actual_atts++; - } - if (tblinfo[i].adef_expr[j] != NULL) - sprintf(q, "%s DEFAULT %s", q, tblinfo[i].adef_expr[j]); - if (tblinfo[i].notnull[j]) - sprintf(q, "%s NOT NULL", q); - } - } - - /* put the CONSTRAINTS inside the table def */ - for (k = 0; k < tblinfo[i].ncheck; k++) - { - sprintf(q, "%s%s %s", - q, - (actual_atts + k > 0) ? ", " : "", - tblinfo[i].check_expr[k]); - } - - strcat(q, ")"); - - if (numParents > 0) - { - sprintf(q, "%s inherits ( ", q); - for (k = 0; k < numParents; k++) - { - sprintf(q, "%s%s%s", + sprintf(q, "%s%s%s char", q, - (k > 0) ? ", " : "", - fmtId(parentRels[k])); - } - strcat(q, ")"); - } - strcat(q, ";\n"); - } /* end of if view ... else .... */ + (actual_atts > 0) ? ", " : "", + fmtId(tblinfo[i].attnames[j])); + sprintf(q, "%s(%d)", + q, + tblinfo[i].atttypmod[j] - VARHDRSZ); + actual_atts++; + } + else if (!strcmp(tblinfo[i].typnames[j], "varchar")) + { + sprintf(q, "%s%s%s %s", + q, + (actual_atts > 0) ? ", " : "", + fmtId(tblinfo[i].attnames[j]), + tblinfo[i].typnames[j]); + + sprintf(q, "%s(%d)", + q, + tblinfo[i].atttypmod[j] - VARHDRSZ); + actual_atts++; + } + else + { + strcpy(id1, fmtId(tblinfo[i].attnames[j])); + strcpy(id2, fmtId(tblinfo[i].typnames[j])); + sprintf(q, "%s%s%s %s", + q, + (actual_atts > 0) ? ", " : "", + id1, + id2); + actual_atts++; + } + if (tblinfo[i].adef_expr[j] != NULL) + sprintf(q, "%s DEFAULT %s", q, tblinfo[i].adef_expr[j]); + if (tblinfo[i].notnull[j]) + sprintf(q, "%s NOT NULL", q); + } + } + + /* put the CONSTRAINTS inside the table def */ + for (k = 0; k < tblinfo[i].ncheck; k++) + { + sprintf(q, "%s%s %s", + q, + (actual_atts + k > 0) ? ", " : "", + tblinfo[i].check_expr[k]); + } + + strcat(q, ")"); + + if (numParents > 0) + { + sprintf(q, "%s inherits ( ", q); + for (k = 0; k < numParents; k++) + { + sprintf(q, "%s%s%s", + q, + (k > 0) ? ", " : "", + fmtId(parentRels[k])); + } + strcat(q, ")"); + } + + strcat(q, ";\n"); fputs(q, fout); if (acls) dumpACL(fout, tblinfo[i]); + } } } @@ -2744,7 +2846,7 @@ dumpIndices(FILE *fout, IndInfo *indinfo, int numIndices, if (funcname) { sprintf(q, "%s %s (%s) %s );\n", - q, funcname, attlist, fmtId(classname[0])); + q, fmtId(funcname), attlist, fmtId(classname[0])); free(funcname); free(classname[0]); } @@ -3039,6 +3141,75 @@ dumpTriggers(FILE *fout, const char *tablename, } +static void +dumpRules(FILE *fout, const char *tablename, + TableInfo *tblinfo, int numTables) +{ + PGresult *res; + int nrules; + int i, + t; + char query[MAXQUERYLEN]; + + int i_definition; + + if (g_verbose) + fprintf(stderr, "%s dumping out rules %s\n", + g_comment_start, g_comment_end); + + /* + * For each table we dump + */ + for (t = 0; t < numTables; t++) + { + if (tablename && strcmp(tblinfo[t].relname, tablename)) + continue; + res = PQexec(g_conn, "begin"); + if (!res || + PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "BEGIN command failed\n"); + exit_nicely(g_conn); + } + PQclear(res); + + /* + * Get all rules defined for this table + */ + sprintf(query, "SELECT pg_get_ruledef(pg_rewrite.rulename) " + "AS definition FROM pg_rewrite, pg_class " + "WHERE pg_class.relname = '%s' " + "AND pg_rewrite.ev_class = pg_class.oid " + "ORDER BY pg_rewrite.oid", + tblinfo[t].relname); + res = PQexec(g_conn, query); + if (!res || + PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "dumpRules(): SELECT failed for table %s\n", + tblinfo[t].relname); + exit_nicely(g_conn); + } + + nrules = PQntuples(res); + i_definition = PQfnumber(res, "definition"); + + /* + * Dump them out + */ + for (i = 0; i < nrules; i++) + { + fprintf(fout, "%s\n", PQgetvalue(res, i, i_definition)); + } + + PQclear(res); + + res = PQexec(g_conn, "end"); + PQclear(res); + } +} + + /* Issue a psql \connect command to become the specified user. * We want to do this only if we are dumping ACLs, * and only if the new username is different from the last one diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index 3192898b46..67e2bfc9d0 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -5,7 +5,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: pg_dump.h,v 1.34 1998/10/06 03:09:01 momjian Exp $ + * $Id: pg_dump.h,v 1.35 1998/10/06 22:14:21 momjian Exp $ * * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2 * @@ -66,7 +66,6 @@ typedef struct _tableInfo { char *oid; char *relname; - char *viewdef; char *relacl; bool sequence; int numatts; /* number of attributes */ @@ -223,6 +222,8 @@ extern void getTableAttrs(TableInfo *tbinfo, int numTables); extern IndInfo *getIndices(int *numIndices); extern void dumpTypes(FILE *fout, FuncInfo *finfo, int numFuncs, TypeInfo *tinfo, int numTypes); +extern void dumpProcLangs(FILE *fout, FuncInfo *finfo, int numFuncs, + TypeInfo *tinfo, int numTypes); extern void dumpFuncs(FILE *fout, FuncInfo *finfo, int numFuncs, TypeInfo *tinfo, int numTypes); extern void dumpAggs(FILE *fout, AggInfo *agginfo, int numAggregates,