OSDN Git Service

Subselects in FROM clause, per ISO syntax: FROM (SELECT ...) [AS] alias.
[pg-rex/syncrep.git] / src / backend / parser / parse_expr.c
1 /*-------------------------------------------------------------------------
2  *
3  * parse_expr.c
4  *        handle expressions in parser
5  *
6  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.84 2000/09/29 18:21:36 tgl Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15
16 #include "postgres.h"
17
18 #include "catalog/pg_operator.h"
19 #include "catalog/pg_proc.h"
20 #include "nodes/makefuncs.h"
21 #include "nodes/params.h"
22 #include "parser/analyze.h"
23 #include "parser/gramparse.h"
24 #include "parser/parse.h"
25 #include "parser/parse_coerce.h"
26 #include "parser/parse_expr.h"
27 #include "parser/parse_func.h"
28 #include "parser/parse_oper.h"
29 #include "parser/parse_relation.h"
30 #include "parser/parse_target.h"
31 #include "parser/parse_type.h"
32 #include "utils/builtins.h"
33 #include "utils/syscache.h"
34
35
36 int                     max_expr_depth = DEFAULT_MAX_EXPR_DEPTH;
37
38 static int      expr_depth_counter = 0;
39
40 static Node *parser_typecast_constant(Value *expr, TypeName *typename);
41 static Node *parser_typecast_expression(ParseState *pstate,
42                                                    Node *expr, TypeName *typename);
43 static Node *transformAttr(ParseState *pstate, Attr *att, int precedence);
44 static Node *transformIdent(ParseState *pstate, Ident *ident, int precedence);
45 static Node *transformIndirection(ParseState *pstate, Node *basenode,
46                                          List *indirection);
47
48
49 /*
50  * Initialize for parsing a new query.
51  *
52  * We reset the expression depth counter here, in case it was left nonzero
53  * due to elog()'ing out of the last parsing operation.
54  */
55 void
56 parse_expr_init(void)
57 {
58         expr_depth_counter = 0;
59 }
60
61
62 /*
63  * transformExpr -
64  *        Analyze and transform expressions. Type checking and type casting is
65  *        done here. The optimizer and the executor cannot handle the original
66  *        (raw) expressions collected by the parse tree. Hence the transformation
67  *        here.
68  *
69  * NOTE: there are various cases in which this routine will get applied to
70  * an already-transformed expression.  Some examples:
71  *      1. At least one construct (BETWEEN/AND) puts the same nodes
72  *      into two branches of the parse tree; hence, some nodes
73  *      are transformed twice.
74  *      2. Another way it can happen is that coercion of an operator or
75  *      function argument to the required type (via coerce_type())
76  *      can apply transformExpr to an already-transformed subexpression.
77  *      An example here is "SELECT count(*) + 1.0 FROM table".
78  * While it might be possible to eliminate these cases, the path of
79  * least resistance so far has been to ensure that transformExpr() does
80  * no damage if applied to an already-transformed tree.  This is pretty
81  * easy for cases where the transformation replaces one node type with
82  * another, such as A_Const => Const; we just do nothing when handed
83  * a Const.  More care is needed for node types that are used as both
84  * input and output of transformExpr; see SubLink for example.
85  */
86 Node *
87 transformExpr(ParseState *pstate, Node *expr, int precedence)
88 {
89         Node       *result = NULL;
90
91         if (expr == NULL)
92                 return NULL;
93
94         /*
95          * Guard against an overly complex expression leading to coredump due
96          * to stack overflow here, or in later recursive routines that
97          * traverse expression trees.  Note that this is very unlikely to
98          * happen except with pathological queries; but we don't want someone
99          * to be able to crash the backend quite that easily...
100          */
101         if (++expr_depth_counter > max_expr_depth)
102                 elog(ERROR, "Expression too complex: nesting depth exceeds max_expr_depth = %d",
103                          max_expr_depth);
104
105         switch (nodeTag(expr))
106         {
107                 case T_Attr:
108                         {
109                                 result = transformAttr(pstate, (Attr *) expr, precedence);
110                                 break;
111                         }
112                 case T_A_Const:
113                         {
114                                 A_Const    *con = (A_Const *) expr;
115                                 Value      *val = &con->val;
116
117                                 if (con->typename != NULL)
118                                         result = parser_typecast_constant(val, con->typename);
119                                 else
120                                         result = (Node *) make_const(val);
121                                 break;
122                         }
123                 case T_ParamNo:
124                         {
125                                 ParamNo    *pno = (ParamNo *) expr;
126                                 int                     paramno = pno->number;
127                                 Oid                     toid = param_type(paramno);
128                                 Param      *param = makeNode(Param);
129
130                                 if (!OidIsValid(toid))
131                                         elog(ERROR, "Parameter '$%d' is out of range", paramno);
132                                 param->paramkind = PARAM_NUM;
133                                 param->paramid = (AttrNumber) paramno;
134                                 param->paramname = "<unnamed>";
135                                 param->paramtype = toid;
136                                 result = transformIndirection(pstate, (Node *) param,
137                                                                                           pno->indirection);
138                                 /* cope with typecast applied to param */
139                                 if (pno->typename != NULL)
140                                         result = parser_typecast_expression(pstate, result,
141                                                                                                                 pno->typename);
142                                 break;
143                         }
144                 case T_TypeCast:
145                         {
146                                 TypeCast   *tc = (TypeCast *) expr;
147                                 Node       *arg = transformExpr(pstate, tc->arg, precedence);
148
149                                 result = parser_typecast_expression(pstate, arg, tc->typename);
150                                 break;
151                         }
152                 case T_A_Expr:
153                         {
154                                 A_Expr     *a = (A_Expr *) expr;
155
156                                 switch (a->oper)
157                                 {
158                                         case OP:
159                                                 {
160                                                         Node       *lexpr = transformExpr(pstate,
161                                                                                                                           a->lexpr,
162                                                                                                                           precedence);
163                                                         Node       *rexpr = transformExpr(pstate,
164                                                                                                                           a->rexpr,
165                                                                                                                           precedence);
166
167                                                         result = (Node *) make_op(a->opname, lexpr, rexpr);
168                                                 }
169                                                 break;
170                                         case ISNULL:
171                                                 {
172                                                         Node       *lexpr = transformExpr(pstate,
173                                                                                                                           a->lexpr,
174                                                                                                                           precedence);
175
176                                                         result = ParseFuncOrColumn(pstate,
177                                                                                                            "nullvalue",
178                                                                                                            makeList1(lexpr),
179                                                                                                            false, false,
180                                                                                                            precedence);
181                                                 }
182                                                 break;
183                                         case NOTNULL:
184                                                 {
185                                                         Node       *lexpr = transformExpr(pstate,
186                                                                                                                           a->lexpr,
187                                                                                                                           precedence);
188
189                                                         result = ParseFuncOrColumn(pstate,
190                                                                                                            "nonnullvalue",
191                                                                                                            makeList1(lexpr),
192                                                                                                            false, false,
193                                                                                                            precedence);
194                                                 }
195                                                 break;
196                                         case AND:
197                                                 {
198                                                         Node       *lexpr = transformExpr(pstate,
199                                                                                                                           a->lexpr,
200                                                                                                                           precedence);
201                                                         Node       *rexpr = transformExpr(pstate,
202                                                                                                                           a->rexpr,
203                                                                                                                           precedence);
204                                                         Expr       *expr = makeNode(Expr);
205
206                                                         if (exprType(lexpr) != BOOLOID)
207                                                                 elog(ERROR, "left-hand side of AND is type '%s', not '%s'",
208                                                                          typeidTypeName(exprType(lexpr)), typeidTypeName(BOOLOID));
209
210                                                         if (exprType(rexpr) != BOOLOID)
211                                                                 elog(ERROR, "right-hand side of AND is type '%s', not '%s'",
212                                                                          typeidTypeName(exprType(rexpr)), typeidTypeName(BOOLOID));
213
214                                                         expr->typeOid = BOOLOID;
215                                                         expr->opType = AND_EXPR;
216                                                         expr->args = makeList2(lexpr, rexpr);
217                                                         result = (Node *) expr;
218                                                 }
219                                                 break;
220                                         case OR:
221                                                 {
222                                                         Node       *lexpr = transformExpr(pstate,
223                                                                                                                           a->lexpr,
224                                                                                                                           precedence);
225                                                         Node       *rexpr = transformExpr(pstate,
226                                                                                                                           a->rexpr,
227                                                                                                                           precedence);
228                                                         Expr       *expr = makeNode(Expr);
229
230                                                         if (exprType(lexpr) != BOOLOID)
231                                                                 elog(ERROR, "left-hand side of OR is type '%s', not '%s'",
232                                                                          typeidTypeName(exprType(lexpr)), typeidTypeName(BOOLOID));
233                                                         if (exprType(rexpr) != BOOLOID)
234                                                                 elog(ERROR, "right-hand side of OR is type '%s', not '%s'",
235                                                                          typeidTypeName(exprType(rexpr)), typeidTypeName(BOOLOID));
236                                                         expr->typeOid = BOOLOID;
237                                                         expr->opType = OR_EXPR;
238                                                         expr->args = makeList2(lexpr, rexpr);
239                                                         result = (Node *) expr;
240                                                 }
241                                                 break;
242                                         case NOT:
243                                                 {
244                                                         Node       *rexpr = transformExpr(pstate,
245                                                                                                                           a->rexpr,
246                                                                                                                           precedence);
247                                                         Expr       *expr = makeNode(Expr);
248
249                                                         if (exprType(rexpr) != BOOLOID)
250                                                                 elog(ERROR, "argument to NOT is type '%s', not '%s'",
251                                                                          typeidTypeName(exprType(rexpr)), typeidTypeName(BOOLOID));
252                                                         expr->typeOid = BOOLOID;
253                                                         expr->opType = NOT_EXPR;
254                                                         expr->args = makeList1(rexpr);
255                                                         result = (Node *) expr;
256                                                 }
257                                                 break;
258                                 }
259                                 break;
260                         }
261                 case T_Ident:
262                         {
263                                 result = transformIdent(pstate, (Ident *) expr, precedence);
264                                 break;
265                         }
266                 case T_FuncCall:
267                         {
268                                 FuncCall   *fn = (FuncCall *) expr;
269                                 List       *args;
270
271                                 /* transform the list of arguments */
272                                 foreach(args, fn->args)
273                                         lfirst(args) = transformExpr(pstate,
274                                                                                                  (Node *) lfirst(args),
275                                                                                                  precedence);
276                                 result = ParseFuncOrColumn(pstate,
277                                                                                    fn->funcname,
278                                                                                    fn->args,
279                                                                                    fn->agg_star,
280                                                                                    fn->agg_distinct,
281                                                                                    precedence);
282                                 break;
283                         }
284                 case T_SubLink:
285                         {
286                                 SubLink    *sublink = (SubLink *) expr;
287                                 List       *qtrees;
288                                 Query      *qtree;
289
290                                 /* If we already transformed this node, do nothing */
291                                 if (IsA(sublink->subselect, Query))
292                                 {
293                                         result = expr;
294                                         break;
295                                 }
296                                 pstate->p_hasSubLinks = true;
297                                 qtrees = parse_analyze(makeList1(sublink->subselect),
298                                                                            pstate);
299                                 if (length(qtrees) != 1)
300                                         elog(ERROR, "Bad query in subselect");
301                                 qtree = (Query *) lfirst(qtrees);
302                                 if (qtree->commandType != CMD_SELECT ||
303                                         qtree->resultRelation != 0)
304                                         elog(ERROR, "Bad query in subselect");
305                                 sublink->subselect = (Node *) qtree;
306
307                                 if (sublink->subLinkType == EXISTS_SUBLINK)
308                                 {
309
310                                         /*
311                                          * EXISTS needs no lefthand or combining operator.
312                                          * These fields should be NIL already, but make sure.
313                                          */
314                                         sublink->lefthand = NIL;
315                                         sublink->oper = NIL;
316                                 }
317                                 else if (sublink->subLinkType == EXPR_SUBLINK)
318                                 {
319                                         List       *tlist = qtree->targetList;
320
321                                         /*
322                                          * Make sure the subselect delivers a single column
323                                          * (ignoring resjunk targets).
324                                          */
325                                         if (tlist == NIL ||
326                                                 ((TargetEntry *) lfirst(tlist))->resdom->resjunk)
327                                                 elog(ERROR, "Subselect must have a field");
328                                         while ((tlist = lnext(tlist)) != NIL)
329                                         {
330                                                 if (!((TargetEntry *) lfirst(tlist))->resdom->resjunk)
331                                                         elog(ERROR, "Subselect must have only one field");
332                                         }
333
334                                         /*
335                                          * EXPR needs no lefthand or combining operator. These
336                                          * fields should be NIL already, but make sure.
337                                          */
338                                         sublink->lefthand = NIL;
339                                         sublink->oper = NIL;
340                                 }
341                                 else
342                                 {
343                                         /* ALL, ANY, or MULTIEXPR: generate operator list */
344                                         List       *left_list = sublink->lefthand;
345                                         List       *right_list = qtree->targetList;
346                                         char       *op;
347                                         List       *elist;
348
349                                         foreach(elist, left_list)
350                                                 lfirst(elist) = transformExpr(pstate, lfirst(elist),
351                                                                                                           precedence);
352
353                                         Assert(IsA(sublink->oper, A_Expr));
354                                         op = ((A_Expr *) sublink->oper)->opname;
355                                         sublink->oper = NIL;
356
357                                         /* Combining operators other than =/<> is dubious... */
358                                         if (length(left_list) != 1 &&
359                                                 strcmp(op, "=") != 0 && strcmp(op, "<>") != 0)
360                                                 elog(ERROR, "Row comparison cannot use '%s'",
361                                                          op);
362
363                                         /*
364                                          * Scan subquery's targetlist to find values that will
365                                          * be matched against lefthand values.  We need to
366                                          * ignore resjunk targets, so doing the outer
367                                          * iteration over right_list is easier than doing it
368                                          * over left_list.
369                                          */
370                                         while (right_list != NIL)
371                                         {
372                                                 TargetEntry *tent = (TargetEntry *) lfirst(right_list);
373                                                 Node       *lexpr;
374                                                 Operator        optup;
375                                                 Form_pg_operator opform;
376                                                 Oper       *newop;
377
378                                                 right_list = lnext(right_list);
379                                                 if (tent->resdom->resjunk)
380                                                         continue;
381
382                                                 if (left_list == NIL)
383                                                         elog(ERROR, "Subselect has too many fields");
384                                                 lexpr = lfirst(left_list);
385                                                 left_list = lnext(left_list);
386
387                                                 optup = oper(op,
388                                                                          exprType(lexpr),
389                                                                          exprType(tent->expr),
390                                                                          FALSE);
391                                                 opform = (Form_pg_operator) GETSTRUCT(optup);
392
393                                                 if (opform->oprresult != BOOLOID)
394                                                         elog(ERROR, "'%s' result type of '%s' must return '%s'"
395                                                                  " to be used with quantified predicate subquery",
396                                                                  op, typeidTypeName(opform->oprresult),
397                                                                  typeidTypeName(BOOLOID));
398
399                                                 newop = makeOper(oprid(optup),  /* opno */
400                                                                                  InvalidOid,    /* opid */
401                                                                                  opform->oprresult);
402                                                 sublink->oper = lappend(sublink->oper, newop);
403                                         }
404                                         if (left_list != NIL)
405                                                 elog(ERROR, "Subselect has too few fields");
406                                 }
407                                 result = (Node *) expr;
408                                 break;
409                         }
410
411                 case T_CaseExpr:
412                         {
413                                 CaseExpr   *c = (CaseExpr *) expr;
414                                 CaseWhen   *w;
415                                 List       *args;
416                                 Oid                     ptype;
417                                 CATEGORY        pcategory;
418
419                                 /* transform the list of arguments */
420                                 foreach(args, c->args)
421                                 {
422                                         w = lfirst(args);
423                                         if (c->arg != NULL)
424                                         {
425                                                 /* shorthand form was specified, so expand... */
426                                                 A_Expr     *a = makeNode(A_Expr);
427
428                                                 a->oper = OP;
429                                                 a->opname = "=";
430                                                 a->lexpr = c->arg;
431                                                 a->rexpr = w->expr;
432                                                 w->expr = (Node *) a;
433                                         }
434                                         lfirst(args) = transformExpr(pstate, (Node *) w, precedence);
435                                 }
436
437                                 /*
438                                  * It's not shorthand anymore, so drop the implicit
439                                  * argument. This is necessary to keep the executor from
440                                  * seeing an untransformed expression... not to mention
441                                  * keeping a re-application of transformExpr from doing
442                                  * the wrong thing.
443                                  */
444                                 c->arg = NULL;
445
446                                 /* transform the default clause */
447                                 if (c->defresult == NULL)
448                                 {
449                                         A_Const    *n = makeNode(A_Const);
450
451                                         n->val.type = T_Null;
452                                         c->defresult = (Node *) n;
453                                 }
454                                 c->defresult = transformExpr(pstate, c->defresult, precedence);
455
456                                 /* now check types across result clauses... */
457                                 c->casetype = exprType(c->defresult);
458                                 ptype = c->casetype;
459                                 pcategory = TypeCategory(ptype);
460                                 foreach(args, c->args)
461                                 {
462                                         Oid                     wtype;
463
464                                         w = lfirst(args);
465                                         wtype = exprType(w->result);
466                                         /* move on to next one if no new information... */
467                                         if (wtype && (wtype != UNKNOWNOID)
468                                                 && (wtype != ptype))
469                                         {
470                                                 if (!ptype || ptype == UNKNOWNOID)
471                                                 {
472                                                         /* so far, only nulls so take anything... */
473                                                         ptype = wtype;
474                                                         pcategory = TypeCategory(ptype);
475                                                 }
476                                                 else if ((TypeCategory(wtype) != pcategory)
477                                                                  || ((TypeCategory(wtype) == USER_TYPE)
478                                                         && (TypeCategory(c->casetype) == USER_TYPE)))
479                                                 {
480
481                                                         /*
482                                                          * both types in different categories? then
483                                                          * not much hope...
484                                                          */
485                                                         elog(ERROR, "CASE/WHEN types '%s' and '%s' not matched",
486                                                                  typeidTypeName(c->casetype), typeidTypeName(wtype));
487                                                 }
488                                                 else if (IsPreferredType(pcategory, wtype)
489                                                                  && can_coerce_type(1, &ptype, &wtype))
490                                                 {
491
492                                                         /*
493                                                          * new one is preferred and can convert? then
494                                                          * take it...
495                                                          */
496                                                         ptype = wtype;
497                                                         pcategory = TypeCategory(ptype);
498                                                 }
499                                         }
500                                 }
501
502                                 /* Convert default result clause, if necessary */
503                                 if (c->casetype != ptype)
504                                 {
505                                         if (!c->casetype || c->casetype == UNKNOWNOID)
506                                         {
507
508                                                 /*
509                                                  * default clause is NULL, so assign preferred
510                                                  * type from WHEN clauses...
511                                                  */
512                                                 c->casetype = ptype;
513                                         }
514                                         else if (can_coerce_type(1, &c->casetype, &ptype))
515                                         {
516                                                 c->defresult = coerce_type(pstate, c->defresult,
517                                                                                                  c->casetype, ptype, -1);
518                                                 c->casetype = ptype;
519                                         }
520                                         else
521                                         {
522                                                 elog(ERROR, "CASE/ELSE unable to convert to type '%s'",
523                                                          typeidTypeName(ptype));
524                                         }
525                                 }
526
527                                 /* Convert when clauses, if not null and if necessary */
528                                 foreach(args, c->args)
529                                 {
530                                         Oid                     wtype;
531
532                                         w = lfirst(args);
533                                         wtype = exprType(w->result);
534
535                                         /*
536                                          * only bother with conversion if not NULL and
537                                          * different type...
538                                          */
539                                         if (wtype && (wtype != UNKNOWNOID)
540                                                 && (wtype != ptype))
541                                         {
542                                                 if (can_coerce_type(1, &wtype, &ptype))
543                                                 {
544                                                         w->result = coerce_type(pstate, w->result, wtype,
545                                                                                                         ptype, -1);
546                                                 }
547                                                 else
548                                                 {
549                                                         elog(ERROR, "CASE/WHEN unable to convert to type '%s'",
550                                                                  typeidTypeName(ptype));
551                                                 }
552                                         }
553                                 }
554
555                                 result = expr;
556                                 break;
557                         }
558
559                 case T_CaseWhen:
560                         {
561                                 CaseWhen   *w = (CaseWhen *) expr;
562
563                                 w->expr = transformExpr(pstate, (Node *) w->expr, precedence);
564                                 if (exprType(w->expr) != BOOLOID)
565                                         elog(ERROR, "WHEN clause must have a boolean result");
566
567                                 /*
568                                  * result is NULL for NULLIF() construct - thomas
569                                  * 1998-11-11
570                                  */
571                                 if (w->result == NULL)
572                                 {
573                                         A_Const    *n = makeNode(A_Const);
574
575                                         n->val.type = T_Null;
576                                         w->result = (Node *) n;
577                                 }
578                                 w->result = transformExpr(pstate, (Node *) w->result, precedence);
579                                 result = expr;
580                                 break;
581                         }
582
583                         /*
584                          * Quietly accept node types that may be presented when we are
585                          * called on an already-transformed tree.
586                          *
587                          * Do any other node types need to be accepted?  For now we are
588                          * taking a conservative approach, and only accepting node
589                          * types that are demonstrably necessary to accept.
590                          */
591                 case T_Expr:
592                 case T_Var:
593                 case T_Const:
594                 case T_Param:
595                 case T_Aggref:
596                 case T_ArrayRef:
597                 case T_FieldSelect:
598                 case T_RelabelType:
599                         {
600                                 result = (Node *) expr;
601                                 break;
602                         }
603
604                 default:
605                         /* should not reach here */
606                         elog(ERROR, "transformExpr: does not know how to transform node %d"
607                                  " (internal error)", nodeTag(expr));
608                         break;
609         }
610
611         expr_depth_counter--;
612
613         return result;
614 }
615
616 static Node *
617 transformIndirection(ParseState *pstate, Node *basenode, List *indirection)
618 {
619         if (indirection == NIL)
620                 return basenode;
621         return (Node *) transformArraySubscripts(pstate, basenode,
622                                                                                          indirection, false, NULL);
623 }
624
625 static Node *
626 transformAttr(ParseState *pstate, Attr *att, int precedence)
627 {
628         Node       *basenode;
629
630         basenode = ParseNestedFuncOrColumn(pstate, att, precedence);
631         return transformIndirection(pstate, basenode, att->indirection);
632 }
633
634 static Node *
635 transformIdent(ParseState *pstate, Ident *ident, int precedence)
636 {
637         Node       *result = NULL;
638
639         /*
640          * try to find the ident as a relation ... but not if subscripts
641          * appear
642          */
643         if (ident->indirection == NIL &&
644                 refnameRangeTableEntry(pstate, ident->name) != NULL)
645         {
646                 ident->isRel = TRUE;
647                 result = (Node *) ident;
648         }
649
650         if (result == NULL || precedence == EXPR_COLUMN_FIRST)
651         {
652                 /* try to find the ident as a column */
653                 Node   *var = colnameToVar(pstate, ident->name);
654
655                 if (var != NULL)
656                         result = transformIndirection(pstate, var, ident->indirection);
657         }
658
659         if (result == NULL)
660                 elog(ERROR, "Attribute '%s' not found", ident->name);
661
662         return result;
663 }
664
665 /*
666  *      exprType -
667  *        returns the Oid of the type of the expression. (Used for typechecking.)
668  */
669 Oid
670 exprType(Node *expr)
671 {
672         Oid                     type = (Oid) InvalidOid;
673
674         if (!expr)
675                 return type;
676
677         switch (nodeTag(expr))
678         {
679                 case T_Func:
680                         type = ((Func *) expr)->functype;
681                         break;
682                 case T_Iter:
683                         type = ((Iter *) expr)->itertype;
684                         break;
685                 case T_Var:
686                         type = ((Var *) expr)->vartype;
687                         break;
688                 case T_Expr:
689                         type = ((Expr *) expr)->typeOid;
690                         break;
691                 case T_Const:
692                         type = ((Const *) expr)->consttype;
693                         break;
694                 case T_ArrayRef:
695                         type = ((ArrayRef *) expr)->refelemtype;
696                         break;
697                 case T_Aggref:
698                         type = ((Aggref *) expr)->aggtype;
699                         break;
700                 case T_Param:
701                         type = ((Param *) expr)->paramtype;
702                         break;
703                 case T_FieldSelect:
704                         type = ((FieldSelect *) expr)->resulttype;
705                         break;
706                 case T_RelabelType:
707                         type = ((RelabelType *) expr)->resulttype;
708                         break;
709                 case T_SubLink:
710                         {
711                                 SubLink    *sublink = (SubLink *) expr;
712
713                                 if (sublink->subLinkType == EXPR_SUBLINK)
714                                 {
715                                         /* get the type of the subselect's first target column */
716                                         Query      *qtree = (Query *) sublink->subselect;
717                                         TargetEntry *tent;
718
719                                         if (!qtree || !IsA(qtree, Query))
720                                                 elog(ERROR, "Cannot get type for untransformed sublink");
721                                         tent = (TargetEntry *) lfirst(qtree->targetList);
722                                         type = tent->resdom->restype;
723                                 }
724                                 else
725                                 {
726                                         /* for all other sublink types, result is boolean */
727                                         type = BOOLOID;
728                                 }
729                         }
730                         break;
731                 case T_CaseExpr:
732                         type = ((CaseExpr *) expr)->casetype;
733                         break;
734                 case T_CaseWhen:
735                         type = exprType(((CaseWhen *) expr)->result);
736                         break;
737                 case T_Ident:
738                         /* is this right? */
739                         type = UNKNOWNOID;
740                         break;
741                 default:
742                         elog(ERROR, "Do not know how to get type for %d node",
743                                  nodeTag(expr));
744                         break;
745         }
746         return type;
747 }
748
749 /*
750  *      exprTypmod -
751  *        returns the type-specific attrmod of the expression, if it can be
752  *        determined.  In most cases, it can't and we return -1.
753  */
754 int32
755 exprTypmod(Node *expr)
756 {
757         if (!expr)
758                 return -1;
759
760         switch (nodeTag(expr))
761         {
762                 case T_Var:
763                         return ((Var *) expr)->vartypmod;
764                 case T_Const:
765                         {
766                                 /* Be smart about string constants... */
767                                 Const      *con = (Const *) expr;
768
769                                 switch (con->consttype)
770                                 {
771                                         case BPCHAROID:
772                                                 if (!con->constisnull)
773                                                         return VARSIZE(DatumGetPointer(con->constvalue));
774                                                 break;
775                                         default:
776                                                 break;
777                                 }
778                         }
779                         break;
780                 case T_Expr:
781                         {
782                                 int32           coercedTypmod;
783
784                                 /* Be smart about length-coercion functions... */
785                                 if (exprIsLengthCoercion(expr, &coercedTypmod))
786                                         return coercedTypmod;
787                         }
788                         break;
789                 case T_FieldSelect:
790                         return ((FieldSelect *) expr)->resulttypmod;
791                         break;
792                 case T_RelabelType:
793                         return ((RelabelType *) expr)->resulttypmod;
794                         break;
795                 default:
796                         break;
797         }
798         return -1;
799 }
800
801 /*
802  * exprIsLengthCoercion
803  *              Detect whether an expression tree is an application of a datatype's
804  *              typmod-coercion function.  Optionally extract the result's typmod.
805  *
806  * If coercedTypmod is not NULL, the typmod is stored there if the expression
807  * is a length-coercion function, else -1 is stored there.
808  *
809  * We assume that a two-argument function named for a datatype, whose
810  * output and first argument types are that datatype, and whose second
811  * input is an int32 constant, represents a forced length coercion.
812  *
813  * XXX It'd be better if the parsetree retained some explicit indication
814  * of the coercion, so we didn't need these heuristics.
815  */
816 bool
817 exprIsLengthCoercion(Node *expr, int32 *coercedTypmod)
818 {
819         Func       *func;
820         Const      *second_arg;
821         HeapTuple       tup;
822         Form_pg_proc procStruct;
823         Form_pg_type typeStruct;
824
825         if (coercedTypmod != NULL)
826                 *coercedTypmod = -1;    /* default result on failure */
827
828         /* Is it a function-call at all? */
829         if (expr == NULL ||
830                 !IsA(expr, Expr) ||
831                 ((Expr *) expr)->opType != FUNC_EXPR)
832                 return false;
833         func = (Func *) (((Expr *) expr)->oper);
834         Assert(IsA(func, Func));
835
836         /*
837          * If it's not a two-argument function with the second argument being
838          * an int4 constant, it can't have been created from a length
839          * coercion.
840          */
841         if (length(((Expr *) expr)->args) != 2)
842                 return false;
843         second_arg = (Const *) lsecond(((Expr *) expr)->args);
844         if (!IsA(second_arg, Const) ||
845                 second_arg->consttype != INT4OID ||
846                 second_arg->constisnull)
847                 return false;
848
849         /*
850          * Lookup the function in pg_proc
851          */
852         tup = SearchSysCacheTuple(PROCOID,
853                                                           ObjectIdGetDatum(func->funcid),
854                                                           0, 0, 0);
855         if (!HeapTupleIsValid(tup))
856                 elog(ERROR, "cache lookup for proc %u failed", func->funcid);
857         procStruct = (Form_pg_proc) GETSTRUCT(tup);
858
859         /*
860          * It must be a function with two arguments where the first is of the
861          * same type as the return value and the second is an int4. Also, just
862          * to be sure, check return type agrees with expr node.
863          */
864         if (procStruct->pronargs != 2 ||
865                 procStruct->prorettype != procStruct->proargtypes[0] ||
866                 procStruct->proargtypes[1] != INT4OID ||
867                 procStruct->prorettype != ((Expr *) expr)->typeOid)
868                 return false;
869
870         /*
871          * Furthermore, the name of the function must be the same as the
872          * argument/result type's name.
873          */
874         tup = SearchSysCacheTuple(TYPEOID,
875                                                           ObjectIdGetDatum(procStruct->prorettype),
876                                                           0, 0, 0);
877         if (!HeapTupleIsValid(tup))
878                 elog(ERROR, "cache lookup for type %u failed",
879                          procStruct->prorettype);
880         typeStruct = (Form_pg_type) GETSTRUCT(tup);
881         if (strncmp(NameStr(procStruct->proname),
882                                 NameStr(typeStruct->typname),
883                                 NAMEDATALEN) != 0)
884                 return false;
885
886         /*
887          * OK, it is indeed a length-coercion function.
888          */
889         if (coercedTypmod != NULL)
890                 *coercedTypmod = DatumGetInt32(second_arg->constvalue);
891         return true;
892 }
893
894 /*
895  * Produce an appropriate Const node from a constant value produced
896  * by the parser and an explicit type name to cast to.
897  */
898 static Node *
899 parser_typecast_constant(Value *expr, TypeName *typename)
900 {
901         Const      *con;
902         Type            tp;
903         Datum           datum;
904         char       *const_string = NULL;
905         bool            string_palloced = false;
906         bool            isNull = false;
907
908         switch (nodeTag(expr))
909         {
910                 case T_Integer:
911                         string_palloced = true;
912                         const_string = DatumGetCString(DirectFunctionCall1(int4out,
913                                                                                    Int32GetDatum(expr->val.ival)));
914                         break;
915                 case T_Float:
916                 case T_String:
917                         const_string = expr->val.str;
918                         break;
919                 case T_Null:
920                         isNull = true;
921                         break;
922                 default:
923                         elog(ERROR, "Cannot cast this expression to type '%s'",
924                                  typename->name);
925         }
926
927         if (typename->arrayBounds != NIL)
928         {
929                 char            type_string[NAMEDATALEN + 2];
930
931                 sprintf(type_string, "_%s", typename->name);
932                 tp = (Type) typenameType(type_string);
933         }
934         else
935                 tp = (Type) typenameType(typename->name);
936
937         if (isNull)
938                 datum = (Datum) NULL;
939         else
940                 datum = stringTypeDatum(tp, const_string, typename->typmod);
941
942         con = makeConst(typeTypeId(tp),
943                                         typeLen(tp),
944                                         datum,
945                                         isNull,
946                                         typeByVal(tp),
947                                         false,          /* not a set */
948                                         true /* is cast */ );
949
950         if (string_palloced)
951                 pfree(const_string);
952
953         return (Node *) con;
954 }
955
956 /*
957  * Handle an explicit CAST applied to a non-constant expression.
958  * (Actually, this works for constants too, but gram.y won't generate
959  * a TypeCast node if the argument is just a constant.)
960  *
961  * The given expr has already been transformed, but we need to lookup
962  * the type name and then apply any necessary coercion function(s).
963  */
964 static Node *
965 parser_typecast_expression(ParseState *pstate,
966                                                    Node *expr, TypeName *typename)
967 {
968         Oid                     inputType = exprType(expr);
969         Type            tp;
970         Oid                     targetType;
971
972         if (typename->arrayBounds != NIL)
973         {
974                 char            type_string[NAMEDATALEN + 2];
975
976                 sprintf(type_string, "_%s", typename->name);
977                 tp = (Type) typenameType(type_string);
978         }
979         else
980                 tp = (Type) typenameType(typename->name);
981         targetType = typeTypeId(tp);
982
983         if (inputType == InvalidOid)
984                 return expr;                    /* do nothing if NULL input */
985
986         if (inputType != targetType)
987         {
988                 expr = CoerceTargetExpr(pstate, expr, inputType,
989                                                                 targetType, typename->typmod);
990                 if (expr == NULL)
991                         elog(ERROR, "Cannot cast type '%s' to '%s'",
992                                  typeidTypeName(inputType),
993                                  typeidTypeName(targetType));
994         }
995
996         /*
997          * If the target is a fixed-length type, it may need a length coercion
998          * as well as a type coercion.
999          */
1000         expr = coerce_type_typmod(pstate, expr,
1001                                                           targetType, typename->typmod);
1002
1003         return expr;
1004 }