sqlp.y 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /*****************************************************************************
  2. *
  3. * MODULE: SQL statement parser library
  4. *
  5. * AUTHOR(S): lex.l and yac.y were originally taken from unixODBC and
  6. * probably written by Peter Harvey <pharvey@codebydesigns.com>,
  7. * modifications and other code by Radim Blazek
  8. *
  9. * PURPOSE: Parse input string containing SQL statement to
  10. * SQLPSTMT structure.
  11. * SQL parser may be used by simple database drivers.
  12. *
  13. * COPYRIGHT: (C) 2000 by the GRASS Development Team
  14. *
  15. * This program is free software under the GNU General Public
  16. * License (>=v2). Read the file COPYING that comes with GRASS
  17. * for details.
  18. *
  19. *****************************************************************************/
  20. %{
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <math.h>
  24. #include <grass/sqlp.h>
  25. #define YYDEBUG 1
  26. #define YYERROR_VERBOSE 1
  27. %}
  28. /* symbolic tokens */
  29. %union {
  30. int intval;
  31. double floatval;
  32. char *strval;
  33. int subtok;
  34. SQLPNODE *node;
  35. }
  36. /* operators */
  37. %type <node> y_column
  38. %type <node> y_value
  39. %type <node> y_atom
  40. %type <node> y_term
  41. %type <node> y_product
  42. %type <node> y_expression
  43. %type <node> y_comparison
  44. %type <node> y_boolean
  45. %type <node> y_sub_condition2
  46. %type <node> y_sub_condition
  47. %type <node> y_condition
  48. /* literal keyword tokens */
  49. %token <strval> COMPARISON_OPERATOR
  50. %token <strval> NAME
  51. %token <strval> STRING
  52. %token <intval> INTNUM
  53. %token <floatval> FLOATNUM
  54. %token ADD
  55. %token DROP
  56. %token COLUMN
  57. %token EQUAL
  58. %token SELECT FROM WHERE
  59. %token DELETE
  60. %token INSERT INTO VALUES
  61. %token UPDATE SET
  62. %token AND
  63. %token OR
  64. %token NOT
  65. %token ALTER TABLE
  66. %token CREATE
  67. %token NULL_VALUE
  68. %token VARCHAR
  69. %token INT
  70. %token INTEGER
  71. %token DOUBLE
  72. %token PRECISION
  73. %token DATE
  74. %token TIME
  75. %token ORDER BY
  76. %token IS
  77. %token ASC
  78. %token DESC
  79. %{
  80. extern int yylex(void);
  81. %}
  82. %%
  83. y_sql:
  84. y_alter
  85. | y_create
  86. | y_drop
  87. | y_insert
  88. | y_select
  89. | y_update
  90. | y_delete
  91. | y_sql ';'
  92. ;
  93. y_alter:
  94. ALTER TABLE y_table ADD COLUMN y_columndef { sqpCommand(SQLP_ADD_COLUMN); }
  95. | ALTER TABLE y_table ADD y_columndef { sqpCommand(SQLP_ADD_COLUMN); }
  96. | ALTER TABLE y_table DROP COLUMN NAME { sqpCommand(SQLP_DROP_COLUMN); sqpColumn($6);}
  97. ;
  98. y_create:
  99. CREATE TABLE y_table '(' y_columndefs ')' { sqpCommand(SQLP_CREATE); }
  100. ;
  101. y_drop:
  102. DROP TABLE y_table { sqpCommand(SQLP_DROP); }
  103. ;
  104. y_select:
  105. SELECT y_columns FROM y_table { sqpCommand(SQLP_SELECT); }
  106. | SELECT y_columns FROM y_table WHERE y_condition { sqpCommand(SQLP_SELECT); }
  107. | SELECT y_columns FROM y_table ORDER BY y_order { sqpCommand(SQLP_SELECT); }
  108. | SELECT y_columns FROM y_table WHERE y_condition ORDER BY y_order { sqpCommand(SQLP_SELECT); }
  109. ;
  110. y_delete:
  111. DELETE FROM y_table { sqpCommand(SQLP_DELETE); }
  112. | DELETE FROM y_table WHERE y_condition { sqpCommand(SQLP_DELETE); }
  113. ;
  114. y_insert:
  115. INSERT INTO y_table y_values { sqpCommand(SQLP_INSERT); }
  116. | INSERT INTO y_table '(' y_columns ')' y_values { sqpCommand(SQLP_INSERT); }
  117. ;
  118. y_update:
  119. UPDATE y_table SET y_assignments { sqpCommand(SQLP_UPDATE); }
  120. | UPDATE y_table SET y_assignments WHERE y_condition { sqpCommand(SQLP_UPDATE); }
  121. ;
  122. y_columndefs:
  123. y_columndef
  124. | y_columndefs ',' y_columndef
  125. ;
  126. y_columndef:
  127. NAME VARCHAR '(' INTNUM ')' { sqpColumnDef( $1, SQLP_VARCHAR, $4, 0 ); }
  128. | NAME INT { sqpColumnDef( $1, SQLP_INTEGER, 0, 0 ); }
  129. | NAME INTEGER { sqpColumnDef( $1, SQLP_INTEGER, 0, 0 ); }
  130. | NAME DOUBLE { sqpColumnDef( $1, SQLP_DOUBLE, 0, 0 ); }
  131. | NAME DOUBLE PRECISION { sqpColumnDef( $1, SQLP_DOUBLE, 0, 0 ); }
  132. | NAME DATE { sqpColumnDef( $1, SQLP_DATE, 0, 0 ); }
  133. | NAME TIME { sqpColumnDef( $1, SQLP_TIME, 0, 0 ); }
  134. ;
  135. y_columns:
  136. '*'
  137. | y_column_list
  138. ;
  139. y_column_list:
  140. NAME { sqpColumn( $1 ); }
  141. | y_column_list ',' NAME { sqpColumn( $3 ); }
  142. ;
  143. y_table:
  144. NAME { sqpTable( $1 ); }
  145. ;
  146. y_values:
  147. VALUES '(' y_value_list ')'
  148. ;
  149. y_value_list:
  150. NULL_VALUE { sqpValue( NULL, 0, 0.0, SQLP_NULL ); }
  151. | STRING { sqpValue( $1, 0, 0.0, SQLP_S ); }
  152. | INTNUM { sqpValue( NULL, $1, 0.0, SQLP_I ); }
  153. | '-' INTNUM { sqpValue( NULL, -$2, 0.0, SQLP_I ); }
  154. | FLOATNUM { sqpValue( NULL, 0, $1, SQLP_D ); }
  155. | '-' FLOATNUM { sqpValue( NULL, 0, -$2, SQLP_D ); }
  156. | y_value_list ',' NULL_VALUE { sqpValue( NULL, 0, 0.0, SQLP_NULL ); }
  157. | y_value_list ',' STRING { sqpValue( $3, 0, 0.0, SQLP_S ); }
  158. | y_value_list ',' INTNUM { sqpValue( NULL, $3, 0.0, SQLP_I ); }
  159. | y_value_list ',' '-' INTNUM { sqpValue( NULL, -$4, 0.0, SQLP_I ); }
  160. | y_value_list ',' FLOATNUM { sqpValue( NULL, 0, $3, SQLP_D ); }
  161. | y_value_list ',' '-' FLOATNUM { sqpValue( NULL, 0, -$4, SQLP_D ); }
  162. ;
  163. y_assignments:
  164. y_assignment
  165. | y_assignments ',' y_assignment
  166. ;
  167. y_assignment:
  168. NAME EQUAL NULL_VALUE { sqpAssignment( $1, NULL, 0, 0.0, NULL, SQLP_NULL ); }
  169. /* | NAME EQUAL STRING { sqpAssignment( $1, $3, 0, 0.0, NULL, SQLP_S ); }
  170. | NAME EQUAL INTNUM { sqpAssignment( $1, NULL, $3, 0.0, NULL, SQLP_I ); }
  171. | NAME EQUAL FLOATNUM { sqpAssignment( $1, NULL, 0, $3, NULL, SQLP_D ); }
  172. */ | NAME EQUAL y_expression { sqpAssignment( $1, NULL, 0, 0.0, $3, SQLP_EXPR ); }
  173. ;
  174. y_condition:
  175. y_sub_condition {
  176. $$ = $1;
  177. sqlpStmt->upperNodeptr = $$;
  178. }
  179. ;
  180. y_sub_condition:
  181. y_sub_condition2 { $$ = $1; }
  182. | y_sub_condition OR y_sub_condition2 { $$ = sqpNewExpressionNode (SQLP_OR, $1, $3); }
  183. ;
  184. y_sub_condition2:
  185. y_boolean { $$ = $1; }
  186. | y_sub_condition2 AND y_boolean { $$ = sqpNewExpressionNode (SQLP_AND, $1, $3); }
  187. ;
  188. y_boolean:
  189. y_comparison { $$ = $1; }
  190. | '(' y_sub_condition ')' { $$ = $2; }
  191. | NOT y_boolean { $$ = sqpNewExpressionNode ( SQLP_NOT, NULL, $2); }
  192. ;
  193. /* Note EQUAL should be one of COMPARISON but there is maybe some reason ... */
  194. y_comparison:
  195. y_expression EQUAL y_expression {
  196. $$ = sqpNewExpressionNode ( SQLP_EQ, $1, $3);
  197. }
  198. | y_expression COMPARISON_OPERATOR y_expression {
  199. $$ = sqpNewExpressionNode ( sqpOperatorCode($2), $1, $3);
  200. }
  201. | y_expression IS NULL_VALUE {
  202. $$ = sqpNewExpressionNode ( SQLP_ISNULL, NULL, $1);
  203. }
  204. | y_expression NOT NULL_VALUE {
  205. $$ = sqpNewExpressionNode ( SQLP_NOTNULL, NULL, $1);
  206. }
  207. ;
  208. /* Mathematical expression */
  209. y_expression:
  210. y_product { $$ = $1; }
  211. | y_expression '+' y_product {
  212. $$ = sqpNewExpressionNode ( sqpOperatorCode("+"), $1, $3 );
  213. }
  214. | y_expression '-' y_product {
  215. $$ = sqpNewExpressionNode ( sqpOperatorCode("-"), $1, $3 );
  216. }
  217. ;
  218. y_product:
  219. y_term { $$ = $1; }
  220. | y_product '*' y_term {
  221. $$ = sqpNewExpressionNode ( sqpOperatorCode("*"), $1, $3 );
  222. }
  223. | y_product '/' y_term {
  224. $$ = sqpNewExpressionNode ( sqpOperatorCode("/"), $1, $3 );
  225. }
  226. ;
  227. y_term:
  228. y_atom { $$ = $1; }
  229. | '-' y_term {
  230. $$ = sqpNewExpressionNode ( sqpOperatorCode("-"), sqpNewValueNode ( NULL, 0, 0.0, SQLP_I ), $2 );
  231. }
  232. ;
  233. y_atom:
  234. y_value { $$ = $1; }
  235. | y_column { $$ = $1; }
  236. | '(' y_expression ')' { $$ = $2; }
  237. ;
  238. /* Value used in expressions */
  239. y_value:
  240. STRING { $$ = sqpNewValueNode ( $1, 0, 0.0, SQLP_S ); }
  241. | INTNUM { $$ = sqpNewValueNode ( NULL, $1, 0.0, SQLP_I ); }
  242. | FLOATNUM { $$ = sqpNewValueNode ( NULL, 0, $1, SQLP_D ); }
  243. ;
  244. /* Column used in expressions */
  245. y_column:
  246. NAME {$$ = sqpNewColumnNode ( $1 );}
  247. ;
  248. y_order: y_order_asc | y_order_desc;
  249. y_order_asc:
  250. NAME { sqpOrderColumn( $1, SORT_ASC ); }
  251. | NAME ASC { sqpOrderColumn( $1, SORT_ASC ); }
  252. ;
  253. y_order_desc:
  254. NAME DESC { sqpOrderColumn( $1, SORT_DESC ); }
  255. ;
  256. %%