parse_expr.c 20.7 KB
Newer Older
1 2 3 4 5 6 7 8 9
/*-------------------------------------------------------------------------
 *
 * parse_expr.c
 *	  handle expressions in parser
 *
 * Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
10
 *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.66 2000/01/17 02:04:16 tgl Exp $
11 12 13 14 15
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"
16 17

#include "catalog/pg_operator.h"
18 19 20
#include "nodes/makefuncs.h"
#include "nodes/params.h"
#include "nodes/relation.h"
Bruce Momjian's avatar
Bruce Momjian committed
21
#include "parse.h"
22
#include "parser/analyze.h"
23
#include "parser/gramparse.h"
Bruce Momjian's avatar
Bruce Momjian committed
24
#include "parser/parse_coerce.h"
25 26
#include "parser/parse_expr.h"
#include "parser/parse_func.h"
27
#include "parser/parse_oper.h"
28 29 30 31
#include "parser/parse_relation.h"
#include "parser/parse_target.h"
#include "utils/builtins.h"

32 33 34
static Node *parser_typecast_constant(Value *expr, TypeName *typename);
static Node *parser_typecast_expression(ParseState *pstate,
										Node *expr, TypeName *typename);
35 36 37
static Node *transformAttr(ParseState *pstate, Attr *att, int precedence);
static Node *transformIdent(ParseState *pstate, Ident *ident, int precedence);
static Node *transformIndirection(ParseState *pstate, Node *basenode,
38
								  List *indirection);
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58

/*
 * transformExpr -
 *	  analyze and transform expressions. Type checking and type casting is
 *	  done here. The optimizer and the executor cannot handle the original
 *	  (raw) expressions collected by the parse tree. Hence the transformation
 *	  here.
 */
Node *
transformExpr(ParseState *pstate, Node *expr, int precedence)
{
	Node	   *result = NULL;

	if (expr == NULL)
		return NULL;

	switch (nodeTag(expr))
	{
		case T_Attr:
			{
59
				result = transformAttr(pstate, (Attr *) expr, precedence);
60 61 62 63 64 65 66 67
				break;
			}
		case T_A_Const:
			{
				A_Const    *con = (A_Const *) expr;
				Value	   *val = &con->val;

				if (con->typename != NULL)
68
					result = parser_typecast_constant(val, con->typename);
69 70 71 72 73 74 75
				else
					result = (Node *) make_const(val);
				break;
			}
		case T_ParamNo:
			{
				ParamNo    *pno = (ParamNo *) expr;
76 77
				int			paramno = pno->number;
				Oid			toid = param_type(paramno);
78 79 80
				Param	   *param;

				if (!OidIsValid(toid))
81
					elog(ERROR, "Parameter '$%d' is out of range", paramno);
82 83 84 85 86 87
				param = makeNode(Param);
				param->paramkind = PARAM_NUM;
				param->paramid = (AttrNumber) paramno;
				param->paramname = "<unnamed>";
				param->paramtype = (Oid) toid;
				param->param_tlist = (List *) NULL;
88
				result = transformIndirection(pstate, (Node *) param,
89
											  pno->indirection);
90 91 92 93 94 95 96 97 98
				/* XXX what about cast (typename) applied to Param ??? */
				break;
			}
		case T_TypeCast:
			{
				TypeCast   *tc = (TypeCast *) expr;
				Node	   *arg = transformExpr(pstate, tc->arg, precedence);

				result = parser_typecast_expression(pstate, arg, tc->typename);
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
				break;
			}
		case T_A_Expr:
			{
				A_Expr	   *a = (A_Expr *) expr;

				switch (a->oper)
				{
					case OP:
						{
							Node	   *lexpr = transformExpr(pstate, a->lexpr, precedence);
							Node	   *rexpr = transformExpr(pstate, a->rexpr, precedence);

							result = (Node *) make_op(a->opname, lexpr, rexpr);
						}
						break;
					case ISNULL:
						{
							Node	   *lexpr = transformExpr(pstate, a->lexpr, precedence);

Bruce Momjian's avatar
Bruce Momjian committed
119
							result = ParseFuncOrColumn(pstate,
120 121 122 123
													   "nullvalue",
													   lcons(lexpr, NIL),
													   false, false,
													   &pstate->p_last_resno,
124
													   precedence);
125 126 127 128 129 130
						}
						break;
					case NOTNULL:
						{
							Node	   *lexpr = transformExpr(pstate, a->lexpr, precedence);

Bruce Momjian's avatar
Bruce Momjian committed
131
							result = ParseFuncOrColumn(pstate,
132 133 134 135
													   "nonnullvalue",
													   lcons(lexpr, NIL),
													   false, false,
													   &pstate->p_last_resno,
136
													   precedence);
137 138 139 140 141 142 143 144 145
						}
						break;
					case AND:
						{
							Expr	   *expr = makeNode(Expr);
							Node	   *lexpr = transformExpr(pstate, a->lexpr, precedence);
							Node	   *rexpr = transformExpr(pstate, a->rexpr, precedence);

							if (exprType(lexpr) != BOOLOID)
146
								elog(ERROR, "left-hand side of AND is type '%s', not bool",
147
									 typeidTypeName(exprType(lexpr)));
148

149
							if (exprType(rexpr) != BOOLOID)
150
								elog(ERROR, "right-hand side of AND is type '%s', not bool",
151
									 typeidTypeName(exprType(rexpr)));
152

153 154 155 156 157 158 159 160 161 162 163 164 165
							expr->typeOid = BOOLOID;
							expr->opType = AND_EXPR;
							expr->args = makeList(lexpr, rexpr, -1);
							result = (Node *) expr;
						}
						break;
					case OR:
						{
							Expr	   *expr = makeNode(Expr);
							Node	   *lexpr = transformExpr(pstate, a->lexpr, precedence);
							Node	   *rexpr = transformExpr(pstate, a->rexpr, precedence);

							if (exprType(lexpr) != BOOLOID)
166
								elog(ERROR, "left-hand side of OR is type '%s', not bool",
167 168
									 typeidTypeName(exprType(lexpr)));
							if (exprType(rexpr) != BOOLOID)
169
								elog(ERROR, "right-hand side of OR is type '%s', not bool",
170 171 172 173 174 175 176 177 178 179 180 181 182
									 typeidTypeName(exprType(rexpr)));
							expr->typeOid = BOOLOID;
							expr->opType = OR_EXPR;
							expr->args = makeList(lexpr, rexpr, -1);
							result = (Node *) expr;
						}
						break;
					case NOT:
						{
							Expr	   *expr = makeNode(Expr);
							Node	   *rexpr = transformExpr(pstate, a->rexpr, precedence);

							if (exprType(rexpr) != BOOLOID)
183
								elog(ERROR, "argument to NOT is type '%s', not bool",
184 185 186 187 188 189 190 191 192 193 194 195
									 typeidTypeName(exprType(rexpr)));
							expr->typeOid = BOOLOID;
							expr->opType = NOT_EXPR;
							expr->args = makeList(rexpr, -1);
							result = (Node *) expr;
						}
						break;
				}
				break;
			}
		case T_Ident:
			{
196
				result = transformIdent(pstate, (Ident *) expr, precedence);
197 198 199 200 201 202 203 204 205 206
				break;
			}
		case T_FuncCall:
			{
				FuncCall   *fn = (FuncCall *) expr;
				List	   *args;

				/* transform the list of arguments */
				foreach(args, fn->args)
					lfirst(args) = transformExpr(pstate, (Node *) lfirst(args), precedence);
Bruce Momjian's avatar
Bruce Momjian committed
207
				result = ParseFuncOrColumn(pstate,
208 209
										   fn->funcname,
										   fn->args,
210 211
										   fn->agg_star,
										   fn->agg_distinct,
212
										   &pstate->p_last_resno,
213
										   precedence);
214 215
				break;
			}
216 217
		case T_SubLink:
			{
218
				SubLink    *sublink = (SubLink *) expr;
219 220
				List	   *qtrees;
				Query	   *qtree;
Bruce Momjian's avatar
Bruce Momjian committed
221 222

				pstate->p_hasSubLinks = true;
223 224
				qtrees = parse_analyze(lcons(sublink->subselect, NIL), pstate);
				if (length(qtrees) != 1)
225
					elog(ERROR, "parser: bad query in subselect");
226 227 228 229 230
				qtree = (Query *) lfirst(qtrees);
				if (qtree->commandType != CMD_SELECT ||
					qtree->resultRelation != 0)
					elog(ERROR, "parser: bad query in subselect");
				sublink->subselect = (Node *) qtree;
231

232 233 234 235 236 237 238 239
				if (sublink->subLinkType == EXISTS_SUBLINK)
				{
					/* EXISTS needs no lefthand or combining operator.
					 * These fields should be NIL already, but make sure.
					 */
					sublink->lefthand = NIL;
					sublink->oper = NIL;
				}
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
				else if (sublink->subLinkType == EXPR_SUBLINK)
				{
					List	   *tlist = qtree->targetList;

					/* Make sure the subselect delivers a single column
					 * (ignoring resjunk targets).
					 */
					if (tlist == NIL ||
						((TargetEntry *) lfirst(tlist))->resdom->resjunk)
						elog(ERROR, "parser: subselect must have a field");
					while ((tlist = lnext(tlist)) != NIL)
					{
						if (! ((TargetEntry *) lfirst(tlist))->resdom->resjunk)
							elog(ERROR, "parser: subselect must have only one field");
					}
					/* EXPR needs no lefthand or combining operator.
					 * These fields should be NIL already, but make sure.
					 */
					sublink->lefthand = NIL;
					sublink->oper = NIL;
				}
261
				else
262
				{
263
					/* ALL, ANY, or MULTIEXPR: generate operator list */
264
					char	   *op = lfirst(sublink->oper);
265 266
					List	   *left_list = sublink->lefthand;
					List	   *right_list = qtree->targetList;
267
					List	   *elist;
Bruce Momjian's avatar
Bruce Momjian committed
268

269 270 271
					foreach(elist, left_list)
						lfirst(elist) = transformExpr(pstate, lfirst(elist),
													  precedence);
272

273 274
					/* Combining operators other than =/<> is dubious... */
					if (length(left_list) != 1 &&
275
						strcmp(op, "=") != 0 && strcmp(op, "<>") != 0)
276
						elog(ERROR, "parser: '%s' is not usable for row comparison",
277
							 op);
278

279
					sublink->oper = NIL;
280 281 282 283 284 285 286

					/* Scan subquery's targetlist to find values that will be
					 * matched against lefthand values.  We need to ignore
					 * resjunk targets, so doing the outer iteration over
					 * right_list is easier than doing it over left_list.
					 */
					while (right_list != NIL)
Bruce Momjian's avatar
Bruce Momjian committed
287
					{
288 289
						TargetEntry *tent = (TargetEntry *) lfirst(right_list);
						Node	   *lexpr;
290 291 292
						Operator	optup;
						Form_pg_operator opform;
						Oper	   *newop;
Bruce Momjian's avatar
Bruce Momjian committed
293

294
						right_list = lnext(right_list);
295 296 297 298 299 300 301 302 303 304 305 306 307 308
						if (tent->resdom->resjunk)
							continue;

						if (left_list == NIL)
							elog(ERROR, "parser: Subselect has too many fields.");
						lexpr = lfirst(left_list);
						left_list = lnext(left_list);

						optup = oper(op,
									 exprType(lexpr),
									 exprType(tent->expr),
									 FALSE);
						opform = (Form_pg_operator) GETSTRUCT(optup);

309
						if (opform->oprresult != BOOLOID)
310 311 312 313 314 315 316 317
							elog(ERROR, "parser: '%s' must return 'bool' to be used with quantified predicate subquery", op);

						newop = makeOper(oprid(optup),/* opno */
										 InvalidOid, /* opid */
										 opform->oprresult,
										 0,
										 NULL);
						sublink->oper = lappend(sublink->oper, newop);
Bruce Momjian's avatar
Bruce Momjian committed
318
					}
319 320
					if (left_list != NIL)
						elog(ERROR, "parser: Subselect has too few fields.");
321
				}
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
322
				result = (Node *) expr;
323 324
				break;
			}
325

326 327 328 329 330 331 332 333 334 335 336 337 338 339
		case T_CaseExpr:
			{
				CaseExpr   *c = (CaseExpr *) expr;
				CaseWhen   *w;
				List	   *args;
				Oid			ptype;
				CATEGORY	pcategory;

				/* transform the list of arguments */
				foreach(args, c->args)
				{
					w = lfirst(args);
					if (c->arg != NULL)
					{
340
						/* shorthand form was specified, so expand... */
Bruce Momjian's avatar
Bruce Momjian committed
341 342
						A_Expr	   *a = makeNode(A_Expr);

343 344 345 346
						a->oper = OP;
						a->opname = "=";
						a->lexpr = c->arg;
						a->rexpr = w->expr;
Bruce Momjian's avatar
Bruce Momjian committed
347
						w->expr = (Node *) a;
348 349 350 351
					}
					lfirst(args) = transformExpr(pstate, (Node *) w, precedence);
				}

Bruce Momjian's avatar
Bruce Momjian committed
352 353 354 355
				/*
				 * It's not shorthand anymore, so drop the implicit
				 * argument. This is necessary to keep the executor from
				 * seeing an untransformed expression...
356 357 358 359
				 */
				c->arg = NULL;

				/* transform the default clause */
360 361
				if (c->defresult == NULL)
				{
Bruce Momjian's avatar
Bruce Momjian committed
362 363
					A_Const    *n = makeNode(A_Const);

364
					n->val.type = T_Null;
Bruce Momjian's avatar
Bruce Momjian committed
365
					c->defresult = (Node *) n;
366
				}
367
				c->defresult = transformExpr(pstate, c->defresult, precedence);
368 369

				/* now check types across result clauses... */
370
				c->casetype = exprType(c->defresult);
371 372 373 374 375 376 377 378 379 380
				ptype = c->casetype;
				pcategory = TypeCategory(ptype);
				foreach(args, c->args)
				{
					Oid			wtype;

					w = lfirst(args);
					wtype = exprType(w->result);
					/* move on to next one if no new information... */
					if (wtype && (wtype != UNKNOWNOID)
Bruce Momjian's avatar
Bruce Momjian committed
381
						&& (wtype != ptype))
382
					{
383
						if (!ptype || ptype == UNKNOWNOID)
384
						{
385
							/* so far, only nulls so take anything... */
386 387 388 389
							ptype = wtype;
							pcategory = TypeCategory(ptype);
						}
						else if ((TypeCategory(wtype) != pcategory)
Bruce Momjian's avatar
Bruce Momjian committed
390 391
								 || ((TypeCategory(wtype) == USER_TYPE)
							&& (TypeCategory(c->casetype) == USER_TYPE)))
392
						{
393 394 395 396
							/*
							 * both types in different categories?
							 * then not much hope...
							 */
Bruce Momjian's avatar
Bruce Momjian committed
397
							elog(ERROR, "CASE/WHEN types '%s' and '%s' not matched",
398 399 400 401 402
								 typeidTypeName(c->casetype), typeidTypeName(wtype));
						}
						else if (IsPreferredType(pcategory, wtype)
								 && can_coerce_type(1, &ptype, &wtype))
						{
403 404 405 406
							/*
							 * new one is preferred and can convert?
							 * then take it...
							 */
407 408 409 410 411 412
							ptype = wtype;
							pcategory = TypeCategory(ptype);
						}
					}
				}

413
				/* Convert default result clause, if necessary */
414 415
				if (c->casetype != ptype)
				{
416
					if (!c->casetype || c->casetype == UNKNOWNOID)
417
					{
Bruce Momjian's avatar
Bruce Momjian committed
418 419 420 421
						/*
						 * default clause is NULL, so assign preferred
						 * type from WHEN clauses...
						 */
422 423 424 425
						c->casetype = ptype;
					}
					else if (can_coerce_type(1, &c->casetype, &ptype))
					{
Bruce Momjian's avatar
Bruce Momjian committed
426
						c->defresult = coerce_type(pstate, c->defresult,
Bruce Momjian's avatar
Bruce Momjian committed
427
												 c->casetype, ptype, -1);
428 429 430 431
						c->casetype = ptype;
					}
					else
					{
Bruce Momjian's avatar
Bruce Momjian committed
432
						elog(ERROR, "CASE/ELSE unable to convert to type %s",
433 434 435 436 437 438 439
							 typeidTypeName(ptype));
					}
				}

				/* Convert when clauses, if not null and if necessary */
				foreach(args, c->args)
				{
Bruce Momjian's avatar
Bruce Momjian committed
440
					Oid			wtype;
441 442 443

					w = lfirst(args);
					wtype = exprType(w->result);
Bruce Momjian's avatar
Bruce Momjian committed
444 445 446 447 448

					/*
					 * only bother with conversion if not NULL and
					 * different type...
					 */
449 450
					if (wtype && (wtype != UNKNOWNOID)
						&& (wtype != ptype))
451 452 453
					{
						if (can_coerce_type(1, &wtype, &ptype))
						{
Bruce Momjian's avatar
Bruce Momjian committed
454 455
							w->result = coerce_type(pstate, w->result, wtype,
													ptype, -1);
456 457 458
						}
						else
						{
Bruce Momjian's avatar
Bruce Momjian committed
459
							elog(ERROR, "CASE/WHEN unable to convert to type %s",
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
								 typeidTypeName(ptype));
						}
					}
				}

				result = expr;
				break;
			}

		case T_CaseWhen:
			{
				CaseWhen   *w = (CaseWhen *) expr;

				w->expr = transformExpr(pstate, (Node *) w->expr, precedence);
				if (exprType(w->expr) != BOOLOID)
Bruce Momjian's avatar
Bruce Momjian committed
475
					elog(ERROR, "WHEN clause must have a boolean result");
476

Bruce Momjian's avatar
Bruce Momjian committed
477 478 479 480
				/*
				 * result is NULL for NULLIF() construct - thomas
				 * 1998-11-11
				 */
481 482
				if (w->result == NULL)
				{
Bruce Momjian's avatar
Bruce Momjian committed
483 484
					A_Const    *n = makeNode(A_Const);

485
					n->val.type = T_Null;
Bruce Momjian's avatar
Bruce Momjian committed
486
					w->result = (Node *) n;
487 488
				}
				w->result = transformExpr(pstate, (Node *) w->result, precedence);
489 490 491 492
				result = expr;
				break;
			}

493
/* Some nodes do _not_ come from the original parse tree,
494
 *	but result from parser transformation in this phase.
495
 * At least one construct (BETWEEN/AND) puts the same nodes
496 497
 *	into two branches of the parse tree; hence, some nodes
 *	are transformed twice.
498 499 500 501 502 503 504 505 506 507
 * Another way it can happen is that coercion of an operator or
 *	function argument to the required type (via coerce_type())
 *	can apply transformExpr to an already-transformed subexpression.
 *	An example here is "SELECT count(*) + 1.0 FROM table".
 * Thus, we can see node types in this routine that do not appear in the
 *	original parse tree.  Assume they are already transformed, and just
 *	pass them through.
 * Do any other node types need to be accepted?  For now we are taking
 *	a conservative approach, and only accepting node types that are
 *	demonstrably necessary to accept.
508 509 510 511
 */
		case T_Expr:
		case T_Var:
		case T_Const:
512
		case T_Param:
513 514
		case T_Aggref:
		case T_ArrayRef:
515 516 517 518
			{
				result = (Node *) expr;
				break;
			}
519 520
		default:
			/* should not reach here */
521
			elog(ERROR, "transformExpr: does not know how to transform node %d",
522 523 524 525 526 527 528
				 nodeTag(expr));
			break;
	}

	return result;
}

529
static Node *
530
transformIndirection(ParseState *pstate, Node *basenode, List *indirection)
531
{
532 533
	if (indirection == NIL)
		return basenode;
534 535
	return (Node *) transformArraySubscripts(pstate, basenode,
											 indirection, false, NULL);
536
}
537

538 539 540 541 542 543 544
static Node *
transformAttr(ParseState *pstate, Attr *att, int precedence)
{
	Node	   *basenode;

	basenode = ParseNestedFuncOrColumn(pstate, att, &pstate->p_last_resno,
									   precedence);
545
	return transformIndirection(pstate, basenode, att->indirection);
546 547 548 549 550 551 552 553 554 555 556
}

static Node *
transformIdent(ParseState *pstate, Ident *ident, int precedence)
{
	Node	   *result = NULL;
	RangeTblEntry *rte;

	/* try to find the ident as a relation ... but not if subscripts appear */
	if (ident->indirection == NIL &&
		refnameRangeTableEntry(pstate, ident->name) != NULL)
557 558
	{
		ident->isRel = TRUE;
559
		result = (Node *) ident;
560 561
	}

562
	if (result == NULL || precedence == EXPR_COLUMN_FIRST)
563
	{
564 565 566 567 568 569 570 571 572 573 574 575
		/* try to find the ident as a column */
		if ((rte = colnameRangeTableEntry(pstate, ident->name)) != NULL)
		{
			/* Convert it to a fully qualified Attr, and transform that */
			Attr	   *att = makeNode(Attr);

			att->relname = rte->refname;
			att->paramNo = NULL;
			att->attrs = lcons(makeString(ident->name), NIL);
			att->indirection = ident->indirection;
			return transformAttr(pstate, att, precedence);
		}
576 577 578
	}

	if (result == NULL)
579
		elog(ERROR, "attribute '%s' not found", ident->name);
580 581 582 583 584 585 586 587 588 589 590

	return result;
}

/*
 *	exprType -
 *	  returns the Oid of the type of the expression. (Used for typechecking.)
 */
Oid
exprType(Node *expr)
{
591
	Oid			type = (Oid) InvalidOid;
592

593 594 595
	if (!expr)
		return type;

596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615
	switch (nodeTag(expr))
	{
		case T_Func:
			type = ((Func *) expr)->functype;
			break;
		case T_Iter:
			type = ((Iter *) expr)->itertype;
			break;
		case T_Var:
			type = ((Var *) expr)->vartype;
			break;
		case T_Expr:
			type = ((Expr *) expr)->typeOid;
			break;
		case T_Const:
			type = ((Const *) expr)->consttype;
			break;
		case T_ArrayRef:
			type = ((ArrayRef *) expr)->refelemtype;
			break;
Bruce Momjian's avatar
Bruce Momjian committed
616 617
		case T_Aggref:
			type = ((Aggref *) expr)->aggtype;
618 619 620 621
			break;
		case T_Param:
			type = ((Param *) expr)->paramtype;
			break;
622
		case T_SubLink:
623
			{
Bruce Momjian's avatar
Bruce Momjian committed
624 625
				SubLink    *sublink = (SubLink *) expr;

626 627
				if (sublink->subLinkType == EXPR_SUBLINK)
				{
628 629 630 631 632 633 634 635
					/* get the type of the subselect's first target column */
					Query	   *qtree = (Query *) sublink->subselect;
					TargetEntry *tent;

					if (! qtree || ! IsA(qtree, Query))
						elog(ERROR, "exprType: can't get type for untransformed sublink");
					tent = (TargetEntry *) lfirst(qtree->targetList);
					type = tent->resdom->restype;
636 637 638 639 640 641 642
				}
				else
				{
					/* for all other sublink types, result is boolean */
					type = BOOLOID;
				}
			}
643
			break;
644 645 646 647 648 649
		case T_CaseExpr:
			type = ((CaseExpr *) expr)->casetype;
			break;
		case T_CaseWhen:
			type = exprType(((CaseWhen *) expr)->result);
			break;
650 651 652 653 654
		case T_Ident:
			/* is this right? */
			type = UNKNOWNOID;
			break;
		default:
655
			elog(ERROR, "exprType: don't know how to get type for %d node",
656 657 658 659 660 661
				 nodeTag(expr));
			break;
	}
	return type;
}

662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697
/*
 *	exprTypmod -
 *	  returns the type-specific attrmod of the expression, if it can be
 *	  determined.  In most cases, it can't and we return -1.
 */
int32
exprTypmod(Node *expr)
{
	if (!expr)
		return -1;

	switch (nodeTag(expr))
	{
		case T_Var:
			return ((Var *) expr)->vartypmod;
		case T_Const:
			{
				/* Be smart about string constants... */
				Const  *con = (Const *) expr;
				switch (con->consttype)
				{
					case BPCHAROID:
						if (! con->constisnull)
							return VARSIZE(DatumGetPointer(con->constvalue));
						break;
					default:
						break;
				}
			}
			break;
		default:
			break;
	}
	return -1;
}

698 699 700 701
/*
 * Produce an appropriate Const node from a constant value produced
 * by the parser and an explicit type name to cast to.
 */
702
static Node *
703
parser_typecast_constant(Value *expr, TypeName *typename)
704
{
705
	Const	   *con;
706
	Type		tp;
707
	Datum		datum;
708 709
	char	   *const_string = NULL;
	bool		string_palloced = false;
710
	bool		isNull = false;
711 712 713 714 715 716 717 718

	switch (nodeTag(expr))
	{
		case T_String:
			const_string = DatumGetPointer(expr->val.str);
			break;
		case T_Integer:
			string_palloced = true;
719 720 721 722 723
			const_string = int4out(expr->val.ival);
			break;
		case T_Float:
			string_palloced = true;
			const_string = float8out(&expr->val.dval);
724
			break;
725 726 727
		case T_Null:
			isNull = true;
			break;
728
		default:
729
			elog(ERROR,
730
				 "parser_typecast_constant: cannot cast this expression to type '%s'",
731 732 733 734 735
				 typename->name);
	}

	if (typename->arrayBounds != NIL)
	{
736 737
		char		type_string[NAMEDATALEN+2];

738 739 740 741 742 743
		sprintf(type_string, "_%s", typename->name);
		tp = (Type) typenameType(type_string);
	}
	else
		tp = (Type) typenameType(typename->name);

744 745 746
	if (isNull)
		datum = (Datum) NULL;
	else
747
		datum = stringTypeDatum(tp, const_string, typename->typmod);
748

749
	con = makeConst(typeTypeId(tp),
750
					typeLen(tp),
751 752
					datum,
					isNull,
Bruce Momjian's avatar
Bruce Momjian committed
753
					typeByVal(tp),
754 755 756 757 758 759
					false,		/* not a set */
					true /* is cast */ );

	if (string_palloced)
		pfree(const_string);

760
	return (Node *) con;
761
}
762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794

/*
 * Handle an explicit CAST applied to a non-constant expression.
 * (Actually, this works for constants too, but gram.y won't generate
 * a TypeCast node if the argument is just a constant.)
 *
 * The given expr has already been transformed, but we need to lookup
 * the type name and then apply any necessary coercion function(s).
 */
static Node *
parser_typecast_expression(ParseState *pstate,
						   Node *expr, TypeName *typename)
{
	Oid			inputType = exprType(expr);
	Type		tp;
	Oid			targetType;

	if (typename->arrayBounds != NIL)
	{
		char		type_string[NAMEDATALEN+2];

		sprintf(type_string, "_%s", typename->name);
		tp = (Type) typenameType(type_string);
	}
	else
		tp = (Type) typenameType(typename->name);
	targetType = typeTypeId(tp);

	if (inputType == InvalidOid)
		return expr;			/* do nothing if NULL input */

	if (inputType != targetType)
	{
795 796
		expr = CoerceTargetExpr(pstate, expr, inputType,
								targetType, typename->typmod);
797 798 799 800 801 802 803 804 805 806 807 808 809 810
		if (expr == NULL)
			elog(ERROR, "Cannot cast type '%s' to '%s'",
				 typeidTypeName(inputType),
				 typeidTypeName(targetType));
	}
	/*
	 * If the target is a fixed-length type, it may need a length
	 * coercion as well as a type coercion.
	 */
	expr = coerce_type_typmod(pstate, expr,
							  targetType, typename->typmod);

	return expr;
}