]> granicus.if.org Git - postgresql/commitdiff
Allow the second argument of pg_get_expr() to be just zero when deparsing
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 26 May 2009 17:36:05 +0000 (17:36 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 26 May 2009 17:36:05 +0000 (17:36 +0000)
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.

doc/src/sgml/func.sgml
src/backend/utils/adt/ruleutils.c
src/bin/pg_dump/pg_dump.c

index faf0e30b157e5a591c6dc34719bf0f9f9ea66c1d..a594a12ed7b11a4b15685b667968344ed7c6feb2 100644 (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
index 8d06f54e479d46b32eae5ab7a471a498ca068a5a..8e031fd5027074de7aa8a8e77d4e61226f9df1e9 100644 (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);
 }
 
 
index 814c8228545607beb94b0069b0e12e62d8159a53..ccb54e5929daedf5581a0f8286633de5aa8bd478 100644 (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, "