oracle-sql-parser 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 809b6d47e50c4330d56e67f5b5e466280868e868
4
- data.tar.gz: 85083da0a0d2743e599c3a8998b057e0ed807f0a
3
+ metadata.gz: 2ca85fca6a5a499cfd899ec639203fd2ec3cd499
4
+ data.tar.gz: ffa6d405cc453774b56b5c304835aff5e26aa41b
5
5
  SHA512:
6
- metadata.gz: c019067407242c554ccc49f97401e99f9c896ab4369b637fcd93b8f67e65b6ad95dfc72d5ea47aaac7e8aefcb0d4c58a839825bc5c2c94a7b25d377df02599b2
7
- data.tar.gz: 6911dd676c0398c238f42bd1d0e41443ed883d0a0eb70705ea0a9112b14f1876fe3bf29dbe19ca53a3cf11e7eb996e852cdd7bf320b1568a911315eda9a8ecce
6
+ metadata.gz: 4e104b3c6ffac399c5b022871c6305eae5b84cdba4a6b3a84a29d6b5a8ad197c428946c5ac3321491b98c3d6e985b09a13d1c910b5e6c92ca223d371e9e671b5
7
+ data.tar.gz: 39ee53de849e013c2a86399fd6780a201729b4fbd68f7c2e24ee76edca4b08fa914e97c933a1ecd7be9ba1dbbb80487e73636ab646fb8afab9bdebf75f5489ce
data/HISTORY.md CHANGED
@@ -1,11 +1,24 @@
1
+ <<<<<<< HEAD
2
+ ### next version
3
+ * Syntax
4
+ * subquery https://github.com/jksy/sql_parser/issues/8
5
+ * "select col1 from table1 union select col2 from table2 union select col3 from table3"
6
+ * "select col1 from table1 union (select col2 from table2)"
7
+ * compound expression https://github.com/jksy/sql_parser/issues/8
8
+ * "select 1-1 from table1"
9
+ * Broken changes
10
+ * select_list.
11
+ Ast::Array[ Ast::Ident[..], Ast::Ident[..]] Ast::Array[ Ast::SelectColumn[:expr => Ast::Ident[..]],...]
12
+
1
13
  ### 0.7.0
2
- * Enchancement
3
- * added syntax table alias, like "select a.* from table1 a". https://github.com/jksy/sql_parser/issues/8
14
+ * Syntax
15
+ * table alias, like "select a.* from table1 a". https://github.com/jksy/sql_parser/issues/8
4
16
 
5
17
  ### 0.6.0
6
18
  * Enchancement
7
19
  * added travis-ci
8
20
  * added oracle enhanced adapter query(select, includes, joins, where)
21
+ * Syntax
9
22
  * added syntax for column_alias
10
23
 
11
24
  ### 0.5.1
@@ -17,17 +30,17 @@
17
30
  * added NumberLiteral#to_cecimal, TextLiteral#to_s
18
31
 
19
32
  ### 0.4.0
20
- * Enchancement
33
+ * Bugfix
21
34
  * rename ParameternizedQuery#query -> ParameternizedQuery#to_sql
22
- * added grammer
23
- * union [all]
24
- * intersect
25
- * minus
26
- * [inner|outer] join
27
- * conditions
28
- * floating point condition
29
- * multiset condition
30
- * is_of_type condition
35
+ * Syntax
36
+ * union [all]
37
+ * intersect
38
+ * minus
39
+ * [inner|outer] join
40
+ * conditions
41
+ * floating point condition
42
+ * multiset condition
43
+ * is_of_type condition
31
44
 
32
45
  ### 0.3.0
33
46
  * Enchancement
@@ -42,7 +55,7 @@
42
55
  * refactor test cases
43
56
 
44
57
  ### 0.1.1
45
- * Enchancement
58
+ * Syntax
46
59
  * support double-quoted identifer
47
60
 
48
61
  ### 0.1.0
data/README.md CHANGED
@@ -33,23 +33,31 @@ end
33
33
  ast = syntax_tree.ast
34
34
  ```
35
35
  <pre>
36
- =&gt; #&lt;OracleSqlParser::Ast::SelectStatement
37
- :subquery =&gt; #&lt;OracleSqlParser::Ast::Subquery
38
- :query_block =&gt; #&lt;OracleSqlParser::Ast::QueryBlock
39
- :hint =&gt; nil,
40
- :modifier =&gt; nil,
41
- :select_list =&gt; #&lt;OracleSqlParser::Ast::Array [
42
- #&lt;OracleSqlParser::Ast::NumberLiteral {:value=&gt;"1"}&gt;
43
- ]&gt;
44
- ,
45
- :select_sources =&gt; #&lt;OracleSqlParser::Ast::TableReference {:schema_name=&gt;nil, :table_name=&gt;#&lt;OracleSqlParser::Ast::Identifier {:name=&gt;"dual"}&gt;, :dblink=&gt;nil}&gt;,
46
- :where_clause =&gt; nil,
47
- :group_by_clause =&gt; nil,
48
- :model_clause =&gt; nil}&gt;
36
+ =&gt; #&lt;OracleSqlParser::Ast::SelectStatement {:subquery=&gt;#&lt;OracleSqlParser::Ast::Subquery
37
+ :has_parenthesis =&gt; nil,
38
+ :query_block =&gt; #&lt;OracleSqlParser::Ast::QueryBlock
39
+ :hint =&gt; nil,
40
+ :modifier =&gt; nil,
41
+ :select_list =&gt; #&lt;OracleSqlParser::Ast::Array [
42
+ #&lt;OracleSqlParser::Ast::SelectColumn
43
+ :expr =&gt; #&lt;OracleSqlParser::Ast::NumberLiteral {:value=&gt;"1"}&gt;,
44
+ :as =&gt; nil,
45
+ :c_alias =&gt; nil}&gt;
46
+
47
+ ]&gt;
49
48
  ,
50
- :order_by_clause =&gt; nil}&gt;
49
+ :select_sources =&gt; #&lt;OracleSqlParser::Ast::Array [
50
+ #&lt;OracleSqlParser::Ast::TableReference {:schema_name=&gt;nil, :table_name=&gt;#&lt;OracleSqlParser::Ast::Identifier {:name=&gt;"dual"}&gt;, :dblink=&gt;nil, :subquery=&gt;nil, :table_alias=&gt;nil}&gt;
51
+ ]&gt;
52
+ ,
53
+ :where_clause =&gt; nil,
54
+ :group_by_clause =&gt; nil,
55
+ :model_clause =&gt; nil}&gt;
51
56
  ,
52
- :for_update_clause =&gt; nil}&gt;
57
+ :subqueries =&gt; nil,
58
+ :subquery =&gt; nil,
59
+ :order_by_clause =&gt; nil}&gt;
60
+ , :for_update_clause=&gt;nil}&gt;=> nil
53
61
  </pre>
54
62
 
55
63
  ```ruby
data/Rakefile CHANGED
@@ -47,18 +47,29 @@ end
47
47
 
48
48
 
49
49
  def generate_parser_files(force = false)
50
- sh "ruby lib/oracle-sql-parser/grammar/reserved_word_generator.rb"
50
+ word_generator = "lib/oracle-sql-parser/grammar/reserved_word_generator.rb"
51
+ output = "lib/oracle-sql-parser/grammar/reserved_word.treetop"
52
+ do_if_changed(word_generator, output, force) do
53
+ sh "ruby #{word_generator}"
54
+ end
55
+
51
56
  GRAMMAR_FILES.each do |f|
52
57
  tt(f, force)
53
58
  end
54
59
  end
55
60
 
56
61
  def tt(f, force = false)
57
- output_file_name = "#{f.gsub(/\.treetop$/,'')}.rb"
62
+ output = "#{f.gsub(/\.treetop$/,'')}.rb"
63
+
64
+ do_if_changed(f, output, force) do
65
+ sh "tt #{f} -f -o #{output}"
66
+ end
67
+ end
58
68
 
59
- force = true unless File.exists?(output_file_name)
60
- if force || File::Stat.new(f).mtime >= File::Stat.new(output_file_name).mtime
61
- sh "tt #{f} -f -o #{output_file_name}"
69
+ def do_if_changed(src, output, force = false, &block)
70
+ force = true unless File.exists?(output)
71
+ if force || File::Stat.new(src).mtime >= File::Stat.new(output).mtime
72
+ yield
62
73
  end
63
74
  end
64
75
 
@@ -7,6 +7,7 @@ require 'oracle-sql-parser/ast/base.rb'
7
7
  require 'oracle-sql-parser/ast/array.rb'
8
8
  require 'oracle-sql-parser/ast/hash.rb'
9
9
  require 'oracle-sql-parser/ast/select_statement.rb'
10
+ require 'oracle-sql-parser/ast/select_column.rb'
10
11
  require 'oracle-sql-parser/ast/subquery.rb'
11
12
  require 'oracle-sql-parser/ast/query_block.rb'
12
13
  require 'oracle-sql-parser/ast/inner_cross_join_clause.rb'
@@ -40,6 +41,7 @@ require 'oracle-sql-parser/ast/order_by_clause_item.rb'
40
41
  require 'oracle-sql-parser/ast/update_statement.rb'
41
42
  require 'oracle-sql-parser/ast/update_set_column.rb'
42
43
  require 'oracle-sql-parser/ast/update_set_clause.rb'
44
+ require 'oracle-sql-parser/ast/compound_expression.rb'
43
45
  require 'oracle-sql-parser/ast/simple_case_expression.rb'
44
46
  require 'oracle-sql-parser/ast/searched_case_expression.rb'
45
47
  require 'oracle-sql-parser/ast/function_expression.rb'
@@ -0,0 +1,15 @@
1
+ module OracleSqlParser::Ast
2
+ class CompoundExpression < Hash
3
+ def to_sql(options = {})
4
+ r = @ast.values_at(:left,
5
+ :op,
6
+ :right,
7
+ ).map(&:to_sql)
8
+ if @ast[:has_parenthesis]
9
+ r.unshift('(')
10
+ r.push(')')
11
+ end
12
+ r.compact.join(' ')
13
+ end
14
+ end
15
+ end
@@ -1,6 +1,6 @@
1
1
  module OracleSqlParser::Ast
2
2
  class CrossNaturalJoinClause < InnerCrossJoinClause
3
- def to_sql
3
+ def to_sql(options = {})
4
4
  @ast.values_at(:table1, :cross, :natural, :inner, :join, :table2).
5
5
  compact.map(&:to_sql).join(' ')
6
6
  end
@@ -1,5 +1,5 @@
1
1
  module OracleSqlParser::Ast
2
- class FunctionExpressoin < Hash
2
+ class FunctionExpression < Hash
3
3
  def to_sql(options = {})
4
4
  sql = []
5
5
  sql << @ast[:name].to_sql
@@ -1,6 +1,6 @@
1
1
  module OracleSqlParser::Ast
2
2
  class InnerJoinClause < InnerCrossJoinClause
3
- def to_sql
3
+ def to_sql(options = {})
4
4
  @ast.values_at(:table1, :inner, :join, :table2, :on_or_using_clause).
5
5
  map(&:to_sql).compact.join(' ')
6
6
  end
@@ -4,7 +4,7 @@ module OracleSqlParser::Ast
4
4
  @ast[:table1] = value
5
5
  end
6
6
 
7
- def to_sql
7
+ def to_sql(options = {})
8
8
  @ast.values_at(:table1, :natural, :join_type, :outer, :join, :table2, :on_or_using_clause).
9
9
  compact.map(&:to_sql).join(' ')
10
10
  end
@@ -5,9 +5,9 @@ module OracleSqlParser::Ast
5
5
  "select",
6
6
  @ast[:hint],
7
7
  @ast[:modifier],
8
- @ast[:select_list].map(&:to_sql).join(','),
8
+ @ast[:select_list].to_sql(:separator => ','),
9
9
  "from",
10
- @ast[:select_sources],
10
+ @ast[:select_sources].to_sql(:separator => ','),
11
11
  @ast[:where_clause],
12
12
  @ast[:group_by_clause],
13
13
  @ast[:model_clause]
@@ -0,0 +1,7 @@
1
+ module OracleSqlParser::Ast
2
+ class SelectColumn < Hash
3
+ def to_sql(options = {})
4
+ @ast.values_at(:expr, :as, :c_alias).compact.map(&:to_sql).join(' ')
5
+ end
6
+ end
7
+ end
@@ -1,9 +1,7 @@
1
1
  module OracleSqlParser::Ast
2
2
  class SelectStatement < Hash
3
3
  def to_sql(options = {})
4
- sql = @ast[:subquery].to_sql
5
- sql += " #{@ast[:for_update_clause].to_sql}" if @ast[:for_update_clause]
6
- sql
4
+ @ast.values_at(:subquery, :for_update_clause).compact.map(&:to_sql).join(' ')
7
5
  end
8
6
  end
9
7
  end
@@ -1,23 +1,15 @@
1
1
  module OracleSqlParser::Ast
2
2
  class Subquery < Hash
3
3
  def to_sql(options = {})
4
- if @ast[:union]
5
- [
6
- @ast[:query_block1],
7
- @ast[:union].map(&:to_sql).join(' '),
8
- @ast[:query_block2],
9
- @ast[:order_by_clause],
10
- ].compact.map(&:to_sql).join(' ')
11
- else
12
- [
13
- @ast[:query_block],
14
- @ast[:order_by_clause]
15
- ].compact.map(&:to_sql).join(' ')
4
+ result = @ast.values_at(:query_block,
5
+ :subqueries,
6
+ :subquery,
7
+ :order_by_clause).map(&:to_sql)
8
+ if @ast[:has_parenthesis]
9
+ result.unshift('(')
10
+ result.push(')')
16
11
  end
17
- end
18
-
19
- def order_by_clause=(value)
20
- @ast[:order_by_clause] = value
12
+ result.compact.map(&:to_sql).join(' ')
21
13
  end
22
14
  end
23
15
  end
@@ -8,8 +8,9 @@ module OracleSqlParser::Ast
8
8
  def to_sql(options = {})
9
9
  result = ''
10
10
  result += "#{@ast[:schema_name].to_sql}." if @ast[:schema_name]
11
- result += @ast[:table_name].to_sql
11
+ result += @ast[:table_name].to_sql if @ast[:table_name]
12
12
  result += "@#{@ast[:dblink].to_sql}" if @ast[:dblink]
13
+ result += @ast[:subquery].to_sql if @ast[:subquery]
13
14
  result += " #{@ast[:table_alias].to_sql}" if @ast[:table_alias]
14
15
  result
15
16
  end
@@ -1,9 +1,8 @@
1
1
  module OracleSqlParser::Grammar
2
2
  grammar Delete
3
3
  rule delete_statement
4
- delete_keyword space?
5
- delete_from_clause space?
6
- delete_condition:delete_condition?
4
+ delete_keyword space delete_from_clause
5
+ condition:(space delete_condition)?
7
6
  returning_clause:returning_clause? {
8
7
  def ast
9
8
  OracleSqlParser::Ast::DeleteStatement[
@@ -11,11 +10,15 @@ module OracleSqlParser::Grammar
11
10
  :where_clause => delete_condition.ast
12
11
  ]
13
12
  end
13
+
14
+ def delete_condition
15
+ condition.delete_condition if condition.respond_to? :delete_condition
16
+ end
14
17
  }
15
18
  end
16
19
 
17
20
  rule delete_from_clause
18
- from_keyword space? delete_target {
21
+ from_keyword space delete_target {
19
22
  def ast
20
23
  delete_target.ast
21
24
  end
@@ -26,8 +29,8 @@ module OracleSqlParser::Grammar
26
29
  t:(
27
30
  table_reference /
28
31
  delete_target_subquery
29
- ) space?
30
- t_alias:t_alias? {
32
+ )
33
+ a:(space t_alias)? {
31
34
  def ast
32
35
  table_or_subquery = t.ast
33
36
  if table_or_subquery.instance_of? OracleSqlParser::Ast::DeleteTarget
@@ -39,6 +42,10 @@ module OracleSqlParser::Grammar
39
42
  ]
40
43
  end
41
44
  end
45
+
46
+ def t_alias
47
+ a.t_alias if a.respond_to? :t_alias
48
+ end
42
49
  }
43
50
  end
44
51
 
@@ -54,7 +61,7 @@ module OracleSqlParser::Grammar
54
61
  end
55
62
 
56
63
  rule delete_condition
57
- where_keyword space?
64
+ where_keyword space
58
65
  where:(
59
66
  search_condition /
60
67
  delete_current_of
@@ -2,10 +2,10 @@ module OracleSqlParser::Grammar
2
2
  grammar Expression
3
3
  rule sql_expression
4
4
  ex:(
5
+ compound_expression /
5
6
  function_expression /
6
7
  case_expression /
7
8
  cursor_expression /
8
- compound_expression /
9
9
  datetime_expression /
10
10
  interval_expression /
11
11
  object_access_expression /
@@ -13,14 +13,15 @@ module OracleSqlParser::Grammar
13
13
  model_expression /
14
14
  type_constructor_expression /
15
15
  simple_expression /
16
- variable_expression)
17
- alias_name:(space as_keyword space ident)?
18
- {
16
+ variable_expression
17
+ ) {
19
18
  def ast
20
- tree = ex.ast
21
- tree[:as] = alias_name.try(:as_keyword).try(:ast)
22
- tree[:alias] = alias_name.try(:ident).try(:ast)
23
- tree
19
+ ex.ast
20
+ # super
21
+ # tree = ex.ast
22
+ ## tree[:as] = alias_name.try(:as_keyword).try(:ast)
23
+ # tree[:alias] = alias_name.try(:ident).try(:ast)
24
+ # tree
24
25
  end
25
26
  }
26
27
  end
@@ -51,13 +52,63 @@ module OracleSqlParser::Grammar
51
52
  }
52
53
  end
53
54
 
55
+ rule not_compound_expressions
56
+ ex:(
57
+ function_expression /
58
+ case_expression /
59
+ cursor_expression /
60
+ datetime_expression /
61
+ interval_expression /
62
+ object_access_expression /
63
+ scalar_subquery_expression /
64
+ model_expression /
65
+ type_constructor_expression /
66
+ simple_expression /
67
+ variable_expression)
68
+ {
69
+ def ast
70
+ ex.ast
71
+ end
72
+ }
73
+ end
74
+
54
75
  rule compound_expression
55
- 'compound_expression' # not implemented
56
- # (
57
- # ('+' / '-' / prior_keyword) space? expr /
58
- # (expr space? ('||' / '*' / '/' / '+' / '-') space? expr) /
59
- # '(' space? expr space? ')'
60
- # )
76
+ ex:(
77
+ left_parenthesis:'(' space? left:expr space? right_parenthesis:')' /
78
+ left:not_compound_expressions space? op:('*' / '/' / '+' / '-' / '||') space? right:expr /
79
+ !number_literal op:(prior_keyword / '-' / '+') space? right:expr
80
+ )
81
+
82
+ {
83
+ def ast
84
+ OracleSqlParser::Ast::CompoundExpression[
85
+ :has_parenthesis => ex.respond_to?(:left_parenthesis) ? true : nil,
86
+ :left => left.ast,
87
+ :op => op.ast,
88
+ :right => right.ast,
89
+ ]
90
+ end
91
+
92
+ def left
93
+ ex.left if ex.respond_to? :left
94
+ end
95
+
96
+ def not_compound_expressions
97
+ ex.not_compound_expressions if ex.respond_to? :not_compound_expressions
98
+ end
99
+
100
+ def op
101
+ ex.op if ex.respond_to? :op
102
+ end
103
+
104
+ def right
105
+ ex.right if ex.respond_to? :right
106
+ end
107
+
108
+ def right_parenthesis
109
+ ex.right_parenthesis if ex.respond_to? :right_parenthesis
110
+ end
111
+ }
61
112
  end
62
113
 
63
114
  rule case_expression
@@ -145,7 +196,7 @@ module OracleSqlParser::Grammar
145
196
  rule function_expression
146
197
  function_name space? '(' space? function_args:function_args? space? ')' {
147
198
  def ast
148
- OracleSqlParser::Ast::FunctionExpressoin[
199
+ OracleSqlParser::Ast::FunctionExpression[
149
200
  :name => function_name.ast,
150
201
  :args => function_args.ast
151
202
  ]
@@ -134,6 +134,7 @@ module OracleSqlParser::Grammar
134
134
 
135
135
  rule table_reference
136
136
  t:(
137
+ &'(' space? subquery /
137
138
  schema_name:schema_name '.' table_name:table_name /
138
139
  table_name:table_name
139
140
  ) l:('@' dblink)? a:(space t_alias)? {
@@ -142,6 +143,7 @@ module OracleSqlParser::Grammar
142
143
  :schema_name => t.try(:schema_name).ast,
143
144
  :table_name => t.try(:table_name).ast,
144
145
  :dblink => l.try(:dblink).ast,
146
+ :subquery => t.try(:subquery).ast,
145
147
  :table_alias => a.try(:t_alias).ast,
146
148
  ]
147
149
  end
@@ -1,49 +1,63 @@
1
1
  module OracleSqlParser::Grammar
2
2
  grammar Select
3
3
  rule select_statement
4
- subquery for_update_clause:for_update_clause? {
4
+ space? subquery for_update:(space for_update_clause)? space? {
5
5
  def ast
6
6
  OracleSqlParser::Ast::SelectStatement[
7
7
  :subquery => subquery.ast,
8
- :for_update_clause => for_update_clause.ast]
8
+ :for_update_clause => for_update.try(:for_update_clause).ast
9
+ ]
9
10
  end
10
11
  }
11
12
  end
12
13
 
13
14
  rule subquery
14
15
  query:(
15
- subquery_with_union /
16
- subquery_only_query_block
16
+ left_parenthesis:'(' space? subquery space? right_parenthesis:')' /
17
+ query_block !(space union_or_intersect_or_minus) /
18
+ subqueries:subqueries_with_union
17
19
  )
18
- space? order_by_clause:order_by_clause? {
20
+ order:(space order_by_clause)? {
19
21
  def ast
20
- result = query.ast
21
- result.order_by_clause = order_by_clause.ast
22
- result
22
+ OracleSqlParser::Ast::Subquery[
23
+ :has_parenthesis => has_parenthesis,
24
+ :query_block => query_block.ast,
25
+ :subqueries => subqueries.ast,
26
+ :subquery => subquery.ast,
27
+ :order_by_clause => order.try(:order_by_clause).ast,
28
+ ]
29
+ end
30
+
31
+ def has_parenthesis
32
+ true if query.respond_to? :left_parenthesis
33
+ end
34
+
35
+ def query_block
36
+ query.query_block if query.respond_to? :query_block
37
+ end
38
+
39
+ def subqueries
40
+ query.subqueries if query.respond_to? :subqueries
41
+ end
42
+
43
+ def subquery
44
+ query.subquery if query.respond_to? :subquery
23
45
  end
24
46
  }
25
47
  end
26
48
 
27
- rule subquery_only_query_block
28
- '(' space? query_block:query_block space? ')' /
29
- query_block:query_block {
49
+ rule subqueries_with_union
50
+ query_block space? more:(union_or_intersect_or_minus space? subquery)+
51
+ {
30
52
  def ast
31
- OracleSqlParser::Ast::Subquery[
32
- :query_block => query_block.ast
53
+ OracleSqlParser::Ast::Array[
54
+ query_block.ast,
55
+ *more_queries.map(&:ast),
33
56
  ]
34
57
  end
35
- }
36
- end
37
58
 
38
- rule subquery_with_union
39
- '(' query_block1:query_block space? union_or_intersect_or_minus space? query_block2:query_block ')' /
40
- query_block1:query_block space? union_or_intersect_or_minus space? query_block2:query_block {
41
- def ast
42
- OracleSqlParser::Ast::Subquery[
43
- :query_block1 => query_block1.ast,
44
- :union => union_or_intersect_or_minus.ast,
45
- :query_block2 => query_block2.ast
46
- ]
59
+ def more_queries
60
+ more.elements.map{|e| [e.union_or_intersect_or_minus, e.subquery]}.flatten
47
61
  end
48
62
  }
49
63
  end
@@ -82,21 +96,21 @@ module OracleSqlParser::Grammar
82
96
  select_keyword space
83
97
  hint:hint?
84
98
  mod:(modifier:(all_keyword / distinct_keyword / unique_keyword) space)?
85
- select_list space?
86
- from_keyword space?
87
- select_sources space?
88
- where_clause:where_clause? space?
89
- group_by_clause:group_by_clause? space?
90
- model_clause:model_clause? space? {
99
+ select_list space
100
+ from_keyword
101
+ select:(space select_sources)?
102
+ where:(space where_clause)?
103
+ group:(space group_by_clause)?
104
+ model:(space model_clause)? {
91
105
  def ast
92
106
  OracleSqlParser::Ast::QueryBlock[
93
107
  :hint => hint.ast,
94
108
  :modifier => modifier.ast,
95
109
  :select_list => select_list.ast,
96
- :select_sources => select_sources.ast,
97
- :where_clause => where_clause.ast,
98
- :group_by_clause => group_by_clause.ast,
99
- :model_clause => model_clause.ast]
110
+ :select_sources => select.try(:select_sources).ast,
111
+ :where_clause => where.try(:where_clause).ast,
112
+ :group_by_clause => group.try(:group_by_clause).ast,
113
+ :model_clause => model.try(:model_clause).ast]
100
114
  end
101
115
 
102
116
  def modifier
@@ -106,9 +120,26 @@ module OracleSqlParser::Grammar
106
120
  end
107
121
 
108
122
  rule select_sources
123
+ select_source more:(space? ',' space? select_source)* {
124
+ def ast
125
+ OracleSqlParser::Ast::Array[
126
+ select_source.ast,
127
+ *more_select_sources.map(&:ast),
128
+ ]
129
+ end
130
+
131
+ def more_select_sources
132
+ more.elements.map(&:select_source)
133
+ end
134
+ }
135
+ end
136
+
137
+ rule select_source
109
138
  join_clause /
110
139
  '(' space? join_clause:join_clause space? ')' /
111
- table_reference {
140
+ table_reference /
141
+ subquery
142
+ {
112
143
  def ast
113
144
  if respond_to? :join_clause
114
145
  join_clause.ast
@@ -281,12 +312,11 @@ module OracleSqlParser::Grammar
281
312
  end
282
313
 
283
314
  rule for_update_clause
284
- for_keyword space?
285
- update_keyword space?
286
- of:(of_keyword space for_update_clause_columns space?)?
315
+ for_keyword space update_keyword
316
+ of:(space of_keyword space for_update_clause_columns)?
287
317
  wait:(
288
- w:wait_keyword space? time:integer /
289
- w:nowait_keyword
318
+ space w:wait_keyword space time:integer /
319
+ space w:nowait_keyword
290
320
  )? {
291
321
  def ast
292
322
  OracleSqlParser::Ast::ForUpdateClause[
@@ -299,7 +329,7 @@ module OracleSqlParser::Grammar
299
329
  end
300
330
 
301
331
  rule for_update_clause_columns
302
- for_update_clause_column more:(space? ',' space? more_for_update_clause_columns:for_update_clause_column)* {
332
+ for_update_clause_column more:(space? ',' space? for_update_clause_column)* {
303
333
  def ast
304
334
  OracleSqlParser::Ast::Array[
305
335
  for_update_clause_column.ast, *more_for_update_clause_columns.map(&:ast)
@@ -307,7 +337,7 @@ module OracleSqlParser::Grammar
307
337
  end
308
338
 
309
339
  def more_for_update_clause_columns
310
- more.elements.map(&:more_for_update_clause_columns)
340
+ more.elements.map(&:for_update_clause_column)
311
341
  end
312
342
  }
313
343
  end
@@ -381,22 +411,21 @@ module OracleSqlParser::Grammar
381
411
  end
382
412
 
383
413
  rule select_list
384
- select_one_column more_list:( space? ',' space? c:select_one_column space? )* {
414
+ select_one more_list:( space? ',' space? select_one)* {
385
415
  def ast
386
- OracleSqlParser::Ast::Array[select_one_column.ast, *more_columns.map(&:ast)]
416
+ OracleSqlParser::Ast::Array[select_one.ast, *more_columns.map(&:ast)]
387
417
  end
388
418
 
389
419
  def more_columns
390
- more_list.elements.map{|element| element.c}
420
+ more_list.elements.map(&:select_one)
391
421
  end
392
422
  }
393
423
  end
394
424
 
395
- rule select_one_column
396
- ( select_table /
397
- expr /
425
+ rule select_one
426
+ select_table /
398
427
  select_column
399
- ) {
428
+ {
400
429
  def ast
401
430
  super
402
431
  end
@@ -412,9 +441,25 @@ module OracleSqlParser::Grammar
412
441
  end
413
442
 
414
443
  rule select_column
415
- sql_expression ( space ( as_keyword space )? c_alias )? {
444
+ expr _alias:( space as:( as_keyword space )? c_alias )? {
416
445
  def ast
417
- sql_expression.ast
446
+ OracleSqlParser::Ast::SelectColumn[
447
+ :expr => expr.ast,
448
+ :as => as_keyword.ast,
449
+ :c_alias => c_alias.ast,
450
+ ]
451
+ end
452
+
453
+ def c_alias
454
+ if _alias.respond_to? :c_alias
455
+ _alias.c_alias
456
+ end
457
+ end
458
+
459
+ def as_keyword
460
+ if respond_to? :_alias and _alias.respond_to? :as
461
+ _alias.as.as_keyword
462
+ end
418
463
  end
419
464
  }
420
465
  end
@@ -1,3 +1,3 @@
1
1
  module OracleSqlParser
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.0"
3
3
  end
@@ -26,4 +26,6 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "activerecord", "~> 4.2"
27
27
  spec.add_development_dependency "activerecord-oracle_enhanced-adapter", "~> 1.6.0"
28
28
  spec.add_development_dependency "ruby-oci8", "~> 2.0"
29
+ spec.add_development_dependency "pry-byebug", "3.4.0" if RUBY_VERSION >= '2.0.0'
30
+ spec.add_development_dependency "colorize", "~> 0.8"
29
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oracle-sql-parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Junichiro Kasuya
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-02 00:00:00.000000000 Z
11
+ date: 2016-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: treetop
@@ -108,6 +108,34 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '2.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pry-byebug
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '='
116
+ - !ruby/object:Gem::Version
117
+ version: 3.4.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '='
123
+ - !ruby/object:Gem::Version
124
+ version: 3.4.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: colorize
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.8'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.8'
111
139
  description: SQL Parser for Oracle
112
140
  email:
113
141
  - junichiro.kasuya@gmail.com
@@ -126,6 +154,7 @@ files:
126
154
  - lib/oracle-sql-parser/ast/base.rb
127
155
  - lib/oracle-sql-parser/ast/between_condition.rb
128
156
  - lib/oracle-sql-parser/ast/compound_condition.rb
157
+ - lib/oracle-sql-parser/ast/compound_expression.rb
129
158
  - lib/oracle-sql-parser/ast/cross_natural_join_clause.rb
130
159
  - lib/oracle-sql-parser/ast/current_of.rb
131
160
  - lib/oracle-sql-parser/ast/delete_statement.rb
@@ -160,6 +189,7 @@ files:
160
189
  - lib/oracle-sql-parser/ast/regexp_condition.rb
161
190
  - lib/oracle-sql-parser/ast/rollup_cube_clause.rb
162
191
  - lib/oracle-sql-parser/ast/searched_case_expression.rb
192
+ - lib/oracle-sql-parser/ast/select_column.rb
163
193
  - lib/oracle-sql-parser/ast/select_statement.rb
164
194
  - lib/oracle-sql-parser/ast/simple_case_expression.rb
165
195
  - lib/oracle-sql-parser/ast/simple_comparision_condition.rb