oracle-sql-parser 0.7.0 → 0.8.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 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