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

数据库系统

开发平台:

Unix_Linux

  1. sort_clause:  ORDER BY sortby_list { $$ = $3; }
  2. | /*EMPTY*/ { $$ = NIL; }
  3. ;
  4. sortby_list:  sortby { $$ = lcons($1, NIL); }
  5. | sortby_list ',' sortby { $$ = lappend($1, $3); }
  6. ;
  7. sortby: a_expr OptUseOp
  8. {
  9. $$ = makeNode(SortGroupBy);
  10. $$->node = $1;
  11. $$->useOp = $2;
  12. }
  13. ;
  14. OptUseOp:  USING Op { $$ = $2; }
  15. | USING '<' { $$ = "<"; }
  16. | USING '>' { $$ = ">"; }
  17. | ASC { $$ = "<"; }
  18. | DESC { $$ = ">"; }
  19. | /*EMPTY*/ { $$ = "<"; /*default*/ }
  20. ;
  21. opt_select_limit: LIMIT select_limit_value ',' select_offset_value
  22. { $$ = lappend(lappend(NIL, $4), $2); }
  23. | LIMIT select_limit_value OFFSET select_offset_value
  24. { $$ = lappend(lappend(NIL, $4), $2); }
  25. | LIMIT select_limit_value
  26. { $$ = lappend(lappend(NIL, NULL), $2); }
  27. | OFFSET select_offset_value LIMIT select_limit_value
  28. { $$ = lappend(lappend(NIL, $2), $4); }
  29. | OFFSET select_offset_value
  30. { $$ = lappend(lappend(NIL, $2), NULL); }
  31. | /* EMPTY */
  32. { $$ = lappend(lappend(NIL, NULL), NULL); }
  33. ;
  34. select_limit_value: Iconst
  35. {
  36. Const *n = makeNode(Const);
  37. if ($1 < 1)
  38. elog(ERROR, "selection limit must be ALL or a positive integer value > 0");
  39. n->consttype = INT4OID;
  40. n->constlen = sizeof(int4);
  41. n->constvalue = (Datum)$1;
  42. n->constisnull = FALSE;
  43. n->constbyval = TRUE;
  44. n->constisset = FALSE;
  45. n->constiscast = FALSE;
  46. $$ = (Node *)n;
  47. }
  48. | ALL
  49. {
  50. Const *n = makeNode(Const);
  51. n->consttype = INT4OID;
  52. n->constlen = sizeof(int4);
  53. n->constvalue = (Datum)0;
  54. n->constisnull = FALSE;
  55. n->constbyval = TRUE;
  56. n->constisset = FALSE;
  57. n->constiscast = FALSE;
  58. $$ = (Node *)n;
  59. }
  60. | PARAM
  61. {
  62. Param *n = makeNode(Param);
  63. n->paramkind = PARAM_NUM;
  64. n->paramid = $1;
  65. n->paramtype = INT4OID;
  66. $$ = (Node *)n;
  67. }
  68. ;
  69. select_offset_value: Iconst
  70. {
  71. Const *n = makeNode(Const);
  72. n->consttype = INT4OID;
  73. n->constlen = sizeof(int4);
  74. n->constvalue = (Datum)$1;
  75. n->constisnull = FALSE;
  76. n->constbyval = TRUE;
  77. n->constisset = FALSE;
  78. n->constiscast = FALSE;
  79. $$ = (Node *)n;
  80. }
  81. | PARAM
  82. {
  83. Param *n = makeNode(Param);
  84. n->paramkind = PARAM_NUM;
  85. n->paramid = $1;
  86. n->paramtype = INT4OID;
  87. $$ = (Node *)n;
  88. }
  89. ;
  90. /*
  91.  * jimmy bell-style recursive queries aren't supported in the
  92.  * current system.
  93.  *
  94.  * ...however, recursive addattr and rename supported.  make special
  95.  * cases for these.
  96.  */
  97. opt_inh_star:  '*' { $$ = TRUE; }
  98. | /*EMPTY*/ { $$ = FALSE; }
  99. ;
  100. relation_name_list:  name_list;
  101. name_list:  name
  102. { $$ = lcons(makeString($1),NIL); }
  103. | name_list ',' name
  104. { $$ = lappend($1,makeString($3)); }
  105. ;
  106. group_clause:  GROUP BY expr_list { $$ = $3; }
  107. | /*EMPTY*/ { $$ = NIL; }
  108. ;
  109. having_clause:  HAVING a_expr
  110. {
  111. $$ = $2;
  112. }
  113. | /*EMPTY*/ { $$ = NULL; }
  114. ;
  115. for_update_clause:  FOR UPDATE update_list { $$ = $3; }
  116. | FOR READ ONLY { $$ = NULL; }
  117. | /* EMPTY */ { $$ = NULL; }
  118. ;
  119. update_list:  OF va_list { $$ = $2; }
  120. | /* EMPTY */ { $$ = lcons(NULL, NULL); }
  121. ;
  122. /*****************************************************************************
  123.  *
  124.  * clauses common to all Optimizable Stmts:
  125.  * from_clause -
  126.  * where_clause -
  127.  *
  128.  *****************************************************************************/
  129. from_clause:  FROM from_expr { $$ = $2; }
  130. | /*EMPTY*/ { $$ = NIL; }
  131. ;
  132. from_expr:  '(' join_clause_with_union ')'
  133. { $$ = $2; }
  134. | join_clause
  135. { $$ = $1; }
  136. | table_list
  137. { $$ = $1; }
  138. ;
  139. table_list:  table_list ',' table_expr
  140. { $$ = lappend($1, $3); }
  141. | table_expr
  142. { $$ = lcons($1, NIL); }
  143. ;
  144. table_expr:  relation_expr AS ColLabel
  145. {
  146. $$ = makeNode(RangeVar);
  147. $$->relExpr = $1;
  148. $$->name = $3;
  149. }
  150. | relation_expr ColId
  151. {
  152. $$ = makeNode(RangeVar);
  153. $$->relExpr = $1;
  154. $$->name = $2;
  155. }
  156. | relation_expr
  157. {
  158. $$ = makeNode(RangeVar);
  159. $$->relExpr = $1;
  160. $$->name = NULL;
  161. }
  162. ;
  163. /* A UNION JOIN is the same as a FULL OUTER JOIN which *omits*
  164.  * all result rows which would have matched on an INNER JOIN.
  165.  * Let's reject this for now. - thomas 1999-01-08
  166.  */
  167. join_clause_with_union:  join_clause
  168. { $$ = $1; }
  169. | table_expr UNION JOIN table_expr
  170. { elog(ERROR,"UNION JOIN not yet implemented"); }
  171. ;
  172. join_clause:  table_expr join_list
  173. {
  174. Node *n = lfirst($2);
  175. /* JoinExpr came back? then it is a join of some sort...
  176.  */
  177. if (IsA(n, JoinExpr))
  178. {
  179. JoinExpr *j = (JoinExpr *)n;
  180. j->larg = $1;
  181. $$ = $2;
  182. }
  183. /* otherwise, it was a cross join,
  184.  * which we just represent as an inner join...
  185.  */
  186. else
  187. $$ = lcons($1, $2);
  188. }
  189. ;
  190. join_list:  join_list join_expr
  191. {
  192. $$ = lappend($1, $2);
  193. }
  194. | join_expr
  195. {
  196. $$ = lcons($1, NIL);
  197. }
  198. ;
  199. /* This is everything but the left side of a join.
  200.  * Note that a CROSS JOIN is the same as an unqualified
  201.  * inner join, so just pass back the right-side table.
  202.  * A NATURAL JOIN implicitly matches column names between
  203.  * tables, so we'll collect those during the later transformation.
  204.  */
  205. join_expr:  join_type JOIN table_expr join_qual
  206. {
  207. JoinExpr *n = makeNode(JoinExpr);
  208. n->jointype = $1;
  209. n->rarg = (Node *)$3;
  210. n->quals = $4;
  211. $$ = (Node *)n;
  212. }
  213. | NATURAL join_type JOIN table_expr
  214. {
  215. JoinExpr *n = makeNode(JoinExpr);
  216. n->jointype = $2;
  217. n->rarg = (Node *)$4;
  218. n->quals = NULL; /* figure out which columns later... */
  219. $$ = (Node *)n;
  220. }
  221. | CROSS JOIN table_expr
  222. { $$ = (Node *)$3; }
  223. ;
  224. /* OUTER is just noise... */
  225. join_type:  FULL join_outer
  226. {
  227. $$ = FULL;
  228. elog(NOTICE,"FULL OUTER JOIN not yet implemented");
  229. }
  230. | LEFT join_outer
  231. {
  232. $$ = LEFT;
  233. elog(NOTICE,"LEFT OUTER JOIN not yet implemented");
  234. }
  235. | RIGHT join_outer
  236. {
  237. $$ = RIGHT;
  238. elog(NOTICE,"RIGHT OUTER JOIN not yet implemented");
  239. }
  240. | OUTER_P
  241. {
  242. $$ = LEFT;
  243. elog(NOTICE,"OUTER JOIN not yet implemented");
  244. }
  245. | INNER_P
  246. {
  247. $$ = INNER_P;
  248. }
  249. | /*EMPTY*/
  250. {
  251. $$ = INNER_P;
  252. }
  253. ;
  254. join_outer:  OUTER_P { $$ = NULL; }
  255. | /*EMPTY*/ { $$ = NULL;  /* no qualifiers */ }
  256. ;
  257. /* JOIN qualification clauses
  258.  * Possibilities are:
  259.  *  USING ( column list ) allows only unqualified column names,
  260.  *                        which must match between tables.
  261.  *  ON expr allows more general qualifications.
  262.  * - thomas 1999-01-07
  263.  */
  264. join_qual:  USING '(' using_list ')' { $$ = $3; }
  265. | ON a_expr { $$ = lcons($2, NIL); }
  266. ;
  267. using_list:  using_list ',' using_expr { $$ = lappend($1, $3); }
  268. | using_expr { $$ = lcons($1, NIL); }
  269. ;
  270. using_expr:  ColId
  271. {
  272. /* could be a column name or a relation_name */
  273. Ident *n = makeNode(Ident);
  274. n->name = $1;
  275. n->indirection = NULL;
  276. $$ = (Node *)n;
  277. }
  278. ;
  279. where_clause:  WHERE a_expr { $$ = $2; }
  280. | /*EMPTY*/ { $$ = NULL;  /* no qualifiers */ }
  281. ;
  282. relation_expr: relation_name
  283. {
  284. /* normal relations */
  285. $$ = makeNode(RelExpr);
  286. $$->relname = $1;
  287. $$->inh = FALSE;
  288. }
  289. | relation_name '*'   %prec '='
  290. {
  291. /* inheritance query */
  292. $$ = makeNode(RelExpr);
  293. $$->relname = $1;
  294. $$->inh = TRUE;
  295. }
  296. opt_array_bounds:  '[' ']' nest_array_bounds
  297. {  $$ = lcons(makeInteger(-1), $3); }
  298. | '[' Iconst ']' nest_array_bounds
  299. {  $$ = lcons(makeInteger($2), $4); }
  300. | /*EMPTY*/
  301. {  $$ = NIL; }
  302. ;
  303. nest_array_bounds: '[' ']' nest_array_bounds
  304. {  $$ = lcons(makeInteger(-1), $3); }
  305. | '[' Iconst ']' nest_array_bounds
  306. {  $$ = lcons(makeInteger($2), $4); }
  307. | /*EMPTY*/
  308. {  $$ = NIL; }
  309. ;
  310. /*****************************************************************************
  311.  *
  312.  * Type syntax
  313.  * SQL92 introduces a large amount of type-specific syntax.
  314.  * Define individual clauses to handle these cases, and use
  315.  *  the generic case to handle regular type-extensible Postgres syntax.
  316.  * - thomas 1997-10-10
  317.  *
  318.  *****************************************************************************/
  319. Typename:  Array opt_array_bounds
  320. {
  321. $$ = $1;
  322. $$->arrayBounds = $2;
  323. /* Is this the name of a complex type? If so, implement
  324.  * it as a set.
  325.  */
  326. if (!strcmp(saved_relname, $$->name))
  327. /* This attr is the same type as the relation
  328.  * being defined. The classic example: create
  329.  * emp(name=text,mgr=emp)
  330.  */
  331. $$->setof = TRUE;
  332. else if (typeTypeRelid(typenameType($$->name)) != InvalidOid)
  333.  /* (Eventually add in here that the set can only
  334.   * contain one element.)
  335.   */
  336. $$->setof = TRUE;
  337. else
  338. $$->setof = FALSE;
  339. }
  340. | SETOF Array
  341. {
  342. $$ = $2;
  343. $$->setof = TRUE;
  344. }
  345. ;
  346. Array:  Generic
  347. | Datetime
  348. | Numeric
  349. | Character
  350. ;
  351. Generic:  generic
  352. {
  353. $$ = makeNode(TypeName);
  354. $$->name = xlateSqlType($1);
  355. $$->typmod = -1;
  356. }
  357. ;
  358. generic:  IDENT { $$ = $1; }
  359. | TYPE_P { $$ = xlateSqlType("type"); }
  360. ;
  361. /* SQL92 numeric data types
  362.  * Check FLOAT() precision limits assuming IEEE floating types.
  363.  * Provide real DECIMAL() and NUMERIC() implementations now - Jan 1998-12-30
  364.  * - thomas 1997-09-18
  365.  */
  366. Numeric:  FLOAT opt_float
  367. {
  368. $$ = makeNode(TypeName);
  369. $$->name = xlateSqlType($2);
  370. $$->typmod = -1;
  371. }
  372. | DOUBLE PRECISION
  373. {
  374. $$ = makeNode(TypeName);
  375. $$->name = xlateSqlType("float");
  376. }
  377. | DECIMAL opt_decimal
  378. {
  379. $$ = makeNode(TypeName);
  380. $$->name = xlateSqlType("numeric");
  381. $$->typmod = $2;
  382. }
  383. | NUMERIC opt_numeric
  384. {
  385. $$ = makeNode(TypeName);
  386. $$->name = xlateSqlType("numeric");
  387. $$->typmod = $2;
  388. }
  389. ;
  390. numeric:  FLOAT
  391. { $$ = xlateSqlType("float8"); }
  392. | DOUBLE PRECISION
  393. { $$ = xlateSqlType("float8"); }
  394. | DECIMAL
  395. { $$ = xlateSqlType("numeric"); }
  396. | NUMERIC
  397. { $$ = xlateSqlType("numeric"); }
  398. ;
  399. opt_float:  '(' Iconst ')'
  400. {
  401. if ($2 < 1)
  402. elog(ERROR,"precision for FLOAT must be at least 1");
  403. else if ($2 < 7)
  404. $$ = xlateSqlType("float4");
  405. else if ($2 < 16)
  406. $$ = xlateSqlType("float8");
  407. else
  408. elog(ERROR,"precision for FLOAT must be less than 16");
  409. }
  410. | /*EMPTY*/
  411. {
  412. $$ = xlateSqlType("float8");
  413. }
  414. ;
  415. opt_numeric:  '(' Iconst ',' Iconst ')'
  416. {
  417. if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
  418. elog(ERROR,"NUMERIC precision %d must be beween 1 and %d",
  419. $2, NUMERIC_MAX_PRECISION);
  420. if ($4 < 0 || $4 > $2)
  421. elog(ERROR,"NUMERIC scale %d must be between 0 and precision %d",
  422. $4,$2);
  423. $$ = (($2 << 16) | $4) + VARHDRSZ;
  424. }
  425. | '(' Iconst ')'
  426. {
  427. if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
  428. elog(ERROR,"NUMERIC precision %d must be beween 1 and %d",
  429. $2, NUMERIC_MAX_PRECISION);
  430. $$ = ($2 << 16) + VARHDRSZ;
  431. }
  432. | /*EMPTY*/
  433. {
  434. $$ = ((NUMERIC_DEFAULT_PRECISION << 16) | NUMERIC_DEFAULT_SCALE) + VARHDRSZ;
  435. }
  436. ;
  437. opt_decimal:  '(' Iconst ',' Iconst ')'
  438. {
  439. if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
  440. elog(ERROR,"DECIMAL precision %d must be beween 1 and %d",
  441. $2, NUMERIC_MAX_PRECISION);
  442. if ($4 < 0 || $4 > $2)
  443. elog(ERROR,"DECIMAL scale %d must be between 0 and precision %d",
  444. $4,$2);
  445. $$ = (($2 << 16) | $4) + VARHDRSZ;
  446. }
  447. | '(' Iconst ')'
  448. {
  449. if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
  450. elog(ERROR,"DECIMAL precision %d must be beween 1 and %d",
  451. $2, NUMERIC_MAX_PRECISION);
  452. $$ = ($2 << 16) + VARHDRSZ;
  453. }
  454. | /*EMPTY*/
  455. {
  456. $$ = ((NUMERIC_DEFAULT_PRECISION << 16) | NUMERIC_DEFAULT_SCALE) + VARHDRSZ;
  457. }
  458. ;
  459. /* SQL92 character data types
  460.  * The following implements CHAR() and VARCHAR().
  461.  */
  462. Character:  character '(' Iconst ')'
  463. {
  464. $$ = makeNode(TypeName);
  465. if (strcasecmp($1, "char") == 0)
  466. $$->name = xlateSqlType("bpchar");
  467. else if (strcasecmp($1, "varchar") == 0)
  468. $$->name = xlateSqlType("varchar");
  469. else
  470. yyerror("internal parsing error; unrecognized character type");
  471. if ($3 < 1)
  472. elog(ERROR,"length for '%s' type must be at least 1",$1);
  473. else if ($3 > MaxAttrSize)
  474. elog(ERROR,"length for type '%s' cannot exceed %d",$1,
  475. MaxAttrSize);
  476. /* we actually implement this sort of like a varlen, so
  477.  * the first 4 bytes is the length. (the difference
  478.  * between this and "text" is that we blank-pad and
  479.  * truncate where necessary
  480.  */
  481. $$->typmod = VARHDRSZ + $3;
  482. }
  483. | character
  484. {
  485. $$ = makeNode(TypeName);
  486. /* Let's try to make all single-character types into bpchar(1)
  487.  * - thomas 1998-05-07
  488.  */
  489. if (strcasecmp($1, "char") == 0)
  490. {
  491. $$->name = xlateSqlType("bpchar");
  492. $$->typmod = VARHDRSZ + 1;
  493. }
  494. else
  495. {
  496. $$->name = xlateSqlType($1);
  497. $$->typmod = -1;
  498. }
  499. }
  500. ;
  501. character:  CHARACTER opt_varying opt_charset opt_collate
  502. {
  503. char *type, *c;
  504. if (($3 == NULL) || (strcasecmp($3, "sql_text") == 0)) {
  505. if ($2) type = xlateSqlType("varchar");
  506. else type = xlateSqlType("char");
  507. } else {
  508. if ($2) {
  509. c = palloc(strlen("var") + strlen($3) + 1);
  510. strcpy(c, "var");
  511. strcat(c, $3);
  512. type = xlateSqlType(c);
  513. } else {
  514. type = xlateSqlType($3);
  515. }
  516. };
  517. if ($4 != NULL)
  518. elog(NOTICE,"COLLATE %s not yet implemented; clause ignored",$4);
  519. $$ = type;
  520. }
  521. | CHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
  522. | VARCHAR { $$ = xlateSqlType("varchar"); }
  523. | NATIONAL CHARACTER opt_varying { $$ = xlateSqlType($3? "varchar": "char"); }
  524. | NCHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
  525. ;
  526. opt_varying:  VARYING { $$ = TRUE; }
  527. | /*EMPTY*/ { $$ = FALSE; }
  528. ;
  529. opt_charset:  CHARACTER SET ColId { $$ = $3; }
  530. | /*EMPTY*/ { $$ = NULL; }
  531. ;
  532. opt_collate:  COLLATE ColId { $$ = $2; }
  533. | /*EMPTY*/ { $$ = NULL; }
  534. ;
  535. Datetime:  datetime
  536. {
  537. $$ = makeNode(TypeName);
  538. $$->name = xlateSqlType($1);
  539. $$->typmod = -1;
  540. }
  541. | TIMESTAMP opt_timezone
  542. {
  543. $$ = makeNode(TypeName);
  544. $$->name = xlateSqlType("timestamp");
  545. $$->timezone = $2;
  546. $$->typmod = -1;
  547. }
  548. | TIME
  549. {
  550. $$ = makeNode(TypeName);
  551. $$->name = xlateSqlType("time");
  552. $$->typmod = -1;
  553. }
  554. | INTERVAL opt_interval
  555. {
  556. $$ = makeNode(TypeName);
  557. $$->name = xlateSqlType("interval");
  558. $$->typmod = -1;
  559. }
  560. ;
  561. datetime:  YEAR_P { $$ = "year"; }
  562. | MONTH_P { $$ = "month"; }
  563. | DAY_P { $$ = "day"; }
  564. | HOUR_P { $$ = "hour"; }
  565. | MINUTE_P { $$ = "minute"; }
  566. | SECOND_P { $$ = "second"; }
  567. ;
  568. opt_timezone:  WITH TIME ZONE { $$ = TRUE; }
  569. | /*EMPTY*/ { $$ = FALSE; }
  570. ;
  571. opt_interval:  datetime { $$ = lcons($1, NIL); }
  572. | YEAR_P TO MONTH_P { $$ = NIL; }
  573. | DAY_P TO HOUR_P { $$ = NIL; }
  574. | DAY_P TO MINUTE_P { $$ = NIL; }
  575. | DAY_P TO SECOND_P { $$ = NIL; }
  576. | HOUR_P TO MINUTE_P { $$ = NIL; }
  577. | HOUR_P TO SECOND_P { $$ = NIL; }
  578. | MINUTE_P TO SECOND_P { $$ = NIL; }
  579. | /*EMPTY*/ { $$ = NIL; }
  580. ;
  581. /*****************************************************************************
  582.  *
  583.  * expression grammar, still needs some cleanup
  584.  *
  585.  *****************************************************************************/
  586. a_expr_or_null:  a_expr
  587. { $$ = $1; }
  588. | NULL_P
  589. {
  590. A_Const *n = makeNode(A_Const);
  591. n->val.type = T_Null;
  592. $$ = (Node *)n;
  593. }
  594. ;
  595. /* Expressions using row descriptors
  596.  * Define row_descriptor to allow yacc to break the reduce/reduce conflict
  597.  *  with singleton expressions.
  598.  * Eliminated lots of code by defining row_op and sub_type clauses.
  599.  * However, can not consolidate EXPR_LINK case with others subselects
  600.  *  due to shift/reduce conflict with the non-subselect clause (the parser
  601.  *  would have to look ahead more than one token to resolve the conflict).
  602.  * - thomas 1998-05-09
  603.  */
  604. row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
  605. {
  606. SubLink *n = makeNode(SubLink);
  607. n->lefthand = $2;
  608. n->oper = lcons("=",NIL);
  609. n->useor = false;
  610. n->subLinkType = ANY_SUBLINK;
  611. n->subselect = $6;
  612. $$ = (Node *)n;
  613. }
  614. | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
  615. {
  616. SubLink *n = makeNode(SubLink);
  617. n->lefthand = $2;
  618. n->oper = lcons("<>",NIL);
  619. n->useor = true;
  620. n->subLinkType = ALL_SUBLINK;
  621. n->subselect = $7;
  622. $$ = (Node *)n;
  623. }
  624. | '(' row_descriptor ')' row_op sub_type '(' SubSelect ')'
  625. {
  626. SubLink *n = makeNode(SubLink);
  627. n->lefthand = $2;
  628. n->oper = lcons($4, NIL);
  629. if (strcmp($4,"<>") == 0)
  630. n->useor = true;
  631. else
  632. n->useor = false;
  633. n->subLinkType = $5;
  634. n->subselect = $7;
  635. $$ = (Node *)n;
  636. }
  637. | '(' row_descriptor ')' row_op '(' SubSelect ')'
  638. {
  639. SubLink *n = makeNode(SubLink);
  640. n->lefthand = $2;
  641. n->oper = lcons($4, NIL);
  642. if (strcmp($4,"<>") == 0)
  643. n->useor = true;
  644. else
  645. n->useor = false;
  646. n->subLinkType = EXPR_SUBLINK;
  647. n->subselect = $6;
  648. $$ = (Node *)n;
  649. }
  650. | '(' row_descriptor ')' row_op '(' row_descriptor ')'
  651. {
  652. $$ = makeRowExpr($4, $2, $6);
  653. }
  654. ;
  655. row_descriptor:  row_list ',' a_expr
  656. {
  657. $$ = lappend($1, $3);
  658. }
  659. ;
  660. row_list:  row_list ',' a_expr
  661. {
  662. $$ = lappend($1, $3);
  663. }
  664. | a_expr
  665. {
  666. $$ = lcons($1, NIL);
  667. }
  668. ;
  669. row_op:  Op { $$ = $1; }
  670. | '<' { $$ = "<"; }
  671. | '=' { $$ = "="; }
  672. | '>' { $$ = ">"; }
  673. | '+' { $$ = "+"; }
  674. | '-' { $$ = "-"; }
  675. | '*' { $$ = "*"; }
  676. | '/' { $$ = "/"; }
  677. | '%' { $$ = "%"; }
  678. ;
  679. sub_type:  ANY { $$ = ANY_SUBLINK; }
  680. | ALL { $$ = ALL_SUBLINK; }
  681. ;
  682. /* General expressions
  683.  * This is the heart of the expression syntax.
  684.  * Note that the BETWEEN clause looks similar to a boolean expression
  685.  *  and so we must define b_expr which is almost the same as a_expr
  686.  *  but without the boolean expressions.
  687.  * All operations/expressions are allowed in a BETWEEN clause
  688.  *  if surrounded by parens.
  689.  */
  690. a_expr:  attr opt_indirection
  691. {
  692. $1->indirection = $2;
  693. $$ = (Node *)$1;
  694. }
  695. | row_expr
  696. { $$ = $1;  }
  697. | AexprConst
  698. { $$ = $1;  }
  699. | ColId
  700. {
  701. /* could be a column name or a relation_name */
  702. Ident *n = makeNode(Ident);
  703. n->name = $1;
  704. n->indirection = NULL;
  705. $$ = (Node *)n;
  706. }
  707. | '-' a_expr %prec UMINUS
  708. { $$ = doNegate($2); }
  709. | '%' a_expr
  710. { $$ = makeA_Expr(OP, "%", NULL, $2); }
  711. | '^' a_expr
  712. { $$ = makeA_Expr(OP, "^", NULL, $2); }
  713. | a_expr '%'
  714. { $$ = makeA_Expr(OP, "%", $1, NULL); }
  715. | a_expr '^'
  716. { $$ = makeA_Expr(OP, "^", $1, NULL); }
  717. | a_expr '+' a_expr
  718. { $$ = makeA_Expr(OP, "+", $1, $3); }
  719. | a_expr '-' a_expr
  720. { $$ = makeA_Expr(OP, "-", $1, $3); }
  721. | a_expr '/' a_expr
  722. { $$ = makeA_Expr(OP, "/", $1, $3); }
  723. | a_expr '%' a_expr
  724. { $$ = makeA_Expr(OP, "%", $1, $3); }
  725. | a_expr '*' a_expr
  726. { $$ = makeA_Expr(OP, "*", $1, $3); }
  727. | a_expr '^' a_expr
  728. { $$ = makeA_Expr(OP, "^", $1, $3); }
  729. | a_expr '<' a_expr
  730. { $$ = makeA_Expr(OP, "<", $1, $3); }
  731. | a_expr '>' a_expr
  732. { $$ = makeA_Expr(OP, ">", $1, $3); }
  733.    | a_expr '=' NULL_P
  734.    { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
  735. /* We allow this for standards-broken SQL products, like MS stuff */
  736.    | NULL_P '=' a_expr
  737.    { $$ = makeA_Expr(ISNULL, NULL, $3, NULL); }
  738. | a_expr '=' a_expr
  739. { $$ = makeA_Expr(OP, "=", $1, $3); }
  740. | ':' a_expr
  741. { $$ = makeA_Expr(OP, ":", NULL, $2); }
  742. | ';' a_expr
  743. { $$ = makeA_Expr(OP, ";", NULL, $2); }
  744. | '|' a_expr
  745. { $$ = makeA_Expr(OP, "|", NULL, $2); }
  746. | a_expr TYPECAST Typename
  747. {
  748. $$ = (Node *)$1;
  749. /* AexprConst can be either A_Const or ParamNo */
  750. if (nodeTag($1) == T_A_Const) {
  751. ((A_Const *)$1)->typename = $3;
  752. } else if (nodeTag($1) == T_Param) {
  753. ((ParamNo *)$1)->typename = $3;
  754. /* otherwise, try to transform to a function call */
  755. } else {
  756. FuncCall *n = makeNode(FuncCall);
  757. n->funcname = $3->name;
  758. n->args = lcons($1,NIL);
  759. $$ = (Node *)n;
  760. }
  761. }
  762. | CAST '(' a_expr AS Typename ')'
  763. {
  764. $$ = (Node *)$3;
  765. /* AexprConst can be either A_Const or ParamNo */
  766. if (nodeTag($3) == T_A_Const) {
  767. ((A_Const *)$3)->typename = $5;
  768. } else if (nodeTag($5) == T_Param) {
  769. ((ParamNo *)$3)->typename = $5;
  770. /* otherwise, try to transform to a function call */
  771. } else {
  772. FuncCall *n = makeNode(FuncCall);
  773. n->funcname = $5->name;
  774. n->args = lcons($3,NIL);
  775. $$ = (Node *)n;
  776. }
  777. }
  778. | '(' a_expr_or_null ')'
  779. { $$ = $2; }
  780. | a_expr Op a_expr
  781. { $$ = makeIndexable($2,$1,$3); }
  782. | a_expr LIKE a_expr
  783. { $$ = makeIndexable("~~", $1, $3); }
  784. | a_expr NOT LIKE a_expr
  785. { $$ = makeA_Expr(OP, "!~~", $1, $4); }
  786. | Op a_expr
  787. { $$ = makeA_Expr(OP, $1, NULL, $2); }
  788. | a_expr Op
  789. { $$ = makeA_Expr(OP, $2, $1, NULL); }
  790. | func_name '(' '*' ')'
  791. {
  792. /* cheap hack for aggregate (eg. count) */
  793. FuncCall *n = makeNode(FuncCall);
  794. A_Const *star = makeNode(A_Const);
  795. star->val.type = T_String;
  796. star->val.val.str = "";
  797. n->funcname = $1;
  798. n->args = lcons(star, NIL);
  799. $$ = (Node *)n;
  800. }
  801. | func_name '(' ')'
  802. {
  803. FuncCall *n = makeNode(FuncCall);
  804. n->funcname = $1;
  805. n->args = NIL;
  806. $$ = (Node *)n;
  807. }
  808. | func_name '(' expr_list ')'
  809. {
  810. FuncCall *n = makeNode(FuncCall);
  811. n->funcname = $1;
  812. n->args = $3;
  813. $$ = (Node *)n;
  814. }
  815. | CURRENT_DATE
  816. {
  817. A_Const *n = makeNode(A_Const);
  818. TypeName *t = makeNode(TypeName);
  819. n->val.type = T_String;
  820. n->val.val.str = "now";
  821. n->typename = t;
  822. t->name = xlateSqlType("date");
  823. t->setof = FALSE;
  824. t->typmod = -1;
  825.  
  826. $$ = (Node *)n;
  827. }
  828. | CURRENT_TIME
  829. {
  830. A_Const *n = makeNode(A_Const);
  831. TypeName *t = makeNode(TypeName);
  832. n->val.type = T_String;
  833. n->val.val.str = "now";
  834. n->typename = t;
  835. t->name = xlateSqlType("time");
  836. t->setof = FALSE;
  837. t->typmod = -1;
  838. $$ = (Node *)n;
  839. }
  840. | CURRENT_TIME '(' Iconst ')'
  841. {
  842. FuncCall *n = makeNode(FuncCall);
  843. A_Const *s = makeNode(A_Const);
  844. TypeName *t = makeNode(TypeName);
  845. n->funcname = xlateSqlType("time");
  846. n->args = lcons(s, NIL);
  847. s->val.type = T_String;
  848. s->val.val.str = "now";
  849. s->typename = t;
  850. t->name = xlateSqlType("time");
  851. t->setof = FALSE;
  852. t->typmod = -1;
  853. if ($3 != 0)
  854. elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
  855. $$ = (Node *)n;
  856. }
  857. | CURRENT_TIMESTAMP
  858. {
  859. A_Const *n = makeNode(A_Const);
  860. TypeName *t = makeNode(TypeName);
  861. n->val.type = T_String;
  862. n->val.val.str = "now";
  863. n->typename = t;
  864. t->name = xlateSqlType("timestamp");
  865. t->setof = FALSE;
  866. t->typmod = -1;
  867. $$ = (Node *)n;
  868. }
  869. | CURRENT_TIMESTAMP '(' Iconst ')'
  870. {
  871. FuncCall *n = makeNode(FuncCall);
  872. A_Const *s = makeNode(A_Const);
  873. TypeName *t = makeNode(TypeName);
  874. n->funcname = xlateSqlType("timestamp");
  875. n->args = lcons(s, NIL);
  876. s->val.type = T_String;
  877. s->val.val.str = "now";
  878. s->typename = t;
  879. t->name = xlateSqlType("timestamp");
  880. t->setof = FALSE;
  881. t->typmod = -1;
  882. if ($3 != 0)
  883. elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
  884. $$ = (Node *)n;
  885. }
  886. | CURRENT_USER
  887. {
  888. FuncCall *n = makeNode(FuncCall);
  889. n->funcname = "getpgusername";
  890. n->args = NIL;
  891. $$ = (Node *)n;
  892. }
  893. | USER
  894. {
  895. FuncCall *n = makeNode(FuncCall);
  896. n->funcname = "getpgusername";
  897. n->args = NIL;
  898. $$ = (Node *)n;
  899. }
  900. | EXISTS '(' SubSelect ')'
  901. {
  902. SubLink *n = makeNode(SubLink);
  903. n->lefthand = NIL;
  904. n->useor = false;
  905. n->oper = NIL;
  906. n->subLinkType = EXISTS_SUBLINK;
  907. n->subselect = $3;
  908. $$ = (Node *)n;
  909. }
  910. | EXTRACT '(' extract_list ')'
  911. {
  912. FuncCall *n = makeNode(FuncCall);
  913. n->funcname = "date_part";
  914. n->args = $3;
  915. $$ = (Node *)n;
  916. }
  917. | POSITION '(' position_list ')'
  918. {
  919. FuncCall *n = makeNode(FuncCall);
  920. n->funcname = "strpos";
  921. n->args = $3;
  922. $$ = (Node *)n;
  923. }
  924. | SUBSTRING '(' substr_list ')'
  925. {
  926. FuncCall *n = makeNode(FuncCall);
  927. n->funcname = "substr";
  928. n->args = $3;
  929. $$ = (Node *)n;
  930. }
  931. /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
  932. | TRIM '(' BOTH trim_list ')'
  933. {
  934. FuncCall *n = makeNode(FuncCall);
  935. n->funcname = "btrim";
  936. n->args = $4;
  937. $$ = (Node *)n;
  938. }
  939. | TRIM '(' LEADING trim_list ')'
  940. {
  941. FuncCall *n = makeNode(FuncCall);
  942. n->funcname = "ltrim";
  943. n->args = $4;
  944. $$ = (Node *)n;
  945. }
  946. | TRIM '(' TRAILING trim_list ')'
  947. {
  948. FuncCall *n = makeNode(FuncCall);
  949. n->funcname = "rtrim";
  950. n->args = $4;
  951. $$ = (Node *)n;
  952. }
  953. | TRIM '(' trim_list ')'
  954. {
  955. FuncCall *n = makeNode(FuncCall);
  956. n->funcname = "btrim";
  957. n->args = $3;
  958. $$ = (Node *)n;
  959. }
  960. | a_expr ISNULL
  961. { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
  962. | a_expr IS NULL_P
  963. { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
  964. | a_expr NOTNULL
  965. { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
  966. | a_expr IS NOT NULL_P
  967. { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
  968. /* IS TRUE, IS FALSE, etc used to be function calls
  969.  *  but let's make them expressions to allow the optimizer
  970.  *  a chance to eliminate them if a_expr is a constant string.
  971.  * - thomas 1997-12-22
  972.  */
  973. | a_expr IS TRUE_P
  974. {
  975. A_Const *n = makeNode(A_Const);
  976. n->val.type = T_String;
  977. n->val.val.str = "t";
  978. n->typename = makeNode(TypeName);
  979. n->typename->name = xlateSqlType("bool");
  980. n->typename->typmod = -1;
  981. $$ = makeA_Expr(OP, "=", $1,(Node *)n);
  982. }
  983. | a_expr IS NOT FALSE_P
  984. {
  985. A_Const *n = makeNode(A_Const);
  986. n->val.type = T_String;
  987. n->val.val.str = "t";
  988. n->typename = makeNode(TypeName);
  989. n->typename->name = xlateSqlType("bool");
  990. n->typename->typmod = -1;
  991. $$ = makeA_Expr(OP, "=", $1,(Node *)n);
  992. }
  993. | a_expr IS FALSE_P
  994. {
  995. A_Const *n = makeNode(A_Const);
  996. n->val.type = T_String;
  997. n->val.val.str = "f";
  998. n->typename = makeNode(TypeName);
  999. n->typename->name = xlateSqlType("bool");
  1000. n->typename->typmod = -1;
  1001. $$ = makeA_Expr(OP, "=", $1,(Node *)n);
  1002. }
  1003. | a_expr IS NOT TRUE_P
  1004. {
  1005. A_Const *n = makeNode(A_Const);
  1006. n->val.type = T_String;
  1007. n->val.val.str = "f";
  1008. n->typename = makeNode(TypeName);
  1009. n->typename->name = xlateSqlType("bool");
  1010. n->typename->typmod = -1;
  1011. $$ = makeA_Expr(OP, "=", $1,(Node *)n);
  1012. }
  1013. | a_expr BETWEEN b_expr AND b_expr
  1014. {
  1015. $$ = makeA_Expr(AND, NULL,
  1016. makeA_Expr(OP, ">=", $1, $3),
  1017. makeA_Expr(OP, "<=", $1, $5));
  1018. }
  1019. | a_expr NOT BETWEEN b_expr AND b_expr
  1020. {
  1021. $$ = makeA_Expr(OR, NULL,
  1022. makeA_Expr(OP, "<", $1, $4),
  1023. makeA_Expr(OP, ">", $1, $6));
  1024. }
  1025. | a_expr IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' in_expr ')'
  1026. {
  1027. saved_In_Expr = lnext(saved_In_Expr);
  1028. if (nodeTag($5) == T_SubLink)
  1029. {
  1030. SubLink *n = (SubLink *)$5;
  1031. n->lefthand = lcons($1, NIL);
  1032. n->oper = lcons("=",NIL);
  1033. n->useor = false;
  1034. n->subLinkType = ANY_SUBLINK;
  1035. $$ = (Node *)n;
  1036. }
  1037. else $$ = $5;
  1038. }
  1039. | a_expr NOT IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' not_in_expr ')'
  1040. {
  1041. saved_In_Expr = lnext(saved_In_Expr);
  1042. if (nodeTag($6) == T_SubLink)
  1043. {
  1044. SubLink *n = (SubLink *)$6;
  1045. n->lefthand = lcons($1, NIL);
  1046. n->oper = lcons("<>",NIL);
  1047. n->useor = false;
  1048. n->subLinkType = ALL_SUBLINK;
  1049. $$ = (Node *)n;
  1050. }
  1051. else $$ = $6;
  1052. }
  1053. | a_expr Op '(' SubSelect ')'
  1054. {
  1055. SubLink *n = makeNode(SubLink);
  1056. n->lefthand = lcons($1, NULL);
  1057. n->oper = lcons($2,NIL);
  1058. n->useor = false;
  1059. n->subLinkType = EXPR_SUBLINK;
  1060. n->subselect = $4;
  1061. $$ = (Node *)n;
  1062. }
  1063. | a_expr '+' '(' SubSelect ')'
  1064. {
  1065. SubLink *n = makeNode(SubLink);
  1066. n->lefthand = lcons($1, NULL);
  1067. n->oper = lcons("+",NIL);
  1068. n->useor = false;
  1069. n->subLinkType = EXPR_SUBLINK;
  1070. n->subselect = $4;
  1071. $$ = (Node *)n;
  1072. }
  1073. | a_expr '-' '(' SubSelect ')'
  1074. {
  1075. SubLink *n = makeNode(SubLink);
  1076. n->lefthand = lcons($1, NULL);
  1077. n->oper = lcons("-",NIL);
  1078. n->useor = false;
  1079. n->subLinkType = EXPR_SUBLINK;
  1080. n->subselect = $4;
  1081. $$ = (Node *)n;
  1082. }
  1083. | a_expr '/' '(' SubSelect ')'
  1084. {
  1085. SubLink *n = makeNode(SubLink);
  1086. n->lefthand = lcons($1, NULL);
  1087. n->oper = lcons("/",NIL);
  1088. n->useor = false;
  1089. n->subLinkType = EXPR_SUBLINK;
  1090. n->subselect = $4;
  1091. $$ = (Node *)n;
  1092. }
  1093. | a_expr '%' '(' SubSelect ')'
  1094. {
  1095. SubLink *n = makeNode(SubLink);
  1096. n->lefthand = lcons($1, NULL);
  1097. n->oper = lcons("%",NIL);
  1098. n->useor = false;
  1099. n->subLinkType = EXPR_SUBLINK;
  1100. n->subselect = $4;
  1101. $$ = (Node *)n;
  1102. }
  1103. | a_expr '*' '(' SubSelect ')'
  1104. {
  1105. SubLink *n = makeNode(SubLink);
  1106. n->lefthand = lcons($1, NULL);
  1107. n->oper = lcons("*",NIL);
  1108. n->useor = false;
  1109. n->subLinkType = EXPR_SUBLINK;
  1110. n->subselect = $4;
  1111. $$ = (Node *)n;
  1112. }
  1113. | a_expr '<' '(' SubSelect ')'
  1114. {
  1115. SubLink *n = makeNode(SubLink);
  1116. n->lefthand = lcons($1, NULL);
  1117. n->oper = lcons("<",NIL);
  1118. n->useor = false;
  1119. n->subLinkType = EXPR_SUBLINK;
  1120. n->subselect = $4;
  1121. $$ = (Node *)n;
  1122. }
  1123. | a_expr '>' '(' SubSelect ')'
  1124. {
  1125. SubLink *n = makeNode(SubLink);
  1126. n->lefthand = lcons($1, NULL);
  1127. n->oper = lcons(">",NIL);
  1128. n->useor = false;
  1129. n->subLinkType = EXPR_SUBLINK;
  1130. n->subselect = $4;
  1131. $$ = (Node *)n;
  1132. }
  1133. | a_expr '=' '(' SubSelect ')'
  1134. {
  1135. SubLink *n = makeNode(SubLink);
  1136. n->lefthand = lcons($1, NULL);
  1137. n->oper = lcons("=",NIL);
  1138. n->useor = false;
  1139. n->subLinkType = EXPR_SUBLINK;
  1140. n->subselect = $4;
  1141. $$ = (Node *)n;
  1142. }
  1143. | a_expr Op ANY '(' SubSelect ')'
  1144. {
  1145. SubLink *n = makeNode(SubLink);
  1146. n->lefthand = lcons($1,NIL);
  1147. n->oper = lcons($2,NIL);
  1148. n->useor = false;
  1149. n->subLinkType = ANY_SUBLINK;
  1150. n->subselect = $5;
  1151. $$ = (Node *)n;
  1152. }
  1153. | a_expr '+' ANY '(' SubSelect ')'
  1154. {
  1155. SubLink *n = makeNode(SubLink);
  1156. n->lefthand = lcons($1,NIL);
  1157. n->oper = lcons("+",NIL);
  1158. n->useor = false;
  1159. n->subLinkType = ANY_SUBLINK;
  1160. n->subselect = $5;
  1161. $$ = (Node *)n;
  1162. }
  1163. | a_expr '-' ANY '(' SubSelect ')'
  1164. {
  1165. SubLink *n = makeNode(SubLink);
  1166. n->lefthand = lcons($1,NIL);
  1167. n->oper = lcons("-",NIL);
  1168. n->useor = false;
  1169. n->subLinkType = ANY_SUBLINK;
  1170. n->subselect = $5;
  1171. $$ = (Node *)n;
  1172. }
  1173. | a_expr '/' ANY '(' SubSelect ')'
  1174. {
  1175. SubLink *n = makeNode(SubLink);
  1176. n->lefthand = lcons($1,NIL);
  1177. n->oper = lcons("/",NIL);
  1178. n->useor = false;
  1179. n->subLinkType = ANY_SUBLINK;
  1180. n->subselect = $5;
  1181. $$ = (Node *)n;
  1182. }
  1183. | a_expr '%' ANY '(' SubSelect ')'
  1184. {
  1185. SubLink *n = makeNode(SubLink);
  1186. n->lefthand = lcons($1,NIL);
  1187. n->oper = lcons("%",NIL);
  1188. n->useor = false;
  1189. n->subLinkType = ANY_SUBLINK;
  1190. n->subselect = $5;
  1191. $$ = (Node *)n;
  1192. }
  1193. | a_expr '*' ANY '(' SubSelect ')'
  1194. {
  1195. SubLink *n = makeNode(SubLink);
  1196. n->lefthand = lcons($1,NIL);
  1197. n->oper = lcons("*",NIL);
  1198. n->useor = false;
  1199. n->subLinkType = ANY_SUBLINK;
  1200. n->subselect = $5;
  1201. $$ = (Node *)n;
  1202. }
  1203. | a_expr '<' ANY '(' SubSelect ')'
  1204. {
  1205. SubLink *n = makeNode(SubLink);
  1206. n->lefthand = lcons($1,NIL);
  1207. n->oper = lcons("<",NIL);
  1208. n->useor = false;
  1209. n->subLinkType = ANY_SUBLINK;
  1210. n->subselect = $5;
  1211. $$ = (Node *)n;
  1212. }
  1213. | a_expr '>' ANY '(' SubSelect ')'
  1214. {
  1215. SubLink *n = makeNode(SubLink);
  1216. n->lefthand = lcons($1,NIL);
  1217. n->oper = lcons(">",NIL);
  1218. n->useor = false;
  1219. n->subLinkType = ANY_SUBLINK;
  1220. n->subselect = $5;
  1221. $$ = (Node *)n;
  1222. }
  1223. | a_expr '=' ANY '(' SubSelect ')'
  1224. {
  1225. SubLink *n = makeNode(SubLink);
  1226. n->lefthand = lcons($1,NIL);
  1227. n->oper = lcons("=",NIL);
  1228. n->useor = false;
  1229. n->subLinkType = ANY_SUBLINK;
  1230. n->subselect = $5;
  1231. $$ = (Node *)n;
  1232. }
  1233. | a_expr Op ALL '(' SubSelect ')'
  1234. {
  1235. SubLink *n = makeNode(SubLink);
  1236. n->lefthand = lcons($1, NULL);
  1237. n->oper = lcons($2,NIL);
  1238. n->useor = false;
  1239. n->subLinkType = ALL_SUBLINK;
  1240. n->subselect = $5;
  1241. $$ = (Node *)n;
  1242. }
  1243. | a_expr '+' ALL '(' SubSelect ')'
  1244. {
  1245. SubLink *n = makeNode(SubLink);
  1246. n->lefthand = lcons($1, NULL);
  1247. n->oper = lcons("+",NIL);
  1248. n->useor = false;
  1249. n->subLinkType = ALL_SUBLINK;
  1250. n->subselect = $5;
  1251. $$ = (Node *)n;
  1252. }
  1253. | a_expr '-' ALL '(' SubSelect ')'
  1254. {
  1255. SubLink *n = makeNode(SubLink);
  1256. n->lefthand = lcons($1, NULL);
  1257. n->oper = lcons("-",NIL);
  1258. n->useor = false;
  1259. n->subLinkType = ALL_SUBLINK;
  1260. n->subselect = $5;
  1261. $$ = (Node *)n;
  1262. }
  1263. | a_expr '/' ALL '(' SubSelect ')'
  1264. {
  1265. SubLink *n = makeNode(SubLink);
  1266. n->lefthand = lcons($1, NULL);
  1267. n->oper = lcons("/",NIL);
  1268. n->useor = false;
  1269. n->subLinkType = ALL_SUBLINK;
  1270. n->subselect = $5;
  1271. $$ = (Node *)n;
  1272. }
  1273. | a_expr '%' ALL '(' SubSelect ')'
  1274. {
  1275. SubLink *n = makeNode(SubLink);
  1276. n->lefthand = lcons($1, NULL);
  1277. n->oper = lcons("%",NIL);
  1278. n->useor = false;
  1279. n->subLinkType = ALL_SUBLINK;
  1280. n->subselect = $5;
  1281. $$ = (Node *)n;
  1282. }
  1283. | a_expr '*' ALL '(' SubSelect ')'
  1284. {
  1285. SubLink *n = makeNode(SubLink);
  1286. n->lefthand = lcons($1, NULL);
  1287. n->oper = lcons("*",NIL);
  1288. n->useor = false;
  1289. n->subLinkType = ALL_SUBLINK;
  1290. n->subselect = $5;
  1291. $$ = (Node *)n;
  1292. }
  1293. | a_expr '<' ALL '(' SubSelect ')'
  1294. {
  1295. SubLink *n = makeNode(SubLink);
  1296. n->lefthand = lcons($1, NULL);
  1297. n->oper = lcons("<",NIL);
  1298. n->useor = false;
  1299. n->subLinkType = ALL_SUBLINK;
  1300. n->subselect = $5;
  1301. $$ = (Node *)n;
  1302. }
  1303. | a_expr '>' ALL '(' SubSelect ')'
  1304. {
  1305. SubLink *n = makeNode(SubLink);
  1306. n->lefthand = lcons($1, NULL);
  1307. n->oper = lcons(">",NIL);
  1308. n->useor = false;
  1309. n->subLinkType = ALL_SUBLINK;
  1310. n->subselect = $5;
  1311. $$ = (Node *)n;
  1312. }
  1313. | a_expr '=' ALL '(' SubSelect ')'
  1314. {
  1315. SubLink *n = makeNode(SubLink);
  1316. n->lefthand = lcons($1, NULL);
  1317. n->oper = lcons("=",NIL);
  1318. n->useor = false;
  1319. n->subLinkType = ALL_SUBLINK;
  1320. n->subselect = $5;
  1321. $$ = (Node *)n;
  1322. }
  1323. | a_expr AND a_expr
  1324. { $$ = makeA_Expr(AND, NULL, $1, $3); }
  1325. | a_expr OR a_expr
  1326. { $$ = makeA_Expr(OR, NULL, $1, $3); }
  1327. | NOT a_expr
  1328. { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
  1329. | case_expr
  1330. { $$ = $1; }
  1331. ;
  1332. /* Restricted expressions
  1333.  * b_expr is a subset of the complete expression syntax
  1334.  *  defined by a_expr. b_expr is used in BETWEEN clauses
  1335.  *  to eliminate parser ambiguities stemming from the AND keyword.
  1336.  */
  1337. b_expr:  attr opt_indirection
  1338. {
  1339. $1->indirection = $2;
  1340. $$ = (Node *)$1;
  1341. }
  1342. | AexprConst
  1343. { $$ = $1;  }
  1344. | ColId
  1345. {
  1346. /* could be a column name or a relation_name */
  1347. Ident *n = makeNode(Ident);
  1348. n->name = $1;
  1349. n->indirection = NULL;
  1350. $$ = (Node *)n;
  1351. }
  1352. | '-' b_expr %prec UMINUS
  1353. { $$ = doNegate($2); }
  1354. | '%' b_expr
  1355. { $$ = makeA_Expr(OP, "%", NULL, $2); }
  1356. | '^' b_expr
  1357. { $$ = makeA_Expr(OP, "^", NULL, $2); }
  1358. | b_expr '%'
  1359. { $$ = makeA_Expr(OP, "%", $1, NULL); }
  1360. | b_expr '^'
  1361. { $$ = makeA_Expr(OP, "^", $1, NULL); }
  1362. | b_expr '+' b_expr
  1363. { $$ = makeA_Expr(OP, "+", $1, $3); }
  1364. | b_expr '-' b_expr
  1365. { $$ = makeA_Expr(OP, "-", $1, $3); }
  1366. | b_expr '/' b_expr
  1367. { $$ = makeA_Expr(OP, "/", $1, $3); }
  1368. | b_expr '%' b_expr
  1369. { $$ = makeA_Expr(OP, "%", $1, $3); }
  1370. | b_expr '^' b_expr
  1371. { $$ = makeA_Expr(OP, "^", $1, $3); }
  1372. | b_expr '*' b_expr
  1373. { $$ = makeA_Expr(OP, "*", $1, $3); }
  1374. | ':' b_expr
  1375. { $$ = makeA_Expr(OP, ":", NULL, $2); }
  1376. | ';' b_expr
  1377. { $$ = makeA_Expr(OP, ";", NULL, $2); }
  1378. | '|' b_expr
  1379. { $$ = makeA_Expr(OP, "|", NULL, $2); }
  1380. | b_expr TYPECAST Typename
  1381. {
  1382. $$ = (Node *)$1;
  1383. /* AexprConst can be either A_Const or ParamNo */
  1384. if (nodeTag($1) == T_A_Const) {
  1385. ((A_Const *)$1)->typename = $3;
  1386. } else if (nodeTag($1) == T_Param) {
  1387. ((ParamNo *)$1)->typename = $3;
  1388. /* otherwise, try to transform to a function call */
  1389. } else {
  1390. FuncCall *n = makeNode(FuncCall);
  1391. n->funcname = $3->name;
  1392. n->args = lcons($1,NIL);
  1393. $$ = (Node *)n;
  1394. }
  1395. }
  1396. | CAST '(' b_expr AS Typename ')'
  1397. {
  1398. $$ = (Node *)$3;
  1399. /* AexprConst can be either A_Const or ParamNo */
  1400. if (nodeTag($3) == T_A_Const) {
  1401. ((A_Const *)$3)->typename = $5;
  1402. } else if (nodeTag($3) == T_Param) {
  1403. ((ParamNo *)$3)->typename = $5;
  1404. /* otherwise, try to transform to a function call */
  1405. } else {
  1406. FuncCall *n = makeNode(FuncCall);
  1407. n->funcname = $5->name;
  1408. n->args = lcons($3,NIL);
  1409. $$ = (Node *)n;
  1410. }
  1411. }
  1412. | '(' a_expr ')'
  1413. { $$ = $2; }
  1414. | b_expr Op b_expr
  1415. { $$ = makeIndexable($2,$1,$3); }
  1416. | Op b_expr
  1417. { $$ = makeA_Expr(OP, $1, NULL, $2); }
  1418. | b_expr Op
  1419. { $$ = makeA_Expr(OP, $2, $1, NULL); }
  1420. | func_name '(' ')'
  1421. {
  1422. FuncCall *n = makeNode(FuncCall);
  1423. n->funcname = $1;
  1424. n->args = NIL;
  1425. $$ = (Node *)n;
  1426. }
  1427. | func_name '(' expr_list ')'
  1428. {
  1429. FuncCall *n = makeNode(FuncCall);
  1430. n->funcname = $1;
  1431. n->args = $3;
  1432. $$ = (Node *)n;
  1433. }
  1434. | CURRENT_DATE
  1435. {
  1436. A_Const *n = makeNode(A_Const);
  1437. TypeName *t = makeNode(TypeName);
  1438. n->val.type = T_String;
  1439. n->val.val.str = "now";
  1440. n->typename = t;
  1441. t->name = xlateSqlType("date");
  1442. t->setof = FALSE;
  1443. t->typmod = -1;
  1444. $$ = (Node *)n;
  1445. }
  1446. | CURRENT_TIME
  1447. {
  1448. A_Const *n = makeNode(A_Const);
  1449. TypeName *t = makeNode(TypeName);
  1450. n->val.type = T_String;
  1451. n->val.val.str = "now";
  1452. n->typename = t;
  1453. t->name = xlateSqlType("time");
  1454. t->setof = FALSE;
  1455. t->typmod = -1;
  1456. $$ = (Node *)n;
  1457. }
  1458. | CURRENT_TIME '(' Iconst ')'
  1459. {
  1460. FuncCall *n = makeNode(FuncCall);
  1461. A_Const *s = makeNode(A_Const);
  1462. TypeName *t = makeNode(TypeName);
  1463. n->funcname = xlateSqlType("time");
  1464. n->args = lcons(s, NIL);
  1465. s->val.type = T_String;
  1466. s->val.val.str = "now";
  1467. s->typename = t;
  1468. t->name = xlateSqlType("time");
  1469. t->setof = FALSE;
  1470. t->typmod = -1;
  1471. if ($3 != 0)
  1472. elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
  1473. $$ = (Node *)n;
  1474. }
  1475. | CURRENT_TIMESTAMP
  1476. {
  1477. A_Const *n = makeNode(A_Const);
  1478. TypeName *t = makeNode(TypeName);
  1479. n->val.type = T_String;
  1480. n->val.val.str = "now";
  1481. n->typename = t;
  1482. t->name = xlateSqlType("timestamp");
  1483. t->setof = FALSE;
  1484. t->typmod = -1;
  1485. $$ = (Node *)n;
  1486. }
  1487. | CURRENT_TIMESTAMP '(' Iconst ')'
  1488. {
  1489. FuncCall *n = makeNode(FuncCall);
  1490. A_Const *s = makeNode(A_Const);
  1491. TypeName *t = makeNode(TypeName);
  1492. n->funcname = xlateSqlType("timestamp");
  1493. n->args = lcons(s, NIL);
  1494. s->val.type = T_String;
  1495. s->val.val.str = "now";
  1496. s->typename = t;
  1497. t->name = xlateSqlType("timestamp");
  1498. t->setof = FALSE;
  1499. t->typmod = -1;
  1500. if ($3 != 0)
  1501. elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
  1502. $$ = (Node *)n;
  1503. }
  1504. | CURRENT_USER
  1505. {
  1506. FuncCall *n = makeNode(FuncCall);
  1507. n->funcname = "getpgusername";
  1508. n->args = NIL;
  1509. $$ = (Node *)n;
  1510. }
  1511. | USER
  1512. {
  1513. FuncCall *n = makeNode(FuncCall);
  1514. n->funcname = "getpgusername";
  1515. n->args = NIL;
  1516. $$ = (Node *)n;
  1517. }
  1518. | POSITION '(' position_list ')'
  1519. {
  1520. FuncCall *n = makeNode(FuncCall);
  1521. n->funcname = "strpos";
  1522. n->args = $3;
  1523. $$ = (Node *)n;
  1524. }
  1525. | SUBSTRING '(' substr_list ')'
  1526. {
  1527. FuncCall *n = makeNode(FuncCall);
  1528. n->funcname = "substr";
  1529. n->args = $3;
  1530. $$ = (Node *)n;
  1531. }
  1532. /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
  1533. | TRIM '(' BOTH trim_list ')'
  1534. {
  1535. FuncCall *n = makeNode(FuncCall);
  1536. n->funcname = "btrim";
  1537. n->args = $4;
  1538. $$ = (Node *)n;
  1539. }
  1540. | TRIM '(' LEADING trim_list ')'
  1541. {
  1542. FuncCall *n = makeNode(FuncCall);
  1543. n->funcname = "ltrim";
  1544. n->args = $4;
  1545. $$ = (Node *)n;
  1546. }
  1547. | TRIM '(' TRAILING trim_list ')'
  1548. {
  1549. FuncCall *n = makeNode(FuncCall);
  1550. n->funcname = "rtrim";
  1551. n->args = $4;
  1552. $$ = (Node *)n;
  1553. }
  1554. | TRIM '(' trim_list ')'
  1555. {
  1556. FuncCall *n = makeNode(FuncCall);
  1557. n->funcname = "btrim";
  1558. n->args = $3;
  1559. $$ = (Node *)n;
  1560. }
  1561. ;
  1562. opt_indirection:  '[' a_expr ']' opt_indirection
  1563. {
  1564. A_Indices *ai = makeNode(A_Indices);
  1565. ai->lidx = NULL;
  1566. ai->uidx = $2;
  1567. $$ = lcons(ai, $4);
  1568. }
  1569. | '[' a_expr ':' a_expr ']' opt_indirection
  1570. {
  1571. A_Indices *ai = makeNode(A_Indices);
  1572. ai->lidx = $2;
  1573. ai->uidx = $4;
  1574. $$ = lcons(ai, $6);
  1575. }
  1576. | /*EMPTY*/
  1577. { $$ = NIL; }
  1578. ;
  1579. expr_list:  a_expr_or_null
  1580. { $$ = lcons($1, NIL); }
  1581. | expr_list ',' a_expr_or_null
  1582. { $$ = lappend($1, $3); }
  1583. | expr_list USING a_expr
  1584. { $$ = lappend($1, $3); }
  1585. ;
  1586. extract_list:  extract_arg FROM a_expr
  1587. {
  1588. A_Const *n = makeNode(A_Const);
  1589. n->val.type = T_String;
  1590. n->val.val.str = $1;
  1591. $$ = lappend(lcons((Node *)n,NIL), $3);
  1592. }
  1593. | /*EMPTY*/
  1594. { $$ = NIL; }
  1595. ;
  1596. extract_arg:  datetime { $$ = $1; }
  1597. | TIMEZONE_HOUR { $$ = "tz_hour"; }
  1598. | TIMEZONE_MINUTE { $$ = "tz_minute"; }
  1599. ;
  1600. position_list:  position_expr IN position_expr
  1601. { $$ = makeList($3, $1, -1); }
  1602. | /*EMPTY*/
  1603. { $$ = NIL; }
  1604. ;
  1605. position_expr:  attr opt_indirection
  1606. {
  1607. $1->indirection = $2;
  1608. $$ = (Node *)$1;
  1609. }
  1610. | AexprConst
  1611. { $$ = $1;  }
  1612. | '-' position_expr %prec UMINUS
  1613. { $$ = makeA_Expr(OP, "-", NULL, $2); }
  1614. | position_expr '+' position_expr
  1615. { $$ = makeA_Expr(OP, "+", $1, $3); }
  1616. | position_expr '-' position_expr
  1617. { $$ = makeA_Expr(OP, "-", $1, $3); }
  1618. | position_expr '/' position_expr
  1619. { $$ = makeA_Expr(OP, "/", $1, $3); }
  1620. | position_expr '%' position_expr
  1621. { $$ = makeA_Expr(OP, "%", $1, $3); }
  1622. | position_expr '*' position_expr
  1623. { $$ = makeA_Expr(OP, "*", $1, $3); }
  1624. | '|' position_expr
  1625. { $$ = makeA_Expr(OP, "|", NULL, $2); }
  1626. | position_expr TYPECAST Typename
  1627. {
  1628. $$ = (Node *)$1;
  1629. /* AexprConst can be either A_Const or ParamNo */
  1630. if (nodeTag($1) == T_A_Const) {
  1631. ((A_Const *)$1)->typename = $3;
  1632. } else if (nodeTag($1) == T_Param) {
  1633. ((ParamNo *)$1)->typename = $3;
  1634. /* otherwise, try to transform to a function call */
  1635. } else {
  1636. FuncCall *n = makeNode(FuncCall);
  1637. n->funcname = $3->name;
  1638. n->args = lcons($1,NIL);
  1639. $$ = (Node *)n;
  1640. }
  1641. }
  1642. | CAST '(' position_expr AS Typename ')'
  1643. {
  1644. $$ = (Node *)$3;
  1645. /* AexprConst can be either A_Const or ParamNo */
  1646. if (nodeTag($3) == T_A_Const) {
  1647. ((A_Const *)$3)->typename = $5;
  1648. } else if (nodeTag($3) == T_Param) {
  1649. ((ParamNo *)$3)->typename = $5;
  1650. /* otherwise, try to transform to a function call */
  1651. } else {
  1652. FuncCall *n = makeNode(FuncCall);
  1653. n->funcname = $5->name;
  1654. n->args = lcons($3,NIL);
  1655. $$ = (Node *)n;
  1656. }
  1657. }
  1658. | '(' position_expr ')'
  1659. { $$ = $2; }
  1660. | position_expr Op position_expr
  1661. { $$ = makeA_Expr(OP, $2, $1, $3); }
  1662. | Op position_expr
  1663. { $$ = makeA_Expr(OP, $1, NULL, $2); }
  1664. | position_expr Op
  1665. { $$ = makeA_Expr(OP, $2, $1, NULL); }
  1666. | ColId
  1667. {
  1668. /* could be a column name or a relation_name */
  1669. Ident *n = makeNode(Ident);
  1670. n->name = $1;
  1671. n->indirection = NULL;
  1672. $$ = (Node *)n;
  1673. }
  1674. | func_name '(' ')'
  1675. {
  1676. FuncCall *n = makeNode(FuncCall);
  1677. n->funcname = $1;
  1678. n->args = NIL;
  1679. $$ = (Node *)n;
  1680. }
  1681. | func_name '(' expr_list ')'
  1682. {
  1683. FuncCall *n = makeNode(FuncCall);
  1684. n->funcname = $1;
  1685. n->args = $3;
  1686. $$ = (Node *)n;
  1687. }
  1688. | POSITION '(' position_list ')'
  1689. {
  1690. FuncCall *n = makeNode(FuncCall);
  1691. n->funcname = "strpos";
  1692. n->args = $3;
  1693. $$ = (Node *)n;
  1694. }
  1695. | SUBSTRING '(' substr_list ')'
  1696. {
  1697. FuncCall *n = makeNode(FuncCall);
  1698. n->funcname = "substr";
  1699. n->args = $3;
  1700. $$ = (Node *)n;
  1701. }
  1702. /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
  1703. | TRIM '(' BOTH trim_list ')'
  1704. {
  1705. FuncCall *n = makeNode(FuncCall);
  1706. n->funcname = "btrim";
  1707. n->args = $4;
  1708. $$ = (Node *)n;
  1709. }
  1710. | TRIM '(' LEADING trim_list ')'
  1711. {
  1712. FuncCall *n = makeNode(FuncCall);
  1713. n->funcname = "ltrim";
  1714. n->args = $4;
  1715. $$ = (Node *)n;
  1716. }
  1717. | TRIM '(' TRAILING trim_list ')'
  1718. {
  1719. FuncCall *n = makeNode(FuncCall);
  1720. n->funcname = "rtrim";
  1721. n->args = $4;
  1722. $$ = (Node *)n;
  1723. }
  1724. | TRIM '(' trim_list ')'
  1725. {
  1726. FuncCall *n = makeNode(FuncCall);
  1727. n->funcname = "btrim";
  1728. n->args = $3;
  1729. $$ = (Node *)n;
  1730. }
  1731. ;
  1732. substr_list:  expr_list substr_from substr_for
  1733. {
  1734. $$ = nconc(nconc($1,$2),$3);
  1735. }
  1736. | /*EMPTY*/
  1737. { $$ = NIL; }
  1738. ;
  1739. substr_from:  FROM expr_list
  1740. { $$ = $2; }
  1741. | /*EMPTY*/
  1742. {
  1743. A_Const *n = makeNode(A_Const);
  1744. n->val.type = T_Integer;
  1745. n->val.val.ival = 1;
  1746. $$ = lcons((Node *)n,NIL);
  1747. }
  1748. ;
  1749. substr_for:  FOR expr_list
  1750. { $$ = $2; }
  1751. | /*EMPTY*/
  1752. { $$ = NIL; }
  1753. ;
  1754. trim_list:  a_expr FROM expr_list
  1755. { $$ = lappend($3, $1); }
  1756. | FROM expr_list
  1757. { $$ = $2; }
  1758. | expr_list
  1759. { $$ = $1; }
  1760. ;
  1761. in_expr:  SubSelect
  1762. {
  1763. SubLink *n = makeNode(SubLink);
  1764. n->subselect = $1;
  1765. $$ = (Node *)n;
  1766. }
  1767. | in_expr_nodes
  1768. { $$ = $1; }
  1769. ;
  1770. in_expr_nodes:  AexprConst
  1771. { $$ = makeA_Expr(OP, "=", lfirst(saved_In_Expr), $1); }
  1772. | in_expr_nodes ',' AexprConst
  1773. { $$ = makeA_Expr(OR, NULL, $1,
  1774. makeA_Expr(OP, "=", lfirst(saved_In_Expr), $3));
  1775. }
  1776. ;
  1777. not_in_expr:  SubSelect
  1778. {
  1779. SubLink *n = makeNode(SubLink);
  1780. n->subselect = $1;
  1781. $$ = (Node *)n;
  1782. }
  1783. | not_in_expr_nodes
  1784. { $$ = $1; }
  1785. ;
  1786. not_in_expr_nodes:  AexprConst
  1787. { $$ = makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $1); }
  1788. | not_in_expr_nodes ',' AexprConst
  1789. { $$ = makeA_Expr(AND, NULL, $1,
  1790. makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $3));
  1791. }
  1792. ;
  1793. /* Case clause
  1794.  * Define SQL92-style case clause.
  1795.  * Allow all four forms described in the standard:
  1796.  * - Full specification
  1797.  *  CASE WHEN a = b THEN c ... ELSE d END
  1798.  * - Implicit argument
  1799.  *  CASE a WHEN b THEN c ... ELSE d END
  1800.  * - Conditional NULL
  1801.  *  NULLIF(x,y)
  1802.  *  same as CASE WHEN x = y THEN NULL ELSE x END
  1803.  * - Conditional substitution from list, use first non-null argument
  1804.  *  COALESCE(a,b,...)
  1805.  * same as CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ... END
  1806.  * - thomas 1998-11-09
  1807.  */
  1808. case_expr:  CASE case_arg when_clause_list case_default END_TRANS
  1809. {
  1810. CaseExpr *c = makeNode(CaseExpr);
  1811. c->arg = $2;
  1812. c->args = $3;
  1813. c->defresult = $4;
  1814. $$ = (Node *)c;
  1815. }
  1816. | NULLIF '(' a_expr ',' a_expr ')'
  1817. {
  1818. CaseExpr *c = makeNode(CaseExpr);
  1819. CaseWhen *w = makeNode(CaseWhen);
  1820. /*
  1821. A_Const *n = makeNode(A_Const);
  1822. n->val.type = T_Null;
  1823. w->result = (Node *)n;
  1824. */
  1825. w->expr = makeA_Expr(OP, "=", $3, $5);
  1826. c->args = lcons(w, NIL);
  1827. c->defresult = $3;
  1828. $$ = (Node *)c;
  1829. }
  1830. | COALESCE '(' expr_list ')'
  1831. {
  1832. CaseExpr *c = makeNode(CaseExpr);
  1833. CaseWhen *w;
  1834. List *l;
  1835. foreach (l,$3)
  1836. {
  1837. w = makeNode(CaseWhen);
  1838. w->expr = makeA_Expr(NOTNULL, NULL, lfirst(l), NULL);
  1839. w->result = lfirst(l);
  1840. c->args = lappend(c->args, w);
  1841. }
  1842. $$ = (Node *)c;
  1843. }
  1844. ;
  1845. when_clause_list:  when_clause_list when_clause
  1846. { $$ = lappend($1, $2); }
  1847. | when_clause
  1848. { $$ = lcons($1, NIL); }
  1849. ;
  1850. when_clause:  WHEN a_expr THEN a_expr_or_null
  1851. {
  1852. CaseWhen *w = makeNode(CaseWhen);
  1853. w->expr = $2;
  1854. w->result = $4;
  1855. $$ = (Node *)w;
  1856. }
  1857. ;
  1858. case_default:  ELSE a_expr_or_null { $$ = $2; }
  1859. | /*EMPTY*/ { $$ = NULL; }
  1860. ;
  1861. case_arg:  attr opt_indirection
  1862. {
  1863. $1->indirection = $2;
  1864. $$ = (Node *)$1;
  1865. }
  1866. | ColId
  1867. {
  1868. /* could be a column name or a relation_name */
  1869. Ident *n = makeNode(Ident);
  1870. n->name = $1;
  1871. n->indirection = NULL;
  1872. $$ = (Node *)n;
  1873. }
  1874. | /*EMPTY*/
  1875. { $$ = NULL; }
  1876. ;
  1877. attr:  relation_name '.' attrs
  1878. {
  1879. $$ = makeNode(Attr);
  1880. $$->relname = $1;
  1881. $$->paramNo = NULL;
  1882. $$->attrs = $3;
  1883. $$->indirection = NULL;
  1884. }
  1885. | ParamNo '.' attrs
  1886. {
  1887. $$ = makeNode(Attr);
  1888. $$->relname = NULL;
  1889. $$->paramNo = $1;
  1890. $$->attrs = $3;
  1891. $$->indirection = NULL;
  1892. }
  1893. ;
  1894. attrs:   attr_name
  1895. { $$ = lcons(makeString($1), NIL); }
  1896. | attrs '.' attr_name
  1897. { $$ = lappend($1, makeString($3)); }
  1898. | attrs '.' '*'
  1899. { $$ = lappend($1, makeString("*")); }
  1900. ;
  1901. /*****************************************************************************
  1902.  *
  1903.  * target lists
  1904.  *
  1905.  *****************************************************************************/
  1906. res_target_list:  res_target_list ',' res_target_el
  1907. { $$ = lappend($1,$3);  }
  1908. | res_target_el
  1909. { $$ = lcons($1, NIL);  }
  1910. | '*'
  1911. {
  1912. ResTarget *rt = makeNode(ResTarget);
  1913. Attr *att = makeNode(Attr);
  1914. att->relname = "*";
  1915. att->paramNo = NULL;
  1916. att->attrs = NULL;
  1917. att->indirection = NIL;
  1918. rt->name = NULL;
  1919. rt->indirection = NULL;
  1920. rt->val = (Node *)att;
  1921. $$ = lcons(rt, NIL);
  1922. }
  1923. ;
  1924. res_target_el:  ColId opt_indirection '=' a_expr_or_null
  1925. {
  1926. $$ = makeNode(ResTarget);
  1927. $$->name = $1;
  1928. $$->indirection = $2;
  1929. $$->val = (Node *)$4;
  1930. }
  1931. | attr opt_indirection
  1932. {
  1933. $$ = makeNode(ResTarget);
  1934. $$->name = NULL;
  1935. $$->indirection = $2;
  1936. $$->val = (Node *)$1;
  1937. }
  1938. | relation_name '.' '*'
  1939. {
  1940. Attr *att = makeNode(Attr);
  1941. att->relname = $1;
  1942. att->paramNo = NULL;
  1943. att->attrs = lcons(makeString("*"), NIL);
  1944. att->indirection = NIL;
  1945. $$ = makeNode(ResTarget);
  1946. $$->name = NULL;
  1947. $$->indirection = NULL;
  1948. $$->val = (Node *)att;
  1949. }
  1950. ;
  1951. /*
  1952. ** target list for select.
  1953. ** should get rid of the other but is still needed by the defunct select into
  1954. ** and update (uses a subset)
  1955. */
  1956. res_target_list2:  res_target_list2 ',' res_target_el2
  1957. { $$ = lappend($1, $3);  }
  1958. | res_target_el2
  1959. { $$ = lcons($1, NIL);  }
  1960. ;
  1961. /* AS is not optional because shift/red conflict with unary ops */
  1962. res_target_el2:  a_expr_or_null AS ColLabel
  1963. {
  1964. $$ = makeNode(ResTarget);
  1965. $$->name = $3;
  1966. $$->indirection = NULL;
  1967. $$->val = (Node *)$1;
  1968. }
  1969. | a_expr_or_null
  1970. {
  1971. $$ = makeNode(ResTarget);
  1972. $$->name = NULL;
  1973. $$->indirection = NULL;
  1974. $$->val = (Node *)$1;
  1975. }
  1976. | relation_name '.' '*'
  1977. {
  1978. Attr *att = makeNode(Attr);
  1979. att->relname = $1;
  1980. att->paramNo = NULL;
  1981. att->attrs = lcons(makeString("*"), NIL);
  1982. att->indirection = NIL;
  1983. $$ = makeNode(ResTarget);
  1984. $$->name = NULL;
  1985. $$->indirection = NULL;
  1986. $$->val = (Node *)att;
  1987. }
  1988. | '*'
  1989. {
  1990. Attr *att = makeNode(Attr);
  1991. att->relname = "*";
  1992. att->paramNo = NULL;
  1993. att->attrs = NULL;
  1994. att->indirection = NIL;
  1995. $$ = makeNode(ResTarget);
  1996. $$->name = NULL;
  1997. $$->indirection = NULL;
  1998. $$->val = (Node *)att;
  1999. }
  2000. ;
  2001. opt_id:  ColId { $$ = $1; }
  2002. | /*EMPTY*/ { $$ = NULL; }
  2003. ;
  2004. relation_name: SpecialRuleRelation
  2005. {
  2006. $$ = $1;
  2007. StrNCpy(saved_relname, $1, NAMEDATALEN);
  2008. }
  2009. | ColId
  2010. {
  2011. /* disallow refs to variable system tables */
  2012. if (strcmp(LogRelationName, $1) == 0
  2013.    || strcmp(VariableRelationName, $1) == 0)
  2014. elog(ERROR,"%s cannot be accessed by users",$1);
  2015. else
  2016. $$ = $1;
  2017. StrNCpy(saved_relname, $1, NAMEDATALEN);
  2018. }
  2019. ;
  2020. database_name: ColId { $$ = $1; };
  2021. access_method: IDENT { $$ = $1; };
  2022. attr_name: ColId { $$ = $1; };
  2023. class: IDENT { $$ = $1; };
  2024. index_name: ColId { $$ = $1; };
  2025. /* Functions
  2026.  * Include date/time keywords as SQL92 extension.
  2027.  * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
  2028.  */
  2029. name: ColId { $$ = $1; };
  2030. func_name: ColId { $$ = xlateSqlFunc($1); };
  2031. file_name: Sconst { $$ = $1; };
  2032. /* NOT USED recipe_name: IDENT { $$ = $1; };*/
  2033. /* Constants
  2034.  * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
  2035.  */
  2036. AexprConst:  Iconst
  2037. {
  2038. A_Const *n = makeNode(A_Const);
  2039. n->val.type = T_Integer;
  2040. n->val.val.ival = $1;
  2041. $$ = (Node *)n;
  2042. }
  2043. | FCONST
  2044. {
  2045. A_Const *n = makeNode(A_Const);
  2046. n->val.type = T_Float;
  2047. n->val.val.dval = $1;
  2048. $$ = (Node *)n;
  2049. }
  2050. | Sconst
  2051. {
  2052. A_Const *n = makeNode(A_Const);
  2053. n->val.type = T_String;
  2054. n->val.val.str = $1;
  2055. $$ = (Node *)n;
  2056. }
  2057. | Typename Sconst
  2058. {
  2059. A_Const *n = makeNode(A_Const);
  2060. n->typename = $1;
  2061. n->val.type = T_String;
  2062. n->val.val.str = $2;
  2063. $$ = (Node *)n;
  2064. }
  2065. | ParamNo
  2066. { $$ = (Node *)$1;  }
  2067. | TRUE_P
  2068. {
  2069. A_Const *n = makeNode(A_Const);
  2070. n->val.type = T_String;
  2071. n->val.val.str = "t";
  2072. n->typename = makeNode(TypeName);
  2073. n->typename->name = xlateSqlType("bool");
  2074. n->typename->typmod = -1;
  2075. $$ = (Node *)n;
  2076. }
  2077. | FALSE_P
  2078. {
  2079. A_Const *n = makeNode(A_Const);
  2080. n->val.type = T_String;
  2081. n->val.val.str = "f";
  2082. n->typename = makeNode(TypeName);
  2083. n->typename->name = xlateSqlType("bool");
  2084. n->typename->typmod = -1;
  2085. $$ = (Node *)n;
  2086. }
  2087. ;
  2088. ParamNo:  PARAM opt_indirection
  2089. {
  2090. $$ = makeNode(ParamNo);
  2091. $$->number = $1;
  2092. $$->indirection = $2;
  2093. }
  2094. ;
  2095. Iconst:  ICONST { $$ = $1; };
  2096. Sconst:  SCONST { $$ = $1; };
  2097. UserId:  IDENT { $$ = $1; };
  2098. /* Column and type identifier
  2099.  * Does not include explicit datetime types
  2100.  *  since these must be decoupled in Typename syntax.
  2101.  * Use ColId for most identifiers. - thomas 1997-10-21
  2102.  */
  2103. TypeId:  ColId
  2104. { $$ = xlateSqlType($1); }
  2105. | numeric
  2106. { $$ = xlateSqlType($1); }
  2107. | character
  2108. { $$ = xlateSqlType($1); }
  2109. ;
  2110. /* Column identifier
  2111.  * Include date/time keywords as SQL92 extension.
  2112.  * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
  2113.  * Add other keywords. Note that as the syntax expands,
  2114.  *  some of these keywords will have to be removed from this
  2115.  *  list due to shift/reduce conflicts in yacc. If so, move
  2116.  *  down to the ColLabel entity. - thomas 1997-11-06
  2117.  */
  2118. ColId:  IDENT { $$ = $1; }
  2119. | datetime { $$ = $1; }
  2120. | ABSOLUTE { $$ = "absolute"; }
  2121. | ACCESS { $$ = "access"; }
  2122. | ACTION { $$ = "action"; }
  2123. | AFTER { $$ = "after"; }
  2124. | AGGREGATE { $$ = "aggregate"; }
  2125. | BACKWARD { $$ = "backward"; }
  2126. | BEFORE { $$ = "before"; }
  2127. | CACHE { $$ = "cache"; }
  2128. | COMMITTED { $$ = "committed"; }
  2129. | CREATEDB { $$ = "createdb"; }
  2130. | CREATEUSER { $$ = "createuser"; }
  2131. | CYCLE { $$ = "cycle"; }
  2132. | DATABASE { $$ = "database"; }
  2133. | DELIMITERS { $$ = "delimiters"; }
  2134. | DOUBLE { $$ = "double"; }
  2135. | EACH { $$ = "each"; }
  2136. | ENCODING { $$ = "encoding"; }
  2137. | EXCLUSIVE { $$ = "exclusive"; }
  2138. | FORWARD { $$ = "forward"; }
  2139. | FUNCTION { $$ = "function"; }
  2140. | HANDLER { $$ = "handler"; }
  2141. | INCREMENT { $$ = "increment"; }
  2142. | INDEX { $$ = "index"; }
  2143. | INHERITS { $$ = "inherits"; }
  2144. | INSENSITIVE { $$ = "insensitive"; }
  2145. | INSTEAD { $$ = "instead"; }
  2146. | ISNULL { $$ = "isnull"; }
  2147. | ISOLATION { $$ = "isolation"; }
  2148. | KEY { $$ = "key"; }
  2149. | LANGUAGE { $$ = "language"; }
  2150. | LANCOMPILER { $$ = "lancompiler"; }
  2151. | LEVEL { $$ = "level"; }
  2152. | LOCATION { $$ = "location"; }
  2153. | MATCH { $$ = "match"; }
  2154. | MAXVALUE { $$ = "maxvalue"; }
  2155. | MINVALUE { $$ = "minvalue"; }
  2156. | MODE { $$ = "mode"; }
  2157. | NEXT { $$ = "next"; }
  2158. | NOCREATEDB { $$ = "nocreatedb"; }
  2159. | NOCREATEUSER { $$ = "nocreateuser"; }
  2160. | NOTHING { $$ = "nothing"; }
  2161. | NOTNULL { $$ = "notnull"; }
  2162. | OF { $$ = "of"; }
  2163. | OIDS { $$ = "oids"; }
  2164. | ONLY { $$ = "only"; }
  2165. | OPERATOR { $$ = "operator"; }
  2166. | OPTION { $$ = "option"; }
  2167. | PASSWORD { $$ = "password"; }
  2168. | PRIOR { $$ = "prior"; }
  2169. | PRIVILEGES { $$ = "privileges"; }
  2170. | PROCEDURAL { $$ = "procedural"; }
  2171. | READ { $$ = "read"; }
  2172. | RELATIVE { $$ = "relative"; }
  2173. | RENAME { $$ = "rename"; }
  2174. | RETURNS { $$ = "returns"; }
  2175. | ROW { $$ = "row"; }
  2176. | RULE { $$ = "rule"; }
  2177. | SCROLL { $$ = "scroll"; }
  2178. | SEQUENCE { $$ = "sequence"; }
  2179. | SERIAL { $$ = "serial"; }
  2180. | SERIALIZABLE { $$ = "serializable"; }
  2181. | SHARE { $$ = "share"; }
  2182. | START { $$ = "start"; }
  2183. | STATEMENT { $$ = "statement"; }
  2184. | STDIN { $$ = "stdin"; }
  2185. | STDOUT { $$ = "stdout"; }
  2186. | TIME { $$ = "time"; }
  2187. | TIMESTAMP { $$ = "timestamp"; }
  2188. | TIMEZONE_HOUR { $$ = "timezone_hour"; }
  2189. | TIMEZONE_MINUTE { $$ = "timezone_minute"; }
  2190. | TRIGGER { $$ = "trigger"; }
  2191. | TRUSTED { $$ = "trusted"; }
  2192. | TYPE_P { $$ = "type"; }
  2193. | VALID { $$ = "valid"; }
  2194. | VERSION { $$ = "version"; }
  2195. | ZONE { $$ = "zone"; }
  2196. ;
  2197. /* Column label
  2198.  * Allowed labels in "AS" clauses.
  2199.  * Include TRUE/FALSE SQL3 reserved words for Postgres backward
  2200.  *  compatibility. Cannot allow this for column names since the
  2201.  *  syntax would not distinguish between the constant value and
  2202.  *  a column name. - thomas 1997-10-24
  2203.  * Add other keywords to this list. Note that they appear here
  2204.  *  rather than in ColId if there was a shift/reduce conflict
  2205.  *  when used as a full identifier. - thomas 1997-11-06
  2206.  */
  2207. ColLabel:  ColId { $$ = $1; }
  2208. | ABORT_TRANS { $$ = "abort"; }
  2209. | ANALYZE { $$ = "analyze"; }
  2210. | BINARY { $$ = "binary"; }
  2211. | CASE { $$ = "case"; }
  2212. | CLUSTER { $$ = "cluster"; }
  2213. | COALESCE { $$ = "coalesce"; }
  2214. | CONSTRAINT { $$ = "constraint"; }
  2215. | COPY { $$ = "copy"; }
  2216. | CURRENT { $$ = "current"; }
  2217. | DO { $$ = "do"; }
  2218. | ELSE { $$ = "else"; }
  2219. | END_TRANS { $$ = "end"; }
  2220. | EXPLAIN { $$ = "explain"; }
  2221. | EXTEND { $$ = "extend"; }
  2222. | FALSE_P { $$ = "false"; }
  2223. | FOREIGN { $$ = "foreign"; }
  2224. | GLOBAL { $$ = "global"; }
  2225. | GROUP { $$ = "group"; }
  2226. | LISTEN { $$ = "listen"; }
  2227. | LOAD { $$ = "load"; }
  2228. | LOCAL { $$ = "local"; }
  2229. | LOCK_P { $$ = "lock"; }
  2230. | MOVE { $$ = "move"; }
  2231. | NEW { $$ = "new"; }
  2232. | NONE { $$ = "none"; }
  2233. | NULLIF { $$ = "nullif"; }
  2234. | ORDER { $$ = "order"; }
  2235. | POSITION { $$ = "position"; }
  2236. | PRECISION { $$ = "precision"; }
  2237. | RESET { $$ = "reset"; }
  2238. | SETOF { $$ = "setof"; }
  2239. | SHOW { $$ = "show"; }
  2240. | TABLE { $$ = "table"; }
  2241. | THEN { $$ = "then"; }
  2242. | TRANSACTION { $$ = "transaction"; }
  2243. | TRUE_P { $$ = "true"; }
  2244. | VACUUM { $$ = "vacuum"; }
  2245. | VERBOSE { $$ = "verbose"; }
  2246. | WHEN { $$ = "when"; }
  2247. ;
  2248. SpecialRuleRelation:  CURRENT
  2249. {
  2250. if (QueryIsRule)
  2251. $$ = "*CURRENT*";
  2252. else
  2253. elog(ERROR,"CURRENT used in non-rule query");
  2254. }
  2255. | NEW
  2256. {
  2257. if (QueryIsRule)
  2258. $$ = "*NEW*";
  2259. else
  2260. elog(ERROR,"NEW used in non-rule query");
  2261. }
  2262. ;
  2263. %%
  2264. static Node *
  2265. makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
  2266. {
  2267. A_Expr *a = makeNode(A_Expr);
  2268. a->oper = oper;
  2269. a->opname = opname;
  2270. a->lexpr = lexpr;
  2271. a->rexpr = rexpr;
  2272. return (Node *)a;
  2273. }
  2274. /* makeRowExpr()
  2275.  * Generate separate operator nodes for a single row descriptor expression.
  2276.  * Perhaps this should go deeper in the parser someday...
  2277.  * - thomas 1997-12-22
  2278.  */
  2279. static Node *
  2280. makeRowExpr(char *opr, List *largs, List *rargs)
  2281. {
  2282. Node *expr = NULL;
  2283. Node *larg, *rarg;
  2284. if (length(largs) != length(rargs))
  2285. elog(ERROR,"Unequal number of entries in row expression");
  2286. if (lnext(largs) != NIL)
  2287. expr = makeRowExpr(opr,lnext(largs),lnext(rargs));
  2288. larg = lfirst(largs);
  2289. rarg = lfirst(rargs);
  2290. if ((strcmp(opr, "=") == 0)
  2291.  || (strcmp(opr, "<") == 0)
  2292.  || (strcmp(opr, "<=") == 0)
  2293.  || (strcmp(opr, ">") == 0)
  2294.  || (strcmp(opr, ">=") == 0))
  2295. {
  2296. if (expr == NULL)
  2297. expr = makeA_Expr(OP, opr, larg, rarg);
  2298. else
  2299. expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
  2300. }
  2301. else if (strcmp(opr, "<>") == 0)
  2302. {
  2303. if (expr == NULL)
  2304. expr = makeA_Expr(OP, opr, larg, rarg);
  2305. else
  2306. expr = makeA_Expr(OR, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
  2307. }
  2308. else
  2309. {
  2310. elog(ERROR,"Operator '%s' not implemented for row expressions",opr);
  2311. }
  2312. return expr;
  2313. }
  2314. static void
  2315. mapTargetColumns(List *src, List *dst)
  2316. {
  2317. ColumnDef *s;
  2318. ResTarget *d;
  2319. if (length(src) != length(dst))
  2320. elog(ERROR,"CREATE TABLE/AS SELECT has mismatched column count");
  2321. while ((src != NIL) && (dst != NIL))
  2322. {
  2323. s = (ColumnDef *)lfirst(src);
  2324. d = (ResTarget *)lfirst(dst);
  2325. d->name = s->colname;
  2326. src = lnext(src);
  2327. dst = lnext(dst);
  2328. }
  2329. return;
  2330. } /* mapTargetColumns() */
  2331. static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
  2332. {
  2333. Node *result = NULL;
  2334. /* we do this so indexes can be used */
  2335. if (strcmp(opname,"~") == 0 ||
  2336. strcmp(opname,"~*") == 0)
  2337. {
  2338. if (nodeTag(rexpr) == T_A_Const &&
  2339.    ((A_Const *)rexpr)->val.type == T_String &&
  2340.    ((A_Const *)rexpr)->val.val.str[0] == '^')
  2341. {
  2342. A_Const *n = (A_Const *)rexpr;
  2343. char *match_least = palloc(strlen(n->val.val.str)+2);
  2344. char *match_most = palloc(strlen(n->val.val.str)+2);
  2345. int pos, match_pos=0;
  2346. bool found_special = false;
  2347. /* Cannot optimize if unquoted | { } is present in pattern */
  2348. for (pos = 1; n->val.val.str[pos]; pos++)
  2349. {
  2350. if (n->val.val.str[pos] == '|' ||
  2351.     n->val.val.str[pos] == '{' ||
  2352.     n->val.val.str[pos] == '}')
  2353. {
  2354. found_special = true;
  2355. break;
  2356. }
  2357.       if (n->val.val.str[pos] == '\')
  2358. {
  2359. pos++;
  2360. if (n->val.val.str[pos] == '')
  2361. break;
  2362. }
  2363. }
  2364. if (!found_special)
  2365. {
  2366. /* note start at pos 1 to skip leading ^ */
  2367. for (pos = 1; n->val.val.str[pos]; pos++)
  2368. {
  2369. if (n->val.val.str[pos] == '.' ||
  2370. n->val.val.str[pos] == '?' ||
  2371. n->val.val.str[pos] == '*' ||
  2372. n->val.val.str[pos] == '[' ||
  2373. n->val.val.str[pos] == '$' ||
  2374. (strcmp(opname,"~*") == 0 && isalpha(n->val.val.str[pos])))
  2375.       break;
  2376.       if (n->val.val.str[pos] == '\')
  2377. {
  2378. pos++;
  2379. if (n->val.val.str[pos] == '')
  2380. break;
  2381. }
  2382. match_least[match_pos] = n->val.val.str[pos];
  2383. match_most[match_pos++] = n->val.val.str[pos];
  2384. }
  2385. if (match_pos != 0)
  2386. {
  2387. A_Const *least = makeNode(A_Const);
  2388. A_Const *most = makeNode(A_Const);
  2389. /* make strings to be used in index use */
  2390. match_least[match_pos] = '';
  2391. match_most[match_pos] = '377';
  2392. match_most[match_pos+1] = '';
  2393. least->val.type = T_String;
  2394. least->val.val.str = match_least;
  2395. most->val.type = T_String;
  2396. most->val.val.str = match_most;
  2397. #ifdef USE_LOCALE
  2398. result = makeA_Expr(AND, NULL,
  2399. makeA_Expr(OP, "~", lexpr, rexpr),
  2400. makeA_Expr(OP, ">=", lexpr, (Node *)least));
  2401. #else
  2402. result = makeA_Expr(AND, NULL,
  2403. makeA_Expr(OP, "~", lexpr, rexpr),
  2404. makeA_Expr(AND, NULL,
  2405. makeA_Expr(OP, ">=", lexpr, (Node *)least),
  2406. makeA_Expr(OP, "<=", lexpr, (Node *)most)));
  2407. #endif
  2408. }
  2409. }
  2410. }
  2411. }
  2412. else if (strcmp(opname,"~~") == 0)
  2413. {
  2414. if (nodeTag(rexpr) == T_A_Const &&
  2415.    ((A_Const *)rexpr)->val.type == T_String)
  2416. {
  2417. A_Const *n = (A_Const *)rexpr;
  2418. char *match_least = palloc(strlen(n->val.val.str)+2);
  2419. char *match_most = palloc(strlen(n->val.val.str)+2);
  2420. int pos, match_pos=0;
  2421. for (pos = 0; n->val.val.str[pos]; pos++)
  2422. {
  2423. /* % and _ are wildcard characters in LIKE */
  2424. if (n->val.val.str[pos] == '%' ||
  2425. n->val.val.str[pos] == '_')
  2426. break;
  2427. /* Backslash quotes the next character */
  2428. if (n->val.val.str[pos] == '\')
  2429. {
  2430. pos++;
  2431. if (n->val.val.str[pos] == '')
  2432. break;
  2433. }
  2434. /*
  2435.  * NOTE: this code used to think that %% meant a literal %,
  2436.  * but textlike() itself does not think that, and the SQL92
  2437.  * spec doesn't say any such thing either.
  2438.  */
  2439. match_least[match_pos] = n->val.val.str[pos];
  2440. match_most[match_pos++] = n->val.val.str[pos];
  2441. }
  2442. if (match_pos != 0)
  2443. {
  2444. A_Const *least = makeNode(A_Const);
  2445. A_Const *most = makeNode(A_Const);
  2446. /* make strings to be used in index use */
  2447. match_least[match_pos] = '';
  2448. match_most[match_pos] = '377';
  2449. match_most[match_pos+1] = '';
  2450. least->val.type = T_String;
  2451. least->val.val.str = match_least;
  2452. most->val.type = T_String;
  2453. most->val.val.str = match_most;
  2454. #ifdef USE_LOCALE
  2455. result = makeA_Expr(AND, NULL,
  2456. makeA_Expr(OP, "~~", lexpr, rexpr),
  2457. makeA_Expr(OP, ">=", lexpr, (Node *)least));
  2458. #else
  2459. result = makeA_Expr(AND, NULL,
  2460. makeA_Expr(OP, "~~", lexpr, rexpr),
  2461. makeA_Expr(AND, NULL,
  2462. makeA_Expr(OP, ">=", lexpr, (Node *)least),
  2463. makeA_Expr(OP, "<=", lexpr, (Node *)most)));
  2464. #endif
  2465. }
  2466. }
  2467. }
  2468. if (result == NULL)
  2469. result = makeA_Expr(OP, opname, lexpr, rexpr);
  2470. return result;
  2471. } /* makeIndexable() */
  2472. /* xlateSqlFunc()
  2473.  * Convert alternate type names to internal Postgres types.
  2474.  * Do not convert "float", since that is handled elsewhere
  2475.  *  for FLOAT(p) syntax.
  2476.  */
  2477. static char *
  2478. xlateSqlFunc(char *name)
  2479. {
  2480. if (!strcasecmp(name,"character_length")
  2481.  || !strcasecmp(name,"char_length"))
  2482. return "length";
  2483. else
  2484. return name;
  2485. } /* xlateSqlFunc() */
  2486. /* xlateSqlType()
  2487.  * Convert alternate type names to internal Postgres types.
  2488.  */
  2489. static char *
  2490. xlateSqlType(char *name)
  2491. {
  2492. if (!strcasecmp(name,"int")
  2493.  || !strcasecmp(name,"integer"))
  2494. return "int4";
  2495. else if (!strcasecmp(name, "smallint"))
  2496. return "int2";
  2497. else if (!strcasecmp(name, "real")
  2498.  || !strcasecmp(name, "float"))
  2499. return "float8";
  2500. else if (!strcasecmp(name, "interval"))
  2501. return "timespan";
  2502. else if (!strcasecmp(name, "boolean"))
  2503. return "bool";
  2504. else
  2505. return name;
  2506. } /* xlateSqlType() */
  2507. void parser_init(Oid *typev, int nargs)
  2508. {
  2509. QueryIsRule = FALSE;
  2510. saved_relname[0]= '';
  2511. saved_In_Expr = NULL;
  2512. param_type_init(typev, nargs);
  2513. }
  2514. /* FlattenStringList()
  2515.  * Traverse list of string nodes and convert to a single string.
  2516.  * Used for reconstructing string form of complex expressions.
  2517.  *
  2518.  * Allocate at least one byte for terminator.
  2519.  */
  2520. static char *
  2521. FlattenStringList(List *list)
  2522. {
  2523. List *l;
  2524. Value *v;
  2525. char *s;
  2526. char *sp;
  2527. int nlist, len = 0;
  2528. nlist = length(list);
  2529. l = list;
  2530. while(l != NIL) {
  2531. v = (Value *)lfirst(l);
  2532. sp = v->val.str;
  2533. l = lnext(l);
  2534. len += strlen(sp);
  2535. };
  2536. len += nlist;
  2537. s = (char*) palloc(len+1);
  2538. *s = '';
  2539. l = list;
  2540. while(l != NIL) {
  2541. v = (Value *)lfirst(l);
  2542. sp = v->val.str;
  2543. l = lnext(l);
  2544. strcat(s,sp);
  2545. if (l != NIL) strcat(s," ");
  2546. };
  2547. *(s+len) = '';
  2548. return s;
  2549. } /* FlattenStringList() */
  2550. /* makeConstantList()
  2551.  * Convert constant value node into string node.
  2552.  */
  2553. static List *
  2554. makeConstantList( A_Const *n)
  2555. {
  2556. List *result = NIL;
  2557. char *typval = NULL;
  2558. char *defval = NULL;
  2559. if (nodeTag(n) != T_A_Const) {
  2560. elog(ERROR,"Cannot handle non-constant parameter");
  2561. } else if (n->val.type == T_Float) {
  2562. defval = (char*) palloc(20+1);
  2563. sprintf( defval, "%g", n->val.val.dval);
  2564. result = lcons( makeString(defval), NIL);
  2565. } else if (n->val.type == T_Integer) {
  2566. defval = (char*) palloc(20+1);
  2567. sprintf( defval, "%ld", n->val.val.ival);
  2568. result = lcons( makeString(defval), NIL);
  2569. } else if (n->val.type == T_String) {
  2570. defval = (char*) palloc(strlen( ((A_Const *) n)->val.val.str) + 3);
  2571. strcpy( defval, "'");
  2572. strcat( defval, ((A_Const *) n)->val.val.str);
  2573. strcat( defval, "'");
  2574. if (n->typename != NULL)
  2575. {
  2576. typval = (char*) palloc(strlen( n->typename->name) + 1);
  2577. strcpy(typval, n->typename->name);
  2578. result = lappend( lcons( makeString(typval), NIL), makeString(defval));
  2579. }
  2580. else
  2581. {
  2582. result = lcons( makeString(defval), NIL);
  2583. }
  2584. } else {
  2585. elog(ERROR,"Internal error in makeConstantList(): cannot encode node");
  2586. };
  2587. return result;
  2588. } /* makeConstantList() */
  2589. /* fmtId()
  2590.  * Check input string for non-lowercase/non-numeric characters.
  2591.  * Returns either input string or input surrounded by double quotes.
  2592.  */
  2593. static char *
  2594. fmtId(char *rawid)
  2595. {
  2596. static char *cp;
  2597. for (cp = rawid; *cp != ''; cp++)
  2598. if (! (islower(*cp) || isdigit(*cp) || (*cp == '_'))) break;
  2599. if (*cp != '') {
  2600. cp = palloc(strlen(rawid)+3);
  2601. strcpy(cp,""");
  2602. strcat(cp,rawid);
  2603. strcat(cp,""");
  2604. } else {
  2605. cp = rawid;
  2606. };
  2607. return cp;
  2608. }
  2609. /*
  2610.  * param_type_init()
  2611.  *
  2612.  * keep enough information around fill out the type of param nodes
  2613.  * used in postquel functions
  2614.  */
  2615. static void
  2616. param_type_init(Oid *typev, int nargs)
  2617. {
  2618. pfunc_num_args = nargs;
  2619. param_type_info = typev;
  2620. }
  2621. Oid param_type(int t)
  2622. {
  2623. if ((t > pfunc_num_args) || (t == 0))
  2624. return InvalidOid;
  2625. return param_type_info[t - 1];
  2626. }
  2627. /*
  2628.  * The optimizer doesn't like '-' 4 for index use.  It only checks for
  2629.  * Var '=' Const.  It wants an integer of -4, so we try to merge the
  2630.  * minus into the constant.
  2631.  */
  2632. static Node *doNegate(Node *n)
  2633. {
  2634. if (IsA(n, A_Const))
  2635. {
  2636. A_Const *con = (A_Const *)n;
  2637. if (con->val.type == T_Integer)
  2638. {
  2639. con->val.val.ival = -con->val.val.ival;
  2640. return n;
  2641. }
  2642. if (con->val.type == T_Float)
  2643. {
  2644. con->val.val.dval = -con->val.val.dval;
  2645. return n;
  2646. }
  2647. }
  2648. return makeA_Expr(OP, "-", NULL, n);
  2649. }