~ubuntu-branches/ubuntu/trusty/postgresql-8.4/trusty

« back to all changes in this revision

Viewing changes to src/backend/parser/analyze.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:
17
17
 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
18
18
 * Portions Copyright (c) 1994, Regents of the University of California
19
19
 *
20
 
 *      $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.388 2009/01/22 20:16:04 tgl Exp $
 
20
 *      $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.389 2009/06/11 14:48:59 momjian Exp $
21
21
 *
22
22
 *-------------------------------------------------------------------------
23
23
 */
50
50
static Query *transformValuesClause(ParseState *pstate, SelectStmt *stmt);
51
51
static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt);
52
52
static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt,
53
 
                                                                           List **colInfo);
 
53
                                                  List **colInfo);
54
54
static void applyColumnNames(List *dst, List *src);
55
55
static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
56
56
static List *transformReturningList(ParseState *pstate, List *returningList);
59
59
static Query *transformExplainStmt(ParseState *pstate,
60
60
                                         ExplainStmt *stmt);
61
61
static void transformLockingClause(ParseState *pstate,
62
 
                                                                   Query *qry, LockingClause *lc);
 
62
                                           Query *qry, LockingClause *lc);
63
63
static bool check_parameter_resolution_walker(Node *node, ParseState *pstate);
64
64
 
65
65
 
81
81
        ParseState *pstate = make_parsestate(NULL);
82
82
        Query      *query;
83
83
 
84
 
        Assert(sourceText != NULL);                             /* required as of 8.4 */
 
84
        Assert(sourceText != NULL); /* required as of 8.4 */
85
85
 
86
86
        pstate->p_sourcetext = sourceText;
87
87
        pstate->p_paramtypes = paramTypes;
109
109
        ParseState *pstate = make_parsestate(NULL);
110
110
        Query      *query;
111
111
 
112
 
        Assert(sourceText != NULL);                             /* required as of 8.4 */
 
112
        Assert(sourceText != NULL); /* required as of 8.4 */
113
113
 
114
114
        pstate->p_sourcetext = sourceText;
115
115
        pstate->p_paramtypes = *paramTypes;
255
255
                        break;
256
256
 
257
257
                case T_ExplainStmt:
 
258
 
258
259
                        /*
259
260
                         * We only need a snapshot in varparams case, but it doesn't seem
260
261
                         * worth complicating this function's API to distinguish that.
423
424
                 * bugs of just that nature...)
424
425
                 */
425
426
                sub_pstate->p_rtable = sub_rtable;
426
 
                sub_pstate->p_joinexprs = NIL;                  /* sub_rtable has no joins */
 
427
                sub_pstate->p_joinexprs = NIL;  /* sub_rtable has no joins */
427
428
                sub_pstate->p_relnamespace = sub_relnamespace;
428
429
                sub_pstate->p_varnamespace = sub_varnamespace;
429
430
 
441
442
                                        (errcode(ERRCODE_SYNTAX_ERROR),
442
443
                                         errmsg("INSERT ... SELECT cannot specify INTO"),
443
444
                                         parser_errposition(pstate,
444
 
                                                                                exprLocation((Node *) selectQuery->intoClause))));
 
445
                                                   exprLocation((Node *) selectQuery->intoClause))));
445
446
 
446
447
                /*
447
448
                 * Make the source be a subquery in the INSERT's rangetable, and add
485
486
                                expr = tle->expr;
486
487
                        else
487
488
                        {
488
 
                                Var        *var = makeVar(rtr->rtindex,
489
 
                                                                          tle->resno,
490
 
                                                                          exprType((Node *) tle->expr),
491
 
                                                                          exprTypmod((Node *) tle->expr),
492
 
                                                                          0);
 
489
                                Var                *var = makeVar(rtr->rtindex,
 
490
                                                                                  tle->resno,
 
491
                                                                                  exprType((Node *) tle->expr),
 
492
                                                                                  exprTypmod((Node *) tle->expr),
 
493
                                                                                  0);
 
494
 
493
495
                                var->location = exprLocation((Node *) tle->expr);
494
496
                                expr = (Expr *) var;
495
497
                        }
563
565
                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
564
566
                                         errmsg("VALUES must not contain table references"),
565
567
                                         parser_errposition(pstate,
566
 
                                                                                locate_var_of_level((Node *) exprsLists, 0))));
 
568
                                                          locate_var_of_level((Node *) exprsLists, 0))));
567
569
 
568
570
                /*
569
571
                 * Another thing we can't currently support is NEW/OLD references in
578
580
                                         errmsg("VALUES must not contain OLD or NEW references"),
579
581
                                         errhint("Use SELECT ... UNION ALL ... instead."),
580
582
                                         parser_errposition(pstate,
581
 
                                                                                locate_var_of_level((Node *) exprsLists, 0))));
 
583
                                                          locate_var_of_level((Node *) exprsLists, 0))));
582
584
 
583
585
                /*
584
586
                 * Generate the VALUES RTE
655
657
                qry->targetList = lappend(qry->targetList, tle);
656
658
 
657
659
                rte->modifiedCols = bms_add_member(rte->modifiedCols,
658
 
                                                                attr_num - FirstLowInvalidHeapAttributeNumber);
 
660
                                                          attr_num - FirstLowInvalidHeapAttributeNumber);
659
661
 
660
662
                icols = lnext(icols);
661
663
                attnos = lnext(attnos);
727
729
                                 errmsg("INSERT has more expressions than target columns"),
728
730
                                 parser_errposition(pstate,
729
731
                                                                        exprLocation(list_nth(exprlist,
730
 
                                                                                                                  list_length(icolumns))))));
 
732
                                                                                                  list_length(icolumns))))));
731
733
        if (stmtcols != NIL &&
732
734
                list_length(exprlist) < list_length(icolumns))
733
735
                ereport(ERROR,
735
737
                                 errmsg("INSERT has more target columns than expressions"),
736
738
                                 parser_errposition(pstate,
737
739
                                                                        exprLocation(list_nth(icolumns,
738
 
                                                                                                                  list_length(exprlist))))));
 
740
                                                                                                  list_length(exprlist))))));
739
741
 
740
742
        /*
741
743
         * Prepare columns for assignment to target table.
816
818
 
817
819
        /*
818
820
         * Transform sorting/grouping stuff.  Do ORDER BY first because both
819
 
         * transformGroupClause and transformDistinctClause need the results.
820
 
         * Note that these functions can also change the targetList, so it's
821
 
         * passed to them by reference.
 
821
         * transformGroupClause and transformDistinctClause need the results. Note
 
822
         * that these functions can also change the targetList, so it's passed to
 
823
         * them by reference.
822
824
         */
823
825
        qry->sortClause = transformSortClause(pstate,
824
826
                                                                                  stmt->sortClause,
1068
1070
                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1069
1071
                                 errmsg("VALUES must not contain table references"),
1070
1072
                                 parser_errposition(pstate,
1071
 
                                                                        locate_var_of_level((Node *) newExprsLists, 0))));
 
1073
                                                   locate_var_of_level((Node *) newExprsLists, 0))));
1072
1074
 
1073
1075
        /*
1074
1076
         * Another thing we can't currently support is NEW/OLD references in rules
1083
1085
                                 errmsg("VALUES must not contain OLD or NEW references"),
1084
1086
                                 errhint("Use SELECT ... UNION ALL ... instead."),
1085
1087
                                 parser_errposition(pstate,
1086
 
                                                                        locate_var_of_level((Node *) newExprsLists, 0))));
 
1088
                                                   locate_var_of_level((Node *) newExprsLists, 0))));
1087
1089
 
1088
1090
        qry->rtable = pstate->p_rtable;
1089
1091
        qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
1095
1097
                                (errcode(ERRCODE_GROUPING_ERROR),
1096
1098
                                 errmsg("cannot use aggregate function in VALUES"),
1097
1099
                                 parser_errposition(pstate,
1098
 
                                                                        locate_agg_of_level((Node *) newExprsLists, 0))));
 
1100
                                                   locate_agg_of_level((Node *) newExprsLists, 0))));
1099
1101
        if (pstate->p_hasWindowFuncs)
1100
1102
                ereport(ERROR,
1101
1103
                                (errcode(ERRCODE_WINDOWING_ERROR),
1102
1104
                                 errmsg("cannot use window function in VALUES"),
1103
1105
                                 parser_errposition(pstate,
1104
 
                                                                        locate_windowfunc((Node *) newExprsLists))));
 
1106
                                                                locate_windowfunc((Node *) newExprsLists))));
1105
1107
 
1106
1108
        return qry;
1107
1109
}
1302
1304
                                 errdetail("Only result column names can be used, not expressions or functions."),
1303
1305
                                 errhint("Add the expression/function to every SELECT, or move the UNION into a FROM clause."),
1304
1306
                                 parser_errposition(pstate,
1305
 
                                                                        exprLocation(list_nth(qry->targetList, tllen)))));
 
1307
                                                   exprLocation(list_nth(qry->targetList, tllen)))));
1306
1308
 
1307
1309
        qry->limitOffset = transformLimitClause(pstate, limitOffset,
1308
1310
                                                                                        "OFFSET");
1368
1370
                                (errcode(ERRCODE_SYNTAX_ERROR),
1369
1371
                                 errmsg("INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT"),
1370
1372
                                 parser_errposition(pstate,
1371
 
                                                                        exprLocation((Node *) stmt->intoClause))));
 
1373
                                                                  exprLocation((Node *) stmt->intoClause))));
1372
1374
 
1373
1375
        /* We don't support FOR UPDATE/SHARE with set ops at the moment. */
1374
1376
        if (stmt->lockingClause)
1428
1430
                                                (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
1429
1431
                                                 errmsg("UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level"),
1430
1432
                                                 parser_errposition(pstate,
1431
 
                                                                                        locate_var_of_level((Node *) selectQuery, 1))));
 
1433
                                                         locate_var_of_level((Node *) selectQuery, 1))));
1432
1434
                }
1433
1435
 
1434
1436
                /*
1790
1792
        /* no new relation references please */
1791
1793
        if (list_length(pstate->p_rtable) != length_rtable)
1792
1794
        {
1793
 
                int             vlocation = -1;
1794
 
                int             relid;
 
1795
                int                     vlocation = -1;
 
1796
                int                     relid;
1795
1797
 
1796
1798
                /* try to locate such a reference to point to */
1797
1799
                for (relid = length_rtable + 1; relid <= list_length(pstate->p_rtable); relid++)
1802
1804
                }
1803
1805
                ereport(ERROR,
1804
1806
                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1805
 
                  errmsg("RETURNING cannot contain references to other relations"),
 
1807
                        errmsg("RETURNING cannot contain references to other relations"),
1806
1808
                                 parser_errposition(pstate, vlocation)));
1807
1809
        }
1808
1810
 
1857
1859
                                (errcode(ERRCODE_INVALID_CURSOR_DEFINITION),
1858
1860
                                 errmsg("DECLARE CURSOR cannot specify INTO"),
1859
1861
                                 parser_errposition(pstate,
1860
 
                                                                        exprLocation((Node *) result->intoClause))));
 
1862
                                                                exprLocation((Node *) result->intoClause))));
1861
1863
 
1862
1864
        /* FOR UPDATE and WITH HOLD are not compatible */
1863
1865
        if (result->rowMarks != NIL && (stmt->options & CURSOR_OPT_HOLD))
2006
2008
                                        {
2007
2009
                                                /*
2008
2010
                                                 * We allow FOR UPDATE/SHARE of a WITH query to be
2009
 
                                                 * propagated into the WITH, but it doesn't seem
2010
 
                                                 * very sane to allow this for a reference to an
2011
 
                                                 * outer-level WITH.  And it definitely wouldn't
2012
 
                                                 * work for a self-reference, since we're not done
 
2011
                                                 * propagated into the WITH, but it doesn't seem very
 
2012
                                                 * sane to allow this for a reference to an
 
2013
                                                 * outer-level WITH.  And it definitely wouldn't work
 
2014
                                                 * for a self-reference, since we're not done
2013
2015
                                                 * analyzing the CTE anyway.
2014
2016
                                                 */
2015
2017
                                                CommonTableExpr *cte;
2073
2075
                                                        ereport(ERROR,
2074
2076
                                                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2075
2077
                                                                         errmsg("SELECT FOR UPDATE/SHARE cannot be applied to a join"),
2076
 
                                                                         parser_errposition(pstate, thisrel->location)));
 
2078
                                                         parser_errposition(pstate, thisrel->location)));
2077
2079
                                                        break;
2078
2080
                                                case RTE_SPECIAL:
2079
2081
                                                        ereport(ERROR,
2080
2082
                                                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2081
2083
                                                                         errmsg("SELECT FOR UPDATE/SHARE cannot be applied to NEW or OLD"),
2082
 
                                                                         parser_errposition(pstate, thisrel->location)));
 
2084
                                                         parser_errposition(pstate, thisrel->location)));
2083
2085
                                                        break;
2084
2086
                                                case RTE_FUNCTION:
2085
2087
                                                        ereport(ERROR,
2086
2088
                                                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2087
2089
                                                                         errmsg("SELECT FOR UPDATE/SHARE cannot be applied to a function"),
2088
 
                                                                         parser_errposition(pstate, thisrel->location)));
 
2090
                                                         parser_errposition(pstate, thisrel->location)));
2089
2091
                                                        break;
2090
2092
                                                case RTE_VALUES:
2091
2093
                                                        ereport(ERROR,
2092
2094
                                                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2093
2095
                                                                         errmsg("SELECT FOR UPDATE/SHARE cannot be applied to VALUES"),
2094
 
                                                                         parser_errposition(pstate, thisrel->location)));
 
2096
                                                         parser_errposition(pstate, thisrel->location)));
2095
2097
                                                        break;
2096
2098
                                                case RTE_CTE:
2097
2099
                                                        {
2108
2110
 
2109
2111
                                                                if (rte->ctelevelsup > 0 || rte->self_reference)
2110
2112
                                                                        ereport(ERROR,
2111
 
                                                                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2112
 
                                                                                         errmsg("SELECT FOR UPDATE/SHARE cannot be applied to an outer-level WITH query"),
2113
 
                                                                                         parser_errposition(pstate, thisrel->location)));
 
2113
                                                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 
2114
                                                                          errmsg("SELECT FOR UPDATE/SHARE cannot be applied to an outer-level WITH query"),
 
2115
                                                                          parser_errposition(pstate, thisrel->location)));
2114
2116
                                                                cte = GetCTEForRTE(pstate, rte, -1);
2115
2117
                                                                /* should be analyzed by now */
2116
2118
                                                                Assert(IsA(cte->ctequery, Query));
2117
2119
                                                                transformLockingClause(pstate,
2118
 
                                                                                                           (Query *) cte->ctequery,
 
2120
                                                                                                         (Query *) cte->ctequery,
2119
2121
                                                                                                           allrels);
2120
2122
                                                        }
2121
2123
                                                        break;