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

数据库系统

开发平台:

Unix_Linux

  1.  */
  2. join_clause_with_union:  join_clause
  3.                                 {       $$ = $1; }
  4.                 | table_expr UNION JOIN table_expr
  5.                                 {       yyerror("UNION JOIN not yet implemented"); }
  6.                 ;
  7. join_clause:  table_expr join_list
  8.                                 {
  9. $$ = cat2_str($1, $2);
  10.                                 }
  11.                 ;
  12. join_list:  join_list join_expr
  13.                                 {
  14.                                         $$ = cat2_str($1, $2);
  15.                                 }
  16.                 | join_expr
  17.                                 {
  18.                                         $$ = $1;
  19.                                 }
  20.                 ;
  21. /* This is everything but the left side of a join.
  22.  * Note that a CROSS JOIN is the same as an unqualified
  23.  * inner join, so just pass back the right-side table.
  24.  * A NATURAL JOIN implicitly matches column names between
  25.  * tables, so we'll collect those during the later transformation.
  26.  */
  27. join_expr:  join_type JOIN table_expr join_qual
  28.                                 {
  29. $$ = cat4_str($1, make1_str("join"), $3, $4);
  30.                                 }
  31.                 | NATURAL join_type JOIN table_expr
  32.                                 {
  33. $$ = cat4_str(make1_str("natural"), $2, make1_str("join"), $4);
  34.                                 }
  35.                 | CROSS JOIN table_expr
  36.                                 {  $$ = cat2_str(make1_str("cross join"), $3); }
  37.                 ;
  38. /* OUTER is just noise... */
  39. join_type:  FULL join_outer
  40.                                 {
  41.                                         $$ = cat2_str(make1_str("full"), $2);
  42.                                         fprintf(stderr,"FULL OUTER JOIN not yet implementedn");
  43.                                 }
  44.                 | LEFT join_outer
  45.                                 {
  46.                                         $$ = cat2_str(make1_str("left"), $2);
  47.                                         fprintf(stderr,"LEFT OUTER JOIN not yet implementedn");
  48.                                 }
  49.                 | RIGHT join_outer
  50.                                 {
  51.                                         $$ = cat2_str(make1_str("right"), $2);
  52.                                         fprintf(stderr,"RIGHT OUTER JOIN not yet implementedn");
  53.                                 }
  54.                 | OUTER_P
  55.                                 {
  56.                                         $$ = make1_str("outer");
  57.                                         fprintf(stderr,"OUTER JOIN not yet implementedn");
  58.                                 }
  59.                 | INNER_P
  60.                                 {
  61.                                         $$ = make1_str("inner");
  62. }
  63.                 | /* EMPTY */
  64.                                 {
  65.                                         $$ = make1_str("");
  66. }
  67. join_outer:  OUTER_P { $$ = make1_str("outer"); }
  68. | /*EMPTY*/ { $$ = make1_str("");  /* no qualifiers */ }
  69. ;
  70. /* JOIN qualification clauses
  71.  * Possibilities are:
  72.  *  USING ( column list ) allows only unqualified column names,
  73.  *                        which must match between tables.
  74.  *  ON expr allows more general qualifications.
  75.  * - thomas 1999-01-07
  76.  */
  77. join_qual:  USING '(' using_list ')'                   { $$ = make3_str(make1_str("using ("), $3, make1_str(")")); }
  78.                | ON a_expr        { $$ = cat2_str(make1_str("on"), $2); }
  79.                 ;
  80. using_list:  using_list ',' using_expr                  { $$ = make3_str($1, make1_str(","), $3); }
  81.                | using_expr { $$ = $1; }
  82.                ;
  83. using_expr:  ColId
  84. {
  85. $$ = $1;
  86. }
  87. ;
  88. where_clause:  WHERE a_expr { $$ = cat2_str(make1_str("where"), $2); }
  89. | /*EMPTY*/ { $$ = make1_str("");  /* no qualifiers */ }
  90. ;
  91. relation_expr: relation_name
  92. {
  93. /* normal relations */
  94. $$ = $1;
  95. }
  96. | relation_name '*'   %prec '='
  97. {
  98. /* inheritance query */
  99. $$ = cat2_str($1, make1_str("*"));
  100. }
  101. opt_array_bounds:  '[' ']' nest_array_bounds
  102. {
  103.                             $$.index1 = 0;
  104.                             $$.index2 = $3.index1;
  105.                             $$.str = cat2_str(make1_str("[]"), $3.str);
  106.                         }
  107. | '[' Iresult ']' nest_array_bounds
  108. {
  109.     char *txt = mm_alloc(20L);
  110.     sprintf (txt, "%d", $2);
  111.                             $$.index1 = $2;
  112.                             $$.index2 = $4.index1;
  113.                             $$.str = cat4_str(make1_str("["), txt, make1_str("]"), $4.str);
  114.                         }
  115. | /* EMPTY */
  116. {
  117.                             $$.index1 = -1;
  118.                             $$.index2 = -1;
  119.                             $$.str= make1_str("");
  120.                         }
  121. ;
  122. nest_array_bounds: '[' ']' nest_array_bounds
  123.                         {
  124.                             $$.index1 = 0;
  125.                             $$.index2 = $3.index1;
  126.                             $$.str = cat2_str(make1_str("[]"), $3.str);
  127.                         }
  128. | '[' Iresult ']' nest_array_bounds
  129. {
  130.     char *txt = mm_alloc(20L);
  131.     sprintf (txt, "%d", $2);
  132.                             $$.index1 = $2;
  133.                             $$.index2 = $4.index1;
  134.                             $$.str = cat4_str(make1_str("["), txt, make1_str("]"), $4.str);
  135.                         }
  136. | /* EMPTY */
  137. {
  138.                             $$.index1 = -1;
  139.                             $$.index2 = -1;
  140.                             $$.str= make1_str("");
  141.                         }
  142.                 ;
  143. Iresult: Iconst { $$ = atol($1); }
  144. | '(' Iresult ')' { $$ = $2; }
  145. | Iresult '+' Iresult { $$ = $1 + $3; }
  146. | Iresult '-' Iresult { $$ = $1 - $3; }
  147. | Iresult '*' Iresult { $$ = $1 * $3; }
  148. | Iresult '/' Iresult { $$ = $1 / $3; }
  149. | Iresult '%' Iresult { $$ = $1 % $3; }
  150. ;
  151. /*****************************************************************************
  152.  *
  153.  * Type syntax
  154.  * SQL92 introduces a large amount of type-specific syntax.
  155.  * Define individual clauses to handle these cases, and use
  156.  *  the generic case to handle regular type-extensible Postgres syntax.
  157.  * - thomas 1997-10-10
  158.  *
  159.  *****************************************************************************/
  160. Typename:  Array opt_array_bounds
  161. {
  162. $$ = cat2_str($1, $2.str);
  163. }
  164. | SETOF Array
  165. {
  166. $$ = cat2_str(make1_str("setof"), $2);
  167. }
  168. ;
  169. Array:  Generic { $$ = $1; }
  170. | Datetime { $$ = $1; }
  171. | Numeric { $$ = $1; }
  172. | Character { $$ = $1; }
  173. ;
  174. Generic:  generic
  175. {
  176. $$ = $1;
  177. }
  178. ;
  179. generic:  ident { $$ = $1; }
  180. | TYPE_P { $$ = make1_str("type"); }
  181. | SQL_AT { $$ = make1_str("at"); }
  182. | SQL_AUTOCOMMIT { $$ = make1_str("autocommit"); }
  183. | SQL_BOOL { $$ = make1_str("bool"); }
  184. | SQL_BREAK { $$ = make1_str("break"); }
  185. | SQL_CALL { $$ = make1_str("call"); }
  186. | SQL_CONNECT { $$ = make1_str("connect"); }
  187. | SQL_CONNECTION { $$ = make1_str("connection"); }
  188. | SQL_CONTINUE { $$ = make1_str("continue"); }
  189. | SQL_DEALLOCATE { $$ = make1_str("deallocate"); }
  190. | SQL_DISCONNECT { $$ = make1_str("disconnect"); }
  191. | SQL_FOUND { $$ = make1_str("found"); }
  192. | SQL_GO { $$ = make1_str("go"); }
  193. | SQL_GOTO { $$ = make1_str("goto"); }
  194. | SQL_IDENTIFIED { $$ = make1_str("identified"); }
  195. | SQL_IMMEDIATE { $$ = make1_str("immediate"); }
  196. | SQL_INDICATOR { $$ = make1_str("indicator"); }
  197. | SQL_INT { $$ = make1_str("int"); }
  198. | SQL_LONG { $$ = make1_str("long"); }
  199. | SQL_OFF { $$ = make1_str("off"); }
  200. | SQL_OPEN { $$ = make1_str("open"); }
  201. | SQL_PREPARE { $$ = make1_str("prepare"); }
  202. | SQL_RELEASE { $$ = make1_str("release"); }
  203. | SQL_SECTION { $$ = make1_str("section"); }
  204. | SQL_SHORT { $$ = make1_str("short"); }
  205. | SQL_SIGNED { $$ = make1_str("signed"); }
  206. | SQL_SQLERROR { $$ = make1_str("sqlerror"); }
  207. | SQL_SQLPRINT { $$ = make1_str("sqlprint"); }
  208. | SQL_SQLWARNING { $$ = make1_str("sqlwarning"); }
  209. | SQL_STOP { $$ = make1_str("stop"); }
  210. | SQL_STRUCT { $$ = make1_str("struct"); }
  211. | SQL_UNSIGNED { $$ = make1_str("unsigned"); }
  212. | SQL_VAR { $$ = make1_str("var"); }
  213. | SQL_WHENEVER { $$ = make1_str("whenever"); }
  214. ;
  215. /* SQL92 numeric data types
  216.  * Check FLOAT() precision limits assuming IEEE floating types.
  217.  * Provide real DECIMAL() and NUMERIC() implementations now - Jan 1998-12-30
  218.  * - thomas 1997-09-18
  219.  */
  220. Numeric:  FLOAT opt_float
  221. {
  222. $$ = cat2_str(make1_str("float"), $2);
  223. }
  224. | DOUBLE PRECISION
  225. {
  226. $$ = make1_str("double precision");
  227. }
  228. | DECIMAL opt_decimal
  229. {
  230. $$ = cat2_str(make1_str("decimal"), $2);
  231. }
  232. | NUMERIC opt_numeric
  233. {
  234. $$ = cat2_str(make1_str("numeric"), $2);
  235. }
  236. ;
  237. numeric:  FLOAT
  238. { $$ = make1_str("float"); }
  239. | DOUBLE PRECISION
  240. { $$ = make1_str("double precision"); }
  241. | DECIMAL
  242. { $$ = make1_str("decimal"); }
  243. | NUMERIC
  244. { $$ = make1_str("numeric"); }
  245. ;
  246. opt_float:  '(' Iconst ')'
  247. {
  248. if (atol($2) < 1)
  249. yyerror("precision for FLOAT must be at least 1");
  250. else if (atol($2) >= 16)
  251. yyerror("precision for FLOAT must be less than 16");
  252. $$ = make3_str(make1_str("("), $2, make1_str(")"));
  253. }
  254. | /*EMPTY*/
  255. {
  256. $$ = make1_str("");
  257. }
  258. ;
  259. opt_numeric:  '(' Iconst ',' Iconst ')'
  260. {
  261. if (atol($2) < 1 || atol($2) > NUMERIC_MAX_PRECISION) {
  262. sprintf(errortext, "NUMERIC precision %s must be between 1 and %d", $2, NUMERIC_MAX_PRECISION);
  263. yyerror(errortext);
  264. }
  265. if (atol($4) < 0 || atol($4) > atol($2)) {
  266. sprintf(errortext, "NUMERIC scale %s must be between 0 and precision %s", $4, $2);
  267. yyerror(errortext);
  268. }
  269. $$ = cat3_str(make2_str(make1_str("("), $2), make1_str(","), make2_str($4, make1_str(")")));
  270. }
  271. | '(' Iconst ')'
  272. {
  273. if (atol($2) < 1 || atol($2) > NUMERIC_MAX_PRECISION) {
  274. sprintf(errortext, "NUMERIC precision %s must be between 1 and %d", $2, NUMERIC_MAX_PRECISION);
  275. yyerror(errortext);
  276. }
  277. $$ = make3_str(make1_str("("), $2, make1_str(")"));
  278. }
  279. | /*EMPTY*/
  280. {
  281. $$ = make1_str("");
  282. }
  283. ;
  284. opt_decimal:  '(' Iconst ',' Iconst ')'
  285. {
  286. if (atol($2) < 1 || atol($2) > NUMERIC_MAX_PRECISION) {
  287. sprintf(errortext, "NUMERIC precision %s must be between 1 and %d", $2, NUMERIC_MAX_PRECISION);
  288. yyerror(errortext);
  289. }
  290. if (atol($4) < 0 || atol($4) > atol($2)) {
  291. sprintf(errortext, "NUMERIC scale %s must be between 0 and precision %s", $4, $2);
  292. yyerror(errortext);
  293. }
  294. $$ = cat3_str(make2_str(make1_str("("), $2), make1_str(","), make2_str($4, make1_str(")")));
  295. }
  296. | '(' Iconst ')'
  297. {
  298. if (atol($2) < 1 || atol($2) > NUMERIC_MAX_PRECISION) {
  299. sprintf(errortext, "NUMERIC precision %s must be between 1 and %d", $2, NUMERIC_MAX_PRECISION);
  300. yyerror(errortext);
  301. }
  302. $$ = make3_str(make1_str("("), $2, make1_str(")"));
  303. }
  304. | /*EMPTY*/
  305. {
  306. $$ = make1_str("");
  307. }
  308. ;
  309. /* SQL92 character data types
  310.  * The following implements CHAR() and VARCHAR().
  311.  * - ay 6/95
  312.  */
  313. Character:  character '(' Iconst ')'
  314. {
  315. if (strncasecmp($1, "char", strlen("char")) && strncasecmp($1, "varchar", strlen("varchar")))
  316. yyerror("internal parsing error; unrecognized character type");
  317. if (atol($3) < 1) {
  318. sprintf(errortext, "length for '%s' type must be at least 1",$1);
  319. yyerror(errortext);
  320. }
  321. else if (atol($3) > MaxAttrSize) {
  322. sprintf(errortext, "length for type '%s' cannot exceed %ld",$1,(long) MaxAttrSize);
  323. yyerror(errortext);
  324. }
  325. $$ = cat2_str($1, make3_str(make1_str("("), $3, make1_str(")")));
  326. }
  327. | character
  328. {
  329. $$ = $1;
  330. }
  331. ;
  332. character:  CHARACTER opt_varying opt_charset opt_collate
  333. {
  334. if (strlen($4) > 0) 
  335. fprintf(stderr, "COLLATE %s not yet implemented",$4);
  336. $$ = cat4_str(make1_str("character"), $2, $3, $4);
  337. }
  338. | CHAR opt_varying { $$ = cat2_str(make1_str("char"), $2); }
  339. | VARCHAR { $$ = make1_str("varchar"); }
  340. | NATIONAL CHARACTER opt_varying { $$ = cat2_str(make1_str("national character"), $3); }
  341. | NCHAR opt_varying { $$ = cat2_str(make1_str("nchar"), $2); }
  342. ;
  343. opt_varying:  VARYING { $$ = make1_str("varying"); }
  344. | /*EMPTY*/ { $$ = make1_str(""); }
  345. ;
  346. opt_charset:  CHARACTER SET ColId { $$ = cat2_str(make1_str("character set"), $3); }
  347. | /*EMPTY*/ { $$ = make1_str(""); }
  348. ;
  349. opt_collate:  COLLATE ColId { $$ = cat2_str(make1_str("collate"), $2); }
  350. | /*EMPTY*/ { $$ = make1_str(""); }
  351. ;
  352. Datetime:  datetime
  353. {
  354. $$ = $1;
  355. }
  356. | TIMESTAMP opt_timezone
  357. {
  358. $$ = cat2_str(make1_str("timestamp"), $2);
  359. }
  360. | TIME
  361. {
  362. $$ = make1_str("time");
  363. }
  364. | INTERVAL opt_interval
  365. {
  366. $$ = cat2_str(make1_str("interval"), $2);
  367. }
  368. ;
  369. datetime:  YEAR_P { $$ = make1_str("year"); }
  370. | MONTH_P { $$ = make1_str("month"); }
  371. | DAY_P { $$ = make1_str("day"); }
  372. | HOUR_P { $$ = make1_str("hour"); }
  373. | MINUTE_P { $$ = make1_str("minute"); }
  374. | SECOND_P { $$ = make1_str("second"); }
  375. ;
  376. opt_timezone:  WITH TIME ZONE { $$ = make1_str("with time zone"); }
  377. | /*EMPTY*/ { $$ = make1_str(""); }
  378. ;
  379. opt_interval:  datetime { $$ = $1; }
  380. | YEAR_P TO MONTH_P { $$ = make1_str("year to #month"); }
  381. | DAY_P TO HOUR_P { $$ = make1_str("day to hour"); }
  382. | DAY_P TO MINUTE_P { $$ = make1_str("day to minute"); }
  383. | DAY_P TO SECOND_P { $$ = make1_str("day to second"); }
  384. | HOUR_P TO MINUTE_P { $$ = make1_str("hour to minute"); }
  385. | MINUTE_P TO SECOND_P { $$ = make1_str("minute to second"); }
  386. | HOUR_P TO SECOND_P { $$ = make1_str("hour to second"); }
  387. | /*EMPTY*/ { $$ = make1_str(""); }
  388. ;
  389. /*****************************************************************************
  390.  *
  391.  * expression grammar, still needs some cleanup
  392.  *
  393.  *****************************************************************************/
  394. a_expr_or_null:  a_expr
  395. { $$ = $1; }
  396. | NULL_P
  397. {
  398. $$ = make1_str("null");
  399. }
  400. ;
  401. /* Expressions using row descriptors
  402.  * Define row_descriptor to allow yacc to break the reduce/reduce conflict
  403.  *  with singleton expressions.
  404.  * Eliminated lots of code by defining row_op and sub_type clauses.
  405.  * However, can not consolidate EXPR_LINK case with others subselects
  406.  *  due to shift/reduce conflict with the non-subselect clause (the parser
  407.  *  would have to look ahead more than one token to resolve the conflict).
  408.  * - thomas 1998-05-09
  409.  */
  410. row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
  411. {
  412. $$ = make5_str(make1_str("("), $2, make1_str(") in ("), $6, make1_str(")"));
  413. }
  414. | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
  415. {
  416. $$ = make5_str(make1_str("("), $2, make1_str(") not in ("), $7, make1_str(")"));
  417. }
  418. | '(' row_descriptor ')' row_op sub_type  '(' SubSelect ')'
  419. {
  420. $$ = make4_str(make5_str(make1_str("("), $2, make1_str(")"), $4, $5), make1_str("("), $7, make1_str(")"));
  421. }
  422. | '(' row_descriptor ')' row_op '(' SubSelect ')'
  423. {
  424. $$ = make3_str(make5_str(make1_str("("), $2, make1_str(")"), $4, make1_str("(")), $6, make1_str(")"));
  425. }
  426. | '(' row_descriptor ')' row_op '(' row_descriptor ')'
  427. {
  428. $$ = cat3_str(make3_str(make1_str("("), $2, make1_str(")")), $4, make3_str(make1_str("("), $6, make1_str(")")));
  429. }
  430. ;
  431. row_descriptor:  row_list ',' a_expr
  432. {
  433. $$ = cat3_str($1, make1_str(","), $3);
  434. }
  435. ;
  436. row_op:  Op { $$ = $1; }
  437. | '<'                   { $$ = "<"; }
  438.         | '='                   { $$ = "="; }
  439.         | '>'                   { $$ = ">"; }
  440.         | '+'                   { $$ = "+"; }
  441.         | '-'                   { $$ = "-"; }
  442.         | '*'                   { $$ = "*"; }
  443.         | '%'                   { $$ = "%"; }
  444.         | '/'                   { $$ = "/"; }
  445.               ;
  446. sub_type:  ANY                  { $$ = make1_str("ANY"); }
  447.          | ALL                  { $$ = make1_str("ALL"); }
  448.               ;
  449. row_list:  row_list ',' a_expr
  450. {
  451. $$ = cat3_str($1, make1_str(","), $3);
  452. }
  453. | a_expr
  454. {
  455. $$ = $1;
  456. }
  457. ;
  458. /* General expressions
  459.  * This is the heart of the expression syntax.
  460.  * Note that the BETWEEN clause looks similar to a boolean expression
  461.  *  and so we must define b_expr which is almost the same as a_expr
  462.  *  but without the boolean expressions.
  463.  * All operations/expressions are allowed in a BETWEEN clause
  464.  *  if surrounded by parens.
  465.  */
  466. a_expr:  attr opt_indirection
  467. {
  468. $$ = cat2_str($1, $2);
  469. }
  470. | row_expr
  471. { $$ = $1;  }
  472. | AexprConst
  473. { $$ = $1;  }
  474. | ColId
  475. {
  476. $$ = $1;
  477. }
  478. | '-' a_expr %prec UMINUS
  479. { $$ = cat2_str(make1_str("-"), $2); }
  480. | '%' a_expr
  481. {       $$ = cat2_str(make1_str("%"), $2); }
  482. | a_expr '%'
  483. {       $$ = cat2_str($1, make1_str("%")); }
  484. | a_expr '+' a_expr
  485. { $$ = cat3_str($1, make1_str("+"), $3); }
  486. | a_expr '-' a_expr
  487. { $$ = cat3_str($1, make1_str("-"), $3); }
  488. | a_expr '/' a_expr
  489. { $$ = cat3_str($1, make1_str("/"), $3); }
  490. | a_expr '%' a_expr
  491. { $$ = cat3_str($1, make1_str("%"), $3); }
  492. | a_expr '*' a_expr
  493. { $$ = cat3_str($1, make1_str("*"), $3); }
  494. | a_expr '<' a_expr
  495. { $$ = cat3_str($1, make1_str("<"), $3); }
  496. | a_expr '>' a_expr
  497. { $$ = cat3_str($1, make1_str(">"), $3); }
  498. | a_expr '=' NULL_P
  499.                                 {       $$ = cat2_str($1, make1_str("= NULL")); }
  500. | NULL_P '=' a_expr
  501.                                 {       $$ = cat2_str(make1_str("= NULL"), $3); }
  502. | a_expr '=' a_expr
  503. { $$ = cat3_str($1, make1_str("="), $3); }
  504. /* not possible in embedded sql | ':' a_expr
  505. { $$ = cat2_str(make1_str(":"), $2); }
  506. */
  507. | ';' a_expr
  508. { $$ = cat2_str(make1_str(";"), $2); }
  509. | '|' a_expr
  510. { $$ = cat2_str(make1_str("|"), $2); }
  511. | a_expr TYPECAST Typename
  512. {
  513. $$ = cat3_str($1, make1_str("::"), $3);
  514. }
  515. | CAST '(' a_expr AS Typename ')'
  516. {
  517. $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
  518. }
  519. | '(' a_expr_or_null ')'
  520. { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
  521. | a_expr Op a_expr
  522. { $$ = cat3_str($1, $2, $3); }
  523. | a_expr LIKE a_expr
  524. { $$ = cat3_str($1, make1_str("like"), $3); }
  525. | a_expr NOT LIKE a_expr
  526. { $$ = cat3_str($1, make1_str("not like"), $4); }
  527. | Op a_expr
  528. { $$ = cat2_str($1, $2); }
  529. | a_expr Op
  530. { $$ = cat2_str($1, $2); }
  531. | func_name '(' '*' ')'
  532. {
  533. $$ = cat2_str($1, make1_str("(*)")); 
  534. }
  535. | func_name '(' ')'
  536. {
  537. $$ = cat2_str($1, make1_str("()")); 
  538. }
  539. | func_name '(' expr_list ')'
  540. {
  541. $$ = make4_str($1, make1_str("("), $3, make1_str(")")); 
  542. }
  543. | CURRENT_DATE
  544. {
  545. $$ = make1_str("current_date");
  546. }
  547. | CURRENT_TIME
  548. {
  549. $$ = make1_str("current_time");
  550. }
  551. | CURRENT_TIME '(' Iconst ')'
  552. {
  553. if (atol($3) != 0)
  554. fprintf(stderr,"CURRENT_TIME(%s) precision not implemented; zero used instead", $3);
  555. $$ = make1_str("current_time");
  556. }
  557. | CURRENT_TIMESTAMP
  558. {
  559. $$ = make1_str("current_timestamp");
  560. }
  561. | CURRENT_TIMESTAMP '(' Iconst ')'
  562. {
  563. if (atol($3) != 0)
  564. fprintf(stderr,"CURRENT_TIMESTAMP(%s) precision not implemented; zero used instead",$3);
  565. $$ = make1_str("current_timestamp");
  566. }
  567. | CURRENT_USER
  568. {
  569. $$ = make1_str("current_user");
  570. }
  571. | USER
  572. {
  573.                  $$ = make1_str("user");
  574.       }
  575. | EXISTS '(' SubSelect ')'
  576. {
  577. $$ = make3_str(make1_str("exists("), $3, make1_str(")"));
  578. }
  579. | EXTRACT '(' extract_list ')'
  580. {
  581. $$ = make3_str(make1_str("extract("), $3, make1_str(")"));
  582. }
  583. | POSITION '(' position_list ')'
  584. {
  585. $$ = make3_str(make1_str("position("), $3, make1_str(")"));
  586. }
  587. | SUBSTRING '(' substr_list ')'
  588. {
  589. $$ = make3_str(make1_str("substring("), $3, make1_str(")"));
  590. }
  591. /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
  592. | TRIM '(' BOTH trim_list ')'
  593. {
  594. $$ = make3_str(make1_str("trim(both"), $4, make1_str(")"));
  595. }
  596. | TRIM '(' LEADING trim_list ')'
  597. {
  598. $$ = make3_str(make1_str("trim(leading"), $4, make1_str(")"));
  599. }
  600. | TRIM '(' TRAILING trim_list ')'
  601. {
  602. $$ = make3_str(make1_str("trim(trailing"), $4, make1_str(")"));
  603. }
  604. | TRIM '(' trim_list ')'
  605. {
  606. $$ = make3_str(make1_str("trim("), $3, make1_str(")"));
  607. }
  608. | a_expr ISNULL
  609. { $$ = cat2_str($1, make1_str("isnull")); }
  610. | a_expr IS NULL_P
  611. { $$ = cat2_str($1, make1_str("is null")); }
  612. | a_expr NOTNULL
  613. { $$ = cat2_str($1, make1_str("notnull")); }
  614. | a_expr IS NOT NULL_P
  615. { $$ = cat2_str($1, make1_str("is not null")); }
  616. /* IS TRUE, IS FALSE, etc used to be function calls
  617.  *  but let's make them expressions to allow the optimizer
  618.  *  a chance to eliminate them if a_expr is a constant string.
  619.  * - thomas 1997-12-22
  620.  */
  621. | a_expr IS TRUE_P
  622. {
  623. { $$ = cat2_str($1, make1_str("is true")); }
  624. }
  625. | a_expr IS NOT FALSE_P
  626. {
  627. { $$ = cat2_str($1, make1_str("is not false")); }
  628. }
  629. | a_expr IS FALSE_P
  630. {
  631. { $$ = cat2_str($1, make1_str("is false")); }
  632. }
  633. | a_expr IS NOT TRUE_P
  634. {
  635. { $$ = cat2_str($1, make1_str("is not true")); }
  636. }
  637. | a_expr BETWEEN b_expr AND b_expr
  638. {
  639. $$ = cat5_str($1, make1_str("between"), $3, make1_str("and"), $5); 
  640. }
  641. | a_expr NOT BETWEEN b_expr AND b_expr
  642. {
  643. $$ = cat5_str($1, make1_str("not between"), $4, make1_str("and"), $6); 
  644. }
  645. | a_expr IN '(' in_expr ')'
  646. {
  647. $$ = make4_str($1, make1_str(" in ("), $4, make1_str(")")); 
  648. }
  649. | a_expr NOT IN '(' not_in_expr ')'
  650. {
  651. $$ = make4_str($1, make1_str(" not in ("), $5, make1_str(")")); 
  652. }
  653. | a_expr Op '(' SubSelect ')'
  654. {
  655. $$ = cat3_str($1, $2, make3_str(make1_str("("), $4, make1_str(")"))); 
  656. }
  657. | a_expr '+' '(' SubSelect ')'
  658. {
  659. $$ = make4_str($1, make1_str("+("), $4, make1_str(")")); 
  660. }
  661. | a_expr '-' '(' SubSelect ')'
  662. {
  663. $$ = make4_str($1, make1_str("-("), $4, make1_str(")")); 
  664. }
  665. | a_expr '/' '(' SubSelect ')'
  666. {
  667. $$ = make4_str($1, make1_str("/("), $4, make1_str(")")); 
  668. }
  669. | a_expr '%' '(' SubSelect ')'
  670. {
  671. $$ = make4_str($1, make1_str("%("), $4, make1_str(")")); 
  672. }
  673. | a_expr '*' '(' SubSelect ')'
  674. {
  675. $$ = make4_str($1, make1_str("*("), $4, make1_str(")")); 
  676. }
  677. | a_expr '<' '(' SubSelect ')'
  678. {
  679. $$ = make4_str($1, make1_str("<("), $4, make1_str(")")); 
  680. }
  681. | a_expr '>' '(' SubSelect ')'
  682. {
  683. $$ = make4_str($1, make1_str(">("), $4, make1_str(")")); 
  684. }
  685. | a_expr '=' '(' SubSelect ')'
  686. {
  687. $$ = make4_str($1, make1_str("=("), $4, make1_str(")")); 
  688. }
  689. | a_expr Op ANY '(' SubSelect ')'
  690. {
  691. $$ = cat3_str($1, $2, make3_str(make1_str("any("), $5, make1_str(")"))); 
  692. }
  693. | a_expr '+' ANY '(' SubSelect ')'
  694. {
  695. $$ = make4_str($1, make1_str("+ any("), $5, make1_str(")")); 
  696. }
  697. | a_expr '-' ANY '(' SubSelect ')'
  698. {
  699. $$ = make4_str($1, make1_str("- any("), $5, make1_str(")")); 
  700. }
  701. | a_expr '/' ANY '(' SubSelect ')'
  702. {
  703. $$ = make4_str($1, make1_str("/ any("), $5, make1_str(")")); 
  704. }
  705. | a_expr '%' ANY '(' SubSelect ')'
  706. {
  707. $$ = make4_str($1, make1_str("% any("), $5, make1_str(")")); 
  708. }
  709. | a_expr '*' ANY '(' SubSelect ')'
  710. {
  711. $$ = make4_str($1, make1_str("* any("), $5, make1_str(")")); 
  712. }
  713. | a_expr '<' ANY '(' SubSelect ')'
  714. {
  715. $$ = make4_str($1, make1_str("< any("), $5, make1_str(")")); 
  716. }
  717. | a_expr '>' ANY '(' SubSelect ')'
  718. {
  719. $$ = make4_str($1, make1_str("> any("), $5, make1_str(")")); 
  720. }
  721. | a_expr '=' ANY '(' SubSelect ')'
  722. {
  723. $$ = make4_str($1, make1_str("= any("), $5, make1_str(")")); 
  724. }
  725. | a_expr Op ALL '(' SubSelect ')'
  726. {
  727. $$ = cat3_str($1, $2, make3_str(make1_str("all ("), $5, make1_str(")"))); 
  728. }
  729. | a_expr '+' ALL '(' SubSelect ')'
  730. {
  731. $$ = make4_str($1, make1_str("+ all("), $5, make1_str(")")); 
  732. }
  733. | a_expr '-' ALL '(' SubSelect ')'
  734. {
  735. $$ = make4_str($1, make1_str("- all("), $5, make1_str(")")); 
  736. }
  737. | a_expr '/' ALL '(' SubSelect ')'
  738. {
  739. $$ = make4_str($1, make1_str("/ all("), $5, make1_str(")")); 
  740. }
  741. | a_expr '%' ALL '(' SubSelect ')'
  742. {
  743. $$ = make4_str($1, make1_str("% all("), $5, make1_str(")")); 
  744. }
  745. | a_expr '*' ALL '(' SubSelect ')'
  746. {
  747. $$ = make4_str($1, make1_str("* all("), $5, make1_str(")")); 
  748. }
  749. | a_expr '<' ALL '(' SubSelect ')'
  750. {
  751. $$ = make4_str($1, make1_str("< all("), $5, make1_str(")")); 
  752. }
  753. | a_expr '>' ALL '(' SubSelect ')'
  754. {
  755. $$ = make4_str($1, make1_str("> all("), $5, make1_str(")")); 
  756. }
  757. | a_expr '=' ALL '(' SubSelect ')'
  758. {
  759. $$ = make4_str($1, make1_str("= all("), $5, make1_str(")")); 
  760. }
  761. | a_expr AND a_expr
  762. { $$ = cat3_str($1, make1_str("and"), $3); }
  763. | a_expr OR a_expr
  764. { $$ = cat3_str($1, make1_str("or"), $3); }
  765. | NOT a_expr
  766. { $$ = cat2_str(make1_str("not"), $2); }
  767. | case_expr
  768. {       $$ = $1; }
  769. | cinputvariable
  770.         { $$ = make1_str("?"); }
  771. ;
  772. /* Restricted expressions
  773.  * b_expr is a subset of the complete expression syntax
  774.  *  defined by a_expr. b_expr is used in BETWEEN clauses
  775.  *  to eliminate parser ambiguities stemming from the AND keyword.
  776.  */
  777. b_expr:  attr opt_indirection
  778. {
  779. $$ = cat2_str($1, $2);
  780. }
  781. | AexprConst
  782. { $$ = $1;  }
  783. | ColId
  784. {
  785. $$ = $1;
  786. }
  787. | '-' b_expr %prec UMINUS
  788. { $$ = cat2_str(make1_str("-"), $2); }
  789. | '%' b_expr
  790. {       $$ = cat2_str(make1_str("%"), $2); }
  791. | b_expr '%'
  792. {       $$ = cat2_str($1, make1_str("%")); }
  793. | b_expr '+' b_expr
  794. { $$ = cat3_str($1, make1_str("+"), $3); }
  795. | b_expr '-' b_expr
  796. { $$ = cat3_str($1, make1_str("-"), $3); }
  797. | b_expr '/' b_expr
  798. { $$ = cat3_str($1, make1_str("/"), $3); }
  799. | b_expr '%' b_expr
  800. { $$ = cat3_str($1, make1_str("%"), $3); }
  801. | b_expr '*' b_expr
  802. { $$ = cat3_str($1, make1_str("*"), $3); }
  803. /* not possible in embedded sql | ':' b_expr
  804. { $$ = cat2_str(make1_str(":"), $2); }
  805. */
  806. | ';' b_expr
  807. { $$ = cat2_str(make1_str(";"), $2); }
  808. | '|' b_expr
  809. { $$ = cat2_str(make1_str("|"), $2); }
  810. | b_expr TYPECAST Typename
  811. {
  812. $$ = cat3_str($1, make1_str("::"), $3);
  813. }
  814. | CAST '(' b_expr AS Typename ')'
  815. {
  816. $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
  817. }
  818. | '(' a_expr ')'
  819. { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
  820. | b_expr Op b_expr
  821. { $$ = cat3_str($1, $2, $3); }
  822. | Op b_expr
  823. { $$ = cat2_str($1, $2); }
  824. | b_expr Op
  825. { $$ = cat2_str($1, $2); }
  826. | func_name '(' ')'
  827. {
  828. $$ = cat2_str($1, make1_str("()")); 
  829. }
  830. | func_name '(' expr_list ')'
  831. {
  832. $$ = make4_str($1, make1_str("("), $3, make1_str(")")); 
  833. }
  834. | CURRENT_DATE
  835. {
  836. $$ = make1_str("current_date");
  837. }
  838. | CURRENT_TIME
  839. {
  840. $$ = make1_str("current_time");
  841. }
  842. | CURRENT_TIME '(' Iconst ')'
  843. {
  844. if ($3 != 0)
  845. fprintf(stderr,"CURRENT_TIME(%s) precision not implemented; zero used instead", $3);
  846. $$ = make1_str("current_time");
  847. }
  848. | CURRENT_TIMESTAMP
  849. {
  850. $$ = make1_str("current_timestamp");
  851. }
  852. | CURRENT_TIMESTAMP '(' Iconst ')'
  853. {
  854. if (atol($3) != 0)
  855. fprintf(stderr,"CURRENT_TIMESTAMP(%s) precision not implemented; zero used instead",$3);
  856. $$ = make1_str("current_timestamp");
  857. }
  858. | CURRENT_USER
  859. {
  860. $$ = make1_str("current_user");
  861. }
  862. | USER
  863. {
  864. $$ = make1_str("user");
  865. }
  866. | POSITION '(' position_list ')'
  867. {
  868. $$ = make3_str(make1_str("position ("), $3, make1_str(")"));
  869. }
  870. | SUBSTRING '(' substr_list ')'
  871. {
  872. $$ = make3_str(make1_str("substring ("), $3, make1_str(")"));
  873. }
  874. /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
  875. | TRIM '(' BOTH trim_list ')'
  876. {
  877. $$ = make3_str(make1_str("trim(both"), $4, make1_str(")"));
  878. }
  879. | TRIM '(' LEADING trim_list ')'
  880. {
  881. $$ = make3_str(make1_str("trim(leading"), $4, make1_str(")"));
  882. }
  883. | TRIM '(' TRAILING trim_list ')'
  884. {
  885. $$ = make3_str(make1_str("trim(trailing"), $4, make1_str(")"));
  886. }
  887. | TRIM '(' trim_list ')'
  888. {
  889. $$ = make3_str(make1_str("trim("), $3, make1_str(")"));
  890. }
  891. | civariableonly
  892.         {  $$ = $1; }
  893. ;
  894. opt_indirection:  '[' ecpg_expr ']' opt_indirection
  895. {
  896. $$ = cat4_str(make1_str("["), $2, make1_str("]"), $4);
  897. }
  898. | '[' ecpg_expr ':' ecpg_expr ']' opt_indirection
  899. {
  900. $$ = cat2_str(cat5_str(make1_str("["), $2, make1_str(":"), $4, make1_str("]")), $6);
  901. }
  902. | /* EMPTY */
  903. { $$ = make1_str(""); }
  904. ;
  905. expr_list:  a_expr_or_null
  906. { $$ = $1; }
  907. | expr_list ',' a_expr_or_null
  908. { $$ = cat3_str($1, make1_str(","), $3); }
  909. | expr_list USING a_expr
  910. { $$ = cat3_str($1, make1_str("using"), $3); }
  911. ;
  912. extract_list:  extract_arg FROM a_expr
  913. {
  914. $$ = cat3_str($1, make1_str("from"), $3);
  915. }
  916. | /* EMPTY */
  917. { $$ = make1_str(""); }
  918. | cinputvariable
  919.         { $$ = make1_str("?"); }
  920. ;
  921. extract_arg:  datetime { $$ = $1; }
  922. | TIMEZONE_HOUR  { $$ = make1_str("timezone_hour"); }
  923. | TIMEZONE_MINUTE  { $$ = make1_str("timezone_minute"); }
  924. ;
  925. position_list:  position_expr IN position_expr
  926. { $$ = cat3_str($1, make1_str("in"), $3); }
  927. | /* EMPTY */
  928. { $$ = make1_str(""); }
  929. ;
  930. position_expr:  attr opt_indirection
  931. {
  932. $$ = cat2_str($1, $2);
  933. }
  934. | AexprConst
  935. { $$ = $1;  }
  936. | '-' position_expr %prec UMINUS
  937. { $$ = cat2_str(make1_str("-"), $2); }
  938. | position_expr '+' position_expr
  939. { $$ = cat3_str($1, make1_str("+"), $3); }
  940. | position_expr '-' position_expr
  941. { $$ = cat3_str($1, make1_str("-"), $3); }
  942. | position_expr '/' position_expr
  943. { $$ = cat3_str($1, make1_str("/"), $3); }
  944. | position_expr '%' position_expr
  945. { $$ = cat3_str($1, make1_str("%"), $3); }
  946. | position_expr '*' position_expr
  947. { $$ = cat3_str($1, make1_str("*"), $3); }
  948. | '|' position_expr
  949. { $$ = cat2_str(make1_str("|"), $2); }
  950. | position_expr TYPECAST Typename
  951. {
  952. $$ = cat3_str($1, make1_str("::"), $3);
  953. }
  954. | CAST '(' position_expr AS Typename ')'
  955. {
  956. $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
  957. }
  958. | '(' position_expr ')'
  959. { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
  960. | position_expr Op position_expr
  961. { $$ = cat3_str($1, $2, $3); }
  962. | Op position_expr
  963. { $$ = cat2_str($1, $2); }
  964. | position_expr Op
  965. { $$ = cat2_str($1, $2); }
  966. | ColId
  967. {
  968. $$ = $1;
  969. }
  970. | func_name '(' ')'
  971. {
  972. $$ = cat2_str($1, make1_str("()"));
  973. }
  974. | func_name '(' expr_list ')'
  975. {
  976. $$ = make4_str($1, make1_str("("), $3, make1_str(")"));
  977. }
  978. | POSITION '(' position_list ')'
  979. {
  980. $$ = make3_str(make1_str("position("), $3, make1_str(")"));
  981. }
  982. | SUBSTRING '(' substr_list ')'
  983. {
  984. $$ = make3_str(make1_str("substring("), $3, make1_str(")"));
  985. }
  986. /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
  987. | TRIM '(' BOTH trim_list ')'
  988. {
  989. $$ = make3_str(make1_str("trim(both"), $4, make1_str(")"));
  990. }
  991. | TRIM '(' LEADING trim_list ')'
  992. {
  993. $$ = make3_str(make1_str("trim(leading"), $4, make1_str(")"));
  994. }
  995. | TRIM '(' TRAILING trim_list ')'
  996. {
  997. $$ = make3_str(make1_str("trim(trailing"), $4, make1_str(")"));
  998. }
  999. | TRIM '(' trim_list ')'
  1000. {
  1001. $$ = make3_str(make1_str("trim("), $3, make1_str(")"));
  1002. }
  1003. ;
  1004. substr_list:  expr_list substr_from substr_for
  1005. {
  1006. $$ = cat3_str($1, $2, $3);
  1007. }
  1008. | /* EMPTY */
  1009. { $$ = make1_str(""); }
  1010. ;
  1011. substr_from:  FROM expr_list
  1012. { $$ = cat2_str(make1_str("from"), $2); }
  1013. | /* EMPTY */
  1014. {
  1015. $$ = make1_str("");
  1016. }
  1017. ;
  1018. substr_for:  FOR expr_list
  1019. { $$ = cat2_str(make1_str("for"), $2); }
  1020. | /* EMPTY */
  1021. { $$ = make1_str(""); }
  1022. ;
  1023. trim_list:  a_expr FROM expr_list
  1024. { $$ = cat3_str($1, make1_str("from"), $3); }
  1025. | FROM expr_list
  1026. { $$ = cat2_str(make1_str("from"), $2); }
  1027. | expr_list
  1028. { $$ = $1; }
  1029. ;
  1030. in_expr:  SubSelect
  1031. {
  1032. $$ = $1;
  1033. }
  1034. | in_expr_nodes
  1035. { $$ = $1; }
  1036. ;
  1037. in_expr_nodes:  AexprConst
  1038. { $$ = $1; }
  1039. | in_expr_nodes ',' AexprConst
  1040. { $$ = cat3_str($1, make1_str(","), $3);}
  1041. ;
  1042. not_in_expr:  SubSelect
  1043. {
  1044. $$ = $1; 
  1045. }
  1046. | not_in_expr_nodes
  1047. { $$ = $1; }
  1048. ;
  1049. not_in_expr_nodes:  AexprConst
  1050. { $$ = $1; }
  1051. | not_in_expr_nodes ',' AexprConst
  1052. { $$ = cat3_str($1, make1_str(","), $3);}
  1053. ;
  1054. /* Case clause
  1055.  * Define SQL92-style case clause.
  1056.  * Allow all four forms described in the standard:
  1057.  * - Full specification
  1058.  *  CASE WHEN a = b THEN c ... ELSE d END
  1059.  * - Implicit argument
  1060.  *  CASE a WHEN b THEN c ... ELSE d END
  1061.  * - Conditional NULL
  1062.  *  NULLIF(x,y)
  1063.  *  same as CASE WHEN x = y THEN NULL ELSE x END
  1064.  * - Conditional substitution from list, use first non-null argument
  1065.  *  COALESCE(a,b,...)
  1066.  * same as CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ... END
  1067.  * - thomas 1998-11-09
  1068.  */
  1069. case_expr:  CASE case_arg when_clause_list case_default END_TRANS
  1070.                                 { $$ = cat5_str(make1_str("case"), $2, $3, $4, make1_str("end")); }
  1071.                 | NULLIF '(' a_expr ',' a_expr ')'
  1072.                                 {
  1073. $$ = cat5_str(make1_str("nullif("), $3, make1_str(","), $5, make1_str(")"));
  1074. fprintf(stderr, "NULLIF() not yet fully implemented");
  1075.                                 }
  1076.                 | COALESCE '(' expr_list ')'
  1077.                                 {
  1078. $$ = cat3_str(make1_str("coalesce("), $3, make1_str(")"));
  1079. }
  1080. ;
  1081. when_clause_list:  when_clause_list when_clause
  1082.                                { $$ = cat2_str($1, $2); }
  1083.                | when_clause
  1084.                                { $$ = $1; }
  1085.                ;
  1086. when_clause:  WHEN a_expr THEN a_expr_or_null
  1087.                                {
  1088. $$ = cat4_str(make1_str("when"), $2, make1_str("then"), $4);
  1089.                                }
  1090.                ;
  1091. case_default:  ELSE a_expr_or_null { $$ = cat2_str(make1_str("else"), $2); }
  1092.                | /*EMPTY*/         { $$ = make1_str(""); }
  1093.                ;
  1094. case_arg:  attr opt_indirection
  1095.                                {
  1096.                                        $$ = cat2_str($1, $2);
  1097.                                }
  1098.                | ColId
  1099.                                {
  1100.                                        $$ = $1;
  1101.                                }
  1102.                | /*EMPTY*/
  1103.                                {       $$ = make1_str(""); }
  1104.                ;
  1105. attr:  relation_name '.' attrs
  1106. {
  1107. $$ = make3_str($1, make1_str("."), $3);
  1108. }
  1109. | ParamNo '.' attrs
  1110. {
  1111. $$ = make3_str($1, make1_str("."), $3);
  1112. }
  1113. ;
  1114. attrs:   attr_name
  1115. { $$ = $1; }
  1116. | attrs '.' attr_name
  1117. { $$ = make3_str($1, make1_str("."), $3); }
  1118. | attrs '.' '*'
  1119. { $$ = make2_str($1, make1_str(".*")); }
  1120. ;
  1121. /*****************************************************************************
  1122.  *
  1123.  * target lists
  1124.  *
  1125.  *****************************************************************************/
  1126. res_target_list:  res_target_list ',' res_target_el
  1127. { $$ = cat3_str($1, make1_str(","),$3);  }
  1128. | res_target_el
  1129. { $$ = $1;  }
  1130. | '*' { $$ = make1_str("*"); }
  1131. ;
  1132. res_target_el:  ColId opt_indirection '=' a_expr_or_null
  1133. {
  1134. $$ = cat4_str($1, $2, make1_str("="), $4);
  1135. }
  1136. | attr opt_indirection
  1137. {
  1138. $$ = cat2_str($1, $2);
  1139. }
  1140. | relation_name '.' '*'
  1141. {
  1142. $$ = make2_str($1, make1_str(".*"));
  1143. }
  1144. ;
  1145. /*
  1146. ** target list for select.
  1147. ** should get rid of the other but is still needed by the defunct select into
  1148. ** and update (uses a subset)
  1149. */
  1150. res_target_list2:  res_target_list2 ',' res_target_el2
  1151. { $$ = cat3_str($1, make1_str(","), $3);  }
  1152. | res_target_el2
  1153. { $$ = $1;  }
  1154. ;
  1155. /* AS is not optional because shift/red conflict with unary ops */
  1156. res_target_el2:  a_expr_or_null AS ColLabel
  1157. {
  1158. $$ = cat3_str($1, make1_str("as"), $3);
  1159. }
  1160. | a_expr_or_null
  1161. {
  1162. $$ = $1;
  1163. }
  1164. | relation_name '.' '*'
  1165. {
  1166. $$ = make2_str($1, make1_str(".*"));
  1167. }
  1168. | '*'
  1169. {
  1170. $$ = make1_str("*");
  1171. }
  1172. ;
  1173. opt_id:  ColId { $$ = $1; }
  1174. | /* EMPTY */ { $$ = make1_str(""); }
  1175. ;
  1176. relation_name: SpecialRuleRelation
  1177. {
  1178. $$ = $1;
  1179. }
  1180. | ColId
  1181. {
  1182. /* disallow refs to variable system tables */
  1183. if (strcmp(LogRelationName, $1) == 0
  1184.    || strcmp(VariableRelationName, $1) == 0) {
  1185. sprintf(errortext, make1_str("%s cannot be accessed by users"),$1);
  1186. yyerror(errortext);
  1187. }
  1188. else
  1189. $$ = $1;
  1190. }
  1191. ;
  1192. database_name: ColId { $$ = $1; };
  1193. access_method: ident { $$ = $1; };
  1194. attr_name: ColId { $$ = $1; };
  1195. class: ident { $$ = $1; };
  1196. index_name: ColId { $$ = $1; };
  1197. /* Functions
  1198.  * Include date/time keywords as SQL92 extension.
  1199.  * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
  1200.  */
  1201. name: ColId { $$ = $1; };
  1202. func_name: ColId { $$ = $1; };
  1203. file_name: Sconst { $$ = $1; };
  1204. /* NOT USED recipe_name: ident { $$ = $1; };*/
  1205. /* Constants
  1206.  * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
  1207.  */
  1208. AexprConst:  Iconst
  1209. {
  1210. $$ = $1;
  1211. }
  1212. | Fconst
  1213. {
  1214. $$ = $1;
  1215. }
  1216. | Sconst
  1217. {
  1218. $$ = $1;
  1219. }
  1220. | Typename Sconst
  1221. {
  1222. $$ = cat2_str($1, $2);
  1223. }
  1224. | ParamNo
  1225. { $$ = $1;  }
  1226. | TRUE_P
  1227. {
  1228. $$ = make1_str("true");
  1229. }
  1230. | FALSE_P
  1231. {
  1232. $$ = make1_str("false");
  1233. }
  1234. ;
  1235. ParamNo:  PARAM opt_indirection
  1236. {
  1237. $$ = cat2_str(make_name(), $2);
  1238. }
  1239. ;
  1240. Iconst:  ICONST                                 { $$ = make_name();};
  1241. Fconst:  FCONST                                 { $$ = make_name();};
  1242. Sconst:  SCONST                                 {
  1243. $$ = (char *)mm_alloc(strlen($1) + 3);
  1244. $$[0]=''';
  1245.               strcpy($$+1, $1);
  1246. $$[strlen($1)+2]='';
  1247. $$[strlen($1)+1]=''';
  1248. free($1);
  1249. }
  1250. UserId:  ident                                  { $$ = $1;};
  1251. /* Column and type identifier
  1252.  * Does not include explicit datetime types
  1253.  *  since these must be decoupled in Typename syntax.
  1254.  * Use ColId for most identifiers. - thomas 1997-10-21
  1255.  */
  1256. TypeId:  ColId
  1257. { $$ = $1; }
  1258. | numeric
  1259. { $$ = $1; }
  1260. | character
  1261. { $$ = $1; }
  1262. ;
  1263. /* Column identifier
  1264.  * Include date/time keywords as SQL92 extension.
  1265.  * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
  1266.  * Add other keywords. Note that as the syntax expands,
  1267.  *  some of these keywords will have to be removed from this
  1268.  *  list due to shift/reduce conflicts in yacc. If so, move
  1269.  *  down to the ColLabel entity. - thomas 1997-11-06
  1270.  */
  1271. ColId:  ident { $$ = $1; }
  1272. | datetime { $$ = $1; }
  1273. | ABSOLUTE { $$ = make1_str("absolute"); }
  1274. | ACCESS { $$ = make1_str("access"); }
  1275. | ACTION { $$ = make1_str("action"); }
  1276. | AFTER { $$ = make1_str("after"); }
  1277. | AGGREGATE { $$ = make1_str("aggregate"); }
  1278. | BACKWARD { $$ = make1_str("backward"); }
  1279. | BEFORE { $$ = make1_str("before"); }
  1280. | CACHE { $$ = make1_str("cache"); }
  1281. | COMMITTED { $$ = make1_str("committed"); }
  1282. | CREATEDB { $$ = make1_str("createdb"); }
  1283. | CREATEUSER { $$ = make1_str("createuser"); }
  1284. | CYCLE { $$ = make1_str("cycle"); }
  1285. | DATABASE { $$ = make1_str("database"); }
  1286. | DELIMITERS { $$ = make1_str("delimiters"); }
  1287. | DOUBLE { $$ = make1_str("double"); }
  1288. | EACH { $$ = make1_str("each"); }
  1289. | ENCODING { $$ = make1_str("encoding"); }
  1290. | EXCLUSIVE { $$ = make1_str("exclusive"); }
  1291. | FORWARD { $$ = make1_str("forward"); }
  1292. | FUNCTION { $$ = make1_str("function"); }
  1293. | HANDLER { $$ = make1_str("handler"); }
  1294. | INCREMENT { $$ = make1_str("increment"); }
  1295. | INDEX { $$ = make1_str("index"); }
  1296. | INHERITS { $$ = make1_str("inherits"); }
  1297. | INSENSITIVE { $$ = make1_str("insensitive"); }
  1298. | INSTEAD { $$ = make1_str("instead"); }
  1299. | ISNULL { $$ = make1_str("isnull"); }
  1300. | KEY { $$ = make1_str("key"); }
  1301. | LANGUAGE { $$ = make1_str("language"); }
  1302. | LANCOMPILER { $$ = make1_str("lancompiler"); }
  1303. | LOCATION { $$ = make1_str("location"); }
  1304. | MATCH { $$ = make1_str("match"); }
  1305. | MAXVALUE { $$ = make1_str("maxvalue"); }
  1306. | MINVALUE { $$ = make1_str("minvalue"); }
  1307. | MODE { $$ = make1_str("mode"); }
  1308. | NEXT { $$ = make1_str("next"); }
  1309. | NOCREATEDB { $$ = make1_str("nocreatedb"); }
  1310. | NOCREATEUSER { $$ = make1_str("nocreateuser"); }
  1311. | NOTHING { $$ = make1_str("nothing"); }
  1312. | NOTNULL { $$ = make1_str("notnull"); }
  1313. | OF { $$ = make1_str("of"); }
  1314. | OIDS { $$ = make1_str("oids"); }
  1315. | ONLY { $$ = make1_str("only"); }
  1316. | OPERATOR { $$ = make1_str("operator"); }
  1317. | OPTION { $$ = make1_str("option"); }
  1318. | PASSWORD { $$ = make1_str("password"); }
  1319. | PRIOR { $$ = make1_str("prior"); }
  1320. | PRIVILEGES { $$ = make1_str("privileges"); }
  1321. | PROCEDURAL { $$ = make1_str("procedural"); }
  1322. | READ { $$ = make1_str("read"); }
  1323. /* NOT USED | RECIPE { $$ = make1_str("recipe"); } */
  1324. | RELATIVE { $$ = make1_str("relative"); }
  1325. | RENAME { $$ = make1_str("rename"); }
  1326. | RETURNS { $$ = make1_str("returns"); }
  1327. | ROW { $$ = make1_str("row"); }
  1328. | RULE { $$ = make1_str("rule"); }
  1329. | SCROLL { $$ = make1_str("scroll"); }
  1330. | SEQUENCE                      { $$ = make1_str("sequence"); }
  1331. | SERIAL { $$ = make1_str("serial"); }
  1332. | SERIALIZABLE { $$ = make1_str("serializable"); }
  1333. | SHARE { $$ = make1_str("share"); }
  1334. | START { $$ = make1_str("start"); }
  1335. | STATEMENT { $$ = make1_str("statement"); }
  1336. | STDIN                         { $$ = make1_str("stdin"); }
  1337. | STDOUT                        { $$ = make1_str("stdout"); }
  1338. | TIME { $$ = make1_str("time"); }
  1339. | TIMESTAMP { $$ = make1_str("timestamp"); }
  1340. | TIMEZONE_HOUR                 { $$ = make1_str("timezone_hour"); }
  1341.                 | TIMEZONE_MINUTE               { $$ = make1_str("timezone_minute"); }
  1342. | TRIGGER { $$ = make1_str("trigger"); }
  1343. | TRUSTED { $$ = make1_str("trusted"); }
  1344. | TYPE_P { $$ = make1_str("type"); }
  1345. | VALID { $$ = make1_str("valid"); }
  1346. | VERSION { $$ = make1_str("version"); }
  1347. | ZONE { $$ = make1_str("zone"); }
  1348. | SQL_AT { $$ = make1_str("at"); }
  1349. | SQL_BOOL { $$ = make1_str("bool"); }
  1350. | SQL_BREAK { $$ = make1_str("break"); }
  1351. | SQL_CALL { $$ = make1_str("call"); }
  1352. | SQL_CONNECT { $$ = make1_str("connect"); }
  1353. | SQL_CONTINUE { $$ = make1_str("continue"); }
  1354. | SQL_DEALLOCATE { $$ = make1_str("deallocate"); }
  1355. | SQL_DISCONNECT { $$ = make1_str("disconnect"); }
  1356. | SQL_FOUND { $$ = make1_str("found"); }
  1357. | SQL_GO { $$ = make1_str("go"); }
  1358. | SQL_GOTO { $$ = make1_str("goto"); }
  1359. | SQL_IDENTIFIED { $$ = make1_str("identified"); }
  1360. | SQL_IMMEDIATE { $$ = make1_str("immediate"); }
  1361. | SQL_INDICATOR { $$ = make1_str("indicator"); }
  1362. | SQL_INT { $$ = make1_str("int"); }
  1363. | SQL_LONG { $$ = make1_str("long"); }
  1364. | SQL_OFF { $$ = make1_str("off"); }
  1365. | SQL_OPEN { $$ = make1_str("open"); }
  1366. | SQL_PREPARE { $$ = make1_str("prepare"); }
  1367. | SQL_RELEASE { $$ = make1_str("release"); }
  1368. | SQL_SECTION { $$ = make1_str("section"); }
  1369. | SQL_SHORT { $$ = make1_str("short"); }
  1370. | SQL_SIGNED { $$ = make1_str("signed"); }
  1371. | SQL_SQLERROR { $$ = make1_str("sqlerror"); }
  1372. | SQL_SQLPRINT { $$ = make1_str("sqlprint"); }
  1373. | SQL_SQLWARNING { $$ = make1_str("sqlwarning"); }
  1374. | SQL_STOP { $$ = make1_str("stop"); }
  1375. | SQL_STRUCT { $$ = make1_str("struct"); }
  1376. | SQL_UNSIGNED { $$ = make1_str("unsigned"); }
  1377. | SQL_VAR { $$ = make1_str("var"); }
  1378. | SQL_WHENEVER { $$ = make1_str("whenever"); }
  1379. ;
  1380. /* Column label
  1381.  * Allowed labels in "AS" clauses.
  1382.  * Include TRUE/FALSE SQL3 reserved words for Postgres backward
  1383.  *  compatibility. Cannot allow this for column names since the
  1384.  *  syntax would not distinguish between the constant value and
  1385.  *  a column name. - thomas 1997-10-24
  1386.  * Add other keywords to this list. Note that they appear here
  1387.  *  rather than in ColId if there was a shift/reduce conflict
  1388.  *  when used as a full identifier. - thomas 1997-11-06
  1389.  */
  1390. ColLabel:  ColId { $$ = $1; }
  1391. | ABORT_TRANS                                   { $$ = make1_str("abort"); }
  1392. | ANALYZE                                       { $$ = make1_str("analyze"); }
  1393. | BINARY                                        { $$ = make1_str("binary"); }
  1394. | CASE                                        { $$ = make1_str("case"); }
  1395. | CLUSTER { $$ = make1_str("cluster"); }
  1396. | COALESCE                                        { $$ = make1_str("coalesce"); }
  1397. | CONSTRAINT { $$ = make1_str("constraint"); }
  1398. | COPY { $$ = make1_str("copy"); }
  1399. | CURRENT { $$ = make1_str("current"); }
  1400. | DO { $$ = make1_str("do"); }
  1401. | ELSE                                        { $$ = make1_str("else"); }
  1402. | END_TRANS                                        { $$ = make1_str("end"); }
  1403. | EXPLAIN { $$ = make1_str("explain"); }
  1404. | EXTEND { $$ = make1_str("extend"); }
  1405. | FALSE_P { $$ = make1_str("false"); }
  1406. | FOREIGN { $$ = make1_str("foreign"); }
  1407. | GROUP { $$ = make1_str("group"); }
  1408. | LISTEN { $$ = make1_str("listen"); }
  1409. | LOAD { $$ = make1_str("load"); }
  1410. | LOCK_P { $$ = make1_str("lock"); }
  1411. | MOVE { $$ = make1_str("move"); }
  1412. | NEW { $$ = make1_str("new"); }
  1413. | NONE { $$ = make1_str("none"); }
  1414. | NULLIF                                        { $$ = make1_str("nullif"); }
  1415. | ORDER { $$ = make1_str("order"); }
  1416. | POSITION { $$ = make1_str("position"); }
  1417. | PRECISION { $$ = make1_str("precision"); }
  1418. | RESET { $$ = make1_str("reset"); }
  1419. | SETOF { $$ = make1_str("setof"); }
  1420. | SHOW { $$ = make1_str("show"); }
  1421. | TABLE { $$ = make1_str("table"); }
  1422. | THEN                                        { $$ = make1_str("then"); }
  1423. | TRANSACTION { $$ = make1_str("transaction"); }
  1424. | TRUE_P { $$ = make1_str("true"); }
  1425. | VACUUM { $$ = make1_str("vacuum"); }
  1426. | VERBOSE { $$ = make1_str("verbose"); }
  1427. | WHEN                                        { $$ = make1_str("when"); }
  1428. ;
  1429. SpecialRuleRelation:  CURRENT
  1430. {
  1431. if (QueryIsRule)
  1432. $$ = make1_str("current");
  1433. else
  1434. yyerror("CURRENT used in non-rule query");
  1435. }
  1436. | NEW
  1437. {
  1438. if (QueryIsRule)
  1439. $$ = make1_str("new");
  1440. else
  1441. yyerror("NEW used in non-rule query");
  1442. }
  1443. ;
  1444. /*
  1445.  * and now special embedded SQL stuff
  1446.  */
  1447. /*
  1448.  * the exec sql connect statement: connect to the given database 
  1449.  */
  1450. ECPGConnect: SQL_CONNECT TO connection_target opt_connection_name opt_user
  1451. {
  1452. $$ = make5_str($3, make1_str(","), $5, make1_str(","), $4);
  1453.                 }
  1454. | SQL_CONNECT TO DEFAULT
  1455.          {
  1456.                  $$ = make1_str("NULL,NULL,NULL,"DEFAULT"");
  1457.                 }
  1458.       /* also allow ORACLE syntax */
  1459.         | SQL_CONNECT ora_user
  1460.                 {
  1461.        $$ = make3_str(make1_str("NULL,"), $2, make1_str(",NULL"));
  1462. }
  1463. connection_target: database_name opt_server opt_port
  1464.                 {
  1465.   /* old style: dbname[@server][:port] */
  1466.   if (strlen($2) > 0 && *($2) != '@')
  1467.   {
  1468.     sprintf(errortext, "parse error at or near '%s'", $2);
  1469.     yyerror(errortext);
  1470.   }
  1471.   $$ = make5_str(make1_str("""), $1, $2, $3, make1_str("""));
  1472. }
  1473.         |  db_prefix server opt_port '/' database_name opt_options
  1474.                 {
  1475.   /* new style: <tcp|unix>:postgresql://server[:port][/dbname] */
  1476.                   if (strncmp($2, "://", 3) != 0)
  1477.   {
  1478.     sprintf(errortext, "parse error at or near '%s'", $2);
  1479.     yyerror(errortext);
  1480.   }
  1481.   if (strncmp($1, "unix", 4) == 0 && strncmp($2 + 3, "localhost", 9) != 0)
  1482.   {
  1483.     sprintf(errortext, "unix domain sockets only work on 'localhost' but not on '%9.9s'", $2);
  1484.                     yyerror(errortext);
  1485.   }
  1486.   if (strncmp($1, "unix", 4) != 0 && strncmp($1, "tcp", 3) != 0)
  1487.   {
  1488.     sprintf(errortext, "only protocols 'tcp' and 'unix' are supported");
  1489.                     yyerror(errortext);
  1490.   }
  1491.   $$ = make4_str(make5_str(make1_str("""), $1, $2, $3, make1_str("/")), $5, $6, make1_str("""));
  1492. }
  1493. | char_variable
  1494.                 {
  1495.   $$ = $1;
  1496. }
  1497. | Sconst
  1498. {
  1499.   $$ = mm_strdup($1);
  1500.   $$[0] = '"';
  1501.   $$[strlen($$) - 1] = '"';
  1502.   free($1);
  1503. }
  1504. db_prefix: ident cvariable
  1505.                 {
  1506.   if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0)
  1507.   {
  1508.     sprintf(errortext, "parse error at or near '%s'", $2);
  1509.     yyerror(errortext);
  1510.   }
  1511.   if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0)
  1512.   {
  1513.     sprintf(errortext, "Illegal connection type %s", $1);
  1514.     yyerror(errortext);
  1515.   }
  1516.   $$ = make3_str($1, make1_str(":"), $2);
  1517. }
  1518.         
  1519. server: Op server_name
  1520.                 {
  1521.   if (strcmp($1, "@") != 0 && strcmp($1, "://") != 0)
  1522.   {
  1523.     sprintf(errortext, "parse error at or near '%s'", $1);
  1524.     yyerror(errortext);
  1525.   }
  1526.   $$ = make2_str($1, $2);
  1527.         }
  1528. opt_server: server { $$ = $1; }
  1529.         | /* empty */ { $$ = make1_str(""); }
  1530. server_name: ColId   { $$ = $1; }
  1531.         | ColId '.' server_name { $$ = make3_str($1, make1_str("."), $3); }
  1532. opt_port: ':' Iconst { $$ = make2_str(make1_str(":"), $2); }
  1533.         | /* empty */ { $$ = make1_str(""); }
  1534. opt_connection_name: AS connection_target { $$ = $2; }
  1535.         | /* empty */ { $$ = make1_str("NULL"); }
  1536. opt_user: USER ora_user { $$ = $2; }
  1537.           | /* empty */ { $$ = make1_str("NULL,NULL"); }
  1538. ora_user: user_name
  1539. {
  1540.                         $$ = make2_str($1, make1_str(",NULL"));
  1541.         }
  1542. | user_name '/' user_name
  1543. {
  1544.          $$ = make3_str($1, make1_str(","), $3);
  1545.                 }
  1546.         | user_name SQL_IDENTIFIED BY user_name
  1547.                 {
  1548.          $$ = make3_str($1, make1_str(","), $4);
  1549.                 }
  1550.         | user_name USING user_name
  1551.                 {
  1552.          $$ = make3_str($1, make1_str(","), $3);
  1553.                 }
  1554. user_name: UserId       { if ($1[0] == '"')
  1555. $$ = $1;
  1556.   else
  1557. $$ = make3_str(make1_str("""), $1, make1_str("""));
  1558. }
  1559.         | char_variable { $$ = $1; }
  1560.         | SCONST        { $$ = make3_str(make1_str("""), $1, make1_str(""")); }
  1561. char_variable: cvariable
  1562. { /* check if we have a char variable */
  1563. struct variable *p = find_variable($1);
  1564. enum ECPGttype typ = p->type->typ;
  1565. /* if array see what's inside */
  1566. if (typ == ECPGt_array)
  1567. typ = p->type->u.element->typ;
  1568.                         switch (typ)
  1569.                         {
  1570.                             case ECPGt_char:
  1571.                             case ECPGt_unsigned_char:
  1572.                                 $$ = $1;
  1573.                                 break;
  1574.                             case ECPGt_varchar:
  1575.                                 $$ = make2_str($1, make1_str(".arr"));
  1576.                                 break;
  1577.                             default:
  1578.                                 yyerror("invalid datatype");
  1579.                                 break;
  1580.                         }
  1581. }
  1582. opt_options: Op ColId
  1583. {
  1584. if (strlen($1) == 0)
  1585. yyerror("parse error");
  1586. if (strcmp($1, "?") != 0)
  1587. {
  1588. sprintf(errortext, "parse error at or near %s", $1);
  1589. yyerror(errortext);
  1590. }
  1591. $$ = make2_str(make1_str("?"), $2);
  1592. }
  1593. | /* empty */ { $$ = make1_str(""); }
  1594. /*
  1595.  * Declare a prepared cursor. The syntax is different from the standard
  1596.  * declare statement, so we create a new rule.
  1597.  */
  1598. ECPGCursorStmt:  DECLARE name opt_cursor CURSOR FOR ident
  1599. {
  1600. struct cursor *ptr, *this;
  1601. struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
  1602. for (ptr = cur; ptr != NULL; ptr = ptr->next)
  1603. {
  1604. if (strcmp($2, ptr->name) == 0)
  1605. {
  1606.         /* re-definition is a bug */
  1607. sprintf(errortext, "cursor %s already defined", $2);
  1608. yyerror(errortext);
  1609.                 }
  1610.          }
  1611.          this = (struct cursor *) mm_alloc(sizeof(struct cursor));
  1612.          /* initial definition */
  1613.         this->next = cur;
  1614.         this->name = $2;
  1615. this->connection = connection;
  1616.         this->command =  cat4_str(make1_str("declare"), mm_strdup($2), $3, make1_str("cursor for ?"));
  1617. this->argsresult = NULL;
  1618. thisquery->type = &ecpg_query;
  1619. thisquery->brace_level = 0;
  1620. thisquery->next = NULL;
  1621. thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement("")") + strlen($6));
  1622. sprintf(thisquery->name, "ECPGprepared_statement("%s")", $6);
  1623. this->argsinsert = NULL;
  1624. add_variable(&(this->argsinsert), thisquery, &no_indicator); 
  1625.          cur = this;
  1626. $$ = cat3_str(make1_str("/*"), mm_strdup(this->command), make1_str("*/"));
  1627. }
  1628. ;
  1629. /*
  1630.  * the exec sql deallocate prepare command to deallocate a previously
  1631.  * prepared statement
  1632.  */
  1633. ECPGDeallocate: SQL_DEALLOCATE SQL_PREPARE ident { $$ = make3_str(make1_str("ECPGdeallocate(__LINE__, ""), $3, make1_str("");")); }
  1634. /*
  1635.  * variable declaration inside the exec sql declare block
  1636.  */
  1637. ECPGDeclaration: sql_startdeclare
  1638. {
  1639. fputs("/* exec sql begin declare section */", yyout);
  1640.         output_line_number();
  1641. }
  1642. variable_declarations sql_enddeclare
  1643. {
  1644. fprintf(yyout, "%s/* exec sql end declare section */", $3);
  1645. free($3);
  1646. output_line_number();
  1647. }
  1648. sql_startdeclare : ecpgstart BEGIN_TRANS DECLARE SQL_SECTION ';' {}
  1649. sql_enddeclare: ecpgstart END_TRANS DECLARE SQL_SECTION ';' {}
  1650. variable_declarations: /* empty */
  1651. {
  1652. $$ = make1_str("");
  1653. }
  1654. | declaration variable_declarations
  1655. {
  1656. $$ = cat2_str($1, $2);
  1657. }
  1658. declaration: storage_clause
  1659. {
  1660. actual_storage[struct_level] = mm_strdup($1);
  1661. }
  1662. type
  1663. {
  1664. actual_type[struct_level].type_enum = $3.type_enum;
  1665. actual_type[struct_level].type_dimension = $3.type_dimension;
  1666. actual_type[struct_level].type_index = $3.type_index;
  1667. }
  1668. variable_list ';'
  1669. {
  1670.   $$ = cat4_str($1, $3.type_str, $5, make1_str(";n"));
  1671. }
  1672. storage_clause : S_EXTERN { $$ = make1_str("extern"); }
  1673.        | S_STATIC { $$ = make1_str("static"); }
  1674.        | S_SIGNED { $$ = make1_str("signed"); }
  1675.        | S_CONST { $$ = make1_str("const"); }
  1676.        | S_REGISTER { $$ = make1_str("register"); }
  1677.        | S_AUTO { $$ = make1_str("auto"); }
  1678.        | /* empty */ { $$ = make1_str(""); }
  1679. type: simple_type
  1680. {
  1681. $$.type_enum = $1;
  1682. $$.type_str = mm_strdup(ECPGtype_name($1));
  1683. $$.type_dimension = -1;
  1684.    $$.type_index = -1;
  1685. }
  1686. | varchar_type
  1687. {
  1688. $$.type_enum = ECPGt_varchar;
  1689. $$.type_str = make1_str("");
  1690. $$.type_dimension = -1;
  1691.    $$.type_index = -1;
  1692. }
  1693. | struct_type
  1694. {
  1695. $$.type_enum = ECPGt_struct;
  1696. $$.type_str = $1;
  1697. $$.type_dimension = -1;
  1698.    $$.type_index = -1;
  1699. }
  1700. | union_type
  1701. {
  1702. $$.type_enum = ECPGt_union;
  1703. $$.type_str = $1;
  1704. $$.type_dimension = -1;
  1705.    $$.type_index = -1;
  1706. }
  1707. | enum_type
  1708. {
  1709. $$.type_str = $1;
  1710. $$.type_enum = ECPGt_int;
  1711. $$.type_dimension = -1;
  1712.    $$.type_index = -1;
  1713. }
  1714. | symbol
  1715. {
  1716. /* this is for typedef'ed types */
  1717. struct typedefs *this = get_typedef($1);
  1718. $$.type_str = (this->type->type_enum == ECPGt_varchar) ? make1_str("") : mm_strdup(this->name);
  1719.                         $$.type_enum = this->type->type_enum;
  1720. $$.type_dimension = this->type->type_dimension;
  1721.    $$.type_index = this->type->type_index;
  1722. struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
  1723. }
  1724. enum_type: s_enum '{' c_line '}'
  1725. {
  1726. $$ = cat4_str($1, make1_str("{"), $3, make1_str("}"));
  1727. }
  1728. s_enum: S_ENUM opt_symbol { $$ = cat2_str(make1_str("enum"), $2); }
  1729. struct_type: s_struct '{' variable_declarations '}'
  1730. {
  1731.     ECPGfree_struct_member(struct_member_list[struct_level]);
  1732.     free(actual_storage[struct_level--]);
  1733.     $$ = cat4_str($1, make1_str("{"), $3, make1_str("}"));
  1734. }
  1735. union_type: s_union '{' variable_declarations '}'
  1736. {
  1737.     ECPGfree_struct_member(struct_member_list[struct_level]);
  1738.     free(actual_storage[struct_level--]);
  1739.     $$ = cat4_str($1, make1_str("{"), $3, make1_str("}"));
  1740. }
  1741. s_struct : S_STRUCT opt_symbol
  1742.         {
  1743.             struct_member_list[struct_level++] = NULL;
  1744.             if (struct_level >= STRUCT_DEPTH)
  1745.                  yyerror("Too many levels in nested structure definition");
  1746.     $$ = cat2_str(make1_str("struct"), $2);
  1747. }
  1748. s_union : S_UNION opt_symbol
  1749.         {
  1750.             struct_member_list[struct_level++] = NULL;
  1751.             if (struct_level >= STRUCT_DEPTH)
  1752.                  yyerror("Too many levels in nested structure definition");
  1753.     $$ = cat2_str(make1_str("union"), $2);
  1754. }
  1755. opt_symbol: /* empty */  { $$ = make1_str(""); }
  1756. | symbol { $$ = $1; }
  1757. simple_type: S_SHORT { $$ = ECPGt_short; }
  1758.            | S_UNSIGNED S_SHORT { $$ = ECPGt_unsigned_short; }
  1759.    | S_INT  { $$ = ECPGt_int; }
  1760.            | S_UNSIGNED S_INT { $$ = ECPGt_unsigned_int; }
  1761.    | S_LONG { $$ = ECPGt_long; }
  1762.            | S_UNSIGNED S_LONG { $$ = ECPGt_unsigned_long; }
  1763.            | S_FLOAT { $$ = ECPGt_float; }
  1764.            | S_DOUBLE { $$ = ECPGt_double; }
  1765.    | S_BOOL { $$ = ECPGt_bool; };
  1766.    | S_CHAR { $$ = ECPGt_char; }
  1767.            | S_UNSIGNED S_CHAR { $$ = ECPGt_unsigned_char; }
  1768. varchar_type:  S_VARCHAR { $$ = ECPGt_varchar; }
  1769. variable_list: variable 
  1770. {
  1771. $$ = $1;
  1772. }
  1773. | variable_list ',' variable
  1774. {
  1775. $$ = cat3_str($1, make1_str(","), $3);
  1776. }
  1777. variable: opt_pointer symbol opt_array_bounds opt_initializer
  1778. {
  1779. struct ECPGtype * type;
  1780.                         int dimension = $3.index1; /* dimension of array */
  1781.                         int length = $3.index2;    /* lenght of string */
  1782.                         char dim[14L], ascii_len[12];
  1783. adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1));
  1784. switch (actual_type[struct_level].type_enum)
  1785. {
  1786.    case ECPGt_struct:
  1787.    case ECPGt_union:
  1788.                                if (dimension < 0)
  1789.                                    type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum);
  1790.                                else
  1791.                                    type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum), dimension); 
  1792.                                $$ = make4_str($1, mm_strdup($2), $3.str, $4);
  1793.                                break;
  1794.                            case ECPGt_varchar:
  1795.                                if (dimension == -1)
  1796.                                    type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
  1797.                                else
  1798.                                    type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
  1799.                                switch(dimension)
  1800.                                {
  1801.                                   case 0:
  1802.   case -1:
  1803.                                   case 1:
  1804.                                       *dim = '';
  1805.                                       break;
  1806.                                   default:
  1807.                                       sprintf(dim, "[%d]", dimension);
  1808.                                       break;
  1809.                                }
  1810.        sprintf(ascii_len, "%d", length);
  1811.                                if (length == 0)
  1812.    yyerror ("pointer to varchar are not implemented");
  1813.        if (dimension == 0)
  1814.    $$ = make4_str(make5_str(mm_strdup(actual_storage[struct_level]), make1_str(" struct varchar_"), mm_strdup($2), make1_str(" { int len; char arr["), mm_strdup(ascii_len)), make1_str("]; } *"), mm_strdup($2), $4);
  1815.        else
  1816.                                    $$ = make5_str(make5_str(mm_strdup(actual_storage[struct_level]), make1_str(" struct varchar_"), mm_strdup($2), make1_str(" { int len; char arr["), mm_strdup(ascii_len)), make1_str("]; } "), mm_strdup($2), mm_strdup(dim), $4);
  1817.                                break;
  1818.                            case ECPGt_char:
  1819.                            case ECPGt_unsigned_char:
  1820.                                if (dimension == -1)
  1821.                                    type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
  1822.                                else
  1823.                                    type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
  1824.        $$ = make4_str($1, mm_strdup($2), $3.str, $4);
  1825.                                break;
  1826.                            default:
  1827.                                if (dimension < 0)
  1828.                                    type = ECPGmake_simple_type(actual_type[struct_level].type_enum, 1);
  1829.                                else
  1830.                                    type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, 1), dimension);
  1831.        $$ = make4_str($1, mm_strdup($2), $3.str, $4);
  1832.                                break;
  1833. }
  1834. if (struct_level == 0)
  1835. new_variable($2, type);
  1836. else
  1837. ECPGmake_struct_member($2, type, &(struct_member_list[struct_level - 1]));
  1838. free($2);
  1839. }
  1840. opt_initializer: /* empty */ { $$ = make1_str(""); }
  1841. | '=' vartext { $$ = make2_str(make1_str("="), $2); }
  1842. opt_pointer: /* empty */ { $$ = make1_str(""); }
  1843. | '*' { $$ = make1_str("*"); }
  1844. /*
  1845.  * As long as the prepare statement is not supported by the backend, we will
  1846.  * try to simulate it here so we get dynamic SQL 
  1847.  */
  1848. ECPGDeclare: DECLARE STATEMENT ident
  1849. {
  1850. /* this is only supported for compatibility */
  1851. $$ = cat3_str(make1_str("/* declare statement"), $3, make1_str("*/"));
  1852. }
  1853. /*
  1854.  * the exec sql disconnect statement: disconnect from the given database 
  1855.  */
  1856. ECPGDisconnect: SQL_DISCONNECT dis_name { $$ = $2; }
  1857. dis_name: connection_object { $$ = $1; }
  1858. | CURRENT { $$ = make1_str("CURRENT"); }
  1859. | ALL { $$ = make1_str("ALL"); }
  1860. | /* empty */ { $$ = make1_str("CURRENT"); }
  1861. connection_object: connection_target { $$ = $1; }
  1862. | DEFAULT { $$ = make1_str("DEFAULT"); }
  1863. /*
  1864.  * execute a given string as sql command
  1865.  */
  1866. ECPGExecute : EXECUTE SQL_IMMEDIATE execstring
  1867. struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
  1868. thisquery->type = &ecpg_query;
  1869. thisquery->brace_level = 0;
  1870. thisquery->next = NULL;
  1871. thisquery->name = $3;
  1872. add_variable(&argsinsert, thisquery, &no_indicator); 
  1873. $$ = make1_str("?");
  1874. }
  1875. | EXECUTE ident 
  1876. {
  1877. struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
  1878. thisquery->type = &ecpg_query;
  1879. thisquery->brace_level = 0;
  1880. thisquery->next = NULL;
  1881. thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement("")") + strlen($2));
  1882. sprintf(thisquery->name, "ECPGprepared_statement("%s")", $2);
  1883. add_variable(&argsinsert, thisquery, &no_indicator); 
  1884. } opt_using
  1885. {
  1886. $$ = make1_str("?");
  1887. }
  1888. execstring: char_variable |
  1889. CSTRING  { $$ = make3_str(make1_str("""), $1, make1_str(""")); };
  1890. /*
  1891.  * the exec sql free command to deallocate a previously
  1892.  * prepared statement
  1893.  */
  1894. ECPGFree: SQL_FREE ident { $$ = $2; }
  1895. /*
  1896.  * open is an open cursor, at the moment this has to be removed
  1897.  */
  1898. ECPGOpen: SQL_OPEN name opt_using {
  1899. $$ = $2;
  1900. };
  1901. opt_using: /* empty */ { $$ = make1_str(""); }
  1902. | USING variablelist {
  1903. /* yyerror ("open cursor with variables not implemented yet"); */
  1904. $$ = make1_str("");
  1905. }
  1906. variablelist: cinputvariable | cinputvariable ',' variablelist
  1907. /*
  1908.  * As long as the prepare statement is not supported by the backend, we will
  1909.  * try to simulate it here so we get dynamic SQL 
  1910.  */
  1911. ECPGPrepare: SQL_PREPARE ident FROM execstring
  1912. {
  1913. $$ = make4_str(make1_str("""), $2, make1_str("", "), $4);
  1914. }
  1915. /*
  1916.  * for compatibility with ORACLE we will also allow the keyword RELEASE
  1917.  * after a transaction statement to disconnect from the database.
  1918.  */
  1919. ECPGRelease: TransactionStmt SQL_RELEASE
  1920. {
  1921. if (strncmp($1, "begin", 5) == 0)
  1922.                         yyerror("RELEASE does not make sense when beginning a transaction");
  1923. fprintf(yyout, "ECPGtrans(__LINE__, %s, "%s");", connection, $1);
  1924. whenever_action(0);
  1925. fprintf(yyout, "ECPGdisconnect("");"); 
  1926. whenever_action(0);
  1927. free($1);
  1928. }
  1929. /* 
  1930.  * set/reset the automatic transaction mode, this needs a differnet handling
  1931.  * as the other set commands
  1932.  */
  1933. ECPGSetAutocommit:  SET SQL_AUTOCOMMIT to_equal on_off
  1934.             {
  1935. $$ = $4;
  1936.                         }
  1937. on_off: ON { $$ = make1_str("on"); }
  1938. | SQL_OFF { $$ = make1_str("off"); }
  1939. to_equal: TO | "=";
  1940. /* 
  1941.  * set the actual connection, this needs a differnet handling as the other
  1942.  * set commands
  1943.  */
  1944. ECPGSetConnection:  SET SQL_CONNECTION to_equal connection_object
  1945.             {
  1946. $$ = $4;
  1947.                         }
  1948. /*
  1949.  * define a new type for embedded SQL
  1950.  */
  1951. ECPGTypedef: TYPE_P symbol IS ctype opt_type_array_bounds opt_reference
  1952. {
  1953. /* add entry to list */
  1954. struct typedefs *ptr, *this;
  1955. int dimension = $5.index1;
  1956. int length = $5.index2;
  1957. for (ptr = types; ptr != NULL; ptr = ptr->next)
  1958. {
  1959. if (strcmp($2, ptr->name) == 0)
  1960. {
  1961.         /* re-definition is a bug */
  1962. sprintf(errortext, "type %s already defined", $2);
  1963. yyerror(errortext);
  1964.                 }
  1965. }
  1966. adjust_array($4.type_enum, &dimension, &length, $4.type_dimension, $4.type_index, strlen($6));
  1967.          this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
  1968.          /* initial definition */
  1969.         this->next = types;
  1970.         this->name = $2;
  1971. this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
  1972. this->type->type_enum = $4.type_enum;
  1973. this->type->type_str = mm_strdup($2);
  1974. this->type->type_dimension = dimension; /* dimension of array */
  1975. this->type->type_index = length;    /* lenght of string */
  1976. this->struct_member_list = struct_member_list[struct_level];
  1977. if ($4.type_enum != ECPGt_varchar &&
  1978.     $4.type_enum != ECPGt_char &&
  1979.             $4.type_enum != ECPGt_unsigned_char &&
  1980.     this->type->type_index >= 0)
  1981.                             yyerror("No multi-dimensional array support for simple data types");
  1982.          types = this;
  1983. $$ = cat5_str(cat3_str(make1_str("/* exec sql type"), mm_strdup($2), make1_str("is")), mm_strdup($4.type_str), mm_strdup($5.str), $6, make1_str("*/"));
  1984. }
  1985. opt_type_array_bounds:  '[' ']' nest_type_array_bounds
  1986. {
  1987.                             $$.index1 = 0;
  1988.                             $$.index2 = $3.index1;
  1989.                             $$.str = cat2_str(make1_str("[]"), $3.str);
  1990.                         }
  1991. | '(' ')' nest_type_array_bounds
  1992. {
  1993.                             $$.index1 = 0;
  1994.                             $$.index2 = $3.index1;
  1995.                             $$.str = cat2_str(make1_str("[]"), $3.str);
  1996.                         }
  1997. | '[' Iresult ']' nest_type_array_bounds
  1998. {
  1999.     char *txt = mm_alloc(20L);
  2000.     sprintf (txt, "%d", $2);
  2001.                             $$.index1 = $2;
  2002.                             $$.index2 = $4.index1;
  2003.                             $$.str = cat4_str(make1_str("["), txt, make1_str("]"), $4.str);
  2004.                         }
  2005. | '(' Iresult ')' nest_type_array_bounds
  2006. {
  2007.     char *txt = mm_alloc(20L);
  2008.     sprintf (txt, "%d", $2);
  2009.                             $$.index1 = $2;
  2010.                             $$.index2 = $4.index1;
  2011.                             $$.str = cat4_str(make1_str("["), txt, make1_str("]"), $4.str);
  2012.                         }
  2013. | /* EMPTY */
  2014. {
  2015.                             $$.index1 = -1;
  2016.                             $$.index2 = -1;
  2017.                             $$.str= make1_str("");
  2018.                         }
  2019. ;
  2020. nest_type_array_bounds: '[' ']' nest_type_array_bounds
  2021.                         {
  2022.                             $$.index1 = 0;
  2023.                             $$.index2 = $3.index1;
  2024.                             $$.str = cat2_str(make1_str("[]"), $3.str);
  2025.                         }
  2026. | '(' ')' nest_type_array_bounds
  2027.                         {
  2028.                             $$.index1 = 0;
  2029.                             $$.index2 = $3.index1;
  2030.                             $$.str = cat2_str(make1_str("[]"), $3.str);
  2031.                         }
  2032. | '[' Iresult ']' nest_type_array_bounds
  2033. {
  2034.     char *txt = mm_alloc(20L);
  2035.     sprintf (txt, "%d", $2);
  2036.                             $$.index1 = $2;
  2037.                             $$.index2 = $4.index1;
  2038.                             $$.str = cat4_str(make1_str("["), txt, make1_str("]"), $4.str);
  2039.                         }
  2040. | '(' Iresult ')' nest_type_array_bounds
  2041. {
  2042.     char *txt = mm_alloc(20L);
  2043.     sprintf (txt, "%d", $2);
  2044.                             $$.index1 = $2;
  2045.                             $$.index2 = $4.index1;
  2046.                             $$.str = cat4_str(make1_str("["), txt, make1_str("]"), $4.str);
  2047.                         }
  2048. | /* EMPTY */
  2049. {
  2050.                             $$.index1 = -1;
  2051.                             $$.index2 = -1;
  2052.                             $$.str= make1_str("");
  2053.                         }
  2054.                 ;
  2055. opt_reference: SQL_REFERENCE { $$ = make1_str("reference"); }
  2056. | /* empty */       { $$ = make1_str(""); }
  2057. ctype: CHAR
  2058. {
  2059. $$.type_str = make1_str("char");
  2060.                 $$.type_enum = ECPGt_char;
  2061. $$.type_index = -1;
  2062. $$.type_dimension = -1;
  2063. }
  2064. | VARCHAR
  2065. {
  2066. $$.type_str = make1_str("varchar");
  2067.                 $$.type_enum = ECPGt_varchar;
  2068. $$.type_index = -1;
  2069. $$.type_dimension = -1;
  2070. }
  2071. | FLOAT
  2072. {
  2073. $$.type_str = make1_str("float");
  2074.                 $$.type_enum = ECPGt_float;
  2075. $$.type_index = -1;
  2076. $$.type_dimension = -1;
  2077. }
  2078. | DOUBLE
  2079. {
  2080. $$.type_str = make1_str("double");
  2081.                 $$.type_enum = ECPGt_double;
  2082. $$.type_index = -1;
  2083. $$.type_dimension = -1;
  2084. }
  2085. | opt_signed SQL_INT
  2086. {
  2087. $$.type_str = make1_str("int");
  2088.                 $$.type_enum = ECPGt_int;
  2089. $$.type_index = -1;
  2090. $$.type_dimension = -1;
  2091. }
  2092. | SQL_ENUM
  2093. {
  2094. $$.type_str = make1_str("int");
  2095.                 $$.type_enum = ECPGt_int;
  2096. $$.type_index = -1;
  2097. $$.type_dimension = -1;
  2098. }
  2099. | opt_signed SQL_SHORT
  2100. {
  2101. $$.type_str = make1_str("short");
  2102.                 $$.type_enum = ECPGt_short;
  2103. $$.type_index = -1;
  2104. $$.type_dimension = -1;
  2105. }
  2106. | opt_signed SQL_LONG
  2107. {
  2108. $$.type_str = make1_str("long");
  2109.                 $$.type_enum = ECPGt_long;
  2110. $$.type_index = -1;
  2111. $$.type_dimension = -1;
  2112. }
  2113. | SQL_BOOL
  2114. {
  2115. $$.type_str = make1_str("bool");
  2116.                 $$.type_enum = ECPGt_bool;
  2117. $$.type_index = -1;
  2118. $$.type_dimension = -1;
  2119. }
  2120. | SQL_UNSIGNED SQL_INT
  2121. {
  2122. $$.type_str = make1_str("unsigned int");
  2123.                 $$.type_enum = ECPGt_unsigned_int;
  2124. $$.type_index = -1;
  2125. $$.type_dimension = -1;
  2126. }
  2127. | SQL_UNSIGNED SQL_SHORT
  2128. {
  2129. $$.type_str = make1_str("unsigned short");
  2130.                 $$.type_enum = ECPGt_unsigned_short;
  2131. $$.type_index = -1;
  2132. $$.type_dimension = -1;
  2133. }
  2134. | SQL_UNSIGNED SQL_LONG
  2135. {
  2136. $$.type_str = make1_str("unsigned long");
  2137.                 $$.type_enum = ECPGt_unsigned_long;
  2138. $$.type_index = -1;
  2139. $$.type_dimension = -1;
  2140. }
  2141. | SQL_STRUCT
  2142. {
  2143. struct_member_list[struct_level++] = NULL;
  2144. if (struct_level >= STRUCT_DEPTH)
  2145.          yyerror("Too many levels in nested structure definition");
  2146. } '{' sql_variable_declarations '}'
  2147. {
  2148. ECPGfree_struct_member(struct_member_list[struct_level--]);
  2149. $$.type_str = cat3_str(make1_str("struct {"), $4, make1_str("}"));
  2150. $$.type_enum = ECPGt_struct;
  2151.                 $$.type_index = -1;
  2152.                 $$.type_dimension = -1;
  2153. }
  2154. | UNION
  2155. {
  2156. struct_member_list[struct_level++] = NULL;
  2157. if (struct_level >= STRUCT_DEPTH)
  2158.          yyerror("Too many levels in nested structure definition");
  2159. } '{' sql_variable_declarations '}'
  2160. {
  2161. ECPGfree_struct_member(struct_member_list[struct_level--]);
  2162. $$.type_str = cat3_str(make1_str("union {"), $4, make1_str("}"));
  2163. $$.type_enum = ECPGt_union;
  2164.                 $$.type_index = -1;
  2165.                 $$.type_dimension = -1;
  2166. }
  2167. | symbol
  2168. {
  2169. struct typedefs *this = get_typedef($1);
  2170. $$.type_str = mm_strdup($1);
  2171. $$.type_enum = this->type->type_enum;
  2172. $$.type_dimension = this->type->type_dimension;
  2173. $$.type_index = this->type->type_index;
  2174. struct_member_list[struct_level] = this->struct_member_list;
  2175. }
  2176. opt_signed: SQL_SIGNED | /* empty */
  2177. sql_variable_declarations: /* empty */
  2178. {
  2179. $$ = make1_str("");
  2180. }
  2181. | sql_declaration sql_variable_declarations
  2182. {
  2183. $$ = cat2_str($1, $2);
  2184. }
  2185. ;
  2186. sql_declaration: ctype
  2187. {
  2188. actual_type[struct_level].type_enum = $1.type_enum;
  2189. actual_type[struct_level].type_dimension = $1.type_dimension;
  2190. actual_type[struct_level].type_index = $1.type_index;
  2191. }
  2192. sql_variable_list ';'
  2193. {
  2194. $$ = cat3_str($1.type_str, $3, make1_str(";"));
  2195. }
  2196. sql_variable_list: sql_variable 
  2197. {
  2198. $$ = $1;
  2199. }
  2200. | sql_variable_list ',' sql_variable
  2201. {
  2202. $$ = make3_str($1, make1_str(","), $3);
  2203. }
  2204. sql_variable: opt_pointer symbol opt_array_bounds
  2205. {
  2206. int dimension = $3.index1;
  2207. int length = $3.index2;
  2208. struct ECPGtype * type;
  2209.                         char dim[14L];
  2210. adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1));
  2211. switch (actual_type[struct_level].type_enum)
  2212. {
  2213.    case ECPGt_struct:
  2214.    case ECPGt_union:
  2215.                                if (dimension < 0)
  2216.                                    type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum);
  2217.                                else
  2218.                                    type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum), dimension); 
  2219.                                break;
  2220.                            case ECPGt_varchar:
  2221.                                if (dimension == -1)
  2222.                                    type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
  2223.                                else
  2224.                                    type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
  2225.                                switch(dimension)
  2226.                                {
  2227.                                   case 0:
  2228.                                       strcpy(dim, "[]");
  2229.                                       break;
  2230.   case -1:
  2231.                                   case 1:
  2232.                                       *dim = '';
  2233.                                       break;
  2234.                                   default:
  2235.                                       sprintf(dim, "[%d]", dimension);
  2236.                                       break;
  2237.                                 }
  2238.                                break;
  2239.                            case ECPGt_char:
  2240.                            case ECPGt_unsigned_char:
  2241.                                if (dimension == -1)
  2242.                                    type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
  2243.                                else
  2244.                                    type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
  2245.                                break;
  2246.                            default:
  2247.        if (length >= 0)
  2248.                              yyerror("No multi-dimensional array support for simple data types");
  2249.                                if (dimension < 0)
  2250.                                    type = ECPGmake_simple_type(actual_type[struct_level].type_enum, 1);
  2251.                                else
  2252.                                    type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, 1), dimension);
  2253.                                break;
  2254. }
  2255. if (struct_level == 0)
  2256. new_variable($2, type);
  2257. else
  2258. ECPGmake_struct_member($2, type, &(struct_member_list[struct_level - 1]));
  2259. $$ = cat3_str($1, $2, $3.str);
  2260. }
  2261. /*
  2262.  * define the type of one variable for embedded SQL
  2263.  */
  2264. ECPGVar: SQL_VAR symbol IS ctype opt_type_array_bounds opt_reference
  2265. {
  2266. struct variable *p = find_variable($2);
  2267. int dimension = $5.index1;
  2268. int length = $5.index2;
  2269. struct ECPGtype * type;
  2270. adjust_array($4.type_enum, &dimension, &length, $4.type_dimension, $4.type_index, strlen($6));
  2271. switch ($4.type_enum)
  2272. {
  2273.    case ECPGt_struct:
  2274.    case ECPGt_union:
  2275.                         if (dimension < 0)
  2276.                             type = ECPGmake_struct_type(struct_member_list[struct_level], $4.type_enum);
  2277.                         else
  2278.                             type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $4.type_enum), dimension); 
  2279.                         break;
  2280.                    case ECPGt_varchar:
  2281.                         if (dimension == -1)
  2282.                             type = ECPGmake_simple_type($4.type_enum, length);
  2283.                         else
  2284.                             type = ECPGmake_array_type(ECPGmake_simple_type($4.type_enum, length), dimension);
  2285. break;
  2286.                    case ECPGt_char:
  2287.                    case ECPGt_unsigned_char:
  2288.                         if (dimension == -1)
  2289.                             type = ECPGmake_simple_type($4.type_enum, length);
  2290.                         else
  2291.                             type = ECPGmake_array_type(ECPGmake_simple_type($4.type_enum, length), dimension);
  2292. break;
  2293.    default:
  2294. if (length >= 0)
  2295.                      yyerror("No multi-dimensional array support for simple data types");
  2296.                         if (dimension < 0)
  2297.                             type = ECPGmake_simple_type($4.type_enum, 1);
  2298.                         else
  2299.                             type = ECPGmake_array_type(ECPGmake_simple_type($4.type_enum, 1), dimension);
  2300. break;
  2301. }
  2302. ECPGfree_type(p->type);
  2303. p->type = type;
  2304. $$ = cat5_str(cat3_str(make1_str("/* exec sql var"), mm_strdup($2), make1_str("is")), mm_strdup($4.type_str), mm_strdup($5.str), $6, make1_str("*/"));
  2305. }
  2306. /*
  2307.  * whenever statement: decide what to do in case of error/no data found
  2308.  * according to SQL standards we lack: SQLSTATE, CONSTRAINT and SQLEXCEPTION
  2309.  */
  2310. ECPGWhenever: SQL_WHENEVER SQL_SQLERROR action {
  2311. when_error.code = $<action>3.code;
  2312. when_error.command = $<action>3.command;
  2313. $$ = cat3_str(make1_str("/* exec sql whenever sqlerror "), $3.str, make1_str("; */n"));
  2314. }
  2315. | SQL_WHENEVER NOT SQL_FOUND action {
  2316. when_nf.code = $<action>4.code;
  2317. when_nf.command = $<action>4.command;
  2318. $$ = cat3_str(make1_str("/* exec sql whenever not found "), $4.str, make1_str("; */n"));
  2319. }
  2320. | SQL_WHENEVER SQL_SQLWARNING action {
  2321. when_warn.code = $<action>3.code;
  2322. when_warn.command = $<action>3.command;
  2323. $$ = cat3_str(make1_str("/* exec sql whenever sql_warning "), $3.str, make1_str("; */n"));
  2324. }
  2325. action : SQL_CONTINUE {
  2326. $<action>$.code = W_NOTHING;
  2327. $<action>$.command = NULL;
  2328. $<action>$.str = make1_str("continue");
  2329. }
  2330.        | SQL_SQLPRINT {
  2331. $<action>$.code = W_SQLPRINT;
  2332. $<action>$.command = NULL;
  2333. $<action>$.str = make1_str("sqlprint");
  2334. }
  2335.        | SQL_STOP {
  2336. $<action>$.code = W_STOP;
  2337. $<action>$.command = NULL;
  2338. $<action>$.str = make1_str("stop");
  2339. }
  2340.        | SQL_GOTO name {
  2341.         $<action>$.code = W_GOTO;
  2342.         $<action>$.command = strdup($2);
  2343. $<action>$.str = cat2_str(make1_str("goto "), $2);
  2344. }
  2345.        | SQL_GO TO name {
  2346.         $<action>$.code = W_GOTO;
  2347.         $<action>$.command = strdup($3);
  2348. $<action>$.str = cat2_str(make1_str("goto "), $3);
  2349. }
  2350.        | DO name '(' dotext ')' {
  2351. $<action>$.code = W_DO;
  2352. $<action>$.command = make4_str($2, make1_str("("), $4, make1_str(")"));
  2353. $<action>$.str = cat2_str(make1_str("do"), mm_strdup($<action>$.command));
  2354. }
  2355.        | DO SQL_BREAK {
  2356.         $<action>$.code = W_BREAK;
  2357.         $<action>$.command = NULL;
  2358.         $<action>$.str = make1_str("break");
  2359. }
  2360.        | SQL_CALL name '(' dotext ')' {
  2361. $<action>$.code = W_DO;
  2362. $<action>$.command = make4_str($2, make1_str("("), $4, make1_str(")"));
  2363. $<action>$.str = cat2_str(make1_str("call"), mm_strdup($<action>$.command));
  2364. }
  2365. /* some other stuff for ecpg */
  2366. ecpg_expr:  attr opt_indirection
  2367. {
  2368. $$ = cat2_str($1, $2);
  2369. }
  2370. | row_expr
  2371. { $$ = $1;  }
  2372. | AexprConst
  2373. { $$ = $1;  }
  2374. | ColId
  2375. {
  2376. $$ = $1;
  2377. }
  2378. | '-' ecpg_expr %prec UMINUS
  2379. { $$ = cat2_str(make1_str("-"), $2); }
  2380. | '%' ecpg_expr
  2381. {       $$ = cat2_str(make1_str("%"), $2); }
  2382. | a_expr '%'
  2383. {       $$ = cat2_str($1, make1_str("%")); }
  2384. | a_expr '+' ecpg_expr
  2385. { $$ = cat3_str($1, make1_str("+"), $3); }
  2386. | a_expr '-' ecpg_expr
  2387. { $$ = cat3_str($1, make1_str("-"), $3); }
  2388. | a_expr '/' ecpg_expr
  2389. { $$ = cat3_str($1, make1_str("/"), $3); }
  2390. | a_expr '%' ecpg_expr
  2391. { $$ = cat3_str($1, make1_str("%"), $3); }
  2392. | a_expr '*' ecpg_expr
  2393. { $$ = cat3_str($1, make1_str("*"), $3); }
  2394. | a_expr '<' ecpg_expr
  2395. { $$ = cat3_str($1, make1_str("<"), $3); }
  2396. | a_expr '>' ecpg_expr
  2397. { $$ = cat3_str($1, make1_str(">"), $3); }
  2398. | a_expr '=' NULL_P
  2399. {       $$ = cat2_str($1, make1_str("= NULL")); }
  2400. | NULL_P '=' a_expr
  2401. {       $$ = cat2_str(make1_str("= NULL"), $3); }
  2402. | a_expr '=' ecpg_expr
  2403. { $$ = cat3_str($1, make1_str("="), $3); }
  2404. /* | ':' ecpg_expr
  2405. { $$ = cat2_str(make1_str(":"), $2); }*/
  2406. | ';' ecpg_expr
  2407. { $$ = cat2_str(make1_str(";"), $2); }
  2408. | '|' ecpg_expr
  2409. { $$ = cat2_str(make1_str("|"), $2); }
  2410. | a_expr TYPECAST Typename
  2411. {
  2412. $$ = cat3_str($1, make1_str("::"), $3);
  2413. }
  2414. | CAST '(' a_expr AS Typename ')'
  2415. {
  2416. $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
  2417. }
  2418. | '(' a_expr_or_null ')'
  2419. { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
  2420. | a_expr Op ecpg_expr
  2421. { $$ = cat3_str($1, $2, $3); }
  2422. | a_expr LIKE ecpg_expr
  2423. { $$ = cat3_str($1, make1_str("like"), $3); }
  2424. | a_expr NOT LIKE ecpg_expr
  2425. { $$ = cat3_str($1, make1_str("not like"), $4); }
  2426. | Op ecpg_expr
  2427. { $$ = cat2_str($1, $2); }
  2428. | a_expr Op
  2429. { $$ = cat2_str($1, $2); }
  2430. | func_name '(' '*' ')'
  2431. {
  2432. $$ = cat2_str($1, make1_str("(*)")); 
  2433. }
  2434. | func_name '(' ')'
  2435. {
  2436. $$ = cat2_str($1, make1_str("()")); 
  2437. }
  2438. | func_name '(' expr_list ')'
  2439. {
  2440. $$ = make4_str($1, make1_str("("), $3, make1_str(")")); 
  2441. }
  2442. | CURRENT_DATE
  2443. {
  2444. $$ = make1_str("current_date");
  2445. }
  2446. | CURRENT_TIME
  2447. {
  2448. $$ = make1_str("current_time");
  2449. }
  2450. | CURRENT_TIME '(' Iconst ')'
  2451. {
  2452. if (atol($3) != 0)
  2453. fprintf(stderr,"CURRENT_TIME(%s) precision not implemented; zero used instead", $3);
  2454. $$ = make1_str("current_time");
  2455. }
  2456. | CURRENT_TIMESTAMP
  2457. {
  2458. $$ = make1_str("current_timestamp");
  2459. }
  2460. | CURRENT_TIMESTAMP '(' Iconst ')'
  2461. {
  2462. if (atol($3) != 0)
  2463. fprintf(stderr,"CURRENT_TIMESTAMP(%s) precision not implemented; zero used instead",$3);
  2464. $$ = make1_str("current_timestamp");
  2465. }
  2466. | CURRENT_USER
  2467. {
  2468. $$ = make1_str("current_user");
  2469. }
  2470. | USER
  2471. {
  2472.                  $$ = make1_str("user");
  2473.       }
  2474. | EXISTS '(' SubSelect ')'
  2475. {
  2476. $$ = make3_str(make1_str("exists("), $3, make1_str(")"));
  2477. }
  2478. | EXTRACT '(' extract_list ')'
  2479. {
  2480. $$ = make3_str(make1_str("extract("), $3, make1_str(")"));
  2481. }
  2482. | POSITION '(' position_list ')'
  2483. {
  2484. $$ = make3_str(make1_str("position("), $3, make1_str(")"));
  2485. }
  2486. | SUBSTRING '(' substr_list ')'
  2487. {
  2488. $$ = make3_str(make1_str("substring("), $3, make1_str(")"));
  2489. }
  2490. /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
  2491. | TRIM '(' BOTH trim_list ')'
  2492. {
  2493. $$ = make3_str(make1_str("trim(both"), $4, make1_str(")"));
  2494. }
  2495. | TRIM '(' LEADING trim_list ')'
  2496. {
  2497. $$ = make3_str(make1_str("trim(leading"), $4, make1_str(")"));
  2498. }
  2499. | TRIM '(' TRAILING trim_list ')'
  2500. {
  2501. $$ = make3_str(make1_str("trim(trailing"), $4, make1_str(")"));
  2502. }
  2503. | TRIM '(' trim_list ')'
  2504. {
  2505. $$ = make3_str(make1_str("trim("), $3, make1_str(")"));
  2506. }
  2507. | a_expr ISNULL
  2508. { $$ = cat2_str($1, make1_str("isnull")); }
  2509. | a_expr IS NULL_P
  2510. { $$ = cat2_str($1, make1_str("is null")); }
  2511. | a_expr NOTNULL
  2512. { $$ = cat2_str($1, make1_str("notnull")); }
  2513. | a_expr IS NOT NULL_P
  2514. { $$ = cat2_str($1, make1_str("is not null")); }
  2515. /* IS TRUE, IS FALSE, etc used to be function calls
  2516.  *  but let's make them expressions to allow the optimizer
  2517.  *  a chance to eliminate them if a_expr is a constant string.
  2518.  * - thomas 1997-12-22
  2519.  */
  2520. | a_expr IS TRUE_P
  2521. {
  2522. { $$ = cat2_str($1, make1_str("is true")); }
  2523. }
  2524. | a_expr IS NOT FALSE_P
  2525. {
  2526. { $$ = cat2_str($1, make1_str("is not false")); }
  2527. }
  2528. | a_expr IS FALSE_P
  2529. {
  2530. { $$ = cat2_str($1, make1_str("is false")); }
  2531. }
  2532. | a_expr IS NOT TRUE_P
  2533. {
  2534. { $$ = cat2_str($1, make1_str("is not true")); }
  2535. }
  2536. | a_expr BETWEEN b_expr AND b_expr
  2537. {
  2538. $$ = cat5_str($1, make1_str("between"), $3, make1_str("and"), $5); 
  2539. }
  2540. | a_expr NOT BETWEEN b_expr AND b_expr
  2541. {
  2542. $$ = cat5_str($1, make1_str("not between"), $4, make1_str("and"), $6); 
  2543. }
  2544. | a_expr IN '(' in_expr ')'
  2545. {
  2546. $$ = make4_str($1, make1_str(" in ("), $4, make1_str(")")); 
  2547. }
  2548. | a_expr NOT IN '(' not_in_expr ')'
  2549. {
  2550. $$ = make4_str($1, make1_str(" not in ("), $5, make1_str(")")); 
  2551. }
  2552. | a_expr Op '(' SubSelect ')'
  2553. {
  2554. $$ = cat3_str($1, $2, make3_str(make1_str("("), $4, make1_str(")"))); 
  2555. }
  2556. | a_expr '+' '(' SubSelect ')'
  2557. {
  2558. $$ = make4_str($1, make1_str("+("), $4, make1_str(")")); 
  2559. }
  2560. | a_expr '-' '(' SubSelect ')'
  2561. {
  2562. $$ = make4_str($1, make1_str("-("), $4, make1_str(")")); 
  2563. }
  2564. | a_expr '/' '(' SubSelect ')'
  2565. {
  2566. $$ = make4_str($1, make1_str("/("), $4, make1_str(")")); 
  2567. }
  2568. | a_expr '%' '(' SubSelect ')'
  2569. {
  2570. $$ = make4_str($1, make1_str("%("), $4, make1_str(")")); 
  2571. }
  2572. | a_expr '*' '(' SubSelect ')'
  2573. {
  2574. $$ = make4_str($1, make1_str("*("), $4, make1_str(")")); 
  2575. }
  2576. | a_expr '<' '(' SubSelect ')'
  2577. {
  2578. $$ = make4_str($1, make1_str("<("), $4, make1_str(")")); 
  2579. }
  2580. | a_expr '>' '(' SubSelect ')'
  2581. {
  2582. $$ = make4_str($1, make1_str(">("), $4, make1_str(")")); 
  2583. }
  2584. | a_expr '=' '(' SubSelect ')'
  2585. {
  2586. $$ = make4_str($1, make1_str("=("), $4, make1_str(")")); 
  2587. }
  2588. | a_expr Op ANY '(' SubSelect ')'
  2589. {
  2590. $$ = cat3_str($1, $2, make3_str(make1_str("any ("), $5, make1_str(")"))); 
  2591. }
  2592. | a_expr '+' ANY '(' SubSelect ')'
  2593. {
  2594. $$ = make4_str($1, make1_str("+ any("), $5, make1_str(")")); 
  2595. }
  2596. | a_expr '-' ANY '(' SubSelect ')'
  2597. {
  2598. $$ = make4_str($1, make1_str("- any("), $5, make1_str(")")); 
  2599. }
  2600. | a_expr '/' ANY '(' SubSelect ')'
  2601. {
  2602. $$ = make4_str($1, make1_str("/ any("), $5, make1_str(")")); 
  2603. }
  2604. | a_expr '%' ANY '(' SubSelect ')'
  2605. {
  2606. $$ = make4_str($1, make1_str("% any("), $5, make1_str(")")); 
  2607. }
  2608. | a_expr '*' ANY '(' SubSelect ')'
  2609. {
  2610. $$ = make4_str($1, make1_str("* any("), $5, make1_str(")")); 
  2611. }
  2612. | a_expr '<' ANY '(' SubSelect ')'
  2613. {
  2614. $$ = make4_str($1, make1_str("< any("), $5, make1_str(")")); 
  2615. }
  2616. | a_expr '>' ANY '(' SubSelect ')'
  2617. {
  2618. $$ = make4_str($1, make1_str("> any("), $5, make1_str(")")); 
  2619. }
  2620. | a_expr '=' ANY '(' SubSelect ')'
  2621. {
  2622. $$ = make4_str($1, make1_str("= any("), $5, make1_str(")")); 
  2623. }
  2624. | a_expr Op ALL '(' SubSelect ')'
  2625. {
  2626. $$ = cat3_str($1, $2, make3_str(make1_str("all ("), $5, make1_str(")"))); 
  2627. }
  2628. | a_expr '+' ALL '(' SubSelect ')'
  2629. {
  2630. $$ = make4_str($1, make1_str("+ all("), $5, make1_str(")")); 
  2631. }
  2632. | a_expr '-' ALL '(' SubSelect ')'
  2633. {
  2634. $$ = make4_str($1, make1_str("- all("), $5, make1_str(")")); 
  2635. }
  2636. | a_expr '/' ALL '(' SubSelect ')'
  2637. {
  2638. $$ = make4_str($1, make1_str("/ all("), $5, make1_str(")")); 
  2639. }
  2640. | a_expr '%' ALL '(' SubSelect ')'
  2641. {
  2642. $$ = make4_str($1, make1_str("% all("), $5, make1_str(")")); 
  2643. }
  2644. | a_expr '*' ALL '(' SubSelect ')'
  2645. {
  2646. $$ = make4_str($1, make1_str("* all("), $5, make1_str(")")); 
  2647. }
  2648. | a_expr '<' ALL '(' SubSelect ')'
  2649. {
  2650. $$ = make4_str($1, make1_str("< all("), $5, make1_str(")")); 
  2651. }
  2652. | a_expr '>' ALL '(' SubSelect ')'
  2653. {
  2654. $$ = make4_str($1, make1_str("> all("), $5, make1_str(")")); 
  2655. }
  2656. | a_expr '=' ALL '(' SubSelect ')'
  2657. {
  2658. $$ = make4_str($1, make1_str("=all("), $5, make1_str(")")); 
  2659. }
  2660. | a_expr AND ecpg_expr
  2661. { $$ = cat3_str($1, make1_str("and"), $3); }
  2662. | a_expr OR ecpg_expr
  2663. { $$ = cat3_str($1, make1_str("or"), $3); }
  2664. | NOT ecpg_expr
  2665. { $$ = cat2_str(make1_str("not"), $2); }
  2666. | case_expr
  2667. {       $$ = $1; }
  2668. | civariableonly
  2669.         {  $$ = $1; }
  2670. ;
  2671. into_list : coutputvariable | into_list ',' coutputvariable;
  2672. ecpgstart: SQL_START { reset_variables();}
  2673. dotext: /* empty */ { $$ = make1_str(""); }
  2674. | dotext do_anything { $$ = make2_str($1, $2); }
  2675. vartext: var_anything { $$ = $1; }
  2676.         | vartext var_anything { $$ = make2_str($1, $2); }
  2677. coutputvariable : cvariable indicator {
  2678. add_variable(&argsresult, find_variable($1), ($2 == NULL) ? &no_indicator : find_variable($2)); 
  2679. }
  2680. cinputvariable : cvariable indicator {
  2681. add_variable(&argsinsert, find_variable($1), ($2 == NULL) ? &no_indicator : find_variable($2)); 
  2682. }
  2683. civariableonly : cvariable {
  2684. add_variable(&argsinsert, find_variable($1), &no_indicator); 
  2685. $$ = make1_str("?");
  2686. }
  2687. cvariable: CVARIABLE { $$ = $1; }
  2688. indicator: /* empty */ { $$ = NULL; }
  2689. | cvariable   { check_indicator((find_variable($1))->type); $$ = $1; }
  2690. | SQL_INDICATOR cvariable  { check_indicator((find_variable($2))->type); $$ = $2; }
  2691. | SQL_INDICATOR name { check_indicator((find_variable($2))->type); $$ = $2; }
  2692. ident: IDENT { $$ = $1; }
  2693. | CSTRING { $$ = $1; }
  2694. /*
  2695.  * C stuff
  2696.  */
  2697. symbol: IDENT { $$ = $1; }
  2698. cpp_line: CPP_LINE { $$ = $1; }
  2699. c_line: c_anything { $$ = $1; }
  2700. | c_line c_anything
  2701. {
  2702. $$ = make2_str($1, $2);
  2703. }
  2704. c_thing: c_anything | ';' { $$ = make1_str(";"); }
  2705. c_anything:  IDENT  { $$ = $1; }
  2706. | CSTRING { $$ = make3_str(make1_str("""), $1, make1_str(""")); }
  2707. | Iconst { $$ = $1; }
  2708. | Fconst { $$ = $1; }
  2709. | '*' { $$ = make1_str("*"); }
  2710. | '+' { $$ = make1_str("+"); }
  2711. | '-' { $$ = make1_str("-"); }
  2712. | '/' { $$ = make1_str("/"); }
  2713. | '%' { $$ = make1_str("%"); }
  2714. | S_AUTO { $$ = make1_str("auto"); }
  2715. | S_BOOL { $$ = make1_str("bool"); }
  2716. | S_CHAR { $$ = make1_str("char"); }
  2717. | S_CONST { $$ = make1_str("const"); }
  2718. | S_DOUBLE { $$ = make1_str("double"); }
  2719. | S_ENUM { $$ = make1_str("enum"); }
  2720. | S_EXTERN { $$ = make1_str("extern"); }
  2721. | S_FLOAT { $$ = make1_str("float"); }
  2722.         | S_INT { $$ = make1_str("int"); }
  2723. | S_LONG { $$ = make1_str("long"); }
  2724. | S_REGISTER { $$ = make1_str("register"); }
  2725. | S_SHORT { $$ = make1_str("short"); }
  2726. | S_SIGNED { $$ = make1_str("signed"); }
  2727. | S_STATIC { $$ = make1_str("static"); }
  2728.         | S_STRUCT { $$ = make1_str("struct"); }
  2729.         | S_UNION { $$ = make1_str("union"); }
  2730. | S_UNSIGNED { $$ = make1_str("unsigned"); }
  2731. | S_VARCHAR { $$ = make1_str("varchar"); }
  2732. | S_ANYTHING { $$ = make_name(); }
  2733.         | '[' { $$ = make1_str("["); }
  2734. | ']' { $$ = make1_str("]"); }
  2735. | '(' { $$ = make1_str("("); }
  2736. | ')' { $$ = make1_str(")"); }
  2737. | '=' { $$ = make1_str("="); }
  2738. | ',' { $$ = make1_str(","); }
  2739. do_anything: IDENT { $$ = $1; }
  2740.         | CSTRING       { $$ = make3_str(make1_str("""), $1, make1_str("""));}
  2741.         | Iconst        { $$ = $1; }
  2742. | Fconst { $$ = $1; }
  2743. | ',' { $$ = make1_str(","); }
  2744. var_anything: IDENT  { $$ = $1; }
  2745. | CSTRING        { $$ = make3_str(make1_str("""), $1, make1_str(""")); }
  2746. | Iconst { $$ = $1; }
  2747. | Fconst { $$ = $1; }
  2748. | '{' c_line '}' { $$ = make3_str(make1_str("{"), $2, make1_str("}")); }
  2749. blockstart : '{' {
  2750.     braces_open++;
  2751.     $$ = make1_str("{");
  2752. }
  2753. blockend : '}' {
  2754.     remove_variables(braces_open--);
  2755.     $$ = make1_str("}");
  2756. }
  2757. %%
  2758. void yyerror(char * error)
  2759. {
  2760.     fprintf(stderr, "%s:%d: %sn", input_filename, yylineno, error);
  2761.     exit(PARSE_ERROR);
  2762. }