aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_target.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>1998-08-23 14:43:46 +0000
committerBruce Momjian <bruce@momjian.us>1998-08-23 14:43:46 +0000
commit9cad9febb172b09ff8c2366a4e19469926304f0d (patch)
tree97bd069a86eb595435d58273826ea6ee9b6c6f3a /src/backend/parser/parse_target.c
parent985f4ab98ab5f5bbf3902c158abcb675ab6889a8 (diff)
downloadpostgresql-9cad9febb172b09ff8c2366a4e19469926304f0d.tar.gz
postgresql-9cad9febb172b09ff8c2366a4e19469926304f0d.zip
cleanup
Diffstat (limited to 'src/backend/parser/parse_target.c')
-rw-r--r--src/backend/parser/parse_target.c299
1 files changed, 149 insertions, 150 deletions
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index a71df492799..b54e1b6786d 100644
--- a/src/backend/parser/parse_target.c
+++ b/src/backend/parser/parse_target.c
@@ -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