oracle-sql-parser 0.1.0
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/.gitignore +19 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/README.md +58 -0
- data/Rakefile +41 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/oracle-sql-parser.rb +7 -0
- data/lib/oracle-sql-parser/ast.rb +38 -0
- data/lib/oracle-sql-parser/ast/array.rb +37 -0
- data/lib/oracle-sql-parser/ast/base.rb +89 -0
- data/lib/oracle-sql-parser/ast/between_condition.rb +4 -0
- data/lib/oracle-sql-parser/ast/current_of.rb +4 -0
- data/lib/oracle-sql-parser/ast/delete_statement.rb +5 -0
- data/lib/oracle-sql-parser/ast/delete_target.rb +6 -0
- data/lib/oracle-sql-parser/ast/exists_condition.rb +4 -0
- data/lib/oracle-sql-parser/ast/for_update_clause.rb +4 -0
- data/lib/oracle-sql-parser/ast/function_expression.rb +4 -0
- data/lib/oracle-sql-parser/ast/group_by_clause.rb +4 -0
- data/lib/oracle-sql-parser/ast/hash.rb +44 -0
- data/lib/oracle-sql-parser/ast/identifier.rb +7 -0
- data/lib/oracle-sql-parser/ast/in_condition.rb +4 -0
- data/lib/oracle-sql-parser/ast/insert_statement.rb +5 -0
- data/lib/oracle-sql-parser/ast/keyword.rb +8 -0
- data/lib/oracle-sql-parser/ast/like_condition.rb +4 -0
- data/lib/oracle-sql-parser/ast/logical_condition.rb +4 -0
- data/lib/oracle-sql-parser/ast/null_condition.rb +4 -0
- data/lib/oracle-sql-parser/ast/number_literal.rb +8 -0
- data/lib/oracle-sql-parser/ast/order_by_clause.rb +4 -0
- data/lib/oracle-sql-parser/ast/order_by_clause_item.rb +4 -0
- data/lib/oracle-sql-parser/ast/query_block.rb +17 -0
- data/lib/oracle-sql-parser/ast/regexp_condition.rb +4 -0
- data/lib/oracle-sql-parser/ast/rollup_cube_clause.rb +4 -0
- data/lib/oracle-sql-parser/ast/searched_case_expression.rb +8 -0
- data/lib/oracle-sql-parser/ast/select_statement.rb +5 -0
- data/lib/oracle-sql-parser/ast/simple_case_expression.rb +7 -0
- data/lib/oracle-sql-parser/ast/simple_comparision_condition.rb +4 -0
- data/lib/oracle-sql-parser/ast/subquery.rb +5 -0
- data/lib/oracle-sql-parser/ast/text_literal.rb +7 -0
- data/lib/oracle-sql-parser/ast/update_set_column.rb +4 -0
- data/lib/oracle-sql-parser/ast/update_statement.rb +4 -0
- data/lib/oracle-sql-parser/ast/where_clause.rb +4 -0
- data/lib/oracle-sql-parser/grammar.rb +10 -0
- data/lib/oracle-sql-parser/grammar/condition.treetop +224 -0
- data/lib/oracle-sql-parser/grammar/delete.treetop +68 -0
- data/lib/oracle-sql-parser/grammar/expression.treetop +236 -0
- data/lib/oracle-sql-parser/grammar/grammar.treetop +166 -0
- data/lib/oracle-sql-parser/grammar/insert.treetop +112 -0
- data/lib/oracle-sql-parser/grammar/reserved_word_generator.rb +233 -0
- data/lib/oracle-sql-parser/grammar/select.treetop +388 -0
- data/lib/oracle-sql-parser/grammar/update.treetop +113 -0
- data/lib/oracle-sql-parser/treetop_ext.rb +11 -0
- data/lib/oracle-sql-parser/version.rb +3 -0
- data/oracle-sql-parser.gemspec +28 -0
- metadata +176 -0
@@ -0,0 +1,233 @@
|
|
1
|
+
module OracleSqlParser
|
2
|
+
module Grammar
|
3
|
+
class ReservedWordGenerator
|
4
|
+
def self.generate_grammer
|
5
|
+
filename = ARGV[1] || File.expand_path("./reserved_word.treetop", File.dirname(__FILE__))
|
6
|
+
File.open(filename, 'w') do |f|
|
7
|
+
f.write self.generate_grammer_string(filename)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class KeywordRule
|
12
|
+
attr_reader :keyword
|
13
|
+
def initialize(keyword)
|
14
|
+
@keyword = keyword
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
content = []
|
19
|
+
content << " rule #{rule_name}"
|
20
|
+
content << " #{matcher} {"
|
21
|
+
content << " def ast"
|
22
|
+
content << " OracleSqlParser::Ast::Keyword.new(:name => text_value)"
|
23
|
+
content << " end"
|
24
|
+
content << " }"
|
25
|
+
content << " end"
|
26
|
+
content.join("\n")
|
27
|
+
end
|
28
|
+
|
29
|
+
def rule_name
|
30
|
+
"#{@keyword.downcase}_keyword"
|
31
|
+
end
|
32
|
+
|
33
|
+
def matcher
|
34
|
+
matcher = []
|
35
|
+
keyword.each_char do |ch|
|
36
|
+
if ch.match(/[A-Z]/)
|
37
|
+
matcher << "[#{ch.downcase}#{ch.upcase}]"
|
38
|
+
else
|
39
|
+
matcher << "'#{ch}'"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
matcher << '( ![A-Za-z0-9] )'
|
43
|
+
matcher.join(' ')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class MatchKeyword < Array
|
48
|
+
attr_reader :rule_name
|
49
|
+
def initialize(rule_name)
|
50
|
+
@rule_name = rule_name
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_s
|
54
|
+
content = []
|
55
|
+
content << " rule #{rule_name}"
|
56
|
+
content << " [a-zA-Z0-9_]+ ![a-zA-Z0-9] &{|w| #{self.to_a.to_s}.include? w.first.text_value.upcase}"
|
57
|
+
content << " end"
|
58
|
+
content.join("\n")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.generate_grammer_string(filename)
|
63
|
+
header = <<EOS
|
64
|
+
#
|
65
|
+
# #{File.basename(filename)} generated by #{__FILE__} at #{Time.now}
|
66
|
+
#
|
67
|
+
module OracleSqlParser::Grammar
|
68
|
+
grammar ReservedWord
|
69
|
+
EOS
|
70
|
+
content = []
|
71
|
+
|
72
|
+
footer = <<EOS
|
73
|
+
end
|
74
|
+
end
|
75
|
+
EOS
|
76
|
+
not_match_keyword = MatchKeyword.new 'keyword'
|
77
|
+
self.keywords.each do |keyword|
|
78
|
+
rule = KeywordRule.new(keyword)
|
79
|
+
content << rule.to_s
|
80
|
+
not_match_keyword << keyword
|
81
|
+
end
|
82
|
+
|
83
|
+
content.unshift not_match_keyword.to_s
|
84
|
+
header + content.join("\n") + footer
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.keywords
|
88
|
+
[
|
89
|
+
'ACCESS',
|
90
|
+
'ADD',
|
91
|
+
'ALL',
|
92
|
+
'ALTER',
|
93
|
+
'AND',
|
94
|
+
'ANY',
|
95
|
+
'AS',
|
96
|
+
'ASC',
|
97
|
+
'AUDIT',
|
98
|
+
'BETWEEN',
|
99
|
+
'BY',
|
100
|
+
'CASE',
|
101
|
+
'CHAR',
|
102
|
+
'CHECK',
|
103
|
+
'CLUSTER',
|
104
|
+
'CURRENT_OF',
|
105
|
+
'COLUMN',
|
106
|
+
'COLUMN_VALUE',
|
107
|
+
'COMMENT',
|
108
|
+
'COMPRESS',
|
109
|
+
'CONNECT',
|
110
|
+
'CREATE',
|
111
|
+
'CROSS',
|
112
|
+
'CUBE',
|
113
|
+
'CURRENT',
|
114
|
+
'CURRVAL',
|
115
|
+
'DATE',
|
116
|
+
'DECIMAL',
|
117
|
+
'DEFAULT',
|
118
|
+
'DELETE',
|
119
|
+
'DESC',
|
120
|
+
'DISTINCT',
|
121
|
+
'DROP',
|
122
|
+
'ELSE',
|
123
|
+
'END',
|
124
|
+
'ESCAPE',
|
125
|
+
'EXCLUSIVE',
|
126
|
+
'EXISTS',
|
127
|
+
'FILE',
|
128
|
+
'FIRST',
|
129
|
+
'FLOAT',
|
130
|
+
'FOR',
|
131
|
+
'FROM',
|
132
|
+
'FULL',
|
133
|
+
'GRANT',
|
134
|
+
'GROUP',
|
135
|
+
'HAVING',
|
136
|
+
'IDENTIFIED',
|
137
|
+
'IMMEDIATE',
|
138
|
+
'IN',
|
139
|
+
'INCREMENT',
|
140
|
+
'INDEX',
|
141
|
+
'INITIAL',
|
142
|
+
'INNER',
|
143
|
+
'INSERT',
|
144
|
+
'INTEGER',
|
145
|
+
'INTERSECT',
|
146
|
+
'INTO',
|
147
|
+
'IS',
|
148
|
+
'JOIN',
|
149
|
+
'LAST',
|
150
|
+
'LEFT',
|
151
|
+
'LEVEL',
|
152
|
+
'LIKE',
|
153
|
+
'LIKE2',
|
154
|
+
'LIKE4',
|
155
|
+
'LIKEC',
|
156
|
+
'LOCK',
|
157
|
+
'LONG',
|
158
|
+
'MAXEXTENTS',
|
159
|
+
'MINUS',
|
160
|
+
'MLSLABEL',
|
161
|
+
'MODE',
|
162
|
+
'MODIFY',
|
163
|
+
'NATURAL',
|
164
|
+
'NESTED_TABLE_ID',
|
165
|
+
'NEXTVAL',
|
166
|
+
'NOAUDIT',
|
167
|
+
'NOCOMPRESS',
|
168
|
+
'NOT',
|
169
|
+
'NOWAIT',
|
170
|
+
'NULL',
|
171
|
+
'NULLS',
|
172
|
+
'NUMBER',
|
173
|
+
'OF',
|
174
|
+
'OFFLINE',
|
175
|
+
'ON',
|
176
|
+
'ONLINE',
|
177
|
+
'OPTION',
|
178
|
+
'OR',
|
179
|
+
'ORDER',
|
180
|
+
'OUTER',
|
181
|
+
'PCTFREE',
|
182
|
+
'PRIOR',
|
183
|
+
'PRIVILEGES',
|
184
|
+
'PUBLIC',
|
185
|
+
'RAW',
|
186
|
+
'REGEXP_LIKE',
|
187
|
+
'RENAME',
|
188
|
+
'RESOURCE',
|
189
|
+
'REVOKE',
|
190
|
+
'RIGHT',
|
191
|
+
'ROLLUP',
|
192
|
+
'ROW',
|
193
|
+
'ROWID',
|
194
|
+
'ROWNUM',
|
195
|
+
'ROWS',
|
196
|
+
'SELECT',
|
197
|
+
'SESSION',
|
198
|
+
'SET',
|
199
|
+
'SHARE',
|
200
|
+
'SIZE',
|
201
|
+
'SIBLINGS',
|
202
|
+
'SMALLINT',
|
203
|
+
'START',
|
204
|
+
'SUCCESSFUL',
|
205
|
+
'SYNONYM',
|
206
|
+
'SYSDATE',
|
207
|
+
'SYSTIMESTAMP',
|
208
|
+
'TABLE',
|
209
|
+
'THEN',
|
210
|
+
'TO',
|
211
|
+
'TRIGGER',
|
212
|
+
'UID',
|
213
|
+
'UNION',
|
214
|
+
'UNIQUE',
|
215
|
+
'UPDATE',
|
216
|
+
'USER',
|
217
|
+
'USING',
|
218
|
+
'VALIDATE',
|
219
|
+
'VALUES',
|
220
|
+
'VARCHAR',
|
221
|
+
'VARCHAR2',
|
222
|
+
'VIEW',
|
223
|
+
'WAIT',
|
224
|
+
'WHEN',
|
225
|
+
'WHENEVER',
|
226
|
+
'WHERE',
|
227
|
+
]
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
OracleSqlParser::Grammar::ReservedWordGenerator.generate_grammer
|
@@ -0,0 +1,388 @@
|
|
1
|
+
module OracleSqlParser::Grammar
|
2
|
+
grammar Select
|
3
|
+
rule select_statement
|
4
|
+
subquery for_update_clause:for_update_clause? {
|
5
|
+
def ast
|
6
|
+
OracleSqlParser::Ast::SelectStatement[
|
7
|
+
:subquery => subquery.ast,
|
8
|
+
:for_update_clause => for_update_clause.ast]
|
9
|
+
end
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
rule subquery
|
14
|
+
query_block
|
15
|
+
(
|
16
|
+
more_queries:(
|
17
|
+
union_keyword (space all_keyword?) /
|
18
|
+
intersect_keyword /
|
19
|
+
minus_keyword
|
20
|
+
) space? subquery )?
|
21
|
+
order_by_clause:order_by_clause? {
|
22
|
+
def ast
|
23
|
+
OracleSqlParser::Ast::Subquery[
|
24
|
+
:query_block => query_block.ast,
|
25
|
+
:order_by_clause => order_by_clause.ast]
|
26
|
+
end
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
rule query_block
|
31
|
+
(subquery_factoring_clause:subquery_factoring_clause space)?
|
32
|
+
select_keyword space
|
33
|
+
hint:hint?
|
34
|
+
mod:(modifier:(all_keyword / distinct_keyword / unique_keyword) space)?
|
35
|
+
select_list space?
|
36
|
+
from_keyword space?
|
37
|
+
select_sources space?
|
38
|
+
where_clause:where_clause? space?
|
39
|
+
group_by_clause:group_by_clause? space?
|
40
|
+
model_clause:model_clause? space? {
|
41
|
+
def ast
|
42
|
+
OracleSqlParser::Ast::QueryBlock[
|
43
|
+
:hint => hint.ast,
|
44
|
+
:modifier => modifier.ast,
|
45
|
+
:select_list => select_list.ast,
|
46
|
+
:select_sources => select_sources.ast,
|
47
|
+
:where_clause => where_clause.ast,
|
48
|
+
:group_by_clause => group_by_clause.ast,
|
49
|
+
:model_clause => model_clause.ast]
|
50
|
+
end
|
51
|
+
|
52
|
+
def modifier
|
53
|
+
mod.modifier if mod.respond_to? :modifier
|
54
|
+
end
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
rule select_sources
|
59
|
+
join_clause /
|
60
|
+
'(' space? join_clause space? ')' /
|
61
|
+
table_reference {
|
62
|
+
def ast
|
63
|
+
if respond_to? :join_clause
|
64
|
+
join_clause.ast
|
65
|
+
else
|
66
|
+
super
|
67
|
+
end
|
68
|
+
end
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
rule join_clause
|
73
|
+
table_reference space
|
74
|
+
(
|
75
|
+
outer_join_clause /
|
76
|
+
inner_cross_join_clause {
|
77
|
+
def ast
|
78
|
+
super
|
79
|
+
end
|
80
|
+
}
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
rule inner_cross_join_clause
|
85
|
+
inner_join_clause /
|
86
|
+
cross_join_clause {
|
87
|
+
def ast
|
88
|
+
super
|
89
|
+
end
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
rule inner_join_clause
|
94
|
+
inner_keyword space? join_keyword space? table_reference space?
|
95
|
+
(
|
96
|
+
on_keyword space? condition /
|
97
|
+
using_keyword space? '(' space? column_list space? ')'
|
98
|
+
) {
|
99
|
+
def ast
|
100
|
+
'inner_join_clause'
|
101
|
+
end
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
rule cross_join_clause
|
106
|
+
(
|
107
|
+
cross_keyword /
|
108
|
+
natural_keyword (space inner_keyword)?
|
109
|
+
) space join_keyword space table_reference {
|
110
|
+
def ast
|
111
|
+
'cross_join_clause'
|
112
|
+
end
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
116
|
+
rule column_list
|
117
|
+
column_name (space? ',' space? column_name)* {
|
118
|
+
def ast
|
119
|
+
'column_list'
|
120
|
+
end
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
rule outer_join_clause
|
125
|
+
query_partition_clause?
|
126
|
+
(
|
127
|
+
outer_join_type space? join_keyword /
|
128
|
+
natural_keyword space? outer_join_type? space? join_keyword
|
129
|
+
) space
|
130
|
+
table_reference space
|
131
|
+
(query_partition_clause space)?
|
132
|
+
(
|
133
|
+
on_keyword space? condition /
|
134
|
+
using_keyword space '(' space? column_list space? ')'
|
135
|
+
) {
|
136
|
+
def ast
|
137
|
+
'outer_join_clause'
|
138
|
+
end
|
139
|
+
}
|
140
|
+
end
|
141
|
+
|
142
|
+
rule query_partition_clause
|
143
|
+
'query_partition_clause' {
|
144
|
+
def ast
|
145
|
+
'query_partition_clause'
|
146
|
+
end
|
147
|
+
}
|
148
|
+
end
|
149
|
+
|
150
|
+
rule outer_join_type
|
151
|
+
(
|
152
|
+
full_keyword /
|
153
|
+
left_keyword /
|
154
|
+
right_keyword
|
155
|
+
) (space outer_keyword)? {
|
156
|
+
def ast
|
157
|
+
'outer_join_type'
|
158
|
+
end
|
159
|
+
}
|
160
|
+
end
|
161
|
+
|
162
|
+
rule for_update_clause
|
163
|
+
for_keyword space?
|
164
|
+
update_keyword space?
|
165
|
+
f:(of_keyword space for_update_clause_columns)?
|
166
|
+
wait:(wait_with_integer / nowait_keyword)? {
|
167
|
+
def ast
|
168
|
+
OracleSqlParser::Ast::ForUpdateClause[
|
169
|
+
:columns => for_update_clause_columns.ast,
|
170
|
+
:wait => wait.ast
|
171
|
+
].remove_nil_values!
|
172
|
+
end
|
173
|
+
|
174
|
+
def for_update_clause_columns
|
175
|
+
if f.respond_to? :for_update_clause_columns
|
176
|
+
f.for_update_clause_columns
|
177
|
+
else
|
178
|
+
nil
|
179
|
+
end
|
180
|
+
end
|
181
|
+
}
|
182
|
+
end
|
183
|
+
|
184
|
+
rule wait_with_integer
|
185
|
+
wait_keyword space? integer {
|
186
|
+
def ast
|
187
|
+
integer.ast
|
188
|
+
end
|
189
|
+
}
|
190
|
+
end
|
191
|
+
|
192
|
+
rule for_update_clause_columns
|
193
|
+
for_update_clause_column more:(space? ',' space? more_for_update_clause_columns:for_update_clause_column)* {
|
194
|
+
def ast
|
195
|
+
OracleSqlParser::Ast::Array[
|
196
|
+
for_update_clause_column.ast, *more_for_update_clause_columns.map(&:ast)
|
197
|
+
]
|
198
|
+
end
|
199
|
+
|
200
|
+
def more_for_update_clause_columns
|
201
|
+
more.elements.map(&:more_for_update_clause_columns)
|
202
|
+
end
|
203
|
+
}
|
204
|
+
end
|
205
|
+
|
206
|
+
rule for_update_clause_column
|
207
|
+
(
|
208
|
+
schema_name space? '.' space? table_name space? '.' space? column_name /
|
209
|
+
table_name space? '.' space? column_name /
|
210
|
+
space? column_name
|
211
|
+
) {
|
212
|
+
def ast
|
213
|
+
OracleSqlParser::Ast::Identifier[:name => text_value]
|
214
|
+
end
|
215
|
+
}
|
216
|
+
end
|
217
|
+
|
218
|
+
rule subquery_factoring_clause
|
219
|
+
'subquery_factoring_clause' { # not implemented
|
220
|
+
def ast
|
221
|
+
'subquery_factoring_clause'
|
222
|
+
end
|
223
|
+
}
|
224
|
+
end
|
225
|
+
|
226
|
+
rule order_by_clause
|
227
|
+
order_keyword space siblings:siblings_keyword? space? by_keyword space order_by_clause_items {
|
228
|
+
def ast
|
229
|
+
OracleSqlParser::Ast::OrderByClause[
|
230
|
+
:siblings => siblings.ast,
|
231
|
+
:items => order_by_clause_items.ast
|
232
|
+
]
|
233
|
+
end
|
234
|
+
}
|
235
|
+
end
|
236
|
+
|
237
|
+
rule order_by_clause_items
|
238
|
+
order_by_clause_item
|
239
|
+
more:(space? ',' space? order_by_clause_item space?)* {
|
240
|
+
def ast
|
241
|
+
OracleSqlParser::Ast::Array[
|
242
|
+
order_by_clause_item.ast, *more_order_by_clause_items.map(&:ast)
|
243
|
+
]
|
244
|
+
end
|
245
|
+
|
246
|
+
def more_order_by_clause_items
|
247
|
+
more.elements.map(&:order_by_clause_item)
|
248
|
+
end
|
249
|
+
}
|
250
|
+
end
|
251
|
+
|
252
|
+
rule order_by_clause_item
|
253
|
+
target:(expr / position / c_alias) space?
|
254
|
+
asc:(asc_keyword / desc_keyword)? space?
|
255
|
+
null:(nulls_keyword space first_or_last:(first_keyword / last_keyword))? {
|
256
|
+
def ast
|
257
|
+
OracleSqlParser::Ast::OrderByClauseItem[
|
258
|
+
:target => target.ast,
|
259
|
+
:asc => asc.ast,
|
260
|
+
:nulls => nulls.ast
|
261
|
+
]
|
262
|
+
end
|
263
|
+
|
264
|
+
def nulls
|
265
|
+
if null.respond_to? :first_or_last
|
266
|
+
null.first_or_last
|
267
|
+
else
|
268
|
+
nil
|
269
|
+
end
|
270
|
+
end
|
271
|
+
}
|
272
|
+
end
|
273
|
+
|
274
|
+
rule select_list
|
275
|
+
select_one_column more_list:( space? ',' space? c:select_one_column space? )* {
|
276
|
+
def ast
|
277
|
+
OracleSqlParser::Ast::Array[select_one_column.ast, *more_columns.map(&:ast)]
|
278
|
+
end
|
279
|
+
|
280
|
+
def more_columns
|
281
|
+
more_list.elements.map{|element| element.c}
|
282
|
+
end
|
283
|
+
}
|
284
|
+
end
|
285
|
+
|
286
|
+
rule select_one_column
|
287
|
+
( select_table /
|
288
|
+
expr /
|
289
|
+
select_column
|
290
|
+
) {
|
291
|
+
def ast
|
292
|
+
super
|
293
|
+
end
|
294
|
+
}
|
295
|
+
end
|
296
|
+
|
297
|
+
rule select_table
|
298
|
+
(table_name '.')? '*' {
|
299
|
+
def ast
|
300
|
+
OracleSqlParser::Ast::Identifier[:name => text_value]
|
301
|
+
end
|
302
|
+
}
|
303
|
+
end
|
304
|
+
|
305
|
+
rule select_column
|
306
|
+
sql_expression ( space ( as_keyword space )? c_alias )? {
|
307
|
+
def ast
|
308
|
+
sql_expression.ast
|
309
|
+
end
|
310
|
+
}
|
311
|
+
end
|
312
|
+
|
313
|
+
# group
|
314
|
+
rule group_by_clause
|
315
|
+
group_keyword space by_keyword space target:group_column space?
|
316
|
+
t:(',' space? more_target:group_column space?)*
|
317
|
+
h:(having_keyword space condition:condition)? {
|
318
|
+
def ast
|
319
|
+
OracleSqlParser::Ast::GroupByClause[
|
320
|
+
:targets => OracleSqlParser::Ast::Array[
|
321
|
+
target.ast, *more_targets.map(&:ast)
|
322
|
+
],
|
323
|
+
:having => condition.ast
|
324
|
+
]
|
325
|
+
end
|
326
|
+
|
327
|
+
def more_targets
|
328
|
+
t.elements.map{|e| e.more_target}
|
329
|
+
end
|
330
|
+
|
331
|
+
def condition
|
332
|
+
if h.respond_to? :condition
|
333
|
+
h.condition
|
334
|
+
else
|
335
|
+
nil
|
336
|
+
end
|
337
|
+
end
|
338
|
+
}
|
339
|
+
end
|
340
|
+
|
341
|
+
rule group_column
|
342
|
+
(
|
343
|
+
expr /
|
344
|
+
rollup_cube_clause /
|
345
|
+
grouping_sets_clause
|
346
|
+
) {
|
347
|
+
def ast
|
348
|
+
super
|
349
|
+
end
|
350
|
+
}
|
351
|
+
end
|
352
|
+
|
353
|
+
rule rollup_cube_clause
|
354
|
+
func_name:(rollup_keyword / cube_keyword) space? grouping_expression_list {
|
355
|
+
def ast
|
356
|
+
OracleSqlParser::Ast::RollupCubeClause[
|
357
|
+
:func_name => func_name.ast,
|
358
|
+
:args => grouping_expression_list.ast
|
359
|
+
]
|
360
|
+
end
|
361
|
+
}
|
362
|
+
end
|
363
|
+
|
364
|
+
rule grouping_sets_clause
|
365
|
+
'grouping_sets_clause' { # not implemented
|
366
|
+
def ast
|
367
|
+
'grouping_sets_clause'
|
368
|
+
end
|
369
|
+
}
|
370
|
+
end
|
371
|
+
|
372
|
+
rule grouping_expression_list
|
373
|
+
expression_list {
|
374
|
+
def ast
|
375
|
+
super
|
376
|
+
end
|
377
|
+
}
|
378
|
+
end
|
379
|
+
|
380
|
+
rule model_clause
|
381
|
+
'model_clause' {
|
382
|
+
def ast
|
383
|
+
'model_clause'
|
384
|
+
end
|
385
|
+
}
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|