diff options
Diffstat (limited to 'src/backend/parser')
-rw-r--r-- | src/backend/parser/analyze.c | 34 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 72 | ||||
-rw-r--r-- | src/backend/parser/keywords.c | 3 | ||||
-rw-r--r-- | src/backend/parser/parse_agg.c | 4 | ||||
-rw-r--r-- | src/backend/parser/parse_clause.c | 6 | ||||
-rw-r--r-- | src/backend/parser/parse_coerce.c | 3 | ||||
-rw-r--r-- | src/backend/parser/parse_expr.c | 12 | ||||
-rw-r--r-- | src/backend/parser/parse_func.c | 8 | ||||
-rw-r--r-- | src/backend/parser/parse_relation.c | 45 | ||||
-rw-r--r-- | src/backend/parser/parse_target.c | 4 |
10 files changed, 120 insertions, 71 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 612481deabc..c192b4ce7a1 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: analyze.c,v 1.139 2000/03/01 05:18:20 tgl Exp $ + * $Id: analyze.c,v 1.140 2000/03/14 23:06:30 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -146,6 +146,34 @@ transformStmt(ParseState *pstate, Node *parseTree) ViewStmt *n = (ViewStmt *) parseTree; n->query = (Query *) transformStmt(pstate, (Node *) n->query); + + /* If a list of column names was given, run through and insert these + * into the actual query tree. - thomas 2000-03-08 + */ + if (n->aliases != NIL) + { + int i; + List *targetList = n->query->targetList; + + if (length(targetList) < length(n->aliases)) + elog(ERROR, "CREATE VIEW specifies %d columns" + " but only %d columns are present", + length(targetList), length(n->aliases)); + + for (i = 0; i < length(n->aliases); i++) + { + Ident *id; + TargetEntry *te; + Resdom *rd; + id = nth(i, n->aliases); + Assert(nodeTag(id) == T_Ident); + te = nth(i, targetList); + Assert(nodeTag(te) == T_TargetEntry); + rd = te->resdom; + Assert(nodeTag(rd) == T_Resdom); + rd->resname = pstrdup(id->name); + } + } result = makeNode(Query); result->commandType = CMD_UTILITY; result->utilityStmt = (Node *) n; @@ -1904,7 +1932,7 @@ transformForUpdate(Query *qry, List *forUpdate) i = 1; foreach(l2, qry->rtable) { - if (strcmp(((RangeTblEntry *) lfirst(l2))->ref->relname, relname) == 0) + if (strcmp(((RangeTblEntry *) lfirst(l2))->eref->relname, relname) == 0) { List *l3; @@ -1925,7 +1953,7 @@ transformForUpdate(Query *qry, List *forUpdate) i++; } if (l2 == NULL) - elog(ERROR, "FOR UPDATE: relation %s not found in FROM clause", + elog(ERROR, "FOR UPDATE: relation '%s' not found in FROM clause", relname); } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index ab69eb4794f..c4d98d203ec 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.155 2000/03/12 20:09:41 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.156 2000/03/14 23:06:31 thomas Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -307,7 +307,7 @@ static void doNegateFloat(Value *v); ISOLATION, JOIN, KEY, LANGUAGE, LEADING, LEFT, LEVEL, LIKE, LOCAL, MATCH, MINUTE_P, MONTH_P, NAMES, NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF, NULL_P, NUMERIC, - OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P, + OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P, OVERLAPS, PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC, READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK, SCROLL, SECOND_P, SELECT, SESSION_USER, SET, SUBSTRING, @@ -363,6 +363,7 @@ static void doNegateFloat(Value *v); %right '=' %nonassoc '<' '>' %nonassoc LIKE +%nonassoc OVERLAPS %nonassoc BETWEEN %nonassoc IN %left Op /* multi-character ops and user-defined operators */ @@ -1903,7 +1904,7 @@ comment_text: Sconst { $$ = $1; } * *****************************************************************************/ -FetchStmt: FETCH direction fetch_how_many from_in name +FetchStmt: FETCH direction fetch_how_many from_in name { FetchStmt *n = makeNode(FetchStmt); if ($2 == RELATIVE) @@ -1923,7 +1924,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name n->ismove = false; $$ = (Node *)n; } - | FETCH fetch_how_many from_in name + | FETCH fetch_how_many from_in name { FetchStmt *n = makeNode(FetchStmt); if ($2 < 0) @@ -1940,7 +1941,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name n->ismove = false; $$ = (Node *)n; } - | FETCH direction from_in name + | FETCH direction from_in name { FetchStmt *n = makeNode(FetchStmt); if ($2 == RELATIVE) @@ -1953,7 +1954,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name n->ismove = false; $$ = (Node *)n; } - | FETCH from_in name + | FETCH from_in name { FetchStmt *n = makeNode(FetchStmt); n->direction = FORWARD; @@ -1962,7 +1963,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name n->ismove = false; $$ = (Node *)n; } - | FETCH name + | FETCH name { FetchStmt *n = makeNode(FetchStmt); n->direction = FORWARD; @@ -1972,7 +1973,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name $$ = (Node *)n; } - | MOVE direction fetch_how_many from_in name + | MOVE direction fetch_how_many from_in name { FetchStmt *n = makeNode(FetchStmt); if ($3 < 0) @@ -1986,7 +1987,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name n->ismove = TRUE; $$ = (Node *)n; } - | MOVE fetch_how_many from_in name + | MOVE fetch_how_many from_in name { FetchStmt *n = makeNode(FetchStmt); if ($2 < 0) @@ -2003,7 +2004,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name n->ismove = TRUE; $$ = (Node *)n; } - | MOVE direction from_in name + | MOVE direction from_in name { FetchStmt *n = makeNode(FetchStmt); n->direction = $2; @@ -2021,7 +2022,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name n->ismove = TRUE; $$ = (Node *)n; } - | MOVE name + | MOVE name { FetchStmt *n = makeNode(FetchStmt); n->direction = FORWARD; @@ -2659,11 +2660,12 @@ opt_trans: WORK { $$ = TRUE; } * *****************************************************************************/ -ViewStmt: CREATE VIEW name AS SelectStmt +ViewStmt: CREATE VIEW name opt_column_list AS SelectStmt { ViewStmt *n = makeNode(ViewStmt); n->viewname = $3; - n->query = (Query *)$5; + n->aliases = $4; + n->query = (Query *)$6; if (((SelectStmt *)n->query)->sortClause != NULL) elog(ERROR,"ORDER BY and DISTINCT on views are not implemented"); if (((SelectStmt *)n->query)->unionClause != NULL) @@ -2737,7 +2739,7 @@ createdb_opt_encoding: int i; i = pg_char_to_encoding($3); if (i == -1) - elog(ERROR, "%s is not a valid encoding name.", $3); + elog(ERROR, "%s is not a valid encoding name", $3); $$ = i; #else elog(ERROR, "Multi-byte support is not enabled"); @@ -2747,7 +2749,7 @@ createdb_opt_encoding: { #ifdef MULTIBYTE if (!pg_get_encent_by_encoding($3)) - elog(ERROR, "%d is not a valid encoding code.", $3); + elog(ERROR, "%d is not a valid encoding code", $3); $$ = $3; #else elog(ERROR, "Multi-byte support is not enabled"); @@ -3979,10 +3981,13 @@ Datetime: datetime $$->timezone = $2; $$->typmod = -1; } - | TIME + | TIME opt_timezone { $$ = makeNode(TypeName); - $$->name = xlateSqlType("time"); + if ($2) + $$->name = xlateSqlType("timetz"); + else + $$->name = xlateSqlType("time"); $$->typmod = -1; } | INTERVAL opt_interval @@ -4077,6 +4082,27 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')' { $$ = makeRowExpr($4, $2, $6); } + | '(' row_descriptor ')' OVERLAPS '(' row_descriptor ')' + { + FuncCall *n = makeNode(FuncCall); + List *largs = $2; + List *rargs = $6; + n->funcname = xlateSqlFunc("overlaps"); + if (length(largs) == 1) + largs = lappend(largs, $2); + else if (length(largs) != 2) + elog(ERROR, "Wrong number of parameters" + " on left side of OVERLAPS expression"); + if (length(rargs) == 1) + rargs = lappend(rargs, $6); + else if (length(rargs) != 2) + elog(ERROR, "Wrong number of parameters" + " on right side of OVERLAPS expression"); + n->args = nconc(largs, rargs); + n->agg_star = false; + n->agg_distinct = false; + $$ = (Node *)n; + } ; row_descriptor: row_list ',' a_expr @@ -4579,7 +4605,8 @@ c_expr: attr n->agg_distinct = false; if ($3 != 0) - elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3); + elog(NOTICE,"CURRENT_TIME(%d) precision not implemented" + "; zero used instead",$3); $$ = (Node *)n; } @@ -4632,7 +4659,8 @@ c_expr: attr n->agg_distinct = false; if ($3 != 0) - elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3); + elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented" + "; zero used instead",$3); $$ = (Node *)n; } @@ -5219,6 +5247,7 @@ ColId: IDENT { $$ = $1; } | ONLY { $$ = "only"; } | OPERATOR { $$ = "operator"; } | OPTION { $$ = "option"; } + | OVERLAPS { $$ = "overlaps"; } | PASSWORD { $$ = "password"; } | PENDANT { $$ = "pendant"; } | PRIOR { $$ = "prior"; } @@ -5454,9 +5483,8 @@ mapTargetColumns(List *src, List *dst) static char * xlateSqlFunc(char *name) { - if (!strcasecmp(name,"character_length") - || !strcasecmp(name,"char_length")) - return "length"; + if (!strcasecmp(name,"character_length")) + return "char_length"; else return name; } /* xlateSqlFunc() */ diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index d971e95762d..5bf703703d3 100644 --- a/src/backend/parser/keywords.c +++ b/src/backend/parser/keywords.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.67 2000/02/18 09:29:40 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.68 2000/03/14 23:06:32 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -184,6 +184,7 @@ static ScanKeyword ScanKeywords[] = { {"or", OR}, {"order", ORDER}, {"outer", OUTER_P}, + {"overlaps", OVERLAPS}, {"partial", PARTIAL}, {"password", PASSWORD}, {"pendant", PENDANT}, diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c index afaa55e54f1..17cc026bfde 100644 --- a/src/backend/parser/parse_agg.c +++ b/src/backend/parser/parse_agg.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.34 2000/02/15 03:37:47 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.35 2000/03/14 23:06:32 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -111,7 +111,7 @@ check_ungrouped_columns_walker(Node *node, elog(ERROR, "cache lookup of attribute %d in relation %u failed", var->varattno, rte->relid); elog(ERROR, "Attribute %s.%s must be GROUPed or used in an aggregate function", - rte->ref->relname, attname); + rte->eref->relname, attname); } /* Otherwise, recurse. */ return expression_tree_walker(node, check_ungrouped_columns_walker, diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index 68da571f922..53d9b25f11b 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.55 2000/02/19 23:45:05 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.56 2000/03/14 23:06:32 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -478,7 +478,7 @@ parseFromClause(ParseState *pstate, List *frmList) { Assert(IsA(j->larg, RangeVar)); l_rte = transformTableEntry(pstate, (RangeVar *) j->larg); - l_name = expandTable(pstate, l_rte->ref->relname, TRUE); + l_name = expandTable(pstate, l_rte->eref->relname, TRUE); } if (IsA(j->rarg, JoinExpr)) @@ -490,7 +490,7 @@ parseFromClause(ParseState *pstate, List *frmList) { Assert(IsA(j->rarg, RangeVar)); r_rte = transformTableEntry(pstate, (RangeVar *) j->rarg); - r_name = expandTable(pstate, r_rte->ref->relname, TRUE); + r_name = expandTable(pstate, r_rte->eref->relname, TRUE); } /* Natural join does not explicitly specify columns; must generate columns to join. diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c index 210a8f946e3..ce06da2669e 100644 --- a/src/backend/parser/parse_coerce.c +++ b/src/backend/parser/parse_coerce.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.34 2000/03/11 23:19:50 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.35 2000/03/14 23:06:32 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -319,6 +319,7 @@ TypeCategory(Oid inType) case (DATEOID): case (TIMEOID): + case (TIMETZOID): case (ABSTIMEOID): case (TIMESTAMPOID): result = DATETIME_TYPE; diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index e1e86199722..e2e297cb6b6 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.72 2000/03/07 23:30:53 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.73 2000/03/14 23:06:32 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -574,15 +574,7 @@ transformIdent(ParseState *pstate, Ident *ident, int precedence) if ((rte = colnameRangeTableEntry(pstate, ident->name)) != NULL) { /* Convert it to a fully qualified Attr, and transform that */ -#ifndef DISABLE_JOIN_SYNTAX - Attr *att = makeAttr(rte->ref->relname, ident->name); -#else - Attr *att = makeNode(Attr); - - att->relname = rte->refname; - att->paramNo = NULL; - att->attrs = lcons(makeString(ident->name), NIL); -#endif + Attr *att = makeAttr(rte->eref->relname, ident->name); att->indirection = ident->indirection; return transformAttr(pstate, att, precedence); } diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 90c65a3830e..eb4884accbb 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.73 2000/03/11 23:17:47 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.74 2000/03/14 23:06:32 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -325,7 +325,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, * now allow column aliases. * - thomas 2000-02-07 */ - if (rte->ref->attrs != NULL) + if (rte->eref->attrs != NULL) { List *c; /* start counting attributes/columns from one. @@ -333,7 +333,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, * - thomas 2000-01-27 */ int i = 1; - foreach (c, rte->ref->attrs) + foreach (c, rte->eref->attrs) { char *colname = strVal(lfirst(c)); /* found a match? */ @@ -550,7 +550,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, relname = rte->relname; - vnum = refnameRangeTablePosn(pstate, rte->ref->relname, NULL); + vnum = refnameRangeTablePosn(pstate, rte->eref->relname, NULL); /* * for func(relname), the param to the function is the tuple diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 265642faaf3..4a943af6739 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.36 2000/03/09 05:00:24 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.37 2000/03/14 23:06:33 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -68,8 +68,12 @@ static char *attnum_type[SPECIALS] = { /* refnameRangeTableEntries() * Given refname, return a list of range table entries * This is possible with JOIN syntax, where tables in a join - * acquire the same reference name + * acquire the same reference name. * - thomas 2000-01-20 + * But at the moment we aren't carrying along a full list of + * table/column aliases, so we don't have the full mechanism + * to support outer joins in place yet. + * - thomas 2000-03-04 */ List * refnameRangeTableEntries(ParseState *pstate, char *refname); @@ -86,7 +90,7 @@ refnameRangeTableEntries(ParseState *pstate, char *refname) { RangeTblEntry *rte = lfirst(temp); - if (strcmp(rte->ref->relname, refname) == 0) + if (strcmp(rte->eref->relname, refname) == 0) rteList = lappend(rteList, rte); } /* only allow correlated columns in WHERE clause */ @@ -110,11 +114,7 @@ refnameRangeTableEntry(ParseState *pstate, char *refname) { RangeTblEntry *rte = lfirst(temp); -#ifndef DISABLE_JOIN_SYNTAX - if (strcmp(rte->ref->relname, refname) == 0) -#else - if (!strcmp(rte->refname, refname)) -#endif + if (strcmp(rte->eref->relname, refname) == 0) return rte; } /* only allow correlated columns in WHERE clause */ @@ -143,11 +143,7 @@ refnameRangeTablePosn(ParseState *pstate, char *refname, int *sublevels_up) { RangeTblEntry *rte = lfirst(temp); -#ifndef DISABLE_JOIN_SYNTAX - if (strcmp(rte->ref->relname, refname) == 0) -#else - if (!strcmp(rte->refname, refname)) -#endif + if (strcmp(rte->eref->relname, refname) == 0) return index; index++; } @@ -191,7 +187,7 @@ colnameRangeTableEntry(ParseState *pstate, char *colname) if (!rte->inFromCl && rte != pstate->p_target_rangetblentry) continue; - if (rte->ref->attrs != NULL) + if (rte->eref->attrs != NULL) { List *c; foreach (c, rte->ref->attrs) @@ -253,6 +249,7 @@ addRangeTableEntry(ParseState *pstate, { Relation rel; RangeTblEntry *rte; + Attr *eref; int maxattrs; int sublevels_up; int varattno; @@ -286,19 +283,22 @@ addRangeTableEntry(ParseState *pstate, rel = heap_openr(relname, AccessShareLock); rte->relid = RelationGetRelid(rel); maxattrs = RelationGetNumberOfAttributes(rel); - if (maxattrs < length(ref->attrs)) + + eref = copyObject(ref); + if (maxattrs < length(eref->attrs)) elog(ERROR, "Table '%s' has %d columns available but %d columns specified", - relname, maxattrs, length(ref->attrs)); + relname, maxattrs, length(eref->attrs)); /* fill in any unspecified alias columns */ - for (varattno = length(ref->attrs); varattno < maxattrs; varattno++) + for (varattno = length(eref->attrs); varattno < maxattrs; varattno++) { char *attrname; attrname = pstrdup(NameStr(rel->rd_att->attrs[varattno]->attname)); - ref->attrs = lappend(ref->attrs, makeString(attrname)); + eref->attrs = lappend(eref->attrs, makeString(attrname)); } heap_close(rel, AccessShareLock); + rte->eref = eref; /* * Flags: @@ -337,10 +337,9 @@ expandTable(ParseState *pstate, char *refname, bool getaliases) rte = refnameRangeTableEntry(pstate, refname); - if (getaliases && (rte != NULL) && (rte->ref != NULL) - && (length(rte->ref->attrs) > 0)) + if (getaliases && (rte != NULL)) { - return rte->ref; + return rte->eref; } if (rte != NULL) @@ -415,8 +414,8 @@ expandAll(ParseState *pstate, char *relname, Attr *ref, int *this_resno) attrname = pstrdup(NameStr(rel->rd_att->attrs[varattno]->attname)); /* varattno is zero-based, so check that length() is always greater */ - if (length(rte->ref->attrs) > varattno) - label = pstrdup(strVal(nth(varattno, rte->ref->attrs))); + if (length(rte->eref->attrs) > varattno) + label = pstrdup(strVal(nth(varattno, rte->eref->attrs))); else label = attrname; varnode = make_var(pstate, rte->relid, relname, attrname); diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index e815efc9639..65a5b33d58c 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.56 2000/03/09 05:00:24 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.57 2000/03/14 23:06:33 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -430,7 +430,7 @@ ExpandAllTables(ParseState *pstate) continue; target = nconc(target, - expandAll(pstate, rte->ref->relname, rte->ref, + expandAll(pstate, rte->eref->relname, rte->eref, &pstate->p_last_resno)); } return target; |