Skip to content
Snippets Groups Projects
Commit 9cad9feb authored by Bruce Momjian's avatar Bruce Momjian
Browse files

cleanup

parent 985f4ab9
No related branches found
No related tags found
No related merge requests found
......@@ -9,11 +9,11 @@ keywords.c turn keywords into specific tokens
gram.y parse the tokens and fill query-type-specific structures
analyze.c handle post-parse processing for each query type
parse_clause.c handle clauses like WHERE, ORDER BY, GROUP BY, ...
parse_coerce.c used for coercing expressions of different types
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, table.column and column identifiers
parse_node.c create nodes for various structures
parse_target.c handle the result list of the query
parse_relation.c support routines for tables and column handling
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.21 1998/08/19 02:02:26 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.22 1998/08/23 14:43:46 momjian Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -187,6 +187,154 @@ printf("transformTargetIdent- attrtype_target = %d; type_mod = %d\n", attrtype_t
} /* transformTargetIdent() */
/* MakeTargetlistExpr()
* Make a TargetEntry from an expression.
* arrayRef is a list of transformed A_Indices.
*
* For type mismatches between expressions and targets, use the same
* techniques as for function and operator type coersion.
* - thomas 1998-05-08
*
* Added resjunk flag and made extern so that it can be use by GROUP/
* ORDER BY a function or expersion not in the target_list
* - daveh@insightdist.com 1998-07-31
*/
TargetEntry *
MakeTargetlistExpr(ParseState *pstate,
char *colname,
Node *expr,
List *arrayRef,
int16 resjunk)
{
Oid type_id,
attrtype;
int32 type_mod,
attrtypmod;
int resdomno;
Relation rd;
bool attrisset;
TargetEntry *tent;
Resdom *resnode;
if (expr == NULL)
elog(ERROR, "MakeTargetlistExpr: invalid use of NULL expression");
type_id = exprType(expr);
if (nodeTag(expr) == T_Var)
type_mod = ((Var *) expr)->vartypmod;
else
type_mod = -1;
/* Processes target columns that will be receiving results */
if (pstate->p_is_insert || pstate->p_is_update)
{
/*
* insert or update query -- insert, update work only on one
* relation, so multiple occurence of same resdomno is bogus
*/
rd = pstate->p_target_relation;
Assert(rd != NULL);
resdomno = attnameAttNum(rd, colname);
attrisset = attnameIsSet(rd, colname);
attrtype = attnumTypeId(rd, resdomno);
if ((arrayRef != NIL) && (lfirst(arrayRef) == NIL))
attrtype = GetArrayElementType(attrtype);
attrtypmod = rd->rd_att->attrs[resdomno - 1]->atttypmod;
/* Check for InvalidOid since that seems to indicate a NULL constant... */
if (type_id != InvalidOid)
{
/* Mismatch on types? then try to coerce to target... */
if (attrtype != type_id)
{
Oid typelem;
if (arrayRef && !(((A_Indices *) lfirst(arrayRef))->lidx))
typelem = typeidTypElem(attrtype);
else
typelem = attrtype;
expr = CoerceTargetExpr(pstate, expr, type_id, typelem);
if (!HeapTupleIsValid(expr))
elog(ERROR, "parser: attribute '%s' is of type '%s'"
" but expression is of type '%s'"
"\n\tYou will need to rewrite or cast the expression",
colname,
typeidTypeName(attrtype),
typeidTypeName(type_id));
}
#ifdef PARSEDEBUG
printf("MakeTargetlistExpr: attrtypmod is %d\n", (int4) attrtypmod);
#endif
/* Apparently going to a fixed-length string?
* Then explicitly size for storage...
*/
if (attrtypmod > 0)
expr = SizeTargetExpr(pstate, expr, attrtype, attrtypmod);
}
if (arrayRef != NIL)
{
Expr *target_expr;
Attr *att = makeNode(Attr);
List *ar = arrayRef;
List *upperIndexpr = NIL;
List *lowerIndexpr = NIL;
att->relname = pstrdup(RelationGetRelationName(rd)->data);
att->attrs = lcons(makeString(colname), NIL);
target_expr = (Expr *) ParseNestedFuncOrColumn(pstate, att,
&pstate->p_last_resno,
EXPR_COLUMN_FIRST);
while (ar != NIL)
{
A_Indices *ind = lfirst(ar);
if (lowerIndexpr || (!upperIndexpr && ind->lidx))
{
/*
* XXX assume all lowerIndexpr is non-null in this
* case
*/
lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
}
upperIndexpr = lappend(upperIndexpr, ind->uidx);
ar = lnext(ar);
}
expr = (Node *) make_array_set(target_expr,
upperIndexpr,
lowerIndexpr,
(Expr *) expr);
attrtype = attnumTypeId(rd, resdomno);
attrtypmod = get_atttypmod(RelationGetRelid(rd), resdomno);
}
}
else
{
resdomno = pstate->p_last_resno++;
attrtype = type_id;
attrtypmod = type_mod;
}
resnode = makeResdom((AttrNumber) resdomno,
(Oid) attrtype,
attrtypmod,
colname,
(Index) 0,
(Oid) 0,
resjunk);
tent = makeTargetEntry(resnode, expr);
return tent;
} /* MakeTargetlistExpr() */
/* transformTargetList()
* Turns a list of ResTarget's into a list of TargetEntry's.
*/
......@@ -299,7 +447,6 @@ printf("transformTargetList: decode T_Expr\n");
/* this is not an array assignment */
if (colname == NULL)
{
/*
* if you're wondering why this is here, look
* at the yacc grammar for why a name can be
......@@ -559,154 +706,6 @@ printf("SizeTargetExpr: no conversion function for sizing\n");
} /* SizeTargetExpr() */
/* MakeTargetlistExpr()
* Make a TargetEntry from an expression.
* arrayRef is a list of transformed A_Indices.
*
* For type mismatches between expressions and targets, use the same
* techniques as for function and operator type coersion.
* - thomas 1998-05-08
*
* Added resjunk flag and made extern so that it can be use by GROUP/
* ORDER BY a function or expersion not in the target_list
* - daveh@insightdist.com 1998-07-31
*/
TargetEntry *
MakeTargetlistExpr(ParseState *pstate,
char *colname,
Node *expr,
List *arrayRef,
int16 resjunk)
{
Oid type_id,
attrtype;
int32 type_mod,
attrtypmod;
int resdomno;
Relation rd;
bool attrisset;
TargetEntry *tent;
Resdom *resnode;
if (expr == NULL)
elog(ERROR, "MakeTargetlistExpr: invalid use of NULL expression");
type_id = exprType(expr);
if (nodeTag(expr) == T_Var)
type_mod = ((Var *) expr)->vartypmod;
else
type_mod = -1;
/* Processes target columns that will be receiving results */
if (pstate->p_is_insert || pstate->p_is_update)
{
/*
* insert or update query -- insert, update work only on one
* relation, so multiple occurence of same resdomno is bogus
*/
rd = pstate->p_target_relation;
Assert(rd != NULL);
resdomno = attnameAttNum(rd, colname);
attrisset = attnameIsSet(rd, colname);
attrtype = attnumTypeId(rd, resdomno);
if ((arrayRef != NIL) && (lfirst(arrayRef) == NIL))
attrtype = GetArrayElementType(attrtype);
attrtypmod = rd->rd_att->attrs[resdomno - 1]->atttypmod;
/* Check for InvalidOid since that seems to indicate a NULL constant... */
if (type_id != InvalidOid)
{
/* Mismatch on types? then try to coerce to target... */
if (attrtype != type_id)
{
Oid typelem;
if (arrayRef && !(((A_Indices *) lfirst(arrayRef))->lidx))
typelem = typeidTypElem(attrtype);
else
typelem = attrtype;
expr = CoerceTargetExpr(pstate, expr, type_id, typelem);
if (!HeapTupleIsValid(expr))
elog(ERROR, "parser: attribute '%s' is of type '%s'"
" but expression is of type '%s'"
"\n\tYou will need to rewrite or cast the expression",
colname,
typeidTypeName(attrtype),
typeidTypeName(type_id));
}
#ifdef PARSEDEBUG
printf("MakeTargetlistExpr: attrtypmod is %d\n", (int4) attrtypmod);
#endif
/* Apparently going to a fixed-length string?
* Then explicitly size for storage...
*/
if (attrtypmod > 0)
expr = SizeTargetExpr(pstate, expr, attrtype, attrtypmod);
}
if (arrayRef != NIL)
{
Expr *target_expr;
Attr *att = makeNode(Attr);
List *ar = arrayRef;
List *upperIndexpr = NIL;
List *lowerIndexpr = NIL;
att->relname = pstrdup(RelationGetRelationName(rd)->data);
att->attrs = lcons(makeString(colname), NIL);
target_expr = (Expr *) ParseNestedFuncOrColumn(pstate, att,
&pstate->p_last_resno,
EXPR_COLUMN_FIRST);
while (ar != NIL)
{
A_Indices *ind = lfirst(ar);
if (lowerIndexpr || (!upperIndexpr && ind->lidx))
{
/*
* XXX assume all lowerIndexpr is non-null in this
* case
*/
lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
}
upperIndexpr = lappend(upperIndexpr, ind->uidx);
ar = lnext(ar);
}
expr = (Node *) make_array_set(target_expr,
upperIndexpr,
lowerIndexpr,
(Expr *) expr);
attrtype = attnumTypeId(rd, resdomno);
attrtypmod = get_atttypmod(RelationGetRelid(rd), resdomno);
}
}
else
{
resdomno = pstate->p_last_resno++;
attrtype = type_id;
attrtypmod = type_mod;
}
resnode = makeResdom((AttrNumber) resdomno,
(Oid) attrtype,
attrtypmod,
colname,
(Index) 0,
(Oid) 0,
resjunk);
tent = makeTargetEntry(resnode, expr);
return tent;
} /* MakeTargetlistExpr() */
/*
* makeTargetNames -
* generate a list of column names if not supplied or
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment