Commit 4a0c3a61 authored by Tom Lane's avatar Tom Lane

Department of second thoughts: suppressing implicit casts everywhere in

ruleutils display is not such a great idea.  For arguments of functions
and operators I think we'd better keep the historical behavior of showing
such casts explicitly, to ensure that the function/operator is reparsed
the same way when the rule is reloaded.  This also makes the output of
EXPLAIN less obscurantist about exactly what's happening.
parent b26dfb95
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.227 2002/09/18 21:35:20 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.228 2002/09/19 22:48:33 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -1179,7 +1179,7 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin) ...@@ -1179,7 +1179,7 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin)
adsrc = deparse_expression(expr, adsrc = deparse_expression(expr,
deparse_context_for(RelationGetRelationName(rel), deparse_context_for(RelationGetRelationName(rel),
RelationGetRelid(rel)), RelationGetRelid(rel)),
false); false, false);
/* /*
* Make the pg_attrdef entry. * Make the pg_attrdef entry.
...@@ -1277,7 +1277,7 @@ StoreRelCheck(Relation rel, char *ccname, char *ccbin) ...@@ -1277,7 +1277,7 @@ StoreRelCheck(Relation rel, char *ccname, char *ccbin)
ccsrc = deparse_expression(expr, ccsrc = deparse_expression(expr,
deparse_context_for(RelationGetRelationName(rel), deparse_context_for(RelationGetRelationName(rel),
RelationGetRelid(rel)), RelationGetRelid(rel)),
false); false, false);
/* /*
* Find columns of rel that are used in ccbin * Find columns of rel that are used in ccbin
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994-5, Regents of the University of California * Portions Copyright (c) 1994-5, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.87 2002/09/04 20:31:15 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.88 2002/09/19 22:48:33 tgl Exp $
* *
*/ */
...@@ -682,7 +682,7 @@ show_scan_qual(List *qual, bool is_or_qual, const char *qlabel, ...@@ -682,7 +682,7 @@ show_scan_qual(List *qual, bool is_or_qual, const char *qlabel,
NIL); NIL);
/* Deparse the expression */ /* Deparse the expression */
exprstr = deparse_expression(node, context, (outercontext != NULL)); exprstr = deparse_expression(node, context, (outercontext != NULL), false);
/* And add to str */ /* And add to str */
for (i = 0; i < indent; i++) for (i = 0; i < indent; i++)
...@@ -729,7 +729,7 @@ show_upper_qual(List *qual, const char *qlabel, ...@@ -729,7 +729,7 @@ show_upper_qual(List *qual, const char *qlabel,
/* Deparse the expression */ /* Deparse the expression */
node = (Node *) make_ands_explicit(qual); node = (Node *) make_ands_explicit(qual);
exprstr = deparse_expression(node, context, (inner_plan != NULL)); exprstr = deparse_expression(node, context, (inner_plan != NULL), false);
/* And add to str */ /* And add to str */
for (i = 0; i < indent; i++) for (i = 0; i < indent; i++)
...@@ -795,8 +795,9 @@ show_sort_keys(List *tlist, int nkeys, const char *qlabel, ...@@ -795,8 +795,9 @@ show_sort_keys(List *tlist, int nkeys, const char *qlabel,
if (target->resdom->reskey == keyno) if (target->resdom->reskey == keyno)
{ {
/* Deparse the expression */ /* Deparse the expression, showing any top-level cast */
exprstr = deparse_expression(target->expr, context, useprefix); exprstr = deparse_expression(target->expr, context,
useprefix, true);
/* And add to str */ /* And add to str */
if (keyno > 1) if (keyno > 1)
appendStringInfo(str, ", "); appendStringInfo(str, ", ");
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.13 2002/09/04 20:31:16 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.14 2002/09/19 22:48:33 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
...@@ -514,7 +514,7 @@ DefineDomain(CreateDomainStmt *stmt) ...@@ -514,7 +514,7 @@ DefineDomain(CreateDomainStmt *stmt)
defaultValue = deparse_expression(defaultExpr, defaultValue = deparse_expression(defaultExpr,
deparse_context_for(domainName, deparse_context_for(domainName,
InvalidOid), InvalidOid),
false); false, false);
defaultValueBin = nodeToString(defaultExpr); defaultValueBin = nodeToString(defaultExpr);
break; break;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* back to source text * back to source text
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.122 2002/09/18 21:35:23 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.123 2002/09/19 22:48:33 tgl Exp $
* *
* This software is copyrighted by Jan Wieck - Hamburg. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -147,9 +147,11 @@ static void get_names_for_var(Var *var, deparse_context *context, ...@@ -147,9 +147,11 @@ static void get_names_for_var(Var *var, deparse_context *context,
char **schemaname, char **refname, char **attname); char **schemaname, char **refname, char **attname);
static RangeTblEntry *find_rte_by_refname(const char *refname, static RangeTblEntry *find_rte_by_refname(const char *refname,
deparse_context *context); deparse_context *context);
static void get_rule_expr(Node *node, deparse_context *context); static void get_rule_expr(Node *node, deparse_context *context,
bool showimplicit);
static void get_oper_expr(Expr *expr, deparse_context *context); static void get_oper_expr(Expr *expr, deparse_context *context);
static void get_func_expr(Expr *expr, deparse_context *context); static void get_func_expr(Expr *expr, deparse_context *context,
bool showimplicit);
static void get_agg_expr(Aggref *aggref, deparse_context *context); static void get_agg_expr(Aggref *aggref, deparse_context *context);
static Node *strip_type_coercion(Node *expr, Oid resultType); static Node *strip_type_coercion(Node *expr, Oid resultType);
static void get_const_expr(Const *constval, deparse_context *context); static void get_const_expr(Const *constval, deparse_context *context);
...@@ -515,7 +517,7 @@ pg_get_indexdef(PG_FUNCTION_ARGS) ...@@ -515,7 +517,7 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
node = (Node *) make_ands_explicit((List *) node); node = (Node *) make_ands_explicit((List *) node);
/* Deparse */ /* Deparse */
context = deparse_context_for(get_rel_name(indrelid), indrelid); context = deparse_context_for(get_rel_name(indrelid), indrelid);
str = deparse_expression(node, context, false); str = deparse_expression(node, context, false, false);
appendStringInfo(&buf, " WHERE %s", str); appendStringInfo(&buf, " WHERE %s", str);
} }
...@@ -792,7 +794,7 @@ pg_get_expr(PG_FUNCTION_ARGS) ...@@ -792,7 +794,7 @@ pg_get_expr(PG_FUNCTION_ARGS)
/* Deparse */ /* Deparse */
context = deparse_context_for(relname, relid); context = deparse_context_for(relname, relid);
str = deparse_expression(node, context, false); str = deparse_expression(node, context, false, false);
/* Pass the result back as TEXT */ /* Pass the result back as TEXT */
result = DatumGetTextP(DirectFunctionCall1(textin, result = DatumGetTextP(DirectFunctionCall1(textin,
...@@ -850,11 +852,14 @@ pg_get_userbyid(PG_FUNCTION_ARGS) ...@@ -850,11 +852,14 @@ pg_get_userbyid(PG_FUNCTION_ARGS)
* *
* forceprefix is TRUE to force all Vars to be prefixed with their table names. * forceprefix is TRUE to force all Vars to be prefixed with their table names.
* *
* showimplicit is TRUE to force all implicit casts to be shown explicitly.
*
* The result is a palloc'd string. * The result is a palloc'd string.
* ---------- * ----------
*/ */
char * char *
deparse_expression(Node *expr, List *dpcontext, bool forceprefix) deparse_expression(Node *expr, List *dpcontext,
bool forceprefix, bool showimplicit)
{ {
StringInfoData buf; StringInfoData buf;
deparse_context context; deparse_context context;
...@@ -864,7 +869,7 @@ deparse_expression(Node *expr, List *dpcontext, bool forceprefix) ...@@ -864,7 +869,7 @@ deparse_expression(Node *expr, List *dpcontext, bool forceprefix)
context.namespaces = dpcontext; context.namespaces = dpcontext;
context.varprefix = forceprefix; context.varprefix = forceprefix;
get_rule_expr(expr, &context); get_rule_expr(expr, &context, showimplicit);
return buf.data; return buf.data;
} }
...@@ -1139,7 +1144,7 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc) ...@@ -1139,7 +1144,7 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc)
dpns.outer_varno = dpns.inner_varno = 0; dpns.outer_varno = dpns.inner_varno = 0;
dpns.outer_rte = dpns.inner_rte = NULL; dpns.outer_rte = dpns.inner_rte = NULL;
get_rule_expr(qual, &context); get_rule_expr(qual, &context, false);
} }
appendStringInfo(buf, " DO "); appendStringInfo(buf, " DO ");
...@@ -1364,7 +1369,7 @@ get_select_query_def(Query *query, deparse_context *context, ...@@ -1364,7 +1369,7 @@ get_select_query_def(Query *query, deparse_context *context,
if (query->limitOffset != NULL) if (query->limitOffset != NULL)
{ {
appendStringInfo(buf, " OFFSET "); appendStringInfo(buf, " OFFSET ");
get_rule_expr(query->limitOffset, context); get_rule_expr(query->limitOffset, context, false);
} }
if (query->limitCount != NULL) if (query->limitCount != NULL)
{ {
...@@ -1373,7 +1378,7 @@ get_select_query_def(Query *query, deparse_context *context, ...@@ -1373,7 +1378,7 @@ get_select_query_def(Query *query, deparse_context *context,
((Const *) query->limitCount)->constisnull) ((Const *) query->limitCount)->constisnull)
appendStringInfo(buf, "ALL"); appendStringInfo(buf, "ALL");
else else
get_rule_expr(query->limitCount, context); get_rule_expr(query->limitCount, context, false);
} }
} }
...@@ -1429,7 +1434,7 @@ get_basic_select_query(Query *query, deparse_context *context, ...@@ -1429,7 +1434,7 @@ get_basic_select_query(Query *query, deparse_context *context,
sep = ", "; sep = ", ";
colno++; colno++;
get_rule_expr(tle->expr, context); get_rule_expr(tle->expr, context, true);
/* /*
* Figure out what the result column should be called. In the * Figure out what the result column should be called. In the
...@@ -1469,7 +1474,7 @@ get_basic_select_query(Query *query, deparse_context *context, ...@@ -1469,7 +1474,7 @@ get_basic_select_query(Query *query, deparse_context *context,
if (query->jointree->quals != NULL) if (query->jointree->quals != NULL)
{ {
appendStringInfo(buf, " WHERE "); appendStringInfo(buf, " WHERE ");
get_rule_expr(query->jointree->quals, context); get_rule_expr(query->jointree->quals, context, false);
} }
/* Add the GROUP BY clause if given */ /* Add the GROUP BY clause if given */
...@@ -1492,7 +1497,7 @@ get_basic_select_query(Query *query, deparse_context *context, ...@@ -1492,7 +1497,7 @@ get_basic_select_query(Query *query, deparse_context *context,
if (query->havingQual != NULL) if (query->havingQual != NULL)
{ {
appendStringInfo(buf, " HAVING "); appendStringInfo(buf, " HAVING ");
get_rule_expr(query->havingQual, context); get_rule_expr(query->havingQual, context, false);
} }
} }
...@@ -1573,7 +1578,7 @@ get_rule_sortgroupclause(SortClause *srt, List *tlist, bool force_colno, ...@@ -1573,7 +1578,7 @@ get_rule_sortgroupclause(SortClause *srt, List *tlist, bool force_colno,
appendStringInfo(buf, "%d", tle->resdom->resno); appendStringInfo(buf, "%d", tle->resdom->resno);
} }
else else
get_rule_expr(expr, context); get_rule_expr(expr, context, true);
return expr; return expr;
} }
...@@ -1642,7 +1647,7 @@ get_insert_query_def(Query *query, deparse_context *context) ...@@ -1642,7 +1647,7 @@ get_insert_query_def(Query *query, deparse_context *context)
appendStringInfo(buf, sep); appendStringInfo(buf, sep);
sep = ", "; sep = ", ";
get_rule_expr(tle->expr, context); get_rule_expr(tle->expr, context, false);
} }
appendStringInfoChar(buf, ')'); appendStringInfoChar(buf, ')');
} }
...@@ -1692,7 +1697,7 @@ get_update_query_def(Query *query, deparse_context *context) ...@@ -1692,7 +1697,7 @@ get_update_query_def(Query *query, deparse_context *context)
if (!tleIsArrayAssign(tle)) if (!tleIsArrayAssign(tle))
appendStringInfo(buf, "%s = ", appendStringInfo(buf, "%s = ",
quote_identifier(tle->resdom->resname)); quote_identifier(tle->resdom->resname));
get_rule_expr(tle->expr, context); get_rule_expr(tle->expr, context, false);
} }
/* Add the FROM clause if needed */ /* Add the FROM clause if needed */
...@@ -1702,7 +1707,7 @@ get_update_query_def(Query *query, deparse_context *context) ...@@ -1702,7 +1707,7 @@ get_update_query_def(Query *query, deparse_context *context)
if (query->jointree->quals != NULL) if (query->jointree->quals != NULL)
{ {
appendStringInfo(buf, " WHERE "); appendStringInfo(buf, " WHERE ");
get_rule_expr(query->jointree->quals, context); get_rule_expr(query->jointree->quals, context, false);
} }
} }
...@@ -1730,7 +1735,7 @@ get_delete_query_def(Query *query, deparse_context *context) ...@@ -1730,7 +1735,7 @@ get_delete_query_def(Query *query, deparse_context *context)
if (query->jointree->quals != NULL) if (query->jointree->quals != NULL)
{ {
appendStringInfo(buf, " WHERE "); appendStringInfo(buf, " WHERE ");
get_rule_expr(query->jointree->quals, context); get_rule_expr(query->jointree->quals, context, false);
} }
} }
...@@ -1890,10 +1895,20 @@ find_rte_by_refname(const char *refname, deparse_context *context) ...@@ -1890,10 +1895,20 @@ find_rte_by_refname(const char *refname, deparse_context *context)
/* ---------- /* ----------
* get_rule_expr - Parse back an expression * get_rule_expr - Parse back an expression
*
* Note: showimplicit determines whether we display any implicit cast that
* is present at the top of the expression tree. It is a passed argument,
* not a field of the context struct, because we change the value as we
* recurse down into the expression. In general we suppress implicit casts
* when the result type is known with certainty (eg, the arguments of an
* OR must be boolean). We display implicit casts for arguments of functions
* and operators, since this is needed to be certain that the same function
* or operator will be chosen when the expression is re-parsed.
* ---------- * ----------
*/ */
static void static void
get_rule_expr(Node *node, deparse_context *context) get_rule_expr(Node *node, deparse_context *context,
bool showimplicit)
{ {
StringInfo buf = context->buf; StringInfo buf = context->buf;
...@@ -1966,42 +1981,44 @@ get_rule_expr(Node *node, deparse_context *context) ...@@ -1966,42 +1981,44 @@ get_rule_expr(Node *node, deparse_context *context)
Node *arg1 = (Node *) lfirst(args); Node *arg1 = (Node *) lfirst(args);
Node *arg2 = (Node *) lsecond(args); Node *arg2 = (Node *) lsecond(args);
get_rule_expr(arg1, context); get_rule_expr(arg1, context, true);
appendStringInfo(buf, " IS DISTINCT FROM "); appendStringInfo(buf, " IS DISTINCT FROM ");
get_rule_expr(arg2, context); get_rule_expr(arg2, context, true);
} }
appendStringInfoChar(buf, ')'); appendStringInfoChar(buf, ')');
break; break;
case FUNC_EXPR: case FUNC_EXPR:
get_func_expr(expr, context); get_func_expr(expr, context, showimplicit);
break; break;
case OR_EXPR: case OR_EXPR:
appendStringInfoChar(buf, '('); appendStringInfoChar(buf, '(');
get_rule_expr((Node *) lfirst(args), context); get_rule_expr((Node *) lfirst(args), context, false);
while ((args = lnext(args)) != NIL) while ((args = lnext(args)) != NIL)
{ {
appendStringInfo(buf, " OR "); appendStringInfo(buf, " OR ");
get_rule_expr((Node *) lfirst(args), context); get_rule_expr((Node *) lfirst(args), context,
false);
} }
appendStringInfoChar(buf, ')'); appendStringInfoChar(buf, ')');
break; break;
case AND_EXPR: case AND_EXPR:
appendStringInfoChar(buf, '('); appendStringInfoChar(buf, '(');
get_rule_expr((Node *) lfirst(args), context); get_rule_expr((Node *) lfirst(args), context, false);
while ((args = lnext(args)) != NIL) while ((args = lnext(args)) != NIL)
{ {
appendStringInfo(buf, " AND "); appendStringInfo(buf, " AND ");
get_rule_expr((Node *) lfirst(args), context); get_rule_expr((Node *) lfirst(args), context,
false);
} }
appendStringInfoChar(buf, ')'); appendStringInfoChar(buf, ')');
break; break;
case NOT_EXPR: case NOT_EXPR:
appendStringInfo(buf, "(NOT "); appendStringInfo(buf, "(NOT ");
get_rule_expr((Node *) lfirst(args), context); get_rule_expr((Node *) lfirst(args), context, false);
appendStringInfoChar(buf, ')'); appendStringInfoChar(buf, ')');
break; break;
...@@ -2042,7 +2059,7 @@ get_rule_expr(Node *node, deparse_context *context) ...@@ -2042,7 +2059,7 @@ get_rule_expr(Node *node, deparse_context *context)
*/ */
if (aref->refassgnexpr) if (aref->refassgnexpr)
context->varprefix = false; context->varprefix = false;
get_rule_expr(aref->refexpr, context); get_rule_expr(aref->refexpr, context, showimplicit);
context->varprefix = savevarprefix; context->varprefix = savevarprefix;
lowlist = aref->reflowerindexpr; lowlist = aref->reflowerindexpr;
foreach(uplist, aref->refupperindexpr) foreach(uplist, aref->refupperindexpr)
...@@ -2050,17 +2067,18 @@ get_rule_expr(Node *node, deparse_context *context) ...@@ -2050,17 +2067,18 @@ get_rule_expr(Node *node, deparse_context *context)
appendStringInfo(buf, "["); appendStringInfo(buf, "[");
if (lowlist) if (lowlist)
{ {
get_rule_expr((Node *) lfirst(lowlist), context); get_rule_expr((Node *) lfirst(lowlist), context,
false);
appendStringInfo(buf, ":"); appendStringInfo(buf, ":");
lowlist = lnext(lowlist); lowlist = lnext(lowlist);
} }
get_rule_expr((Node *) lfirst(uplist), context); get_rule_expr((Node *) lfirst(uplist), context, false);
appendStringInfo(buf, "]"); appendStringInfo(buf, "]");
} }
if (aref->refassgnexpr) if (aref->refassgnexpr)
{ {
appendStringInfo(buf, " = "); appendStringInfo(buf, " = ");
get_rule_expr(aref->refassgnexpr, context); get_rule_expr(aref->refassgnexpr, context, showimplicit);
} }
} }
break; break;
...@@ -2096,7 +2114,7 @@ get_rule_expr(Node *node, deparse_context *context) ...@@ -2096,7 +2114,7 @@ get_rule_expr(Node *node, deparse_context *context)
* are *not* simple. So, always use parenthesized syntax. * are *not* simple. So, always use parenthesized syntax.
*/ */
appendStringInfoChar(buf, '('); appendStringInfoChar(buf, '(');
get_rule_expr(fselect->arg, context); get_rule_expr(fselect->arg, context, true);
appendStringInfo(buf, ").%s", quote_identifier(fieldname)); appendStringInfo(buf, ").%s", quote_identifier(fieldname));
} }
break; break;
...@@ -2106,10 +2124,11 @@ get_rule_expr(Node *node, deparse_context *context) ...@@ -2106,10 +2124,11 @@ get_rule_expr(Node *node, deparse_context *context)
RelabelType *relabel = (RelabelType *) node; RelabelType *relabel = (RelabelType *) node;
Node *arg = relabel->arg; Node *arg = relabel->arg;
if (relabel->relabelformat == COERCE_IMPLICIT_CAST) if (relabel->relabelformat == COERCE_IMPLICIT_CAST &&
!showimplicit)
{ {
/* don't show an implicit cast */ /* don't show the implicit cast */
get_rule_expr(arg, context); get_rule_expr(arg, context, showimplicit);
} }
else else
{ {
...@@ -2122,7 +2141,7 @@ get_rule_expr(Node *node, deparse_context *context) ...@@ -2122,7 +2141,7 @@ get_rule_expr(Node *node, deparse_context *context)
arg = strip_type_coercion(arg, relabel->resulttype); arg = strip_type_coercion(arg, relabel->resulttype);
appendStringInfoChar(buf, '('); appendStringInfoChar(buf, '(');
get_rule_expr(arg, context); get_rule_expr(arg, context, showimplicit);
appendStringInfo(buf, ")::%s", appendStringInfo(buf, ")::%s",
format_type_with_typemod(relabel->resulttype, format_type_with_typemod(relabel->resulttype,
relabel->resulttypmod)); relabel->resulttypmod));
...@@ -2141,12 +2160,12 @@ get_rule_expr(Node *node, deparse_context *context) ...@@ -2141,12 +2160,12 @@ get_rule_expr(Node *node, deparse_context *context)
CaseWhen *when = (CaseWhen *) lfirst(temp); CaseWhen *when = (CaseWhen *) lfirst(temp);
appendStringInfo(buf, " WHEN "); appendStringInfo(buf, " WHEN ");
get_rule_expr(when->expr, context); get_rule_expr(when->expr, context, false);
appendStringInfo(buf, " THEN "); appendStringInfo(buf, " THEN ");
get_rule_expr(when->result, context); get_rule_expr(when->result, context, true);
} }
appendStringInfo(buf, " ELSE "); appendStringInfo(buf, " ELSE ");
get_rule_expr(caseexpr->defresult, context); get_rule_expr(caseexpr->defresult, context, true);
appendStringInfo(buf, " END"); appendStringInfo(buf, " END");
} }
break; break;
...@@ -2156,7 +2175,7 @@ get_rule_expr(Node *node, deparse_context *context) ...@@ -2156,7 +2175,7 @@ get_rule_expr(Node *node, deparse_context *context)
NullTest *ntest = (NullTest *) node; NullTest *ntest = (NullTest *) node;
appendStringInfo(buf, "("); appendStringInfo(buf, "(");
get_rule_expr(ntest->arg, context); get_rule_expr(ntest->arg, context, true);
switch (ntest->nulltesttype) switch (ntest->nulltesttype)
{ {
case IS_NULL: case IS_NULL:
...@@ -2177,7 +2196,7 @@ get_rule_expr(Node *node, deparse_context *context) ...@@ -2177,7 +2196,7 @@ get_rule_expr(Node *node, deparse_context *context)
BooleanTest *btest = (BooleanTest *) node; BooleanTest *btest = (BooleanTest *) node;
appendStringInfo(buf, "("); appendStringInfo(buf, "(");
get_rule_expr(btest->arg, context); get_rule_expr(btest->arg, context, false);
switch (btest->booltesttype) switch (btest->booltesttype)
{ {
case IS_TRUE: case IS_TRUE:
...@@ -2213,7 +2232,7 @@ get_rule_expr(Node *node, deparse_context *context) ...@@ -2213,7 +2232,7 @@ get_rule_expr(Node *node, deparse_context *context)
* We assume that the operations of the constraint node * We assume that the operations of the constraint node
* need not be explicitly represented in the output. * need not be explicitly represented in the output.
*/ */
get_rule_expr(ctest->arg, context); get_rule_expr(ctest->arg, context, showimplicit);
} }
break; break;
...@@ -2267,12 +2286,12 @@ get_oper_expr(Expr *expr, deparse_context *context) ...@@ -2267,12 +2286,12 @@ get_oper_expr(Expr *expr, deparse_context *context)
Node *arg1 = (Node *) lfirst(args); Node *arg1 = (Node *) lfirst(args);
Node *arg2 = (Node *) lsecond(args); Node *arg2 = (Node *) lsecond(args);
get_rule_expr(arg1, context); get_rule_expr(arg1, context, true);
appendStringInfo(buf, " %s ", appendStringInfo(buf, " %s ",
generate_operator_name(opno, generate_operator_name(opno,
exprType(arg1), exprType(arg1),
exprType(arg2))); exprType(arg2)));
get_rule_expr(arg2, context); get_rule_expr(arg2, context, true);
} }
else else
{ {
...@@ -2294,10 +2313,10 @@ get_oper_expr(Expr *expr, deparse_context *context) ...@@ -2294,10 +2313,10 @@ get_oper_expr(Expr *expr, deparse_context *context)
generate_operator_name(opno, generate_operator_name(opno,
InvalidOid, InvalidOid,
exprType(arg))); exprType(arg)));
get_rule_expr(arg, context); get_rule_expr(arg, context, true);
break; break;
case 'r': case 'r':
get_rule_expr(arg, context); get_rule_expr(arg, context, true);
appendStringInfo(buf, " %s", appendStringInfo(buf, " %s",
generate_operator_name(opno, generate_operator_name(opno,
exprType(arg), exprType(arg),
...@@ -2315,7 +2334,8 @@ get_oper_expr(Expr *expr, deparse_context *context) ...@@ -2315,7 +2334,8 @@ get_oper_expr(Expr *expr, deparse_context *context)
* get_func_expr - Parse back a Func node * get_func_expr - Parse back a Func node
*/ */
static void static void
get_func_expr(Expr *expr, deparse_context *context) get_func_expr(Expr *expr, deparse_context *context,
bool showimplicit)
{ {
StringInfo buf = context->buf; StringInfo buf = context->buf;
Func *func = (Func *) (expr->oper); Func *func = (Func *) (expr->oper);
...@@ -2327,19 +2347,20 @@ get_func_expr(Expr *expr, deparse_context *context) ...@@ -2327,19 +2347,20 @@ get_func_expr(Expr *expr, deparse_context *context)
/* /*
* If the function call came from an implicit coercion, then just show * If the function call came from an implicit coercion, then just show
* the first argument. * the first argument --- unless caller wants to see implicit coercions.
*/ */
if (func->funcformat == COERCE_IMPLICIT_CAST) if (func->funcformat == COERCE_IMPLICIT_CAST && !showimplicit)
{ {
get_rule_expr((Node *) lfirst(expr->args), context); get_rule_expr((Node *) lfirst(expr->args), context, showimplicit);
return; return;
} }
/* /*
* If the function call came from an explicit cast, then show * If the function call came from a cast, then show
* the first argument plus an explicit cast operation. * the first argument plus an explicit cast operation.
*/ */
if (func->funcformat == COERCE_EXPLICIT_CAST) if (func->funcformat == COERCE_EXPLICIT_CAST ||
func->funcformat == COERCE_IMPLICIT_CAST)
{ {
Node *arg = lfirst(expr->args); Node *arg = lfirst(expr->args);
Oid rettype = expr->typeOid; Oid rettype = expr->typeOid;
...@@ -2357,7 +2378,7 @@ get_func_expr(Expr *expr, deparse_context *context) ...@@ -2357,7 +2378,7 @@ get_func_expr(Expr *expr, deparse_context *context)
arg = strip_type_coercion(arg, rettype); arg = strip_type_coercion(arg, rettype);
appendStringInfoChar(buf, '('); appendStringInfoChar(buf, '(');
get_rule_expr(arg, context); get_rule_expr(arg, context, showimplicit);
appendStringInfo(buf, ")::%s", appendStringInfo(buf, ")::%s",
format_type_with_typemod(rettype, coercedTypmod)); format_type_with_typemod(rettype, coercedTypmod));
...@@ -2384,7 +2405,7 @@ get_func_expr(Expr *expr, deparse_context *context) ...@@ -2384,7 +2405,7 @@ get_func_expr(Expr *expr, deparse_context *context)
{ {
appendStringInfo(buf, sep); appendStringInfo(buf, sep);
sep = ", "; sep = ", ";
get_rule_expr((Node *) lfirst(l), context); get_rule_expr((Node *) lfirst(l), context, true);
} }
appendStringInfoChar(buf, ')'); appendStringInfoChar(buf, ')');
} }
...@@ -2404,7 +2425,7 @@ get_agg_expr(Aggref *aggref, deparse_context *context) ...@@ -2404,7 +2425,7 @@ get_agg_expr(Aggref *aggref, deparse_context *context)
if (aggref->aggstar) if (aggref->aggstar)
appendStringInfo(buf, "*"); appendStringInfo(buf, "*");
else else
get_rule_expr(aggref->target, context); get_rule_expr(aggref->target, context, true);
appendStringInfoChar(buf, ')'); appendStringInfoChar(buf, ')');
} }
...@@ -2618,7 +2639,7 @@ get_sublink_expr(Node *node, deparse_context *context) ...@@ -2618,7 +2639,7 @@ get_sublink_expr(Node *node, deparse_context *context)
{ {
appendStringInfo(buf, sep); appendStringInfo(buf, sep);
sep = ", "; sep = ", ";
get_rule_expr((Node *) lfirst(l), context); get_rule_expr((Node *) lfirst(l), context, true);
} }
if (need_paren) if (need_paren)
...@@ -2750,7 +2771,7 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context) ...@@ -2750,7 +2771,7 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
break; break;
case RTE_FUNCTION: case RTE_FUNCTION:
/* Function RTE */ /* Function RTE */
get_rule_expr(rte->funcexpr, context); get_rule_expr(rte->funcexpr, context, true);
/* might need to emit column list for RECORD function */ /* might need to emit column list for RECORD function */
coldeflist = rte->coldeflist; coldeflist = rte->coldeflist;
break; break;
...@@ -2850,7 +2871,7 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context) ...@@ -2850,7 +2871,7 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
else if (j->quals) else if (j->quals)
{ {
appendStringInfo(buf, " ON ("); appendStringInfo(buf, " ON (");
get_rule_expr(j->quals, context); get_rule_expr(j->quals, context, false);
appendStringInfoChar(buf, ')'); appendStringInfoChar(buf, ')');
} }
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: builtins.h,v 1.200 2002/09/18 21:35:24 tgl Exp $ * $Id: builtins.h,v 1.201 2002/09/19 22:48:34 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -398,7 +398,7 @@ extern Datum pg_get_constraintdef(PG_FUNCTION_ARGS); ...@@ -398,7 +398,7 @@ extern Datum pg_get_constraintdef(PG_FUNCTION_ARGS);
extern Datum pg_get_userbyid(PG_FUNCTION_ARGS); extern Datum pg_get_userbyid(PG_FUNCTION_ARGS);
extern Datum pg_get_expr(PG_FUNCTION_ARGS); extern Datum pg_get_expr(PG_FUNCTION_ARGS);
extern char *deparse_expression(Node *expr, List *dpcontext, extern char *deparse_expression(Node *expr, List *dpcontext,
bool forceprefix); bool forceprefix, bool showimplicit);
extern List *deparse_context_for(const char *aliasname, Oid relid); extern List *deparse_context_for(const char *aliasname, Oid relid);
extern List *deparse_context_for_plan(int outer_varno, Node *outercontext, extern List *deparse_context_for_plan(int outer_varno, Node *outercontext,
int inner_varno, Node *innercontext, int inner_varno, Node *innercontext,
......
...@@ -1271,7 +1271,7 @@ SELECT viewname, definition FROM pg_views ORDER BY viewname; ...@@ -1271,7 +1271,7 @@ SELECT viewname, definition FROM pg_views ORDER BY viewname;
pg_locks | SELECT l.relation, l."database", l."transaction", l.pid, l."mode", l.granted FROM pg_lock_status() l(relation oid, "database" oid, "transaction" xid, pid integer, "mode" text, granted boolean); pg_locks | SELECT l.relation, l."database", l."transaction", l.pid, l."mode", l.granted FROM pg_lock_status() l(relation oid, "database" oid, "transaction" xid, pid integer, "mode" text, granted boolean);
pg_rules | SELECT n.nspname AS schemaname, c.relname AS tablename, r.rulename, pg_get_ruledef(r.oid) AS definition FROM ((pg_rewrite r JOIN pg_class c ON ((c.oid = r.ev_class))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (r.rulename <> '_RETURN'::name); pg_rules | SELECT n.nspname AS schemaname, c.relname AS tablename, r.rulename, pg_get_ruledef(r.oid) AS definition FROM ((pg_rewrite r JOIN pg_class c ON ((c.oid = r.ev_class))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (r.rulename <> '_RETURN'::name);
pg_settings | SELECT a.name, a.setting FROM pg_show_all_settings() a(name text, setting text); pg_settings | SELECT a.name, a.setting FROM pg_show_all_settings() a(name text, setting text);
pg_stat_activity | SELECT d.oid AS datid, d.datname, pg_stat_get_backend_pid(s.backendid) AS procpid, pg_stat_get_backend_userid(s.backendid) AS usesysid, u.usename, pg_stat_get_backend_activity(s.backendid) AS current_query FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_shadow u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = u.usesysid)); pg_stat_activity | SELECT d.oid AS datid, d.datname, pg_stat_get_backend_pid(s.backendid) AS procpid, pg_stat_get_backend_userid(s.backendid) AS usesysid, u.usename, pg_stat_get_backend_activity(s.backendid) AS current_query FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_shadow u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = (u.usesysid)::oid));
pg_stat_all_indexes | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, pg_stat_get_numscans(i.oid) AS idx_scan, pg_stat_get_tuples_returned(i.oid) AS idx_tup_read, pg_stat_get_tuples_fetched(i.oid) AS idx_tup_fetch FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char"); pg_stat_all_indexes | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, pg_stat_get_numscans(i.oid) AS idx_scan, pg_stat_get_tuples_returned(i.oid) AS idx_tup_read, pg_stat_get_tuples_fetched(i.oid) AS idx_tup_fetch FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char");
pg_stat_all_tables | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, sum(pg_stat_get_numscans(i.indexrelid)) AS idx_scan, sum(pg_stat_get_tuples_fetched(i.indexrelid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del FROM ((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char") GROUP BY c.oid, n.nspname, c.relname; pg_stat_all_tables | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, sum(pg_stat_get_numscans(i.indexrelid)) AS idx_scan, sum(pg_stat_get_tuples_fetched(i.indexrelid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del FROM ((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char") GROUP BY c.oid, n.nspname, c.relname;
pg_stat_database | SELECT d.oid AS datid, d.datname, pg_stat_get_db_numbackends(d.oid) AS numbackends, pg_stat_get_db_xact_commit(d.oid) AS xact_commit, pg_stat_get_db_xact_rollback(d.oid) AS xact_rollback, (pg_stat_get_db_blocks_fetched(d.oid) - pg_stat_get_db_blocks_hit(d.oid)) AS blks_read, pg_stat_get_db_blocks_hit(d.oid) AS blks_hit FROM pg_database d; pg_stat_database | SELECT d.oid AS datid, d.datname, pg_stat_get_db_numbackends(d.oid) AS numbackends, pg_stat_get_db_xact_commit(d.oid) AS xact_commit, pg_stat_get_db_xact_rollback(d.oid) AS xact_rollback, (pg_stat_get_db_blocks_fetched(d.oid) - pg_stat_get_db_blocks_hit(d.oid)) AS blks_read, pg_stat_get_db_blocks_hit(d.oid) AS blks_hit FROM pg_database d;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment