sql-parser-tl 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|