parse_expr.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:21k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * parse_expr.c
  4.  *   handle expressions in parser
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.50.2.1 1999/09/13 04:21:21 thomas Exp $
  11.  *
  12.  *-------------------------------------------------------------------------
  13.  */
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include "postgres.h"
  18. #include "catalog/pg_type.h"
  19. #include "nodes/makefuncs.h"
  20. #include "nodes/nodes.h"
  21. #include "nodes/params.h"
  22. #include "nodes/relation.h"
  23. #include "parse.h"
  24. #include "parser/analyze.h"
  25. #include "parser/gramparse.h"
  26. #include "parser/parse_expr.h"
  27. #include "parser/parse_func.h"
  28. #include "parser/parse_node.h"
  29. #include "parser/parse_relation.h"
  30. #include "parser/parse_target.h"
  31. #include "parser/parse_coerce.h"
  32. #include "utils/builtins.h"
  33. static Node *parser_typecast(Value *expr, TypeName *typename, int32 atttypmod);
  34. static Node *transformIdent(ParseState *pstate, Node *expr, int precedence);
  35. /*
  36.  * transformExpr -
  37.  *   analyze and transform expressions. Type checking and type casting is
  38.  *   done here. The optimizer and the executor cannot handle the original
  39.  *   (raw) expressions collected by the parse tree. Hence the transformation
  40.  *   here.
  41.  */
  42. Node *
  43. transformExpr(ParseState *pstate, Node *expr, int precedence)
  44. {
  45. Node    *result = NULL;
  46. if (expr == NULL)
  47. return NULL;
  48. switch (nodeTag(expr))
  49. {
  50. case T_Attr:
  51. {
  52. Attr    *att = (Attr *) expr;
  53. Node    *temp;
  54. /* what if att.attrs == "*"? */
  55. temp = ParseNestedFuncOrColumn(pstate, att, &pstate->p_last_resno,
  56.    precedence);
  57. if (att->indirection != NIL)
  58. {
  59. List    *idx = att->indirection;
  60. while (idx != NIL)
  61. {
  62. A_Indices  *ai = (A_Indices *) lfirst(idx);
  63. Node    *lexpr = NULL,
  64.    *uexpr;
  65. uexpr = transformExpr(pstate, ai->uidx, precedence); /* must exists */
  66. if (exprType(uexpr) != INT4OID)
  67. elog(ERROR, "array index expressions must be int4's");
  68. if (ai->lidx != NULL)
  69. {
  70. lexpr = transformExpr(pstate, ai->lidx, precedence);
  71. if (exprType(lexpr) != INT4OID)
  72. elog(ERROR, "array index expressions must be int4's");
  73. }
  74. ai->lidx = lexpr;
  75. ai->uidx = uexpr;
  76. /*
  77.  * note we reuse the list of indices, make sure we
  78.  * don't free them! Otherwise, make a new list
  79.  * here
  80.  */
  81. idx = lnext(idx);
  82. }
  83. result = (Node *) make_array_ref(temp, att->indirection);
  84. }
  85. else
  86. result = temp;
  87. break;
  88. }
  89. case T_A_Const:
  90. {
  91. A_Const    *con = (A_Const *) expr;
  92. Value    *val = &con->val;
  93. if (con->typename != NULL)
  94. result = parser_typecast(val, con->typename, -1);
  95. else
  96. result = (Node *) make_const(val);
  97. break;
  98. }
  99. case T_ParamNo:
  100. {
  101. ParamNo    *pno = (ParamNo *) expr;
  102. Oid toid;
  103. int paramno;
  104. Param    *param;
  105. paramno = pno->number;
  106. toid = param_type(paramno);
  107. if (!OidIsValid(toid))
  108. elog(ERROR, "Parameter '$%d' is out of range", paramno);
  109. param = makeNode(Param);
  110. param->paramkind = PARAM_NUM;
  111. param->paramid = (AttrNumber) paramno;
  112. param->paramname = "<unnamed>";
  113. param->paramtype = (Oid) toid;
  114. param->param_tlist = (List *) NULL;
  115. if (pno->indirection != NIL)
  116. {
  117. List    *idx = pno->indirection;
  118. while (idx != NIL)
  119. {
  120. A_Indices  *ai = (A_Indices *) lfirst(idx);
  121. Node    *lexpr = NULL,
  122.    *uexpr;
  123. uexpr = transformExpr(pstate, ai->uidx, precedence); /* must exists */
  124. if (exprType(uexpr) != INT4OID)
  125. elog(ERROR, "array index expressions must be int4's");
  126. if (ai->lidx != NULL)
  127. {
  128. lexpr = transformExpr(pstate, ai->lidx, precedence);
  129. if (exprType(lexpr) != INT4OID)
  130. elog(ERROR, "array index expressions must be int4's");
  131. }
  132. ai->lidx = lexpr;
  133. ai->uidx = uexpr;
  134. /*
  135.  * note we reuse the list of indices, make sure we
  136.  * don't free them! Otherwise, make a new list
  137.  * here
  138.  */
  139. idx = lnext(idx);
  140. }
  141. result = (Node *) make_array_ref((Node *) param, pno->indirection);
  142. }
  143. else
  144. result = (Node *) param;
  145. break;
  146. }
  147. case T_A_Expr:
  148. {
  149. A_Expr    *a = (A_Expr *) expr;
  150. switch (a->oper)
  151. {
  152. case OP:
  153. {
  154. Node    *lexpr = transformExpr(pstate, a->lexpr, precedence);
  155. Node    *rexpr = transformExpr(pstate, a->rexpr, precedence);
  156. result = (Node *) make_op(a->opname, lexpr, rexpr);
  157. }
  158. break;
  159. case ISNULL:
  160. {
  161. Node    *lexpr = transformExpr(pstate, a->lexpr, precedence);
  162. result = ParseFuncOrColumn(pstate,
  163.   "nullvalue", lcons(lexpr, NIL),
  164.    &pstate->p_last_resno,
  165.    precedence);
  166. }
  167. break;
  168. case NOTNULL:
  169. {
  170. Node    *lexpr = transformExpr(pstate, a->lexpr, precedence);
  171. result = ParseFuncOrColumn(pstate,
  172.    "nonnullvalue", lcons(lexpr, NIL),
  173.    &pstate->p_last_resno,
  174.    precedence);
  175. }
  176. break;
  177. case AND:
  178. {
  179. Expr    *expr = makeNode(Expr);
  180. Node    *lexpr = transformExpr(pstate, a->lexpr, precedence);
  181. Node    *rexpr = transformExpr(pstate, a->rexpr, precedence);
  182. if (exprType(lexpr) != BOOLOID)
  183. elog(ERROR, "left-hand side of AND is type '%s', not bool",
  184.  typeidTypeName(exprType(lexpr)));
  185. if (exprType(rexpr) != BOOLOID)
  186. elog(ERROR, "right-hand side of AND is type '%s', not bool",
  187.  typeidTypeName(exprType(rexpr)));
  188. expr->typeOid = BOOLOID;
  189. expr->opType = AND_EXPR;
  190. expr->args = makeList(lexpr, rexpr, -1);
  191. result = (Node *) expr;
  192. }
  193. break;
  194. case OR:
  195. {
  196. Expr    *expr = makeNode(Expr);
  197. Node    *lexpr = transformExpr(pstate, a->lexpr, precedence);
  198. Node    *rexpr = transformExpr(pstate, a->rexpr, precedence);
  199. if (exprType(lexpr) != BOOLOID)
  200. elog(ERROR, "left-hand side of OR is type '%s', not bool",
  201.  typeidTypeName(exprType(lexpr)));
  202. if (exprType(rexpr) != BOOLOID)
  203. elog(ERROR, "right-hand side of OR is type '%s', not bool",
  204.  typeidTypeName(exprType(rexpr)));
  205. expr->typeOid = BOOLOID;
  206. expr->opType = OR_EXPR;
  207. expr->args = makeList(lexpr, rexpr, -1);
  208. result = (Node *) expr;
  209. }
  210. break;
  211. case NOT:
  212. {
  213. Expr    *expr = makeNode(Expr);
  214. Node    *rexpr = transformExpr(pstate, a->rexpr, precedence);
  215. if (exprType(rexpr) != BOOLOID)
  216. elog(ERROR, "argument to NOT is type '%s', not bool",
  217.  typeidTypeName(exprType(rexpr)));
  218. expr->typeOid = BOOLOID;
  219. expr->opType = NOT_EXPR;
  220. expr->args = makeList(rexpr, -1);
  221. result = (Node *) expr;
  222. }
  223. break;
  224. }
  225. break;
  226. }
  227. case T_Ident:
  228. {
  229. /*
  230.  * look for a column name or a relation name (the default
  231.  * behavior)
  232.  */
  233. result = transformIdent(pstate, expr, precedence);
  234. break;
  235. }
  236. case T_FuncCall:
  237. {
  238. FuncCall   *fn = (FuncCall *) expr;
  239. List    *args;
  240. /* transform the list of arguments */
  241. foreach(args, fn->args)
  242. lfirst(args) = transformExpr(pstate, (Node *) lfirst(args), precedence);
  243. result = ParseFuncOrColumn(pstate,
  244.    fn->funcname,
  245.    fn->args,
  246.    &pstate->p_last_resno,
  247.    precedence);
  248. break;
  249. }
  250. case T_SubLink:
  251. {
  252. SubLink    *sublink = (SubLink *) expr;
  253. List    *qtrees;
  254. Query    *qtree;
  255. pstate->p_hasSubLinks = true;
  256. qtrees = parse_analyze(lcons(sublink->subselect, NIL), pstate);
  257. if (length(qtrees) != 1)
  258. elog(ERROR, "parser: bad query in subselect");
  259. qtree = (Query *) lfirst(qtrees);
  260. if (qtree->commandType != CMD_SELECT ||
  261. qtree->resultRelation != 0)
  262. elog(ERROR, "parser: bad query in subselect");
  263. sublink->subselect = (Node *) qtree;
  264. if (sublink->subLinkType != EXISTS_SUBLINK)
  265. {
  266. char    *op = lfirst(sublink->oper);
  267. List    *left_list = sublink->lefthand;
  268. List    *right_list = qtree->targetList;
  269. List    *elist;
  270. foreach(elist, left_list)
  271. lfirst(elist) = transformExpr(pstate, lfirst(elist),
  272.   precedence);
  273. if (length(left_list) > 1 &&
  274. strcmp(op, "=") != 0 && strcmp(op, "<>") != 0)
  275. elog(ERROR, "parser: '%s' is not relational operator",
  276.  op);
  277. sublink->oper = NIL;
  278. /* Scan subquery's targetlist to find values that will be
  279.  * matched against lefthand values.  We need to ignore
  280.  * resjunk targets, so doing the outer iteration over
  281.  * right_list is easier than doing it over left_list.
  282.  */
  283. while (right_list != NIL)
  284. {
  285. TargetEntry *tent = (TargetEntry *) lfirst(right_list);
  286. Node    *lexpr;
  287. Expr    *op_expr;
  288. if (! tent->resdom->resjunk)
  289. {
  290. if (left_list == NIL)
  291. elog(ERROR, "parser: Subselect has too many fields.");
  292. lexpr = lfirst(left_list);
  293. left_list = lnext(left_list);
  294. op_expr = make_op(op, lexpr, tent->expr);
  295. if (op_expr->typeOid != BOOLOID &&
  296. sublink->subLinkType != EXPR_SUBLINK)
  297. elog(ERROR, "parser: '%s' must return 'bool' to be used with quantified predicate subquery", op);
  298. sublink->oper = lappend(sublink->oper, op_expr);
  299. }
  300. right_list = lnext(right_list);
  301. }
  302. if (left_list != NIL)
  303. elog(ERROR, "parser: Subselect has too few fields.");
  304. }
  305. else
  306. sublink->oper = NIL;
  307. result = (Node *) expr;
  308. break;
  309. }
  310. case T_CaseExpr:
  311. {
  312. CaseExpr   *c = (CaseExpr *) expr;
  313. CaseWhen   *w;
  314. List    *args;
  315. Oid ptype;
  316. CATEGORY pcategory;
  317. /* transform the list of arguments */
  318. foreach(args, c->args)
  319. {
  320. w = lfirst(args);
  321. if (c->arg != NULL)
  322. {
  323. /* shorthand form was specified, so expand... */
  324. A_Expr    *a = makeNode(A_Expr);
  325. a->oper = OP;
  326. a->opname = "=";
  327. a->lexpr = c->arg;
  328. a->rexpr = w->expr;
  329. w->expr = (Node *) a;
  330. }
  331. lfirst(args) = transformExpr(pstate, (Node *) w, precedence);
  332. }
  333. /*
  334.  * It's not shorthand anymore, so drop the implicit
  335.  * argument. This is necessary to keep the executor from
  336.  * seeing an untransformed expression...
  337.  */
  338. c->arg = NULL;
  339. /* transform the default clause */
  340. if (c->defresult == NULL)
  341. {
  342. A_Const    *n = makeNode(A_Const);
  343. n->val.type = T_Null;
  344. c->defresult = (Node *) n;
  345. }
  346. c->defresult = transformExpr(pstate, (Node *) c->defresult, precedence);
  347. /* now check types across result clauses... */
  348. c->casetype = exprType(c->defresult);
  349. ptype = c->casetype;
  350. pcategory = TypeCategory(ptype);
  351. foreach(args, c->args)
  352. {
  353. Oid wtype;
  354. w = lfirst(args);
  355. wtype = exprType(w->result);
  356. /* move on to next one if no new information... */
  357. if (wtype && (wtype != UNKNOWNOID)
  358. && (wtype != ptype))
  359. {
  360. /* so far, only nulls so take anything... */
  361. if (!ptype)
  362. {
  363. ptype = wtype;
  364. pcategory = TypeCategory(ptype);
  365. }
  366. /*
  367.  * both types in different categories? then not
  368.  * much hope...
  369.  */
  370. else if ((TypeCategory(wtype) != pcategory)
  371.  || ((TypeCategory(wtype) == USER_TYPE)
  372. && (TypeCategory(c->casetype) == USER_TYPE)))
  373. {
  374. elog(ERROR, "CASE/WHEN types '%s' and '%s' not matched",
  375.  typeidTypeName(c->casetype), typeidTypeName(wtype));
  376. }
  377. /*
  378.  * new one is preferred and can convert? then take
  379.  * it...
  380.  */
  381. else if (IsPreferredType(pcategory, wtype)
  382.  && can_coerce_type(1, &ptype, &wtype))
  383. {
  384. ptype = wtype;
  385. pcategory = TypeCategory(ptype);
  386. }
  387. }
  388. }
  389. /* Convert default result clause, if necessary */
  390. if (c->casetype != ptype)
  391. {
  392. if (!c->casetype)
  393. {
  394. /*
  395.  * default clause is NULL, so assign preferred
  396.  * type from WHEN clauses...
  397.  */
  398. c->casetype = ptype;
  399. }
  400. else if (can_coerce_type(1, &c->casetype, &ptype))
  401. {
  402. c->defresult = coerce_type(pstate, c->defresult,
  403.  c->casetype, ptype, -1);
  404. c->casetype = ptype;
  405. }
  406. else
  407. {
  408. elog(ERROR, "CASE/ELSE unable to convert to type %s",
  409.  typeidTypeName(ptype));
  410. }
  411. }
  412. /* Convert when clauses, if not null and if necessary */
  413. foreach(args, c->args)
  414. {
  415. Oid wtype;
  416. w = lfirst(args);
  417. wtype = exprType(w->result);
  418. /*
  419.  * only bother with conversion if not NULL and
  420.  * different type...
  421.  */
  422. if (wtype && (wtype != UNKNOWNOID)
  423. && (wtype != ptype))
  424. {
  425. if (can_coerce_type(1, &wtype, &ptype))
  426. {
  427. w->result = coerce_type(pstate, w->result, wtype,
  428. ptype, -1);
  429. }
  430. else
  431. {
  432. elog(ERROR, "CASE/WHEN unable to convert to type %s",
  433.  typeidTypeName(ptype));
  434. }
  435. }
  436. }
  437. result = expr;
  438. break;
  439. }
  440. case T_CaseWhen:
  441. {
  442. CaseWhen   *w = (CaseWhen *) expr;
  443. w->expr = transformExpr(pstate, (Node *) w->expr, precedence);
  444. if (exprType(w->expr) != BOOLOID)
  445. elog(ERROR, "WHEN clause must have a boolean result");
  446. /*
  447.  * result is NULL for NULLIF() construct - thomas
  448.  * 1998-11-11
  449.  */
  450. if (w->result == NULL)
  451. {
  452. A_Const    *n = makeNode(A_Const);
  453. n->val.type = T_Null;
  454. w->result = (Node *) n;
  455. }
  456. w->result = transformExpr(pstate, (Node *) w->result, precedence);
  457. result = expr;
  458. break;
  459. }
  460. /* Some nodes do _not_ come from the original parse tree,
  461.  * but result from parser transformation in this phase.
  462.  * At least one construct (BETWEEN/AND) puts the same nodes
  463.  * into two branches of the parse tree; hence, some nodes
  464.  * are transformed twice.
  465.  * Another way it can happen is that coercion of an operator or
  466.  * function argument to the required type (via coerce_type())
  467.  * can apply transformExpr to an already-transformed subexpression.
  468.  * An example here is "SELECT count(*) + 1.0 FROM table".
  469.  * Thus, we can see node types in this routine that do not appear in the
  470.  * original parse tree.  Assume they are already transformed, and just
  471.  * pass them through.
  472.  * Do any other node types need to be accepted?  For now we are taking
  473.  * a conservative approach, and only accepting node types that are
  474.  * demonstrably necessary to accept.
  475.  */
  476. case T_Expr:
  477. case T_Var:
  478. case T_Const:
  479. case T_Param:
  480. case T_Aggref:
  481. case T_ArrayRef:
  482. {
  483. result = (Node *) expr;
  484. break;
  485. }
  486. default:
  487. /* should not reach here */
  488. elog(ERROR, "transformExpr: does not know how to transform node %d",
  489.  nodeTag(expr));
  490. break;
  491. }
  492. return result;
  493. }
  494. static Node *
  495. transformIdent(ParseState *pstate, Node *expr, int precedence)
  496. {
  497. Ident    *ident = (Ident *) expr;
  498. RangeTblEntry *rte;
  499. Node    *column_result,
  500.    *relation_result,
  501.    *result;
  502. column_result = relation_result = result = 0;
  503. /* try to find the ident as a column */
  504. if ((rte = colnameRangeTableEntry(pstate, ident->name)) != NULL)
  505. {
  506. Attr    *att = makeNode(Attr);
  507. /* we add the relation name for them */
  508. att->relname = rte->refname;
  509. att->attrs = lcons(makeString(ident->name), NIL);
  510. column_result = (Node *) ParseNestedFuncOrColumn(pstate, att,
  511.   &pstate->p_last_resno, precedence);
  512. }
  513. /* try to find the ident as a relation */
  514. if (refnameRangeTableEntry(pstate, ident->name) != NULL)
  515. {
  516. ident->isRel = TRUE;
  517. relation_result = (Node *) ident;
  518. }
  519. /* choose the right result based on the precedence */
  520. if (precedence == EXPR_COLUMN_FIRST)
  521. {
  522. if (column_result)
  523. result = column_result;
  524. else
  525. result = relation_result;
  526. }
  527. else
  528. {
  529. if (relation_result)
  530. result = relation_result;
  531. else
  532. result = column_result;
  533. }
  534. if (result == NULL)
  535. elog(ERROR, "attribute '%s' not found", ident->name);
  536. return result;
  537. }
  538. /*
  539.  * exprType -
  540.  *   returns the Oid of the type of the expression. (Used for typechecking.)
  541.  */
  542. Oid
  543. exprType(Node *expr)
  544. {
  545. Oid type = (Oid) 0;
  546. if (!expr)
  547. return type;
  548. switch (nodeTag(expr))
  549. {
  550. case T_Func:
  551. type = ((Func *) expr)->functype;
  552. break;
  553. case T_Iter:
  554. type = ((Iter *) expr)->itertype;
  555. break;
  556. case T_Var:
  557. type = ((Var *) expr)->vartype;
  558. break;
  559. case T_Expr:
  560. type = ((Expr *) expr)->typeOid;
  561. break;
  562. case T_Const:
  563. type = ((Const *) expr)->consttype;
  564. break;
  565. case T_ArrayRef:
  566. type = ((ArrayRef *) expr)->refelemtype;
  567. break;
  568. case T_Aggref:
  569. type = ((Aggref *) expr)->aggtype;
  570. break;
  571. case T_Param:
  572. type = ((Param *) expr)->paramtype;
  573. break;
  574. case T_SubLink:
  575. {
  576. SubLink    *sublink = (SubLink *) expr;
  577. if (sublink->subLinkType == EXPR_SUBLINK)
  578. {
  579. /* return the result type of the combining operator */
  580. Expr    *op_expr = (Expr *) lfirst(sublink->oper);
  581. type = op_expr->typeOid;
  582. }
  583. else
  584. {
  585. /* for all other sublink types, result is boolean */
  586. type = BOOLOID;
  587. }
  588. }
  589. break;
  590. case T_CaseExpr:
  591. type = ((CaseExpr *) expr)->casetype;
  592. break;
  593. case T_CaseWhen:
  594. type = exprType(((CaseWhen *) expr)->result);
  595. break;
  596. case T_Ident:
  597. /* is this right? */
  598. type = UNKNOWNOID;
  599. break;
  600. default:
  601. elog(ERROR, "exprType: don't know how to get type for %d node",
  602.  nodeTag(expr));
  603. break;
  604. }
  605. return type;
  606. }
  607. static Node *
  608. parser_typecast(Value *expr, TypeName *typename, int32 atttypmod)
  609. {
  610. /* check for passing non-ints */
  611. Const    *adt;
  612. Datum lcp;
  613. Type tp;
  614. char type_string[NAMEDATALEN];
  615. int32 len;
  616. char    *cp = NULL;
  617. char    *const_string = NULL;
  618. bool string_palloced = false;
  619. switch (nodeTag(expr))
  620. {
  621. case T_String:
  622. const_string = DatumGetPointer(expr->val.str);
  623. break;
  624. case T_Integer:
  625. string_palloced = true;
  626. const_string = int4out(expr->val.ival);
  627. break;
  628. case T_Float:
  629. string_palloced = true;
  630. const_string = float8out(&expr->val.dval);
  631. break;
  632. default:
  633. elog(ERROR,
  634.  "parser_typecast: cannot cast this expression to type '%s'",
  635.  typename->name);
  636. }
  637. if (typename->arrayBounds != NIL)
  638. {
  639. sprintf(type_string, "_%s", typename->name);
  640. tp = (Type) typenameType(type_string);
  641. }
  642. else
  643. tp = (Type) typenameType(typename->name);
  644. len = typeLen(tp);
  645. cp = stringTypeString(tp, const_string, atttypmod);
  646. if (!typeByVal(tp))
  647. lcp = PointerGetDatum(cp);
  648. else
  649. {
  650. switch (len)
  651. {
  652. case 1:
  653. lcp = Int8GetDatum(cp);
  654. break;
  655. case 2:
  656. lcp = Int16GetDatum(cp);
  657. break;
  658. case 4:
  659. lcp = Int32GetDatum(cp);
  660. break;
  661. default:
  662. lcp = PointerGetDatum(cp);
  663. break;
  664. }
  665. }
  666. adt = makeConst(typeTypeId(tp),
  667. len,
  668. (Datum) lcp,
  669. false,
  670. typeByVal(tp),
  671. false, /* not a set */
  672. true /* is cast */ );
  673. if (string_palloced)
  674. pfree(const_string);
  675. return (Node *) adt;
  676. }
  677. /* parser_typecast2()
  678.  * Convert (only) constants to specified type.
  679.  */
  680. Node *
  681. parser_typecast2(Node *expr, Oid exprType, Type tp, int32 atttypmod)
  682. {
  683. /* check for passing non-ints */
  684. Const    *adt;
  685. Datum lcp;
  686. int32 len = typeLen(tp);
  687. char    *cp = NULL;
  688. char    *const_string = NULL;
  689. bool string_palloced = false;
  690. Assert(IsA(expr, Const));
  691. switch (exprType)
  692. {
  693. case 0: /* NULL */
  694. break;
  695. case INT4OID: /* int4 */
  696. const_string = (char *) palloc(256);
  697. string_palloced = true;
  698. sprintf(const_string, "%d",
  699. (int) ((Const *) expr)->constvalue);
  700. break;
  701. case NAMEOID: /* name */
  702. const_string = (char *) palloc(256);
  703. string_palloced = true;
  704. sprintf(const_string, "%s",
  705. (char *) ((Const *) expr)->constvalue);
  706. break;
  707. case CHAROID: /* char */
  708. const_string = (char *) palloc(256);
  709. string_palloced = true;
  710. sprintf(const_string, "%c",
  711. (char) ((Const *) expr)->constvalue);
  712. break;
  713. case FLOAT4OID: /* float4 */
  714. {
  715. float32 floatVal = DatumGetFloat32(((Const *) expr)->constvalue);
  716. const_string = (char *) palloc(256);
  717. string_palloced = true;
  718. sprintf(const_string, "%f", *floatVal);
  719. break;
  720. }
  721. case FLOAT8OID: /* float8 */
  722. {
  723. float64 floatVal = DatumGetFloat64(((Const *) expr)->constvalue);
  724. const_string = (char *) palloc(256);
  725. string_palloced = true;
  726. sprintf(const_string, "%f", *floatVal);
  727. break;
  728. }
  729. case CASHOID: /* money */
  730. const_string = (char *) palloc(256);
  731. string_palloced = true;
  732. sprintf(const_string, "%ld",
  733. (long) ((Const *) expr)->constvalue);
  734. break;
  735. case TEXTOID: /* text */
  736. const_string = DatumGetPointer(((Const *) expr)->constvalue);
  737. const_string = (char *) textout((struct varlena *) const_string);
  738. break;
  739. case UNKNOWNOID: /* unknown */
  740. const_string = DatumGetPointer(((Const *) expr)->constvalue);
  741. const_string = (char *) textout((struct varlena *) const_string);
  742. break;
  743. default:
  744. elog(ERROR, "unknown type %u", exprType);
  745. }
  746. if (!exprType)
  747. {
  748. adt = makeConst(typeTypeId(tp),
  749. (Size) 0,
  750. (Datum) NULL,
  751. true, /* isnull */
  752. false, /* was omitted */
  753. false, /* not a set */
  754. true /* is cast */ );
  755. return (Node *) adt;
  756. }
  757. cp = stringTypeString(tp, const_string, atttypmod);
  758. if (!typeByVal(tp))
  759. lcp = PointerGetDatum(cp);
  760. else
  761. {
  762. switch (len)
  763. {
  764. case 1:
  765. lcp = Int8GetDatum(cp);
  766. break;
  767. case 2:
  768. lcp = Int16GetDatum(cp);
  769. break;
  770. case 4:
  771. lcp = Int32GetDatum(cp);
  772. break;
  773. default:
  774. lcp = PointerGetDatum(cp);
  775. break;
  776. }
  777. }
  778. adt = makeConst(typeTypeId(tp),
  779. (Size) len,
  780. (Datum) lcp,
  781. false,
  782. typeByVal(tp),
  783. false, /* not a set */
  784. true /* is cast */ );
  785. /*
  786.  * printf("adt %s : %u %d %dn",CString(expr),typeTypeId(tp) ,
  787.  * len,cp);
  788.  */
  789. if (string_palloced)
  790. pfree(const_string);
  791. return (Node *) adt;
  792. }