Allow the second argument of pg_get_expr() to be just zero when deparsing

an expression that's not supposed to contain variables.  Per discussion
with Gevik Babakhani, this eliminates the need for an ugly kluge (namely,
specifying some unrelated relation name).  Remove one such kluge from
pg_dump.
This commit is contained in:
Tom Lane 2009-05-26 17:36:05 +00:00
parent 99bf328237
commit 48938ab506
3 changed files with 50 additions and 23 deletions

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.480 2009/05/18 08:59:29 petere Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.481 2009/05/26 17:36:05 tgl Exp $ -->
<chapter id="functions">
<title>Functions and Operators</title>
@ -12367,7 +12367,9 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
is a decompiled reconstruction, not the original text of the command.)
<function>pg_get_expr</function> decompiles the internal form of an
individual expression, such as the default value for a column. It can be
useful when examining the contents of system catalogs.
useful when examining the contents of system catalogs. If the expression
might contain Vars, specify the OID of the relation they refer to as the
second parameter; if no Vars are expected, zero is sufficient.
<function>pg_get_viewdef</function> reconstructs the <command>SELECT</>
query that defines a view. Most of these functions come in two variants,
one of which can optionally <quote>pretty-print</> the result. The

View File

@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.297 2009/04/05 19:59:40 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.298 2009/05/26 17:36:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -146,7 +146,7 @@ static char *pg_get_indexdef_worker(Oid indexrelid, int colno, bool showTblSpc,
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,
static text *pg_get_expr_worker(text *expr, Oid relid, const char *relname,
int prettyFlags);
static int print_function_arguments(StringInfo buf, HeapTuple proctup,
bool print_table_args, bool print_defaults);
@ -1198,7 +1198,8 @@ decompile_column_index_array(Datum column_index_array, Oid relId,
*
* Currently, the expression can only refer to a single relation, namely
* the one specified by the second parameter. This is sufficient for
* partial indexes, column default expressions, etc.
* partial indexes, column default expressions, etc. We also support
* Var-free expressions, for which the OID can be InvalidOid.
* ----------
*/
Datum
@ -1208,12 +1209,24 @@ pg_get_expr(PG_FUNCTION_ARGS)
Oid relid = PG_GETARG_OID(1);
char *relname;
/* Get the name for the relation */
relname = get_rel_name(relid);
if (relname == NULL)
PG_RETURN_NULL(); /* should we raise an error? */
if (OidIsValid(relid))
{
/* Get the name for the relation */
relname = get_rel_name(relid);
PG_RETURN_TEXT_P(string_to_text(pg_get_expr_worker(expr, relid, relname, 0)));
/*
* If the OID isn't actually valid, don't throw an error, just return
* NULL. This is a bit questionable, but it's what we've done
* historically, and it can help avoid unwanted failures when
* examining catalog entries for just-deleted relations.
*/
if (relname == NULL)
PG_RETURN_NULL();
}
else
relname = NULL;
PG_RETURN_TEXT_P(pg_get_expr_worker(expr, relid, relname, 0));
}
Datum
@ -1227,16 +1240,22 @@ pg_get_expr_ext(PG_FUNCTION_ARGS)
prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : 0;
/* Get the name for the relation */
relname = get_rel_name(relid);
if (relname == NULL)
PG_RETURN_NULL(); /* should we raise an error? */
if (OidIsValid(relid))
{
/* Get the name for the relation */
relname = get_rel_name(relid);
/* See notes above */
if (relname == NULL)
PG_RETURN_NULL();
}
else
relname = NULL;
PG_RETURN_TEXT_P(string_to_text(pg_get_expr_worker(expr, relid, relname, prettyFlags)));
PG_RETURN_TEXT_P(pg_get_expr_worker(expr, relid, relname, prettyFlags));
}
static char *
pg_get_expr_worker(text *expr, Oid relid, char *relname, int prettyFlags)
static text *
pg_get_expr_worker(text *expr, Oid relid, const char *relname, int prettyFlags)
{
Node *node;
List *context;
@ -1249,14 +1268,19 @@ pg_get_expr_worker(text *expr, Oid relid, char *relname, int prettyFlags)
/* Convert expression to node tree */
node = (Node *) stringToNode(exprstr);
pfree(exprstr);
/* Prepare deparse context if needed */
if (OidIsValid(relid))
context = deparse_context_for(relname, relid);
else
context = NIL;
/* Deparse */
context = deparse_context_for(relname, relid);
str = deparse_expression_pretty(node, context, false, false,
prettyFlags, 0);
pfree(exprstr);
return str;
return string_to_text(str);
}

View File

@ -12,7 +12,7 @@
* by PostgreSQL
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.536 2009/05/21 01:08:43 petere Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.537 2009/05/26 17:36:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -6186,13 +6186,14 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
"typanalyze::pg_catalog.oid AS typanalyzeoid, "
"typcategory, typispreferred, "
"typdelim, typbyval, typalign, typstorage, "
"pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, typdefault "
"pg_catalog.pg_get_expr(typdefaultbin, 0) AS typdefaultbin, typdefault "
"FROM pg_catalog.pg_type "
"WHERE oid = '%u'::pg_catalog.oid",
tinfo->dobj.catId.oid);
}
else if (fout->remoteVersion >= 80300)
{
/* Before 8.4, pg_get_expr does not allow 0 for its second arg */
appendPQExpBuffer(query, "SELECT typlen, "
"typinput, typoutput, typreceive, typsend, "
"typmodin, typmodout, typanalyze, "