]> granicus.if.org Git - postgresql/commitdiff
Constant expressions that appear in ORDER BY, GROUP BY, DISTINCT ON
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 15 Apr 2001 03:14:18 +0000 (03:14 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 15 Apr 2001 03:14:18 +0000 (03:14 +0000)
lists should be reverse-compiled into targetlist index numbers, because
that's the only interpretation the parser allows for a constant in these
clauses.  (Ergo, the only way they could have gotten into the list in
the first place is to have come from the targetlist; so this should always
work.)  Per problem report from Peter E.

src/backend/utils/adt/ruleutils.c

index b9aab50f62848bea02ef48119f69279bc49e53c3..474ebdfec745102abc6ef83aa32b347749c633cc 100644 (file)
@@ -3,7 +3,7 @@
  *                             back to source text
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.75 2001/03/22 06:16:18 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.76 2001/04/15 03:14:18 tgl Exp $
  *
  *       This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -120,6 +120,9 @@ static void get_basic_select_query(Query *query, deparse_context *context);
 static void get_setop_query(Node *setOp, Query *query,
                                deparse_context *context, bool toplevel);
 static bool simple_distinct(List *distinctClause, List *targetList);
+static void get_rule_sortgroupclause(SortClause *srt, List *tlist,
+                                                                        bool force_colno,
+                                                                        deparse_context *context);
 static void get_names_for_var(Var *var, deparse_context *context,
                                  char **refname, char **attname);
 static bool get_alias_for_case(CaseExpr *caseexpr, deparse_context *context,
@@ -925,7 +928,7 @@ static void
 get_select_query_def(Query *query, deparse_context *context)
 {
        StringInfo      buf = context->buf;
-       bool            shortform_orderby;
+       bool            force_colno;
        char       *sep;
        List       *l;
 
@@ -938,12 +941,12 @@ get_select_query_def(Query *query, deparse_context *context)
        {
                get_setop_query(query->setOperations, query, context, true);
                /* ORDER BY clauses must be simple in this case */
-               shortform_orderby = true;
+               force_colno = true;
        }
        else
        {
                get_basic_select_query(query, context);
-               shortform_orderby = false;
+               force_colno = false;
        }
 
        /* Add the ORDER BY clause if given */
@@ -954,16 +957,11 @@ get_select_query_def(Query *query, deparse_context *context)
                foreach(l, query->sortClause)
                {
                        SortClause *srt = (SortClause *) lfirst(l);
-                       TargetEntry *sorttle;
                        char       *opname;
 
-                       sorttle = get_sortgroupclause_tle(srt,
-                                                                                         query->targetList);
                        appendStringInfo(buf, sep);
-                       if (shortform_orderby)
-                               appendStringInfo(buf, "%d", sorttle->resdom->resno);
-                       else
-                               get_rule_expr(sorttle->expr, context);
+                       get_rule_sortgroupclause(srt, query->targetList,
+                                                                        force_colno, context);
                        opname = get_opname(srt->sortop);
                        if (strcmp(opname, "<") != 0)
                        {
@@ -1017,12 +1015,10 @@ get_basic_select_query(Query *query, deparse_context *context)
                        foreach(l, query->distinctClause)
                        {
                                SortClause *srt = (SortClause *) lfirst(l);
-                               Node       *sortexpr;
 
-                               sortexpr = get_sortgroupclause_expr(srt,
-                                                                                                       query->targetList);
                                appendStringInfo(buf, sep);
-                               get_rule_expr(sortexpr, context);
+                               get_rule_sortgroupclause(srt, query->targetList,
+                                                                                false, context);
                                sep = ", ";
                        }
                        appendStringInfo(buf, ")");
@@ -1082,12 +1078,10 @@ get_basic_select_query(Query *query, deparse_context *context)
                foreach(l, query->groupClause)
                {
                        GroupClause *grp = (GroupClause *) lfirst(l);
-                       Node       *groupexpr;
 
-                       groupexpr = get_sortgroupclause_expr(grp,
-                                                                                                query->targetList);
                        appendStringInfo(buf, sep);
-                       get_rule_expr(groupexpr, context);
+                       get_rule_sortgroupclause(grp, query->targetList,
+                                                                        false, context);
                        sep = ", ";
                }
        }
@@ -1182,6 +1176,32 @@ simple_distinct(List *distinctClause, List *targetList)
        return true;
 }
 
+/*
+ * Display a sort/group clause.
+ */
+static void
+get_rule_sortgroupclause(SortClause *srt, List *tlist, bool force_colno,
+                                                deparse_context *context)
+{
+       StringInfo      buf = context->buf;
+       TargetEntry *tle;
+       Node       *expr;
+
+       tle = get_sortgroupclause_tle(srt, tlist);
+       expr = tle->expr;
+       /*
+        * Use column-number form if requested by caller or if expression is a
+        * constant --- a constant is ambiguous (and will be misinterpreted
+        * by findTargetlistEntry()) if we dump it explicitly.
+        */
+       if (force_colno || (expr && IsA(expr, Const)))
+       {
+               Assert(!tle->resdom->resjunk);
+               appendStringInfo(buf, "%d", tle->resdom->resno);
+       }
+       else
+               get_rule_expr(expr, context);
+}
 
 /* ----------
  * get_insert_query_def                        - Parse back an INSERT parsetree