vorax 0.1.0pre

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.
Files changed (57) hide show
  1. data/.gitignore +7 -0
  2. data/.rspec +1 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +45 -0
  5. data/Rakefile +30 -0
  6. data/lib/vorax/base_funnel.rb +30 -0
  7. data/lib/vorax/output/html_convertor.rb +120 -0
  8. data/lib/vorax/output/html_funnel.rb +79 -0
  9. data/lib/vorax/output/pagezip_convertor.rb +20 -0
  10. data/lib/vorax/output/tablezip_convertor.rb +22 -0
  11. data/lib/vorax/output/vertical_convertor.rb +53 -0
  12. data/lib/vorax/output/zip_convertor.rb +117 -0
  13. data/lib/vorax/parser/argument.rb~ +125 -0
  14. data/lib/vorax/parser/body_split.rb +168 -0
  15. data/lib/vorax/parser/conn_string.rb +104 -0
  16. data/lib/vorax/parser/grammars/alias.rb +912 -0
  17. data/lib/vorax/parser/grammars/alias.rl +146 -0
  18. data/lib/vorax/parser/grammars/column.rb +454 -0
  19. data/lib/vorax/parser/grammars/column.rl +64 -0
  20. data/lib/vorax/parser/grammars/common.rl +98 -0
  21. data/lib/vorax/parser/grammars/package_spec.rb +1186 -0
  22. data/lib/vorax/parser/grammars/package_spec.rl +78 -0
  23. data/lib/vorax/parser/grammars/plsql_def.rb +469 -0
  24. data/lib/vorax/parser/grammars/plsql_def.rl +59 -0
  25. data/lib/vorax/parser/grammars/statement.rb +925 -0
  26. data/lib/vorax/parser/grammars/statement.rl +83 -0
  27. data/lib/vorax/parser/parser.rb +320 -0
  28. data/lib/vorax/parser/plsql_structure.rb +158 -0
  29. data/lib/vorax/parser/plsql_walker.rb +143 -0
  30. data/lib/vorax/parser/statement_inspector.rb~ +52 -0
  31. data/lib/vorax/parser/stmt_inspector.rb +78 -0
  32. data/lib/vorax/parser/target_ref.rb +110 -0
  33. data/lib/vorax/sqlplus.rb +281 -0
  34. data/lib/vorax/version.rb +7 -0
  35. data/lib/vorax/vorax_io.rb +70 -0
  36. data/lib/vorax.rb +60 -0
  37. data/spec/column_spec.rb +40 -0
  38. data/spec/conn_string_spec.rb +53 -0
  39. data/spec/package_spec_spec.rb +48 -0
  40. data/spec/pagezip_spec.rb +153 -0
  41. data/spec/parser_spec.rb +299 -0
  42. data/spec/plsql_structure_spec.rb +44 -0
  43. data/spec/spec_helper.rb +13 -0
  44. data/spec/sql/create_objects.sql +69 -0
  45. data/spec/sql/dbms_crypto.spc +339 -0
  46. data/spec/sql/dbms_crypto.~spc +339 -0
  47. data/spec/sql/dbms_stats.spc +4097 -0
  48. data/spec/sql/drop_user.sql +10 -0
  49. data/spec/sql/muci.spc +24 -0
  50. data/spec/sql/setup_user.sql +22 -0
  51. data/spec/sql/test.pkg +67 -0
  52. data/spec/sqlplus_spec.rb +52 -0
  53. data/spec/stmt_inspector_spec.rb +84 -0
  54. data/spec/tablezip_spec.rb +111 -0
  55. data/spec/vertical_spec.rb +150 -0
  56. data/vorax.gemspec +21 -0
  57. metadata +139 -0
@@ -0,0 +1,146 @@
1
+ %%{
2
+
3
+ machine alias;
4
+
5
+ action tableref_start {
6
+ #puts "tableref_start: p=#{p}"
7
+ @t_start = p
8
+ }
9
+
10
+ action tableref_end {
11
+ @table_ref = data[(@t_start..p-1)]
12
+ #puts "tableref_end: @table_ref=#@table_ref"
13
+ }
14
+
15
+ action alias_start {
16
+ #puts "alias_start: p=#{p}"
17
+ @a_start = p
18
+ @alias_value = nil
19
+ }
20
+
21
+ action alias_end {
22
+ text = data[(@a_start..p-1)]
23
+ @alias_value = text unless @not_alias.include?(text.upcase)
24
+ #puts "alias_end: @alias_value=#@alias_value"
25
+ }
26
+
27
+ action subquery_start {
28
+ #puts "subquery_start: p=#{p}"
29
+ @subquery_text = Parser.walk_balanced_paren(data[(p..-1)]).gsub(/^\(|\)$/, '')
30
+ p += 1
31
+ @subquery_range = (p..p+@subquery_text.length-1)
32
+ p += @subquery_text.length
33
+ te = p
34
+ #puts "subquery_end: p=#{p} @subquery_text=#@subquery_text @subquery_range=#@subquery_range"
35
+ }
36
+
37
+ action before_with {
38
+ #puts "before_with: p=#{p}"
39
+ @alias_value = nil
40
+ @subquery_range = nil
41
+ @subquery_text = nil
42
+ }
43
+
44
+ action after_with {
45
+ @refs << ExprRef.new(@subquery_text, @subquery_range, @alias_value)
46
+ @alias_value = nil
47
+ @subquery_range = nil
48
+ @subquery_text = nil
49
+ #puts "after_with"
50
+ }
51
+
52
+ action before_tref {
53
+ #puts "before_tref: p=#{p} @alias_value=#@alias_value @subquery_text=#@subquery_text @subquery_range=#@subquery_range"
54
+ add_tableref
55
+ }
56
+
57
+ include common "common.rl";
58
+
59
+ # interesting spots
60
+ plain_table_ref = ((identifier '.')? identifier ('@' identifier)?) >tableref_start %tableref_end;
61
+ alias = identifier >alias_start %alias_end;
62
+ sub_query = '(' >subquery_start;
63
+ table_reference = ((plain_table_ref | sub_query) (ws+ alias)?) >before_tref;
64
+ from_spot = ws+ K_FROM ws+ table_reference (ws* ',' ws* table_reference)*;
65
+ with_reference = (alias ws+ K_AS ws* sub_query) >before_with %after_with;
66
+ with_spot = K_WITH ws+ with_reference (ws* ',' ws* with_reference)*;
67
+ join_spot = ws+ K_JOIN ws+ table_reference;
68
+ start_select = K_SELECT ws+;
69
+
70
+ main := |*
71
+ squoted_string;
72
+ dquoted_string;
73
+ comment;
74
+ start_select => { @start_columns = te };
75
+ from_spot => { @columns = data[(@start_columns..ts)] unless @columns };
76
+ with_spot;
77
+ join_spot;
78
+ any => {};
79
+ *|;
80
+
81
+ }%%
82
+
83
+ module Vorax
84
+
85
+ module Parser
86
+
87
+ # An abstraction for an alias within a SQL statement.
88
+ class Alias
89
+
90
+ def initialize
91
+ @not_alias = ['ON', 'WHERE', 'FROM', 'CONNECT', 'START',
92
+ 'GROUP', 'HAVING', 'MODEL']
93
+ end
94
+
95
+ # Walks the provided statement searching for alias references.
96
+ #
97
+ # @param data the statement
98
+ def walk(data)
99
+ @refs = [];
100
+ @columns = nil;
101
+ data << "\n"
102
+ eof = data.length
103
+ %% write data;
104
+ %% write init;
105
+ %% write exec;
106
+ data.chop!
107
+
108
+ # needed to finalize the last pending tableref
109
+ add_tableref
110
+ end
111
+
112
+ # Get all identified tableref/exprref references. This method
113
+ # should be called after walk.
114
+ #
115
+ # @return an array of references
116
+ def refs
117
+ @refs
118
+ end
119
+
120
+ # A string containing the column list, if there's any.
121
+ #
122
+ # @return a string with all defined columns
123
+ def query_fields
124
+ @columns
125
+ end
126
+
127
+ private
128
+
129
+ def add_tableref
130
+ if (not @table_ref.nil?)
131
+ @refs << TableRef.new(@table_ref, @alias_value)
132
+ elsif (not @subquery_text.nil?)
133
+ @refs << ExprRef.new(@subquery_text,
134
+ @subquery_range,
135
+ @alias_value)
136
+ end
137
+ @alias_value = nil
138
+ @table_ref = nil
139
+ end
140
+
141
+ end
142
+
143
+ end
144
+
145
+ end
146
+
@@ -0,0 +1,454 @@
1
+
2
+ # line 1 "lib/vorax/parser/grammars/column.rl"
3
+
4
+ # line 32 "lib/vorax/parser/grammars/column.rl"
5
+
6
+
7
+ module Vorax
8
+
9
+ module Parser
10
+
11
+ # An abstraction for SQL columns.
12
+ class Column
13
+
14
+ # Given a statement, it walks it in search for a column list. If the statement
15
+ # contains more than one query, the first defined list is returned.
16
+ #
17
+ # @param data the statement to be walked
18
+ # @return the string with the column list
19
+ def walk(data)
20
+ @columns = []
21
+ if data
22
+ data << ","
23
+ eof = data.length
24
+
25
+ # line 26 "lib/vorax/parser/grammars/column.rb"
26
+ class << self
27
+ attr_accessor :_column_actions
28
+ private :_column_actions, :_column_actions=
29
+ end
30
+ self._column_actions = [
31
+ 0, 1, 1, 1, 2, 1, 3, 1,
32
+ 7, 1, 9, 1, 10, 1, 11, 1,
33
+ 12, 1, 13, 1, 14, 1, 15, 2,
34
+ 0, 8, 2, 3, 4, 2, 3, 5,
35
+ 2, 3, 6
36
+ ]
37
+
38
+ class << self
39
+ attr_accessor :_column_key_offsets
40
+ private :_column_key_offsets, :_column_key_offsets=
41
+ end
42
+ self._column_key_offsets = [
43
+ 0, 1, 7, 8, 9, 10, 11, 13,
44
+ 22, 23, 30, 39, 40, 55, 71, 87,
45
+ 88, 89, 90, 92, 105, 106, 113, 129,
46
+ 130, 131, 137, 138
47
+ ]
48
+
49
+ class << self
50
+ attr_accessor :_column_trans_keys
51
+ private :_column_trans_keys, :_column_trans_keys=
52
+ end
53
+ self._column_trans_keys = [
54
+ 34, 32, 44, 45, 47, 9, 13, 45,
55
+ 10, 42, 42, 42, 47, 34, 42, 95,
56
+ 35, 36, 65, 90, 97, 122, 34, 32,
57
+ 44, 45, 46, 47, 9, 13, 34, 42,
58
+ 95, 35, 36, 65, 90, 97, 122, 34,
59
+ 32, 44, 45, 47, 95, 9, 13, 35,
60
+ 36, 48, 57, 65, 90, 97, 122, 32,
61
+ 44, 45, 46, 47, 95, 9, 13, 35,
62
+ 36, 48, 57, 65, 90, 97, 122, 32,
63
+ 44, 45, 46, 47, 95, 9, 13, 35,
64
+ 36, 48, 57, 65, 90, 97, 122, 39,
65
+ 10, 42, 42, 47, 34, 39, 40, 42,
66
+ 45, 47, 95, 35, 36, 65, 90, 97,
67
+ 122, 34, 32, 44, 45, 46, 47, 9,
68
+ 13, 32, 44, 45, 46, 47, 95, 9,
69
+ 13, 35, 36, 48, 57, 65, 90, 97,
70
+ 122, 39, 39, 32, 44, 45, 47, 9,
71
+ 13, 45, 42, 0
72
+ ]
73
+
74
+ class << self
75
+ attr_accessor :_column_single_lengths
76
+ private :_column_single_lengths, :_column_single_lengths=
77
+ end
78
+ self._column_single_lengths = [
79
+ 1, 4, 1, 1, 1, 1, 2, 3,
80
+ 1, 5, 3, 1, 5, 6, 6, 1,
81
+ 1, 1, 2, 7, 1, 5, 6, 1,
82
+ 1, 4, 1, 1
83
+ ]
84
+
85
+ class << self
86
+ attr_accessor :_column_range_lengths
87
+ private :_column_range_lengths, :_column_range_lengths=
88
+ end
89
+ self._column_range_lengths = [
90
+ 0, 1, 0, 0, 0, 0, 0, 3,
91
+ 0, 1, 3, 0, 5, 5, 5, 0,
92
+ 0, 0, 0, 3, 0, 1, 5, 0,
93
+ 0, 1, 0, 0
94
+ ]
95
+
96
+ class << self
97
+ attr_accessor :_column_index_offsets
98
+ private :_column_index_offsets, :_column_index_offsets=
99
+ end
100
+ self._column_index_offsets = [
101
+ 0, 2, 8, 10, 12, 14, 16, 19,
102
+ 26, 28, 35, 42, 44, 55, 67, 79,
103
+ 81, 83, 85, 88, 99, 101, 108, 120,
104
+ 122, 124, 130, 132
105
+ ]
106
+
107
+ class << self
108
+ attr_accessor :_column_indicies
109
+ private :_column_indicies, :_column_indicies=
110
+ end
111
+ self._column_indicies = [
112
+ 2, 1, 4, 5, 6, 7, 4, 3,
113
+ 8, 3, 4, 8, 9, 3, 10, 9,
114
+ 10, 4, 9, 11, 4, 12, 12, 12,
115
+ 12, 3, 13, 11, 4, 5, 6, 14,
116
+ 7, 4, 3, 15, 4, 16, 16, 16,
117
+ 16, 3, 4, 15, 4, 5, 6, 7,
118
+ 16, 4, 16, 16, 16, 16, 3, 4,
119
+ 5, 6, 14, 7, 12, 4, 12, 12,
120
+ 12, 12, 3, 4, 5, 6, 18, 7,
121
+ 17, 4, 17, 17, 17, 17, 0, 20,
122
+ 19, 22, 21, 24, 23, 24, 22, 23,
123
+ 26, 28, 29, 30, 31, 32, 27, 27,
124
+ 27, 27, 25, 2, 1, 4, 5, 6,
125
+ 18, 7, 4, 34, 4, 5, 6, 18,
126
+ 7, 17, 4, 17, 17, 17, 17, 33,
127
+ 20, 19, 19, 35, 4, 5, 6, 7,
128
+ 4, 33, 21, 33, 23, 33, 0
129
+ ]
130
+
131
+ class << self
132
+ attr_accessor :_column_trans_targs
133
+ private :_column_trans_targs, :_column_trans_targs=
134
+ end
135
+ self._column_trans_targs = [
136
+ 19, 0, 21, 19, 1, 19, 2, 4,
137
+ 3, 5, 6, 8, 13, 9, 10, 11,
138
+ 12, 14, 7, 15, 24, 16, 19, 17,
139
+ 18, 19, 20, 22, 23, 19, 25, 26,
140
+ 27, 19, 19, 19
141
+ ]
142
+
143
+ class << self
144
+ attr_accessor :_column_trans_actions
145
+ private :_column_trans_actions, :_column_trans_actions=
146
+ end
147
+ self._column_trans_actions = [
148
+ 19, 0, 29, 21, 0, 9, 0, 0,
149
+ 0, 0, 0, 0, 0, 0, 0, 0,
150
+ 0, 0, 0, 0, 26, 0, 7, 0,
151
+ 0, 11, 5, 32, 32, 23, 32, 5,
152
+ 5, 17, 15, 13
153
+ ]
154
+
155
+ class << self
156
+ attr_accessor :_column_to_state_actions
157
+ private :_column_to_state_actions, :_column_to_state_actions=
158
+ end
159
+ self._column_to_state_actions = [
160
+ 0, 0, 0, 0, 0, 0, 0, 0,
161
+ 0, 0, 0, 0, 0, 0, 0, 0,
162
+ 0, 0, 0, 1, 0, 0, 0, 0,
163
+ 0, 0, 0, 0
164
+ ]
165
+
166
+ class << self
167
+ attr_accessor :_column_from_state_actions
168
+ private :_column_from_state_actions, :_column_from_state_actions=
169
+ end
170
+ self._column_from_state_actions = [
171
+ 0, 0, 0, 0, 0, 0, 0, 0,
172
+ 0, 0, 0, 0, 0, 0, 0, 0,
173
+ 0, 0, 0, 3, 0, 0, 0, 0,
174
+ 0, 0, 0, 0
175
+ ]
176
+
177
+ class << self
178
+ attr_accessor :_column_eof_trans
179
+ private :_column_eof_trans, :_column_eof_trans=
180
+ end
181
+ self._column_eof_trans = [
182
+ 1, 4, 4, 4, 4, 4, 4, 4,
183
+ 4, 4, 4, 4, 4, 4, 1, 4,
184
+ 1, 1, 1, 0, 34, 35, 34, 34,
185
+ 36, 34, 34, 34
186
+ ]
187
+
188
+ class << self
189
+ attr_accessor :column_start
190
+ end
191
+ self.column_start = 19;
192
+ class << self
193
+ attr_accessor :column_first_final
194
+ end
195
+ self.column_first_final = 19;
196
+ class << self
197
+ attr_accessor :column_error
198
+ end
199
+ self.column_error = -1;
200
+
201
+ class << self
202
+ attr_accessor :column_en_main
203
+ end
204
+ self.column_en_main = 19;
205
+
206
+
207
+ # line 52 "lib/vorax/parser/grammars/column.rl"
208
+
209
+ # line 210 "lib/vorax/parser/grammars/column.rb"
210
+ begin
211
+ p ||= 0
212
+ pe ||= data.length
213
+ cs = column_start
214
+ ts = nil
215
+ te = nil
216
+ act = 0
217
+ end
218
+
219
+ # line 53 "lib/vorax/parser/grammars/column.rl"
220
+
221
+ # line 222 "lib/vorax/parser/grammars/column.rb"
222
+ begin
223
+ _klen, _trans, _keys, _acts, _nacts = nil
224
+ _goto_level = 0
225
+ _resume = 10
226
+ _eof_trans = 15
227
+ _again = 20
228
+ _test_eof = 30
229
+ _out = 40
230
+ while true
231
+ _trigger_goto = false
232
+ if _goto_level <= 0
233
+ if p == pe
234
+ _goto_level = _test_eof
235
+ next
236
+ end
237
+ end
238
+ if _goto_level <= _resume
239
+ _acts = _column_from_state_actions[cs]
240
+ _nacts = _column_actions[_acts]
241
+ _acts += 1
242
+ while _nacts > 0
243
+ _nacts -= 1
244
+ _acts += 1
245
+ case _column_actions[_acts - 1]
246
+ when 2 then
247
+ # line 1 "NONE"
248
+ begin
249
+ ts = p
250
+ end
251
+ # line 252 "lib/vorax/parser/grammars/column.rb"
252
+ end # from state action switch
253
+ end
254
+ if _trigger_goto
255
+ next
256
+ end
257
+ _keys = _column_key_offsets[cs]
258
+ _trans = _column_index_offsets[cs]
259
+ _klen = _column_single_lengths[cs]
260
+ _break_match = false
261
+
262
+ begin
263
+ if _klen > 0
264
+ _lower = _keys
265
+ _upper = _keys + _klen - 1
266
+
267
+ loop do
268
+ break if _upper < _lower
269
+ _mid = _lower + ( (_upper - _lower) >> 1 )
270
+
271
+ if data[p].ord < _column_trans_keys[_mid]
272
+ _upper = _mid - 1
273
+ elsif data[p].ord > _column_trans_keys[_mid]
274
+ _lower = _mid + 1
275
+ else
276
+ _trans += (_mid - _keys)
277
+ _break_match = true
278
+ break
279
+ end
280
+ end # loop
281
+ break if _break_match
282
+ _keys += _klen
283
+ _trans += _klen
284
+ end
285
+ _klen = _column_range_lengths[cs]
286
+ if _klen > 0
287
+ _lower = _keys
288
+ _upper = _keys + (_klen << 1) - 2
289
+ loop do
290
+ break if _upper < _lower
291
+ _mid = _lower + (((_upper-_lower) >> 1) & ~1)
292
+ if data[p].ord < _column_trans_keys[_mid]
293
+ _upper = _mid - 2
294
+ elsif data[p].ord > _column_trans_keys[_mid+1]
295
+ _lower = _mid + 2
296
+ else
297
+ _trans += ((_mid - _keys) >> 1)
298
+ _break_match = true
299
+ break
300
+ end
301
+ end # loop
302
+ break if _break_match
303
+ _trans += _klen
304
+ end
305
+ end while false
306
+ _trans = _column_indicies[_trans]
307
+ end
308
+ if _goto_level <= _eof_trans
309
+ cs = _column_trans_targs[_trans]
310
+ if _column_trans_actions[_trans] != 0
311
+ _acts = _column_trans_actions[_trans]
312
+ _nacts = _column_actions[_acts]
313
+ _acts += 1
314
+ while _nacts > 0
315
+ _nacts -= 1
316
+ _acts += 1
317
+ case _column_actions[_acts - 1]
318
+ when 0 then
319
+ # line 5 "lib/vorax/parser/grammars/column.rl"
320
+ begin
321
+
322
+ expr = Parser.walk_balanced_paren(data[(p..-1)])
323
+ p += expr.length
324
+ te = p
325
+ end
326
+ when 3 then
327
+ # line 1 "NONE"
328
+ begin
329
+ te = p+1
330
+ end
331
+ when 4 then
332
+ # line 24 "lib/vorax/parser/grammars/column.rl"
333
+ begin
334
+ act = 1; end
335
+ when 5 then
336
+ # line 25 "lib/vorax/parser/grammars/column.rl"
337
+ begin
338
+ act = 2; end
339
+ when 6 then
340
+ # line 29 "lib/vorax/parser/grammars/column.rl"
341
+ begin
342
+ act = 6; end
343
+ when 7 then
344
+ # line 26 "lib/vorax/parser/grammars/column.rl"
345
+ begin
346
+ te = p+1
347
+ end
348
+ when 8 then
349
+ # line 27 "lib/vorax/parser/grammars/column.rl"
350
+ begin
351
+ te = p+1
352
+ end
353
+ when 9 then
354
+ # line 28 "lib/vorax/parser/grammars/column.rl"
355
+ begin
356
+ te = p+1
357
+ begin @columns << data[(ts..te)].gsub(/\s*,\s*$/, '') end
358
+ end
359
+ when 10 then
360
+ # line 29 "lib/vorax/parser/grammars/column.rl"
361
+ begin
362
+ te = p+1
363
+ end
364
+ when 11 then
365
+ # line 24 "lib/vorax/parser/grammars/column.rl"
366
+ begin
367
+ te = p
368
+ p = p - 1; end
369
+ when 12 then
370
+ # line 25 "lib/vorax/parser/grammars/column.rl"
371
+ begin
372
+ te = p
373
+ p = p - 1; end
374
+ when 13 then
375
+ # line 29 "lib/vorax/parser/grammars/column.rl"
376
+ begin
377
+ te = p
378
+ p = p - 1; end
379
+ when 14 then
380
+ # line 29 "lib/vorax/parser/grammars/column.rl"
381
+ begin
382
+ begin p = ((te))-1; end
383
+ end
384
+ when 15 then
385
+ # line 1 "NONE"
386
+ begin
387
+ case act
388
+ when 6 then
389
+ begin begin p = ((te))-1; end
390
+ end
391
+ else
392
+ begin begin p = ((te))-1; end
393
+ end
394
+ end
395
+ end
396
+ # line 397 "lib/vorax/parser/grammars/column.rb"
397
+ end # action switch
398
+ end
399
+ end
400
+ if _trigger_goto
401
+ next
402
+ end
403
+ end
404
+ if _goto_level <= _again
405
+ _acts = _column_to_state_actions[cs]
406
+ _nacts = _column_actions[_acts]
407
+ _acts += 1
408
+ while _nacts > 0
409
+ _nacts -= 1
410
+ _acts += 1
411
+ case _column_actions[_acts - 1]
412
+ when 1 then
413
+ # line 1 "NONE"
414
+ begin
415
+ ts = nil; end
416
+ # line 417 "lib/vorax/parser/grammars/column.rb"
417
+ end # to state action switch
418
+ end
419
+ if _trigger_goto
420
+ next
421
+ end
422
+ p += 1
423
+ if p != pe
424
+ _goto_level = _resume
425
+ next
426
+ end
427
+ end
428
+ if _goto_level <= _test_eof
429
+ if p == eof
430
+ if _column_eof_trans[cs] > 0
431
+ _trans = _column_eof_trans[cs] - 1;
432
+ _goto_level = _eof_trans
433
+ next;
434
+ end
435
+ end
436
+ end
437
+ if _goto_level <= _out
438
+ break
439
+ end
440
+ end
441
+ end
442
+
443
+ # line 54 "lib/vorax/parser/grammars/column.rl"
444
+ data.chop!
445
+ end
446
+ return @columns
447
+ end
448
+
449
+ end
450
+
451
+ end
452
+
453
+ end
454
+
@@ -0,0 +1,64 @@
1
+ %%{
2
+
3
+ machine column;
4
+
5
+ action expr_start {
6
+ expr = Parser.walk_balanced_paren(data[(p..-1)])
7
+ p += expr.length
8
+ te = p
9
+ }
10
+
11
+ include common "common.rl";
12
+
13
+ # a bracket expression
14
+ expression = '(' >expr_start;
15
+
16
+ # means of a column
17
+ star = '*';
18
+ plain_column = identifier | star;
19
+ column_with_ref = identifier '.' plain_column;
20
+ column_with_owner = identifier '.' identifier '.' plain_column;
21
+ column_spot = (column_with_owner | column_with_ref | plain_column) ws* ',';
22
+
23
+ main := |*
24
+ squoted_string;
25
+ dquoted_string;
26
+ comment;
27
+ expression;
28
+ column_spot => { @columns << data[(ts..te)].gsub(/\s*,\s*$/, '') };
29
+ any => {};
30
+ *|;
31
+
32
+ }%%
33
+
34
+ module Vorax
35
+
36
+ module Parser
37
+
38
+ # An abstraction for SQL columns.
39
+ class Column
40
+
41
+ # Given a statement, it walks it in search for a column list. If the statement
42
+ # contains more than one query, the first defined list is returned.
43
+ #
44
+ # @param data the statement to be walked
45
+ # @return the string with the column list
46
+ def walk(data)
47
+ @columns = []
48
+ if data
49
+ data << ","
50
+ eof = data.length
51
+ %% write data;
52
+ %% write init;
53
+ %% write exec;
54
+ data.chop!
55
+ end
56
+ return @columns
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+