diff options
Diffstat (limited to 'src/backend/utils/adt/ruleutils.c')
-rw-r--r-- | src/backend/utils/adt/ruleutils.c | 212 |
1 files changed, 100 insertions, 112 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 3960152f387..412aa252d62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -3,7 +3,7 @@ * back to source text * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.163 2004/03/17 20:48:42 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.164 2004/05/05 04:48:46 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -149,15 +149,16 @@ static char *query_getviewrule = "SELECT * FROM pg_catalog.pg_rewrite WHERE ev_c static char *deparse_expression_pretty(Node *expr, List *dpcontext, bool forceprefix, bool showimplicit, int prettyFlags, int startIndent); -static text *pg_do_getviewdef(Oid viewoid, int prettyFlags); +static char *pg_get_viewdef_worker(Oid viewoid, int prettyFlags); static void decompile_column_index_array(Datum column_index_array, Oid relId, StringInfo buf); -static Datum pg_get_ruledef_worker(Oid ruleoid, int prettyFlags); -static Datum pg_get_indexdef_worker(Oid indexrelid, int colno, - int prettyFlags); -static Datum pg_get_constraintdef_worker(Oid constraintId, int prettyFlags); -static Datum pg_get_expr_worker(text *expr, Oid relid, char *relname, - int prettyFlags); +static char *pg_get_ruledef_worker(Oid ruleoid, int prettyFlags); +static char *pg_get_indexdef_worker(Oid indexrelid, int colno, + int prettyFlags); +static char *pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, + int prettyFlags); +static char *pg_get_expr_worker(text *expr, Oid relid, char *relname, + int prettyFlags); static void make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, int prettyFlags); static void make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, @@ -208,6 +209,7 @@ static char *generate_relation_name(Oid relid); static char *generate_function_name(Oid funcid, int nargs, Oid *argtypes); static char *generate_operator_name(Oid operid, Oid arg1, Oid arg2); static void print_operator_name(StringInfo buf, List *opname); +static text *string_to_text(char *str); #define only_marker(rte) ((rte)->inh ? "" : "ONLY ") @@ -223,7 +225,7 @@ pg_get_ruledef(PG_FUNCTION_ARGS) { Oid ruleoid = PG_GETARG_OID(0); - return pg_get_ruledef_worker(ruleoid, 0); + PG_RETURN_TEXT_P(string_to_text(pg_get_ruledef_worker(ruleoid, 0))); } @@ -235,21 +237,24 @@ pg_get_ruledef_ext(PG_FUNCTION_ARGS) int prettyFlags; prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : 0; - return pg_get_ruledef_worker(ruleoid, prettyFlags); + PG_RETURN_TEXT_P(string_to_text(pg_get_ruledef_worker(ruleoid, prettyFlags))); } -static Datum +static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { - text *ruledef; Datum args[1]; char nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; StringInfoData buf; - int len; + + /* + * Do this first so that string is alloc'd in outer context not SPI's. + */ + initStringInfo(&buf); /* * Connect to SPI manager @@ -283,39 +288,24 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); if (SPI_processed != 1) + appendStringInfo(&buf, "-"); + else { - if (SPI_finish() != SPI_OK_FINISH) - elog(ERROR, "SPI_finish failed"); - ruledef = palloc(VARHDRSZ + 1); - VARATT_SIZEP(ruledef) = VARHDRSZ + 1; - VARDATA(ruledef)[0] = '-'; - PG_RETURN_TEXT_P(ruledef); + /* + * Get the rules definition and put it into executors memory + */ + ruletup = SPI_tuptable->vals[0]; + rulettc = SPI_tuptable->tupdesc; + make_ruledef(&buf, ruletup, rulettc, prettyFlags); } - ruletup = SPI_tuptable->vals[0]; - rulettc = SPI_tuptable->tupdesc; - - /* - * Get the rules definition and put it into executors memory - */ - initStringInfo(&buf); - make_ruledef(&buf, ruletup, rulettc, prettyFlags); - len = buf.len + VARHDRSZ; - ruledef = SPI_palloc(len); - VARATT_SIZEP(ruledef) = len; - memcpy(VARDATA(ruledef), buf.data, buf.len); - pfree(buf.data); - /* * Disconnect from SPI manager */ if (SPI_finish() != SPI_OK_FINISH) elog(ERROR, "SPI_finish failed"); - /* - * Easy - isn't it? - */ - PG_RETURN_TEXT_P(ruledef); + return buf.data; } @@ -329,10 +319,8 @@ pg_get_viewdef(PG_FUNCTION_ARGS) { /* By OID */ Oid viewoid = PG_GETARG_OID(0); - text *ruledef; - ruledef = pg_do_getviewdef(viewoid, 0); - PG_RETURN_TEXT_P(ruledef); + PG_RETURN_TEXT_P(string_to_text(pg_get_viewdef_worker(viewoid, 0))); } @@ -342,12 +330,10 @@ pg_get_viewdef_ext(PG_FUNCTION_ARGS) /* By OID */ Oid viewoid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); - text *ruledef; int prettyFlags; prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : 0; - ruledef = pg_do_getviewdef(viewoid, prettyFlags); - PG_RETURN_TEXT_P(ruledef); + PG_RETURN_TEXT_P(string_to_text(pg_get_viewdef_worker(viewoid, prettyFlags))); } Datum @@ -357,14 +343,12 @@ pg_get_viewdef_name(PG_FUNCTION_ARGS) text *viewname = PG_GETARG_TEXT_P(0); RangeVar *viewrel; Oid viewoid; - text *ruledef; viewrel = makeRangeVarFromNameList(textToQualifiedNameList(viewname, "get_viewdef")); viewoid = RangeVarGetRelid(viewrel, false); - ruledef = pg_do_getviewdef(viewoid, 0); - PG_RETURN_TEXT_P(ruledef); + PG_RETURN_TEXT_P(string_to_text(pg_get_viewdef_worker(viewoid, 0))); } @@ -377,31 +361,32 @@ pg_get_viewdef_name_ext(PG_FUNCTION_ARGS) int prettyFlags; RangeVar *viewrel; Oid viewoid; - text *ruledef; prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : 0; viewrel = makeRangeVarFromNameList(textToQualifiedNameList(viewname, "get_viewdef")); viewoid = RangeVarGetRelid(viewrel, false); - ruledef = pg_do_getviewdef(viewoid, prettyFlags); - PG_RETURN_TEXT_P(ruledef); + PG_RETURN_TEXT_P(string_to_text(pg_get_viewdef_worker(viewoid, prettyFlags))); } /* * Common code for by-OID and by-name variants of pg_get_viewdef */ -static text * -pg_do_getviewdef(Oid viewoid, int prettyFlags) +static char * +pg_get_viewdef_worker(Oid viewoid, int prettyFlags) { - text *ruledef; Datum args[2]; char nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; StringInfoData buf; - int len; + + /* + * Do this first so that string is alloc'd in outer context not SPI's. + */ + initStringInfo(&buf); /* * Connect to SPI manager @@ -437,7 +422,6 @@ pg_do_getviewdef(Oid viewoid, int prettyFlags) spirc = SPI_execp(plan_getviewrule, args, nulls, 2); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); - initStringInfo(&buf); if (SPI_processed != 1) appendStringInfo(&buf, "Not a view"); else @@ -449,11 +433,6 @@ pg_do_getviewdef(Oid viewoid, int prettyFlags) rulettc = SPI_tuptable->tupdesc; make_viewdef(&buf, ruletup, rulettc, prettyFlags); } - len = buf.len + VARHDRSZ; - ruledef = SPI_palloc(len); - VARATT_SIZEP(ruledef) = len; - memcpy(VARDATA(ruledef), buf.data, buf.len); - pfree(buf.data); /* * Disconnect from SPI manager @@ -461,7 +440,7 @@ pg_do_getviewdef(Oid viewoid, int prettyFlags) if (SPI_finish() != SPI_OK_FINISH) elog(ERROR, "SPI_finish failed"); - return ruledef; + return buf.data; } /* ---------- @@ -472,10 +451,8 @@ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); - text *trigdef; HeapTuple ht_trig; Form_pg_trigger trigrec; - int len; StringInfoData buf; Relation tgrel; ScanKeyData skey[1]; @@ -597,21 +574,12 @@ pg_get_triggerdef(PG_FUNCTION_ARGS) /* We deliberately do not put semi-colon at end */ appendStringInfo(&buf, ")"); - /* - * Create the result as a TEXT datum, and free working data - */ - len = buf.len + VARHDRSZ; - trigdef = (text *) palloc(len); - VARATT_SIZEP(trigdef) = len; - memcpy(VARDATA(trigdef), buf.data, buf.len); - - pfree(buf.data); - + /* Clean up */ systable_endscan(tgscan); heap_close(tgrel, AccessShareLock); - PG_RETURN_TEXT_P(trigdef); + PG_RETURN_TEXT_P(string_to_text(buf.data)); } /* ---------- @@ -627,7 +595,7 @@ pg_get_indexdef(PG_FUNCTION_ARGS) { Oid indexrelid = PG_GETARG_OID(0); - return pg_get_indexdef_worker(indexrelid, 0, 0); + PG_RETURN_TEXT_P(string_to_text(pg_get_indexdef_worker(indexrelid, 0, 0))); } Datum @@ -639,13 +607,19 @@ pg_get_indexdef_ext(PG_FUNCTION_ARGS) int prettyFlags; prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : 0; - return pg_get_indexdef_worker(indexrelid, colno, prettyFlags); + PG_RETURN_TEXT_P(string_to_text(pg_get_indexdef_worker(indexrelid, colno, prettyFlags))); +} + +/* Internal version that returns a palloc'd C string */ +char * +pg_get_indexdef_string(Oid indexrelid) +{ + return pg_get_indexdef_worker(indexrelid, 0, 0); } -static Datum +static char * pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags) { - text *indexdef; HeapTuple ht_idx; HeapTuple ht_idxrel; HeapTuple ht_am; @@ -655,7 +629,6 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags) List *indexprs; List *context; Oid indrelid; - int len; int keyno; Oid keycoltype; StringInfoData buf; @@ -817,21 +790,12 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags) } } - /* - * Create the result as a TEXT datum, and free working data - */ - len = buf.len + VARHDRSZ; - indexdef = (text *) palloc(len); - VARATT_SIZEP(indexdef) = len; - memcpy(VARDATA(indexdef), buf.data, buf.len); - - pfree(buf.data); - + /* Clean up */ ReleaseSysCache(ht_idx); ReleaseSysCache(ht_idxrel); ReleaseSysCache(ht_am); - PG_RETURN_TEXT_P(indexdef); + return buf.data; } @@ -846,7 +810,8 @@ pg_get_constraintdef(PG_FUNCTION_ARGS) { Oid constraintId = PG_GETARG_OID(0); - return pg_get_constraintdef_worker(constraintId, 0); + PG_RETURN_TEXT_P(string_to_text(pg_get_constraintdef_worker(constraintId, + false, 0))); } Datum @@ -857,16 +822,22 @@ pg_get_constraintdef_ext(PG_FUNCTION_ARGS) int prettyFlags; prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : 0; - return pg_get_constraintdef_worker(constraintId, prettyFlags); + PG_RETURN_TEXT_P(string_to_text(pg_get_constraintdef_worker(constraintId, + false, prettyFlags))); } +/* Internal version that returns a palloc'd C string */ +char * +pg_get_constraintdef_string(Oid constraintId) +{ + return pg_get_constraintdef_worker(constraintId, true, 0); +} -static Datum -pg_get_constraintdef_worker(Oid constraintId, int prettyFlags) +static char * +pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, + int prettyFlags) { - text *result; StringInfoData buf; - int len; Relation conDesc; SysScanDesc conscan; ScanKeyData skey[1]; @@ -894,6 +865,13 @@ pg_get_constraintdef_worker(Oid constraintId, int prettyFlags) initStringInfo(&buf); + if (fullCommand && OidIsValid(conForm->conrelid)) + { + appendStringInfo(&buf, "ALTER TABLE ONLY %s ADD CONSTRAINT %s ", + generate_relation_name(conForm->conrelid), + quote_identifier(NameStr(conForm->conname))); + } + switch (conForm->contype) { case CONSTRAINT_FOREIGN: @@ -1087,18 +1065,11 @@ pg_get_constraintdef_worker(Oid constraintId, int prettyFlags) break; } - /* Record the results */ - len = buf.len + VARHDRSZ; - result = (text *) palloc(len); - VARATT_SIZEP(result) = len; - memcpy(VARDATA(result), buf.data, buf.len); - /* Cleanup */ - pfree(buf.data); systable_endscan(conscan); heap_close(conDesc, AccessShareLock); - PG_RETURN_TEXT_P(result); + return buf.data; } @@ -1157,7 +1128,7 @@ pg_get_expr(PG_FUNCTION_ARGS) if (relname == NULL) PG_RETURN_NULL(); /* should we raise an error? */ - return pg_get_expr_worker(expr, relid, relname, 0); + PG_RETURN_TEXT_P(string_to_text(pg_get_expr_worker(expr, relid, relname, 0))); } Datum @@ -1176,13 +1147,12 @@ pg_get_expr_ext(PG_FUNCTION_ARGS) if (relname == NULL) PG_RETURN_NULL(); /* should we raise an error? */ - return pg_get_expr_worker(expr, relid, relname, prettyFlags); + PG_RETURN_TEXT_P(string_to_text(pg_get_expr_worker(expr, relid, relname, prettyFlags))); } -static Datum +static char * pg_get_expr_worker(text *expr, Oid relid, char *relname, int prettyFlags) { - text *result; Node *node; List *context; char *exprstr; @@ -1200,11 +1170,7 @@ pg_get_expr_worker(text *expr, Oid relid, char *relname, int prettyFlags) str = deparse_expression_pretty(node, context, false, false, prettyFlags, 0); - /* Pass the result back as TEXT */ - result = DatumGetTextP(DirectFunctionCall1(textin, - CStringGetDatum(str))); - - PG_RETURN_TEXT_P(result); + return str; } @@ -4364,3 +4330,25 @@ print_operator_name(StringInfo buf, List *opname) appendStringInfo(buf, "%s)", strVal(lfirst(opname))); } } + +/* + * Given a C string, produce a TEXT datum. + * + * We assume that the input was palloc'd and may be freed. + */ +static text * +string_to_text(char *str) +{ + text *result; + int slen = strlen(str); + int tlen; + + tlen = slen + VARHDRSZ; + result = (text *) palloc(tlen); + VARATT_SIZEP(result) = tlen; + memcpy(VARDATA(result), str, slen); + + pfree(str); + + return result; +} |