sql-parser-tl 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/sql-parser/parser.racc +369 -0
- data/lib/sql-parser/parser.racc.rb +1777 -0
- data/lib/sql-parser/parser.rex +113 -0
- data/lib/sql-parser/parser.rex.rb +324 -0
- data/lib/sql-parser/sql_visitor.rb +383 -0
- data/lib/sql-parser/statement.rb +556 -0
- data/lib/sql-parser/version.rb +5 -0
- data/lib/sql-parser.rb +13 -0
- metadata +119 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 538346a6ead5e964823de08bbb90338566ba2a8ef9e6d15039f9b0f138ea5f99
|
4
|
+
data.tar.gz: e3735029f0489e0c11483e2ec4418c7a7372e40b0815698085cc262c538e7945
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2bd9d4bcd605bc659623a865694201a0e55f97856221e44581517b002b11c2552cfa9ea1af6b15aa5a6aa9c8ab61745861bd80beb76fbc8d8214dc29c99e765a
|
7
|
+
data.tar.gz: 78782ebcec7162b855d88a51ea7b848936aa9f619f88dc54314b53dba120d128f4d54252a20ae9fb7346c9d3d7f4a94c3a1183691d403f2fa63346c1e74800b0
|
@@ -0,0 +1,369 @@
|
|
1
|
+
class SQLParser::Parser
|
2
|
+
|
3
|
+
rule
|
4
|
+
# dynamic sql
|
5
|
+
|
6
|
+
direct_sql_statement
|
7
|
+
: direct_sql_data_statement
|
8
|
+
|
9
|
+
direct_sql_data_statement
|
10
|
+
: direct_select_statement_multiple_rows
|
11
|
+
| insert_specification
|
12
|
+
|
13
|
+
direct_select_statement_multiple_rows
|
14
|
+
: query_expression order_by_clause limit_clause { result = SQLParser::Statement::DirectSelect.new(val[0], val[1], val[2]) }
|
15
|
+
|
16
|
+
# module contents
|
17
|
+
limit_clause
|
18
|
+
: # no action
|
19
|
+
| LIMIT unsigned_integer OFFSET unsigned_integer { result = SQLParser::Statement::LimitClause.new(val[1], val[3]) }
|
20
|
+
| LIMIT unsigned_integer comma unsigned_integer { result = SQLParser::Statement::LimitClause.new(val[3], val[1]) }
|
21
|
+
| LIMIT unsigned_integer { result = SQLParser::Statement::LimitClause.new(val[1], 0) }
|
22
|
+
|
23
|
+
order_by_clause
|
24
|
+
: # no action
|
25
|
+
| ORDER BY sort_specification_list { result = SQLParser::Statement::OrderBy.new(val[2]) }
|
26
|
+
|
27
|
+
sort_specification_list
|
28
|
+
: sort_specification_list comma sort_specification { result = Array(val[0]) + Array(val[2]) }
|
29
|
+
| sort_specification
|
30
|
+
|
31
|
+
sort_specification
|
32
|
+
: sort_key ordering_specification { result = val[1].new(val[0]) }
|
33
|
+
|
34
|
+
sort_key
|
35
|
+
: column_reference
|
36
|
+
| unsigned_integer { result = SQLParser::Statement::Integer.new(val[0]) }
|
37
|
+
|
38
|
+
ordering_specification
|
39
|
+
: { result = SQLParser::Statement::Ascending } # default
|
40
|
+
| ASC { result = SQLParser::Statement::Ascending }
|
41
|
+
| DESC { result = SQLParser::Statement::Descending }
|
42
|
+
|
43
|
+
# queries
|
44
|
+
subquery
|
45
|
+
# FIXME: shortcut
|
46
|
+
: left_paren query_expression right_paren { result = SQLParser::Statement::Subquery.new(val[1]) }
|
47
|
+
|
48
|
+
query_expression
|
49
|
+
: query_specification
|
50
|
+
|
51
|
+
insert_specification
|
52
|
+
: INSERT INTO table_reference value_list { result = SQLParser::Statement::Insert.new(val[2], nil, val[3]) }
|
53
|
+
| INSERT INTO table_reference column_list value_list { result = SQLParser::Statement::Insert.new(val[2], val[3], val[4]) }
|
54
|
+
|
55
|
+
column_list
|
56
|
+
: left_paren in_column_list right_paren { result = SQLParser::Statement::InColumnList.new(val[1]) }
|
57
|
+
|
58
|
+
in_column_list
|
59
|
+
: value_expression comma in_column_list { result = Array(val[0]) + Array(val[2]) }
|
60
|
+
| value_expression
|
61
|
+
|
62
|
+
value_list
|
63
|
+
: VALUES left_paren in_value_list right_paren { result = SQLParser::Statement::InValueList.new(val[2]) }
|
64
|
+
|
65
|
+
query_specification
|
66
|
+
: SELECT select_list table_expression { result = SQLParser::Statement::Select.new(val[1], val[2]) }
|
67
|
+
| SELECT select_list { result = SQLParser::Statement::Select.new(val[1]) }
|
68
|
+
|
69
|
+
select_list
|
70
|
+
: asterisk { result = SQLParser::Statement::All.new }
|
71
|
+
| select_sublist { result = SQLParser::Statement::SelectList.new(val[0]) }
|
72
|
+
|
73
|
+
select_sublist
|
74
|
+
: derived_column comma select_sublist { result = Array(val[0]) + Array(val[2]) }
|
75
|
+
| derived_column
|
76
|
+
|
77
|
+
derived_column
|
78
|
+
: value_expression AS column_name { result = SQLParser::Statement::As.new(val[0], val[2]) }
|
79
|
+
| value_expression column_name { result = SQLParser::Statement::As.new(val[0], val[1]) }
|
80
|
+
| value_expression
|
81
|
+
|
82
|
+
table_expression
|
83
|
+
: from_clause where_clause group_by_clause having_clause { result = SQLParser::Statement::TableExpression.new(val[0], val[1], val[2], val[3]) }
|
84
|
+
|
85
|
+
from_clause
|
86
|
+
: FROM table_reference { result = SQLParser::Statement::FromClause.new(val[1]) }
|
87
|
+
|
88
|
+
table_reference
|
89
|
+
: table_name AS column_name { result = SQLParser::Statement::As.new(val[0], val[2]) }
|
90
|
+
| table_name column_name { result = SQLParser::Statement::As.new(val[0], val[1]) }
|
91
|
+
| table_name
|
92
|
+
| joined_table
|
93
|
+
| left_paren table_reference right_paren { result = val[1] }
|
94
|
+
| table_reference hint_type INDEX left_paren identifier right_paren { result = val[1].new(val[0], val[4]) }
|
95
|
+
|
96
|
+
table_subquery
|
97
|
+
: subquery
|
98
|
+
|
99
|
+
joined_table
|
100
|
+
: cross_join
|
101
|
+
| qualified_join
|
102
|
+
|
103
|
+
cross_join
|
104
|
+
: table_reference comma table_reference { result = SQLParser::Statement::CrossJoin.new(val[0], val[2]) }
|
105
|
+
| table_reference CROSS JOIN table_reference { result = SQLParser::Statement::CrossJoin.new(val[0], val[3]) }
|
106
|
+
|
107
|
+
qualified_join
|
108
|
+
: table_reference join_type JOIN table_reference join_specification { result = val[1].new(val[0], val[3], val[4]) }
|
109
|
+
|
110
|
+
join_type
|
111
|
+
: INNER { result = SQLParser::Statement::InnerJoin }
|
112
|
+
| LEFT OUTER { result = SQLParser::Statement::LeftOuterJoin }
|
113
|
+
| LEFT { result = SQLParser::Statement::LeftJoin }
|
114
|
+
| RIGHT OUTER { result = SQLParser::Statement::RightOuterJoin }
|
115
|
+
| RIGHT { result = SQLParser::Statement::RightJoin }
|
116
|
+
| FULL { result = SQLParser::Statement::FullJoin }
|
117
|
+
| FULL OUTER { result = SQLParser::Statement::FullOuterJoin }
|
118
|
+
|
119
|
+
join_specification
|
120
|
+
: join_condition
|
121
|
+
| named_columns_join
|
122
|
+
|
123
|
+
join_condition
|
124
|
+
: ON search_condition { result = SQLParser::Statement::On.new(val[1]) }
|
125
|
+
|
126
|
+
named_columns_join
|
127
|
+
: USING left_paren join_column_list right_paren { result = SQLParser::Statement::Using.new(val[2]) }
|
128
|
+
|
129
|
+
join_column_list
|
130
|
+
: column_name_list
|
131
|
+
|
132
|
+
hint_type
|
133
|
+
: FORCE { result = SQLParser::Statement::ForceIndex }
|
134
|
+
| USE { result = SQLParser::Statement::UseIndex }
|
135
|
+
| IGNORE { result = SQLParser::Statement::IgnoreIndex }
|
136
|
+
|
137
|
+
where_clause
|
138
|
+
: # no action
|
139
|
+
| WHERE search_condition { result = SQLParser::Statement::WhereClause.new(val[1]) }
|
140
|
+
|
141
|
+
group_by_clause
|
142
|
+
: # no action
|
143
|
+
| GROUP BY grouping_column_reference_list { result = SQLParser::Statement::GroupByClause.new(val[2]) }
|
144
|
+
|
145
|
+
grouping_column_reference_list
|
146
|
+
: grouping_column_reference_list comma grouping_column_reference { result = Array(val[0]) + Array(val[2]) }
|
147
|
+
| grouping_column_reference
|
148
|
+
|
149
|
+
grouping_column_reference
|
150
|
+
: column_reference
|
151
|
+
|
152
|
+
having_clause
|
153
|
+
: # no action
|
154
|
+
| HAVING search_condition { result = SQLParser::Statement::HavingClause.new(val[1]) }
|
155
|
+
|
156
|
+
# query expression components
|
157
|
+
row_subquery
|
158
|
+
: subquery
|
159
|
+
|
160
|
+
between_predicate
|
161
|
+
: row_value_constructor NOT BETWEEN row_value_constructor AND row_value_constructor {
|
162
|
+
result = SQLParser::Statement::Not.new(SQLParser::Statement::Between.new(val[0], SQLParser::Statement::BetweenRange.new(val[3], val[5])))
|
163
|
+
}
|
164
|
+
| row_value_constructor BETWEEN row_value_constructor AND row_value_constructor {
|
165
|
+
result = SQLParser::Statement::Between.new(val[0], SQLParser::Statement::BetweenRange.new(val[2], val[4]))
|
166
|
+
}
|
167
|
+
|
168
|
+
in_predicate
|
169
|
+
: row_value_constructor NOT IN in_predicate_value { result = SQLParser::Statement::Not.new(SQLParser::Statement::In.new(val[0], val[3])) }
|
170
|
+
| row_value_constructor IN in_predicate_value { result = SQLParser::Statement::In.new(val[0], val[2]) }
|
171
|
+
|
172
|
+
in_predicate_value
|
173
|
+
: table_subquery
|
174
|
+
| left_paren in_value_list right_paren { result = SQLParser::Statement::InValueList.new(val[1]) }
|
175
|
+
|
176
|
+
in_value_list
|
177
|
+
: value_expression comma in_value_list { result = Array(val[0]) + Array(val[2]) }
|
178
|
+
| value_expression
|
179
|
+
|
180
|
+
like_predicate
|
181
|
+
# FIXME: the SQL-92 grammar indicates these should be
|
182
|
+
# character_value_expression nodes, but changing them causes reduce/reduce
|
183
|
+
# conflicts.
|
184
|
+
: row_value_constructor NOT LIKE row_value_constructor { result = SQLParser::Statement::Not.new(SQLParser::Statement::Like.new(val[0], val[3])) }
|
185
|
+
| row_value_constructor LIKE row_value_constructor { result = SQLParser::Statement::Like.new(val[0], val[2]) }
|
186
|
+
|
187
|
+
null_predicate
|
188
|
+
: row_value_constructor IS NOT NULL { result = SQLParser::Statement::Not.new(SQLParser::Statement::Is.new(val[0], SQLParser::Statement::Null.new)) }
|
189
|
+
| row_value_constructor IS NULL { result = SQLParser::Statement::Is.new(val[0], SQLParser::Statement::Null.new) }
|
190
|
+
|
191
|
+
exists_predicate
|
192
|
+
: EXISTS table_subquery { result = SQLParser::Statement::Exists.new(val[1]) }
|
193
|
+
|
194
|
+
# constraints
|
195
|
+
table_name
|
196
|
+
: identifier { result = SQLParser::Statement::Table.new(val[0]) }
|
197
|
+
|
198
|
+
column_name_list
|
199
|
+
: column_name_list comma column_name { result = Array(val[0]) + Array(val[2]) }
|
200
|
+
| column_name
|
201
|
+
|
202
|
+
# search condition
|
203
|
+
search_condition
|
204
|
+
: boolean_term
|
205
|
+
| search_condition OR boolean_term { result = SQLParser::Statement::Or.new(val[0], val[2]) }
|
206
|
+
|
207
|
+
boolean_term
|
208
|
+
: boolean_factor
|
209
|
+
| boolean_term AND boolean_factor { result = SQLParser::Statement::And.new(val[0], val[2]) }
|
210
|
+
|
211
|
+
boolean_factor:
|
212
|
+
: NOT boolean_test { result = SQLParser::Statement::Not.new(val[1]) }
|
213
|
+
| boolean_test
|
214
|
+
|
215
|
+
boolean_test
|
216
|
+
: boolean_primary
|
217
|
+
|
218
|
+
boolean_primary
|
219
|
+
: predicate
|
220
|
+
| left_paren search_condition right_paren { result = val[1] }
|
221
|
+
|
222
|
+
predicate
|
223
|
+
: comparison_predicate
|
224
|
+
| between_predicate
|
225
|
+
| in_predicate
|
226
|
+
| like_predicate
|
227
|
+
| null_predicate
|
228
|
+
| exists_predicate
|
229
|
+
|
230
|
+
comparison_predicate
|
231
|
+
: row_value_constructor equals_operator row_value_constructor { result = SQLParser::Statement::Equals.new(val[0], val[2]) }
|
232
|
+
| row_value_constructor not_equals_operator row_value_constructor { result = SQLParser::Statement::Not.new(SQLParser::Statement::Equals.new(val[0], val[2])) }
|
233
|
+
| row_value_constructor less_than_operator row_value_constructor { result = SQLParser::Statement::Less.new(val[0], val[2]) }
|
234
|
+
| row_value_constructor greater_than_operator row_value_constructor { result = SQLParser::Statement::Greater.new(val[0], val[2]) }
|
235
|
+
| row_value_constructor less_than_or_equals_operator row_value_constructor { result = SQLParser::Statement::LessOrEquals.new(val[0], val[2]) }
|
236
|
+
| row_value_constructor greater_than_or_equals_operator row_value_constructor { result = SQLParser::Statement::GreaterOrEquals.new(val[0], val[2]) }
|
237
|
+
|
238
|
+
row_value_constructor
|
239
|
+
: row_value_constructor_element
|
240
|
+
| row_subquery
|
241
|
+
|
242
|
+
row_value_constructor_element
|
243
|
+
: value_expression
|
244
|
+
|
245
|
+
aggregate_parameter
|
246
|
+
: value_expression
|
247
|
+
| column_reference
|
248
|
+
| distinct_column_reference
|
249
|
+
|
250
|
+
value_expression
|
251
|
+
: numeric_value_expression
|
252
|
+
| general_literal
|
253
|
+
|
254
|
+
numeric_value_expression
|
255
|
+
: term plus_sign numeric_value_expression { result = SQLParser::Statement::Add.new(val[0], val[2]) }
|
256
|
+
| term minus_sign numeric_value_expression { result = SQLParser::Statement::Subtract.new(val[0], val[2]) }
|
257
|
+
| term
|
258
|
+
|
259
|
+
term
|
260
|
+
: factor asterisk term { result = SQLParser::Statement::Multiply.new(val[0], val[2]) }
|
261
|
+
| factor solidus term { result = SQLParser::Statement::Divide.new(val[0], val[2]) }
|
262
|
+
| factor
|
263
|
+
|
264
|
+
factor
|
265
|
+
: sign value_expression_primary { result = val[0].new(val[1]) }
|
266
|
+
| value_expression_primary
|
267
|
+
|
268
|
+
value_expression_primary
|
269
|
+
: unsigned_value_specification
|
270
|
+
| column_reference
|
271
|
+
| set_function_specification
|
272
|
+
| left_paren value_expression right_paren { result = val[1] }
|
273
|
+
| distinct_column_reference
|
274
|
+
|
275
|
+
unsigned_value_specification
|
276
|
+
: unsigned_literal
|
277
|
+
| general_value_specification
|
278
|
+
|
279
|
+
unsigned_literal
|
280
|
+
: unsigned_numeric_literal
|
281
|
+
| general_literal
|
282
|
+
|
283
|
+
general_value_specification
|
284
|
+
: current_user
|
285
|
+
|
286
|
+
current_user
|
287
|
+
: CURRENT_USER { result = SQLParser::Statement::CurrentUser.new }
|
288
|
+
| CURRENT_USER left_paren right_paren { result = SQLParser::Statement::CurrentUser.new }
|
289
|
+
|
290
|
+
distinct_column_reference
|
291
|
+
: DISTINCT left_paren column_reference right_paren { result = SQLParser::Statement::Distinct.new(val[2]) }
|
292
|
+
| DISTINCT column_reference { result = SQLParser::Statement::Distinct.new(val[1]) }
|
293
|
+
|
294
|
+
column_reference
|
295
|
+
: qualifier period column_name { result = SQLParser::Statement::QualifiedColumn.new(val[0], val[2]) }
|
296
|
+
| column_name
|
297
|
+
|
298
|
+
qualifier
|
299
|
+
: table_name
|
300
|
+
|
301
|
+
set_function_specification
|
302
|
+
: COUNT left_paren asterisk right_paren { result = SQLParser::Statement::Count.new(SQLParser::Statement::All.new) }
|
303
|
+
| general_set_function
|
304
|
+
|
305
|
+
general_set_function
|
306
|
+
: COUNT left_paren aggregate_parameter right_paren { result = SQLParser::Statement::Count.new(val[2]) }
|
307
|
+
| AVG left_paren aggregate_parameter right_paren { result = SQLParser::Statement::Average.new(val[2]) }
|
308
|
+
| MAX left_paren aggregate_parameter right_paren { result = SQLParser::Statement::Maximum.new(val[2]) }
|
309
|
+
| MIN left_paren aggregate_parameter right_paren { result = SQLParser::Statement::Minimum.new(val[2]) }
|
310
|
+
| SUM left_paren aggregate_parameter right_paren { result = SQLParser::Statement::Sum.new(val[2]) }
|
311
|
+
|
312
|
+
# literal numbers, strings, dates and times
|
313
|
+
unsigned_numeric_literal
|
314
|
+
: exact_numeric_literal
|
315
|
+
| approximate_numeric_literal
|
316
|
+
|
317
|
+
exact_numeric_literal
|
318
|
+
: unsigned_integer period unsigned_integer { result = SQLParser::Statement::Float.new("#{val[0]}.#{val[2]}".to_f) }
|
319
|
+
| unsigned_integer period { result = SQLParser::Statement::Float.new(val[0]) }
|
320
|
+
| period unsigned_integer { result = SQLParser::Statement::Float.new("0.#{val[1]}".to_f) }
|
321
|
+
| unsigned_integer { result = SQLParser::Statement::Integer.new(val[0]) }
|
322
|
+
|
323
|
+
approximate_numeric_literal
|
324
|
+
: mantissa E exponent { result = SQLParser::Statement::ApproximateFloat.new(val[0], val[2]) }
|
325
|
+
|
326
|
+
mantissa
|
327
|
+
: exact_numeric_literal
|
328
|
+
|
329
|
+
exponent
|
330
|
+
: signed_integer
|
331
|
+
|
332
|
+
signed_integer
|
333
|
+
: sign unsigned_integer { result = val[0].new(SQLParser::Statement::Integer.new(val[1])) }
|
334
|
+
| unsigned_integer { result = SQLParser::Statement::Integer.new(val[0]) }
|
335
|
+
|
336
|
+
sign
|
337
|
+
: plus_sign { result = SQLParser::Statement::UnaryPlus }
|
338
|
+
| minus_sign { result = SQLParser::Statement::UnaryMinus }
|
339
|
+
|
340
|
+
# sql module
|
341
|
+
column_name
|
342
|
+
: identifier { result = SQLParser::Statement::Column.new(val[0]) }
|
343
|
+
|
344
|
+
# literals
|
345
|
+
general_literal
|
346
|
+
: string_literal
|
347
|
+
| datetime_literal
|
348
|
+
|
349
|
+
string_literal
|
350
|
+
: single_quote character_string_literal single_quote { result = SQLParser::Statement::String.new(val[1].gsub("\\'", "'")) }
|
351
|
+
| single_quote single_quote { result = SQLParser::Statement::String.new('') }
|
352
|
+
| double_quote character_string_literal double_quote { result = SQLParser::Statement::String.new(val[1].gsub('\\"', '"')) }
|
353
|
+
| double_quote double_quote { result = SQLParser::Statement::String.new('') }
|
354
|
+
| string_literal string_literal { result = val[0] + val[1] }
|
355
|
+
|
356
|
+
datetime_literal
|
357
|
+
: date_literal
|
358
|
+
|
359
|
+
date_literal
|
360
|
+
: DATE date_string { result = SQLParser::Statement::Date.new(val[1]) }
|
361
|
+
|
362
|
+
---- header ----
|
363
|
+
require File.dirname(__FILE__) + '/parser.rex.rb'
|
364
|
+
|
365
|
+
---- inner ----
|
366
|
+
|
367
|
+
def self.parse(sql)
|
368
|
+
new.scan_str(sql)
|
369
|
+
end
|