1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-20 05:03:10 +03:00

Add Var.varlevelup to code. More parser cleanup.

This commit is contained in:
Bruce Momjian
1998-01-20 22:12:17 +00:00
parent 412a5e6539
commit 7f31669bea
25 changed files with 158 additions and 104 deletions

View File

@ -12,7 +12,7 @@ parse_clause.c handle clauses like WHERE, ORDER BY, GROUP BY, ...
parse_expr.c handle expressions like col, col + 3, x = 3 or x = 4
parse_oper.c handle operations in expressions
parse_agg.c handle aggregates, like SUM(col1), AVG(col2), ...
parse_func.c handle functions like date_part(col3), trim(col4), ...
parse_func.c handle functions, table.column and column identifiers
parse_node.c create nodes for various structures
parse_target.c handle the result list of the query

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.67 1998/01/20 05:04:05 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.68 1998/01/20 22:11:51 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -219,7 +219,7 @@ transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
qry->qual = transformWhereClause(pstate, stmt->whereClause);
qry->rtable = pstate->p_rtable;
qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
qry->hasAggs = pstate->p_hasAggs;
if (pstate->p_hasAggs)
@ -320,7 +320,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
/* now the range table will not change */
qry->rtable = pstate->p_rtable;
qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
qry->groupClause = transformGroupClause(pstate,
stmt->groupClause,
@ -816,7 +816,7 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
qry->rtable = pstate->p_rtable;
qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
qry->hasAggs = pstate->p_hasAggs;
if (pstate->p_hasAggs)

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.10 1998/01/20 05:04:12 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.11 1998/01/20 22:11:53 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -39,16 +39,15 @@ void
makeRangeTable(ParseState *pstate, char *relname, List *frmList)
{
RangeTblEntry *rte;
parseFromClause(pstate, frmList);
if (relname == NULL)
return;
if (refnameRangeTablePosn(pstate->p_rtable, relname) < 1)
rte = addRangeTableEntry(pstate, relname, relname, FALSE, FALSE);
else
rte = refnameRangeTableEntry(pstate->p_rtable, relname);
Assert(pstate->p_rtable == NULL);
rte = addRangeTableEntry(pstate, relname, relname, FALSE, FALSE);
pstate->p_target_rangetblentry = rte;
Assert(pstate->p_target_relation == NULL);
@ -137,8 +136,7 @@ find_targetlist_entry(ParseState *pstate, SortGroupBy *sortgroupby, List *tlist)
TargetEntry *target_result = NULL;
if (sortgroupby->range)
real_rtable_pos = refnameRangeTablePosn(pstate->p_rtable,
sortgroupby->range);
real_rtable_pos = refnameRangeTablePosn(pstate, sortgroupby->range, NULL);
foreach(i, tlist)
{

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.11 1998/01/20 05:04:14 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.12 1998/01/20 22:11:55 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -304,6 +304,7 @@ transformIdent(ParseState *pstate, Node *expr, int precedence)
{
Attr *att = makeNode(Attr);
/* we add the relation name for them */
att->relname = rte->refname;
att->attrs = lcons(makeString(ident->name), NIL);
column_result =
@ -312,7 +313,7 @@ transformIdent(ParseState *pstate, Node *expr, int precedence)
}
/* try to find the ident as a relation */
if (refnameRangeTableEntry(pstate->p_rtable, ident->name) != NULL)
if (refnameRangeTableEntry(pstate, ident->name) != NULL)
{
ident->isRel = TRUE;
relation_result = (Node *) ident;

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.7 1998/01/20 05:04:16 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.8 1998/01/20 22:11:55 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -174,13 +174,12 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
{
RangeTblEntry *rte;
Ident *ident = (Ident *) first_arg;
/*
* first arg is a relation. This could be a projection.
*/
refname = ident->name;
rte = refnameRangeTableEntry(pstate->p_rtable, refname);
rte = refnameRangeTableEntry(pstate, refname);
if (rte == NULL)
rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE);
@ -196,6 +195,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
Oid dummyTypeId;
return ((Node *) make_var(pstate,
relid,
refname,
funcname,
&dummyTypeId));
@ -288,19 +288,18 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
if (nodeTag(pair) == T_Ident && ((Ident *) pair)->isRel)
{
/*
* a relation
*/
refname = ((Ident *) pair)->name;
rte = refnameRangeTableEntry(pstate->p_rtable, refname);
rte = refnameRangeTableEntry(pstate, refname);
if (rte == NULL)
rte = addRangeTableEntry(pstate, refname, refname,
FALSE, FALSE);
relname = rte->relname;
vnum = refnameRangeTablePosn(pstate->p_rtable, rte->refname);
vnum = refnameRangeTablePosn(pstate, rte->refname, NULL);
/*
* for func(relname), the param to the function is the tuple
@ -312,7 +311,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
toid = typeTypeId(typenameType(relname));
/* replace it in the arg list */
lfirst(fargs) =
makeVar(vnum, 0, toid, vnum, 0);
makeVar(vnum, 0, toid, 0, vnum, 0);
}
else if (!attisset)
{ /* set functions don't have parameters */
@ -1074,7 +1073,7 @@ setup_tlist(char *attname, Oid relid)
0,
(Oid) 0,
0);
varnode = makeVar(-1, attno, typeid, -1, attno);
varnode = makeVar(-1, attno, typeid, 0, -1, attno);
tle = makeNode(TargetEntry);
tle->resdom = resnode;
@ -1101,7 +1100,7 @@ setup_base_tlist(Oid typeid)
0,
(Oid) 0,
0);
varnode = makeVar(-1, 1, typeid, -1, 1);
varnode = makeVar(-1, 1, typeid, 0, -1, 1);
tle = makeNode(TargetEntry);
tle->resdom = resnode;
tle->expr = (Node *) varnode;

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.9 1998/01/20 05:04:21 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.10 1998/01/20 22:11:57 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -239,27 +239,24 @@ make_op(char *opname, Node *ltree, Node *rtree)
}
Var *
make_var(ParseState *pstate, char *refname, char *attrname, Oid *type_id)
make_var(ParseState *pstate, Oid relid, char *refname,
char *attrname, Oid *type_id)
{
Var *varnode;
int vnum,
attid;
Oid vartypeid;
RangeTblEntry *rte;
int sublevels_up;
rte = refnameRangeTableEntry(pstate->p_rtable, refname);
if (rte == NULL)
rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE);
vnum = refnameRangeTablePosn(pstate, refname, &sublevels_up);
vnum = refnameRangeTablePosn(pstate->p_rtable, refname);
attid = get_attnum(rte->relid, attrname);
attid = get_attnum(relid, attrname);
if (attid == InvalidAttrNumber)
elog(ERROR, "Relation %s does not have attribute %s",
rte->relname, attrname);
vartypeid = get_atttype(rte->relid, attid);
refname, attrname);
vartypeid = get_atttype(relid, attid);
varnode = makeVar(vnum, attid, vartypeid, vnum, attid);
varnode = makeVar(vnum, attid, vartypeid, sublevels_up, vnum, attid);
*type_id = vartypeid;
return varnode;

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.7 1998/01/20 05:04:24 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.8 1998/01/20 22:12:01 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -67,35 +67,57 @@ static char *attnum_type[SPECIALS] = {
/* given refname, return a pointer to the range table entry */
RangeTblEntry *
refnameRangeTableEntry(List *rtable, char *refname)
refnameRangeTableEntry(ParseState *pstate, char *refname)
{
List *temp;
foreach(temp, rtable)
while (pstate != NULL)
{
RangeTblEntry *rte = lfirst(temp);
if (!strcmp(rte->refname, refname))
return rte;
foreach(temp, pstate->p_rtable)
{
RangeTblEntry *rte = lfirst(temp);
if (!strcmp(rte->refname, refname))
return rte;
}
/* only allow correlated columns in WHERE clause */
if (pstate->p_in_where_clause)
pstate = pstate->parentParseState;
else break;
}
return NULL;
}
/* given refname, return id of variable; position starts with 1 */
int
refnameRangeTablePosn(List *rtable, char *refname)
refnameRangeTablePosn(ParseState *pstate, char *refname, int *sublevels_up)
{
int index;
List *temp;
index = 1;
foreach(temp, rtable)
{
RangeTblEntry *rte = lfirst(temp);
if (sublevels_up)
*sublevels_up = 0;
if (!strcmp(rte->refname, refname))
return index;
index++;
while (pstate != NULL)
{
index = 1;
foreach(temp, pstate->p_rtable)
{
RangeTblEntry *rte = lfirst(temp);
if (!strcmp(rte->refname, refname))
return index;
index++;
}
/* only allow correlated columns in WHERE clause */
if (pstate->p_in_where_clause)
{
pstate = pstate->parentParseState;
if (sublevels_up)
(*sublevels_up)++;
}
else break;
}
return 0;
}
@ -110,31 +132,38 @@ colnameRangeTableEntry(ParseState *pstate, char *colname)
List *rtable;
RangeTblEntry *rte_result;
if (pstate->p_is_rule)
rtable = lnext(lnext(pstate->p_rtable));
else
rtable = pstate->p_rtable;
rte_result = NULL;
foreach(et, rtable)
while (pstate != NULL)
{
RangeTblEntry *rte = lfirst(et);
if (pstate->p_is_rule)
rtable = lnext(lnext(pstate->p_rtable));
else
rtable = pstate->p_rtable;
/* only entries on outer(non-function?) scope */
if (!rte->inFromCl && rte != pstate->p_target_rangetblentry)
continue;
if (get_attnum(rte->relid, colname) != InvalidAttrNumber)
foreach(et, rtable)
{
if (rte_result != NULL)
RangeTblEntry *rte = lfirst(et);
/* only entries on outer(non-function?) scope */
if (!rte->inFromCl && rte != pstate->p_target_rangetblentry)
continue;
if (get_attnum(rte->relid, colname) != InvalidAttrNumber)
{
if (!pstate->p_is_insert ||
rte != pstate->p_target_rangetblentry)
elog(ERROR, "Column %s is ambiguous", colname);
if (rte_result != NULL)
{
if (!pstate->p_is_insert ||
rte != pstate->p_target_rangetblentry)
elog(ERROR, "Column %s is ambiguous", colname);
}
else
rte_result = rte;
}
else
rte_result = rte;
}
/* only allow correlated columns in WHERE clause */
if (pstate->p_in_where_clause && rte_result == NULL)
pstate = pstate->parentParseState;
else break;
}
return rte_result;
}
@ -152,11 +181,15 @@ addRangeTableEntry(ParseState *pstate,
{
Relation relation;
RangeTblEntry *rte = makeNode(RangeTblEntry);
int sublevels_up;
if (pstate != NULL &&
refnameRangeTableEntry(pstate->p_rtable, refname) != NULL)
elog(ERROR, "Table name %s specified more than once", refname);
if (pstate != NULL)
{
if (refnameRangeTablePosn(pstate, refname, &sublevels_up) != 0 &&
(!inFromCl || sublevels_up == 0))
elog(ERROR, "Table name %s specified more than once", refname);
}
rte->relname = pstrdup(relname);
rte->refname = pstrdup(refname);
@ -191,7 +224,6 @@ addRangeTableEntry(ParseState *pstate,
/*
* expandAll -
* makes a list of attributes
* assumes reldesc caching works
*/
List *
expandAll(ParseState *pstate, char *relname, char *refname, int *this_resno)
@ -206,7 +238,7 @@ expandAll(ParseState *pstate, char *relname, char *refname, int *this_resno)
int type_len;
RangeTblEntry *rte;
rte = refnameRangeTableEntry(pstate->p_rtable, refname);
rte = refnameRangeTableEntry(pstate, refname);
if (rte == NULL)
rte = addRangeTableEntry(pstate, relname, refname, FALSE, FALSE);
@ -225,7 +257,8 @@ expandAll(ParseState *pstate, char *relname, char *refname, int *this_resno)
TargetEntry *te = makeNode(TargetEntry);
attrname = pstrdup((rdesc->rd_att->attrs[varattno]->attname).data);
varnode = (Var *) make_var(pstate, refname, attrname, &type_id);
varnode = (Var *) make_var(pstate, rte->relid, refname,
attrname, &type_id);
type_len = (int) typeLen(typeidType(type_id));
handleTargetColname(pstate, &resname, refname, attrname);
@ -381,7 +414,7 @@ checkTargetTypes(ParseState *pstate, char *target_colname,
return;
if (refname != NULL)
rte = refnameRangeTableEntry(pstate->p_rtable, refname);
rte = refnameRangeTableEntry(pstate, refname);
else
{
rte = colnameRangeTableEntry(pstate, colname);