~ubuntu-branches/ubuntu/natty/postgresql-8.4/natty-security

« back to all changes in this revision

Viewing changes to src/backend/parser/parse_clause.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-07-11 16:59:35 UTC
  • mfrom: (5.1.1 karmic)
  • Revision ID: james.westby@ubuntu.com-20090711165935-jfwin6gfrxf0gfsi
Tags: 8.4.0-2
* debian/libpq-dev.install: Ship catalog/genbki.h. (Closes: #536139)
* debian/rules: Drop --enable-cassert for final release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
 *
9
9
 *
10
10
 * IDENTIFICATION
11
 
 *        $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.188 2009/04/04 21:12:31 tgl Exp $
 
11
 *        $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.189 2009/06/11 14:49:00 momjian Exp $
12
12
 *
13
13
 *-------------------------------------------------------------------------
14
14
 */
42
42
#define DISTINCT_ON_CLAUSE 2
43
43
#define PARTITION_CLAUSE 3
44
44
 
45
 
static const char * const clauseText[] = {
 
45
static const char *const clauseText[] = {
46
46
        "ORDER BY",
47
47
        "GROUP BY",
48
48
        "DISTINCT ON",
75
75
                                   Var *l_colvar, Var *r_colvar);
76
76
static TargetEntry *findTargetlistEntry(ParseState *pstate, Node *node,
77
77
                                        List **tlist, int clause);
78
 
static int      get_matching_location(int sortgroupref,
79
 
                                                                  List *sortgrouprefs, List *exprs);
 
78
static int get_matching_location(int sortgroupref,
 
79
                                          List *sortgrouprefs, List *exprs);
80
80
static List *addTargetToSortList(ParseState *pstate, TargetEntry *tle,
81
81
                                        List *sortlist, List *targetlist, SortBy *sortby,
82
82
                                        bool resolveUnknown);
414
414
                 errmsg("JOIN/ON clause refers to \"%s\", which is not part of JOIN",
415
415
                                rt_fetch(varno, pstate->p_rtable)->eref->aliasname),
416
416
                                 parser_errposition(pstate,
417
 
                                                                        locate_var_of_relation(result, varno, 0))));
 
417
                                                                 locate_var_of_relation(result, varno, 0))));
418
418
        }
419
419
        bms_free(clause_varnos);
420
420
 
493
493
                                (errcode(ERRCODE_SYNTAX_ERROR),
494
494
                                 errmsg("subquery in FROM cannot have SELECT INTO"),
495
495
                                 parser_errposition(pstate,
496
 
                                                                        exprLocation((Node *) query->intoClause))));
 
496
                                                                 exprLocation((Node *) query->intoClause))));
497
497
 
498
498
        /*
499
499
         * The subquery cannot make use of any variables from FROM items created
515
515
                                        (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
516
516
                                         errmsg("subquery in FROM cannot refer to other relations of same query level"),
517
517
                                         parser_errposition(pstate,
518
 
                                                                                locate_var_of_level((Node *) query, 1))));
 
518
                                                                   locate_var_of_level((Node *) query, 1))));
519
519
        }
520
520
 
521
521
        /*
584
584
                checkExprHasWindowFuncs(funcexpr))
585
585
                ereport(ERROR,
586
586
                                (errcode(ERRCODE_WINDOWING_ERROR),
587
 
                                 errmsg("cannot use window function in function expression in FROM"),
 
587
                 errmsg("cannot use window function in function expression in FROM"),
588
588
                                 parser_errposition(pstate,
589
589
                                                                        locate_windowfunc(funcexpr))));
590
590
 
649
649
        if (IsA(n, RangeVar))
650
650
        {
651
651
                /* Plain relation reference, or perhaps a CTE reference */
652
 
                RangeVar *rv = (RangeVar *) n;
 
652
                RangeVar   *rv = (RangeVar *) n;
653
653
                RangeTblRef *rtr;
654
654
                RangeTblEntry *rte = NULL;
655
655
                int                     rtindex;
658
658
                if (!rv->schemaname)
659
659
                {
660
660
                        CommonTableExpr *cte;
661
 
                        Index   levelsup;
 
661
                        Index           levelsup;
662
662
 
663
663
                        cte = scanNameSpaceForCTE(pstate, rv->relname, &levelsup);
664
664
                        if (cte)
1432
1432
                 * info from the (first) matching ORDER BY item.  This means that if
1433
1433
                 * you write something like "GROUP BY foo ORDER BY foo USING <<<", the
1434
1434
                 * GROUP BY operation silently takes on the equality semantics implied
1435
 
                 * by the ORDER BY.  There are two reasons to do this: it improves
1436
 
                 * the odds that we can implement both GROUP BY and ORDER BY with a
1437
 
                 * single sort step, and it allows the user to choose the equality
1438
 
                 * semantics used by GROUP BY, should she be working with a datatype
1439
 
                 * that has more than one equality operator.
 
1435
                 * by the ORDER BY.  There are two reasons to do this: it improves the
 
1436
                 * odds that we can implement both GROUP BY and ORDER BY with a single
 
1437
                 * sort step, and it allows the user to choose the equality semantics
 
1438
                 * used by GROUP BY, should she be working with a datatype that has
 
1439
                 * more than one equality operator.
1440
1440
                 */
1441
1441
                if (tle->ressortgroupref > 0)
1442
1442
                {
1456
1456
                }
1457
1457
 
1458
1458
                /*
1459
 
                 * If no match in ORDER BY, just add it to the result using
1460
 
                 * default sort/group semantics.
 
1459
                 * If no match in ORDER BY, just add it to the result using default
 
1460
                 * sort/group semantics.
1461
1461
                 */
1462
1462
                if (!found)
1463
1463
                        result = addTargetToGroupList(pstate, tle,
1516
1516
 
1517
1517
        foreach(lc, windowdefs)
1518
1518
        {
1519
 
                WindowDef        *windef = (WindowDef *) lfirst(lc);
 
1519
                WindowDef  *windef = (WindowDef *) lfirst(lc);
1520
1520
                WindowClause *refwc = NULL;
1521
 
                List             *partitionClause;
1522
 
                List             *orderClause;
 
1521
                List       *partitionClause;
 
1522
                List       *orderClause;
1523
1523
                WindowClause *wc;
1524
1524
 
1525
1525
                winref++;
1550
1550
 
1551
1551
                /*
1552
1552
                 * Transform PARTITION and ORDER specs, if any.  These are treated
1553
 
                 * exactly like top-level GROUP BY and ORDER BY clauses, including
1554
 
                 * the special handling of nondefault operator semantics.
 
1553
                 * exactly like top-level GROUP BY and ORDER BY clauses, including the
 
1554
                 * special handling of nondefault operator semantics.
1555
1555
                 */
1556
1556
                orderClause = transformSortClause(pstate,
1557
1557
                                                                                  windef->orderClause,
1573
1573
                /*
1574
1574
                 * Per spec, a windowdef that references a previous one copies the
1575
1575
                 * previous partition clause (and mustn't specify its own).  It can
1576
 
                 * specify its own ordering clause. but only if the previous one
1577
 
                 * had none.  It always specifies its own frame clause, and the
1578
 
                 * previous one must not have a frame clause.  (Yeah, it's bizarre
1579
 
                 * that each of these cases works differently, but SQL:2008 says so;
1580
 
                 * see 7.11 <window clause> syntax rule 10 and general rule 1.)
 
1576
                 * specify its own ordering clause. but only if the previous one had
 
1577
                 * none.  It always specifies its own frame clause, and the previous
 
1578
                 * one must not have a frame clause.  (Yeah, it's bizarre that each of
 
1579
                 * these cases works differently, but SQL:2008 says so; see 7.11
 
1580
                 * <window clause> syntax rule 10 and general rule 1.)
1581
1581
                 */
1582
1582
                if (refwc)
1583
1583
                {
1584
1584
                        if (partitionClause)
1585
1585
                                ereport(ERROR,
1586
1586
                                                (errcode(ERRCODE_WINDOWING_ERROR),
1587
 
                                                 errmsg("cannot override PARTITION BY clause of window \"%s\"",
1588
 
                                                                windef->refname),
 
1587
                                errmsg("cannot override PARTITION BY clause of window \"%s\"",
 
1588
                                           windef->refname),
1589
1589
                                                 parser_errposition(pstate, windef->location)));
1590
1590
                        wc->partitionClause = copyObject(refwc->partitionClause);
1591
1591
                }
1596
1596
                        if (orderClause && refwc->orderClause)
1597
1597
                                ereport(ERROR,
1598
1598
                                                (errcode(ERRCODE_WINDOWING_ERROR),
1599
 
                                                 errmsg("cannot override ORDER BY clause of window \"%s\"",
1600
 
                                                                windef->refname),
 
1599
                                   errmsg("cannot override ORDER BY clause of window \"%s\"",
 
1600
                                                  windef->refname),
1601
1601
                                                 parser_errposition(pstate, windef->location)));
1602
1602
                        if (orderClause)
1603
1603
                        {
1652
1652
        ListCell   *tlitem;
1653
1653
 
1654
1654
        /*
1655
 
         * The distinctClause should consist of all ORDER BY items followed
1656
 
         * by all other non-resjunk targetlist items.  There must not be any
1657
 
         * resjunk ORDER BY items --- that would imply that we are sorting
1658
 
         * by a value that isn't necessarily unique within a DISTINCT group,
1659
 
         * so the results wouldn't be well-defined.  This construction
1660
 
         * ensures we follow the rule that sortClause and distinctClause match;
1661
 
         * in fact the sortClause will always be a prefix of distinctClause.
 
1655
         * The distinctClause should consist of all ORDER BY items followed by all
 
1656
         * other non-resjunk targetlist items.  There must not be any resjunk
 
1657
         * ORDER BY items --- that would imply that we are sorting by a value that
 
1658
         * isn't necessarily unique within a DISTINCT group, so the results
 
1659
         * wouldn't be well-defined.  This construction ensures we follow the rule
 
1660
         * that sortClause and distinctClause match; in fact the sortClause will
 
1661
         * always be a prefix of distinctClause.
1662
1662
         *
1663
 
         * Note a corner case: the same TLE could be in the ORDER BY list
1664
 
         * multiple times with different sortops.  We have to include it in
1665
 
         * the distinctClause the same way to preserve the prefix property.
1666
 
         * The net effect will be that the TLE value will be made unique
1667
 
         * according to both sortops.
 
1663
         * Note a corner case: the same TLE could be in the ORDER BY list multiple
 
1664
         * times with different sortops.  We have to include it in the
 
1665
         * distinctClause the same way to preserve the prefix property. The net
 
1666
         * effect will be that the TLE value will be made unique according to both
 
1667
         * sortops.
1668
1668
         */
1669
1669
        foreach(slitem, sortClause)
1670
1670
        {
1681
1681
        }
1682
1682
 
1683
1683
        /*
1684
 
         * Now add any remaining non-resjunk tlist items, using default
1685
 
         * sort/group semantics for their data types.
 
1684
         * Now add any remaining non-resjunk tlist items, using default sort/group
 
1685
         * semantics for their data types.
1686
1686
         */
1687
1687
        foreach(tlitem, *targetlist)
1688
1688
        {
1724
1724
 
1725
1725
        /*
1726
1726
         * Add all the DISTINCT ON expressions to the tlist (if not already
1727
 
         * present, they are added as resjunk items).  Assign sortgroupref
1728
 
         * numbers to them, and make a list of these numbers.  (NB: we rely
1729
 
         * below on the sortgrouprefs list being one-for-one with the original
1730
 
         * distinctlist.  Also notice that we could have duplicate DISTINCT ON
1731
 
         * expressions and hence duplicate entries in sortgrouprefs.)
 
1727
         * present, they are added as resjunk items).  Assign sortgroupref numbers
 
1728
         * to them, and make a list of these numbers.  (NB: we rely below on the
 
1729
         * sortgrouprefs list being one-for-one with the original distinctlist.
 
1730
         * Also notice that we could have duplicate DISTINCT ON expressions and
 
1731
         * hence duplicate entries in sortgrouprefs.)
1732
1732
         */
1733
1733
        foreach(lc, distinctlist)
1734
1734
        {
1743
1743
        }
1744
1744
 
1745
1745
        /*
1746
 
         * If the user writes both DISTINCT ON and ORDER BY, adopt the
1747
 
         * sorting semantics from ORDER BY items that match DISTINCT ON
1748
 
         * items, and also adopt their column sort order.  We insist that
1749
 
         * the distinctClause and sortClause match, so throw error if we
1750
 
         * find the need to add any more distinctClause items after we've
1751
 
         * skipped an ORDER BY item that wasn't in DISTINCT ON.
 
1746
         * If the user writes both DISTINCT ON and ORDER BY, adopt the sorting
 
1747
         * semantics from ORDER BY items that match DISTINCT ON items, and also
 
1748
         * adopt their column sort order.  We insist that the distinctClause and
 
1749
         * sortClause match, so throw error if we find the need to add any more
 
1750
         * distinctClause items after we've skipped an ORDER BY item that wasn't
 
1751
         * in DISTINCT ON.
1752
1752
         */
1753
1753
        skipped_sortitem = false;
1754
1754
        foreach(lc, sortClause)
1762
1762
                                                (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
1763
1763
                                                 errmsg("SELECT DISTINCT ON expressions must match initial ORDER BY expressions"),
1764
1764
                                                 parser_errposition(pstate,
1765
 
                                                                                        get_matching_location(scl->tleSortGroupRef,
1766
 
                                                                                                                                  sortgrouprefs,
1767
 
                                                                                                                                  distinctlist))));
 
1765
                                                                  get_matching_location(scl->tleSortGroupRef,
 
1766
                                                                                                                sortgrouprefs,
 
1767
                                                                                                                distinctlist))));
1768
1768
                        else
1769
1769
                                result = lappend(result, copyObject(scl));
1770
1770
                }
1774
1774
 
1775
1775
        /*
1776
1776
         * Now add any remaining DISTINCT ON items, using default sort/group
1777
 
         * semantics for their data types.  (Note: this is pretty questionable;
1778
 
         * if the ORDER BY list doesn't include all the DISTINCT ON items and more
 
1777
         * semantics for their data types.      (Note: this is pretty questionable; if
 
1778
         * the ORDER BY list doesn't include all the DISTINCT ON items and more
1779
1779
         * besides, you certainly aren't using DISTINCT ON in the intended way,
1780
1780
         * and you probably aren't going to get consistent results.  It might be
1781
1781
         * better to throw an error or warning here.  But historically we've
1870
1870
         * Rather than clutter the API of get_sort_group_operators and the other
1871
1871
         * functions we're about to use, make use of error context callback to
1872
1872
         * mark any error reports with a parse position.  We point to the operator
1873
 
         * location if present, else to the expression being sorted.  (NB: use
1874
 
         * the original untransformed expression here; the TLE entry might well
1875
 
         * point at a duplicate expression in the regular SELECT list.)
 
1873
         * location if present, else to the expression being sorted.  (NB: use the
 
1874
         * original untransformed expression here; the TLE entry might well point
 
1875
         * at a duplicate expression in the regular SELECT list.)
1876
1876
         */
1877
1877
        location = sortby->location;
1878
1878
        if (location < 0)