Allow floating point constants for "def_arg" numeric arguments.

Used in the generic "CREATE xxx" parsing.
Do some automatic type conversion for inserts from other columns.
Previous trouble with "resjunk" regression test remains for now.
REL6_4
Thomas G. Lockhart 28 years ago
parent fa838876e9
commit 92ed9294de
  1. 25
      src/backend/parser/gram.y
  2. 32
      src/backend/parser/parse_clause.c
  3. 4
      src/backend/parser/parse_coerce.c
  4. 6
      src/backend/parser/parse_expr.c
  5. 13
      src/backend/parser/parse_func.c
  6. 36
      src/backend/parser/parse_relation.c
  7. 294
      src/backend/parser/parse_target.c

@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.12 1998/05/09 23:22:15 thomas Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.13 1998/07/08 14:04:09 thomas Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@ -204,8 +204,7 @@ Oid param_type(int t); /* used in parse_expr.c */
%type <ival> sub_type
%type <list> OptCreateAs, CreateAsList
%type <node> CreateAsElement
%type <value> NumConst
%type <value> IntegerOnly
%type <value> NumericOnly, FloatOnly, IntegerOnly
%type <attr> event_object, attr
%type <sortgroupby> groupby
%type <sortgroupby> sortby
@ -1180,6 +1179,20 @@ OptSeqElem: CACHE IntegerOnly
}
;
NumericOnly: FloatOnly { $$ = $1; }
| IntegerOnly { $$ = $1; }
FloatOnly: FCONST
{
$$ = makeFloat($1);
}
| '-' FCONST
{
$$ = makeFloat($2);
$$->val.dval = - $$->val.dval;
}
;
IntegerOnly: Iconst
{
$$ = makeInteger($1);
@ -1384,7 +1397,7 @@ def_elem: def_name '=' def_arg
def_arg: ColId { $$ = (Node *)makeString($1); }
| all_Op { $$ = (Node *)makeString($1); }
| NumConst { $$ = (Node *)$1; /* already a Value */ }
| NumericOnly { $$ = (Node *)$1; }
| Sconst { $$ = (Node *)makeString($1); }
| SETOF ColId
{
@ -4442,10 +4455,6 @@ ParamNo: PARAM
}
;
NumConst: Iconst { $$ = makeInteger($1); }
| FCONST { $$ = makeFloat($1); }
;
Iconst: ICONST { $$ = $1; };
Sconst: SCONST { $$ = $1; };
UserId: IDENT { $$ = $1; };

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.18 1998/06/05 03:49:18 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.19 1998/07/08 14:04:10 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@ -198,29 +198,31 @@ find_targetlist_entry(ParseState *pstate, SortGroupBy *sortgroupby, List *tlist)
List *p_target = tlist;
TargetEntry *tent = makeNode(TargetEntry);
if (sortgroupby->range) {
Attr *missingTarget = (Attr *)makeNode(Attr);
missingTarget->type = T_Attr;
Attr *missingAttr = (Attr *)makeNode(Attr);
missingAttr->type = T_Attr;
missingTarget->relname = palloc(strlen(sortgroupby->range) + 1);
strcpy(missingTarget->relname, sortgroupby->range);
missingAttr->relname = palloc(strlen(sortgroupby->range) + 1);
strcpy(missingAttr->relname, sortgroupby->range);
missingTarget->attrs = lcons(makeString(sortgroupby->name), NIL);
missingAttr->attrs = lcons(makeString(sortgroupby->name), NIL);
transformTargetId(pstate, (Node*)missingTarget, tent, sortgroupby->name, TRUE);
tent = transformTargetIdent(pstate, (Node *)missingAttr, tent,
&missingAttr->relname, NULL,
missingAttr->relname, TRUE);
}
else {
Ident *missingTarget = (Ident *)makeNode(Ident);
missingTarget->type = T_Ident;
Ident *missingIdent = (Ident *)makeNode(Ident);
missingIdent->type = T_Ident;
missingTarget->name = palloc(strlen(sortgroupby->name) + 1);
strcpy(missingTarget->name, sortgroupby->name);
missingIdent->name = palloc(strlen(sortgroupby->name) + 1);
strcpy(missingIdent->name, sortgroupby->name);
transformTargetId(pstate, (Node*)missingTarget, tent, sortgroupby->name, TRUE);
tent = transformTargetIdent(pstate, (Node *)missingIdent, tent,
&missingIdent->name, NULL,
missingIdent->name, TRUE);
}
/* Add to the end of the target list */
while (lnext(p_target) != NIL) {
p_target = lnext(p_target);
@ -457,7 +459,7 @@ transformUnionClause(List *unionClause, List *targetlist)
Node *expr;
expr = ((TargetEntry *)lfirst(next_target))->expr;
expr = coerce_target_expr(NULL, expr, itype, otype);
expr = CoerceTargetExpr(NULL, expr, itype, otype);
if (expr == NULL)
{
elog(ERROR,"Unable to transform %s to %s"

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.2 1998/05/29 14:00:20 thomas Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.3 1998/07/08 14:04:10 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@ -273,6 +273,7 @@ TypeCategory(Oid inType)
case (INT2OID):
case (INT4OID):
case (INT8OID):
case (FLOAT4OID):
case (FLOAT8OID):
case (CASHOID):
@ -387,6 +388,7 @@ PromoteTypeToNext(Oid inType)
break;
case (INT4OID):
case (INT8OID):
case (FLOAT4OID):
result = FLOAT8OID;
break;

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.30 1998/06/15 19:28:54 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.31 1998/07/08 14:04:10 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@ -312,6 +312,10 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
case T_Expr:
case T_Var:
case T_Const:
/* T_Param comes from implicit function calls in INSERT/VALUE statements.
* - thomas 1998-06-11
*/
case T_Param:
{
result = (Node *) expr;
break;

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.19 1998/06/15 19:28:55 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.20 1998/07/08 14:04:10 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@ -153,7 +153,6 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
Oid *true_oid_array;
Node *retval;
bool retset;
bool exists;
bool attisset = false;
Oid toid = (Oid) 0;
Expr *expr;
@ -370,16 +369,18 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
rettype = toid;
retset = true;
true_oid_array = oid_array;
exists = true;
}
else
{
bool exists;
exists = func_get_detail(funcname, nargs, oid_array, &funcid,
&rettype, &retset, &true_oid_array);
}
if (!exists)
elog(ERROR, "No such function '%s' with the specified attributes",
funcname);
if (!exists)
elog(ERROR, "No such attribute or function '%s'", funcname);
}
/* got it */
funcnode = makeNode(Func);

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.11 1998/02/26 04:33:34 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.12 1998/07/08 14:04:11 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@ -20,6 +20,7 @@
#include "catalog/pg_type.h"
#include "nodes/makefuncs.h"
#include "parser/parse_relation.h"
#include "parser/parse_coerce.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
@ -371,9 +372,8 @@ attnumTypeId(Relation rd, int attid)
return (rd->rd_att->attrs[attid - 1]->atttypid);
}
/*
* handleTargetColname -
* use column names from insert
/* handleTargetColname()
* Use column names from insert.
*/
void
handleTargetColname(ParseState *pstate, char **resname,
@ -395,9 +395,8 @@ handleTargetColname(ParseState *pstate, char **resname,
checkTargetTypes(pstate, *resname, refname, colname);
}
/*
* checkTargetTypes -
* checks value and target column types
/* checkTargetTypes()
* Checks value and target column types.
*/
static void
checkTargetTypes(ParseState *pstate, char *target_colname,
@ -432,6 +431,27 @@ checkTargetTypes(ParseState *pstate, char *target_colname,
resdomno_target = attnameAttNum(pstate->p_target_relation, target_colname);
attrtype_target = attnumTypeId(pstate->p_target_relation, resdomno_target);
#if FALSE
if ((attrtype_id != attrtype_target)
|| (get_atttypmod(rte->relid, resdomno_id) !=
get_atttypmod(pstate->p_target_relation->rd_id, resdomno_target)))
{
if (can_coerce_type(1, &attrtype_id, &attrtype_target))
{
Node *expr = coerce_type(pstate, expr, attrtype_id, attrtype_target);
elog(ERROR, "Type %s(%d) can be coerced to match target column %s(%d)",
colname, get_atttypmod(rte->relid, resdomno_id),
target_colname, get_atttypmod(pstate->p_target_relation->rd_id, resdomno_target));
}
else
{
elog(ERROR, "Type or size of %s(%d) does not match target column %s(%d)",
colname, get_atttypmod(rte->relid, resdomno_id),
target_colname, get_atttypmod(pstate->p_target_relation->rd_id, resdomno_target));
}
}
#else
if (attrtype_id != attrtype_target)
elog(ERROR, "Type of %s does not match target column %s",
colname, target_colname);
@ -446,5 +466,5 @@ checkTargetTypes(ParseState *pstate, char *target_colname,
get_atttypmod(pstate->p_target_relation->rd_id, resdomno_target))
elog(ERROR, "Length of %s is longer than length of target column %s",
colname, target_colname);
#endif
}

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.16 1998/06/15 19:28:55 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.17 1998/07/08 14:04:11 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@ -30,67 +30,169 @@
#include "utils/syscache.h"
static List *expandAllTables(ParseState *pstate);
static char *figureColname(Node *expr, Node *resval);
static List *ExpandAllTables(ParseState *pstate);
static char *FigureColname(Node *expr, Node *resval);
static TargetEntry *
make_targetlist_expr(ParseState *pstate,
char *colname,
Node *expr,
List *arrayRef);
MakeTargetlistExpr(ParseState *pstate,
char *colname,
Node *expr,
List *arrayRef);
Node *
size_target_expr(ParseState *pstate,
Node *expr,
Oid attrtype,
int16 attrtypmod);
SizeTargetExpr(ParseState *pstate,
Node *expr,
Oid attrtype,
int16 attrtypmod);
/*
* transformTargetId - transforms an Ident Node to a Target Entry
* Created this a function to allow the ORDER/GROUP BY clause be able
* to construct a TargetEntry from an Ident.
/* transformTargetIdent()
* Transforms an Ident Node to a Target Entry
* Created this function to allow the ORDER/GROUP BY clause to be able
* to construct a TargetEntry from an Ident.
*
* resjunk = TRUE will hide the target entry in the final result tuple.
* daveh@insightdist.com 5/20/98
* resjunk = TRUE will hide the target entry in the final result tuple.
* daveh@insightdist.com 5/20/98
*
* Added more conversion logic to match up types from source to target.
* - thomas 1998-06-02
*/
void
transformTargetId(ParseState *pstate,
Node *node,
TargetEntry *tent,
char *resname,
int16 resjunk)
TargetEntry *
transformTargetIdent(ParseState *pstate,
#if FALSE
Ident *ident,
#else
Node *node,
#endif
TargetEntry *tent,
char **resname,
char *refname,
char *colname,
int16 resjunk)
{
Node *expr;
Oid type_id;
int16 type_mod;
Node *expr = NULL;
Oid attrtype_target;
if (pstate->p_is_insert)
{
if (pstate->p_insert_columns != NIL)
{
Ident *id = lfirst(pstate->p_insert_columns);
*resname = id->name;
pstate->p_insert_columns = lnext(pstate->p_insert_columns);
}
else
elog(ERROR, "insert: more expressions than target columns");
}
if (pstate->p_is_insert || pstate->p_is_update)
{
Oid attrtype_id;
int resdomno_id,
resdomno_target;
RangeTblEntry *rte;
char *target_colname;
int16 attrtypmod,
attrtypmod_target;
target_colname = *resname;
if (target_colname == NULL || colname == NULL)
return (tent);
if (refname != NULL)
rte = refnameRangeTableEntry(pstate, refname);
else
{
rte = colnameRangeTableEntry(pstate, colname);
if (rte == (RangeTblEntry *) NULL)
elog(ERROR, "attribute %s not found", colname);
refname = rte->refname;
}
resdomno_id = get_attnum(rte->relid, colname);
attrtype_id = get_atttype(rte->relid, resdomno_id);
attrtypmod = get_atttypmod(rte->relid, resdomno_id);
resdomno_target = attnameAttNum(pstate->p_target_relation, target_colname);
attrtype_target = attnumTypeId(pstate->p_target_relation, resdomno_target);
attrtypmod_target = get_atttypmod(pstate->p_target_relation->rd_id, resdomno_target);
#ifdef PARSEDEBUG
printf("transformTargetIdent- transform type %d to %d\n",
attrtype_id, attrtype_target);
#endif
if ((attrtype_id != attrtype_target)
|| ((attrtypmod_target >= 0) && (attrtypmod_target != attrtypmod)))
{
if (can_coerce_type(1, &attrtype_id, &attrtype_target))
{
expr = coerce_type(pstate, node, attrtype_id, attrtype_target);
expr = transformExpr(pstate, expr, EXPR_COLUMN_FIRST);
tent = MakeTargetlistExpr(pstate, *resname, expr, FALSE);
expr = tent->expr;
}
else
{
#if TRUE
elog(ERROR, "Unable to convert %s to %s for column %s",
typeidTypeName(attrtype_id), typeidTypeName(attrtype_target),
target_colname);
#else
elog(ERROR, "Type or size of %s(%d) does not match target column %s(%d)",
colname, attrtypmod, target_colname, attrtypmod_target);
#endif
}
}
}
/*
* here we want to look for column names only, not
* relation names (even though they can be stored in
* Ident nodes, too)
*/
expr = transformExpr(pstate, node, EXPR_COLUMN_FIRST);
type_id = exprType(expr);
if (nodeTag(expr) == T_Var)
type_mod = ((Var *) expr)->vartypmod;
else
type_mod = -1;
tent->resdom = makeResdom((AttrNumber) pstate->p_last_resno++,
(Oid) type_id,
type_mod,
resname,
(Index) 0,
(Oid) 0,
resjunk);
if (expr == NULL)
{
char *name;
int16 type_mod;
tent->expr = expr;
return;
}
name = ((*resname != NULL)? *resname: colname);
#ifdef PARSEDEBUG
printf("transformTargetIdent- call transformIdent()\n");
#endif
#if FALSE
expr = transformIdent(pstate, (Node *) ident, EXPR_COLUMN_FIRST);
#else
expr = transformExpr(pstate, node, EXPR_COLUMN_FIRST);
#endif
attrtype_target = exprType(expr);
if (nodeTag(expr) == T_Var)
type_mod = ((Var *) expr)->vartypmod;
else
type_mod = -1;
/*
* transformTargetList -
* turns a list of ResTarget's into a list of TargetEntry's
#ifdef PARSEDEBUG
printf("transformTargetIdent- attrtype_target = %d; type_mod = %d\n", attrtype_target, type_mod);
#endif
tent->resdom = makeResdom((AttrNumber) pstate->p_last_resno++,
(Oid) attrtype_target,
type_mod,
name,
(Index) 0,
(Oid) 0,
resjunk);
tent->expr = expr;
}
return (tent);
} /* transformTargetIdent() */
/* transformTargetList()
* Turns a list of ResTarget's into a list of TargetEntry's.
*/
List *
transformTargetList(ParseState *pstate, List *targetlist)
@ -100,20 +202,23 @@ transformTargetList(ParseState *pstate, List *targetlist)
while (targetlist != NIL)
{
ResTarget *res = (ResTarget *) lfirst(targetlist);
TargetEntry *tent = makeNode(TargetEntry);
ResTarget *res = (ResTarget *) lfirst(targetlist);
TargetEntry *tent = makeNode(TargetEntry);
switch (nodeTag(res->val))
{
case T_Ident:
{
char *identname;
#if FALSE
char *resname;
#endif
#ifdef PARSEDEBUG
printf("transformTargetList: decode T_Ident\n");
#endif
identname = ((Ident *) res->val)->name;
handleTargetColname(pstate, &res->name, NULL, identname);
resname = (res->name) ? res->name : identname;
transformTargetId(pstate, (Node*)res->val, tent, resname, FALSE);
tent = transformTargetIdent(pstate, (Node *)res->val, tent, &res->name, NULL, identname, FALSE);
break;
}
case T_ParamNo:
@ -121,8 +226,11 @@ transformTargetList(ParseState *pstate, List *targetlist)
case T_A_Const:
case T_A_Expr:
{
Node *expr = transformExpr(pstate, (Node *) res->val, EXPR_COLUMN_FIRST);
Node *expr = transformExpr(pstate, (Node *) res->val, EXPR_COLUMN_FIRST);
#ifdef PARSEDEBUG
printf("transformTargetList: decode T_Expr\n");
#endif
handleTargetColname(pstate, &res->name, NULL, NULL);
/* note indirection has not been transformed */
if (pstate->p_is_insert && res->indirection != NIL)
@ -183,9 +291,9 @@ transformTargetList(ParseState *pstate, List *targetlist)
constval = makeNode(Value);
constval->type = T_String;
constval->val.str = save_str;
tent = make_targetlist_expr(pstate, res->name,
(Node *) make_const(constval),
NULL);
tent = MakeTargetlistExpr(pstate, res->name,
(Node *) make_const(constval),
NULL);
pfree(save_str);
}
else
@ -201,7 +309,7 @@ transformTargetList(ParseState *pstate, List *targetlist)
* at the yacc grammar for why a name can be
* missing. -ay
*/
colname = figureColname(expr, res->val);
colname = FigureColname(expr, res->val);
}
if (res->indirection)
{
@ -217,8 +325,8 @@ transformTargetList(ParseState *pstate, List *targetlist)
}
}
res->name = colname;
tent = make_targetlist_expr(pstate, res->name, expr,
res->indirection);
tent = MakeTargetlistExpr(pstate, res->name, expr,
res->indirection);
}
break;
}
@ -240,9 +348,9 @@ transformTargetList(ParseState *pstate, List *targetlist)
if (att->relname != NULL && !strcmp(att->relname, "*"))
{
if (tail_p_target == NIL)
p_target = tail_p_target = expandAllTables(pstate);
p_target = tail_p_target = ExpandAllTables(pstate);
else
lnext(tail_p_target) = expandAllTables(pstate);
lnext(tail_p_target) = ExpandAllTables(pstate);
while (lnext(tail_p_target) != NIL)
/* make sure we point to the last target entry */
@ -291,6 +399,9 @@ transformTargetList(ParseState *pstate, List *targetlist)
* Target item is fully specified: ie.
* relation.attribute
*/
#ifdef PARSEDEBUG
printf("transformTargetList: decode T_Attr\n");
#endif
result = ParseNestedFuncOrColumn(pstate, att, &pstate->p_last_resno, EXPR_COLUMN_FIRST);
handleTargetColname(pstate, &res->name, att->relname, attrname);
if (att->indirection != NIL)
@ -348,15 +459,15 @@ transformTargetList(ParseState *pstate, List *targetlist)
Node *
coerce_target_expr(ParseState *pstate,
Node *expr,
Oid type_id,
Oid attrtype)
CoerceTargetExpr(ParseState *pstate,
Node *expr,
Oid type_id,
Oid attrtype)
{
if (can_coerce_type(1, &type_id, &attrtype))
{
#ifdef PARSEDEBUG
printf("parse_target: coerce type from %s to %s\n",
printf("CoerceTargetExpr: coerce type from %s to %s\n",
typeidTypeName(type_id), typeidTypeName(attrtype));
#endif
expr = coerce_type(pstate, expr, type_id, attrtype);
@ -368,7 +479,7 @@ printf("parse_target: coerce type from %s to %s\n",
{
Oid text_id = TEXTOID;
#ifdef PARSEDEBUG
printf("parse_target: try coercing from %s to %s via text\n",
printf("CoerceTargetExpr: try coercing from %s to %s via text\n",
typeidTypeName(type_id), typeidTypeName(attrtype));
#endif
if (type_id == TEXTOID)
@ -385,18 +496,18 @@ printf("parse_target: try coercing from %s to %s via text\n",
expr = NULL;
return expr;
} /* coerce_target_expr() */
} /* CoerceTargetExpr() */
/* size_target_expr()
/* SizeTargetExpr()
* Apparently going to a fixed-length string?
* Then explicitly size for storage...
*/
Node *
size_target_expr(ParseState *pstate,
Node *expr,
Oid attrtype,
int16 attrtypmod)
SizeTargetExpr(ParseState *pstate,
Node *expr,
Oid attrtype,
int16 attrtypmod)
{
int i;
HeapTuple ftup;
@ -407,7 +518,7 @@ size_target_expr(ParseState *pstate,
A_Const *cons;
#ifdef PARSEDEBUG
printf("parse_target: ensure target fits storage\n");
printf("SizeTargetExpr: ensure target fits storage\n");
#endif
funcname = typeidTypeName(attrtype);
oid_array[0] = attrtype;
@ -415,7 +526,7 @@ printf("parse_target: ensure target fits storage\n");
for (i = 2; i < 8; i++) oid_array[i] = InvalidOid;
#ifdef PARSEDEBUG
printf("parse_target: look for conversion function %s(%s,%s)\n",
printf("SizeTargetExpr: look for conversion function %s(%s,%s)\n",
funcname, typeidTypeName(attrtype), typeidTypeName(INT4OID));
#endif
@ -429,7 +540,7 @@ printf("parse_target: look for conversion function %s(%s,%s)\n",
if (HeapTupleIsValid(ftup))
{
#ifdef PARSEDEBUG
printf("parse_target: found conversion function for sizing\n");
printf("SizeTargetExpr: found conversion function for sizing\n");
#endif
func = makeNode(FuncCall);
func->funcname = funcname;
@ -444,25 +555,24 @@ printf("parse_target: found conversion function for sizing\n");
#ifdef PARSEDEBUG
else
{
printf("parse_target: no conversion function for sizing\n");
printf("SizeTargetExpr: no conversion function for sizing\n");
}
#endif
return expr;
} /* size_target_expr() */
} /* SizeTargetExpr() */
/* make_targetlist_expr()
* Make a TargetEntry from an expression
*
* arrayRef is a list of transformed A_Indices
/* 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
*/
static TargetEntry *
make_targetlist_expr(ParseState *pstate,
MakeTargetlistExpr(ParseState *pstate,
char *colname,
Node *expr,
List *arrayRef)
@ -478,7 +588,7 @@ make_targetlist_expr(ParseState *pstate,
Resdom *resnode;
if (expr == NULL)
elog(ERROR, "make_targetlist_expr: invalid use of NULL expression");
elog(ERROR, "MakeTargetlistExpr: invalid use of NULL expression");
type_id = exprType(expr);
if (nodeTag(expr) == T_Var)
@ -515,28 +625,26 @@ make_targetlist_expr(ParseState *pstate,
else
typelem = attrtype;
expr = coerce_target_expr(pstate, expr, type_id, typelem);
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("parse_target: attrtypmod is %d\n", (int4) attrtypmod);
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 = size_target_expr(pstate, expr, attrtype, attrtypmod);
expr = SizeTargetExpr(pstate, expr, attrtype, attrtypmod);
}
if (arrayRef != NIL)
@ -583,8 +691,8 @@ printf("parse_target: attrtypmod is %d\n", (int4) attrtypmod);
attrtype = type_id;
attrtypmod = type_mod;
}
tent = makeNode(TargetEntry);
tent = makeNode(TargetEntry);
resnode = makeResdom((AttrNumber) resdomno,
(Oid) attrtype,
attrtypmod,
@ -597,7 +705,7 @@ printf("parse_target: attrtypmod is %d\n", (int4) attrtypmod);
tent->expr = expr;
return tent;
} /* make_targetlist_expr() */
} /* MakeTargetlistExpr() */
/*
@ -656,12 +764,12 @@ makeTargetNames(ParseState *pstate, List *cols)
}
/*
* expandAllTables -
* ExpandAllTables -
* turns '*' (in the target list) into a list of attributes
* (of all relations in the range table)
*/
static List *
expandAllTables(ParseState *pstate)
ExpandAllTables(ParseState *pstate)
{
List *target = NIL;
List *legit_rtable = NIL;
@ -720,13 +828,13 @@ expandAllTables(ParseState *pstate)
}
/*
* figureColname -
* FigureColname -
* if the name of the resulting column is not specified in the target
* list, we have to guess.
*
*/
static char *
figureColname(Node *expr, Node *resval)
FigureColname(Node *expr, Node *resval)
{
switch (nodeTag(expr))
{

Loading…
Cancel
Save