alf-sql 0.15.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.
Files changed (121) hide show
  1. data/CHANGELOG.md +5 -0
  2. data/Gemfile +13 -0
  3. data/Gemfile.lock +38 -0
  4. data/LICENCE.md +22 -0
  5. data/Manifest.txt +12 -0
  6. data/README.md +52 -0
  7. data/Rakefile +11 -0
  8. data/lib/alf-sql.rb +1 -0
  9. data/lib/alf/algebra/operand.rb +18 -0
  10. data/lib/alf/predicate/nodes.rb +20 -0
  11. data/lib/alf/predicate/nodes/and.rb +11 -0
  12. data/lib/alf/predicate/nodes/contradiction.rb +12 -0
  13. data/lib/alf/predicate/nodes/dyadic_comp.rb +14 -0
  14. data/lib/alf/predicate/nodes/eq.rb +11 -0
  15. data/lib/alf/predicate/nodes/exists.rb +14 -0
  16. data/lib/alf/predicate/nodes/expr.rb +20 -0
  17. data/lib/alf/predicate/nodes/gt.rb +11 -0
  18. data/lib/alf/predicate/nodes/gte.rb +11 -0
  19. data/lib/alf/predicate/nodes/identifier.rb +12 -0
  20. data/lib/alf/predicate/nodes/in.rb +31 -0
  21. data/lib/alf/predicate/nodes/literal.rb +12 -0
  22. data/lib/alf/predicate/nodes/lt.rb +11 -0
  23. data/lib/alf/predicate/nodes/lte.rb +11 -0
  24. data/lib/alf/predicate/nodes/nadic_bool.rb +18 -0
  25. data/lib/alf/predicate/nodes/native.rb +11 -0
  26. data/lib/alf/predicate/nodes/neq.rb +11 -0
  27. data/lib/alf/predicate/nodes/not.rb +14 -0
  28. data/lib/alf/predicate/nodes/or.rb +11 -0
  29. data/lib/alf/predicate/nodes/qualified_identifier.rb +12 -0
  30. data/lib/alf/predicate/nodes/tautology.rb +12 -0
  31. data/lib/alf/sql.rb +15 -0
  32. data/lib/alf/sql/builder.rb +152 -0
  33. data/lib/alf/sql/cog.rb +32 -0
  34. data/lib/alf/sql/compiler.rb +137 -0
  35. data/lib/alf/sql/grammar.rb +44 -0
  36. data/lib/alf/sql/grammar.sexp.yml +92 -0
  37. data/lib/alf/sql/loader.rb +2 -0
  38. data/lib/alf/sql/nodes/column_name.rb +25 -0
  39. data/lib/alf/sql/nodes/cross_join.rb +28 -0
  40. data/lib/alf/sql/nodes/except.rb +14 -0
  41. data/lib/alf/sql/nodes/expr.rb +90 -0
  42. data/lib/alf/sql/nodes/from_clause.rb +24 -0
  43. data/lib/alf/sql/nodes/inner_join.rb +37 -0
  44. data/lib/alf/sql/nodes/intersect.rb +14 -0
  45. data/lib/alf/sql/nodes/limit_clause.rb +19 -0
  46. data/lib/alf/sql/nodes/literal.rb +18 -0
  47. data/lib/alf/sql/nodes/name_intro.rb +23 -0
  48. data/lib/alf/sql/nodes/offset_clause.rb +19 -0
  49. data/lib/alf/sql/nodes/order_by_clause.rb +25 -0
  50. data/lib/alf/sql/nodes/order_by_term.rb +30 -0
  51. data/lib/alf/sql/nodes/qualified_name.rb +32 -0
  52. data/lib/alf/sql/nodes/range_var_name.rb +17 -0
  53. data/lib/alf/sql/nodes/select_exp.rb +101 -0
  54. data/lib/alf/sql/nodes/select_item.rb +37 -0
  55. data/lib/alf/sql/nodes/select_list.rb +31 -0
  56. data/lib/alf/sql/nodes/select_star.rb +15 -0
  57. data/lib/alf/sql/nodes/set_operator.rb +64 -0
  58. data/lib/alf/sql/nodes/set_quantifier.rb +20 -0
  59. data/lib/alf/sql/nodes/subquery_as.rb +28 -0
  60. data/lib/alf/sql/nodes/table_as.rb +31 -0
  61. data/lib/alf/sql/nodes/table_name.rb +17 -0
  62. data/lib/alf/sql/nodes/union.rb +14 -0
  63. data/lib/alf/sql/nodes/where_clause.rb +20 -0
  64. data/lib/alf/sql/nodes/with_exp.rb +50 -0
  65. data/lib/alf/sql/nodes/with_spec.rb +24 -0
  66. data/lib/alf/sql/processor.rb +85 -0
  67. data/lib/alf/sql/processor/all.rb +17 -0
  68. data/lib/alf/sql/processor/clip.rb +39 -0
  69. data/lib/alf/sql/processor/distinct.rb +17 -0
  70. data/lib/alf/sql/processor/flatten.rb +24 -0
  71. data/lib/alf/sql/processor/from_self.rb +29 -0
  72. data/lib/alf/sql/processor/join.rb +80 -0
  73. data/lib/alf/sql/processor/join_support.rb +27 -0
  74. data/lib/alf/sql/processor/limit_offset.rb +30 -0
  75. data/lib/alf/sql/processor/merge.rb +42 -0
  76. data/lib/alf/sql/processor/order_by.rb +32 -0
  77. data/lib/alf/sql/processor/rename.rb +25 -0
  78. data/lib/alf/sql/processor/reorder.rb +21 -0
  79. data/lib/alf/sql/processor/requalify.rb +24 -0
  80. data/lib/alf/sql/processor/semi_join.rb +57 -0
  81. data/lib/alf/sql/processor/star.rb +17 -0
  82. data/lib/alf/sql/processor/where.rb +25 -0
  83. data/lib/alf/sql/version.rb +16 -0
  84. data/spec/algebra/operand/test_to_sql.rb +32 -0
  85. data/spec/builder/test_order_by_clause.rb +44 -0
  86. data/spec/helpers/ast.rb +242 -0
  87. data/spec/helpers/compiler.rb +23 -0
  88. data/spec/nodes/column_name/test_as_name.rb +14 -0
  89. data/spec/nodes/column_name/test_qualifier.rb +14 -0
  90. data/spec/nodes/order_by_clause/test_to_ordering.rb +30 -0
  91. data/spec/nodes/order_by_term/test_as_name.rb +22 -0
  92. data/spec/nodes/order_by_term/test_direction.rb +22 -0
  93. data/spec/nodes/order_by_term/test_qualifier.rb +22 -0
  94. data/spec/nodes/select_exp/test_order_by_clause.rb +22 -0
  95. data/spec/nodes/select_item/test_as_name.rb +22 -0
  96. data/spec/predicate/nodes/exists/test_not.rb +20 -0
  97. data/spec/processor/clip/test_on_select_exp.rb +32 -0
  98. data/spec/processor/clip/test_on_select_list.rb +24 -0
  99. data/spec/processor/distinct/test_on_set_quantified.rb +31 -0
  100. data/spec/processor/from_self/test_on_nonjoin_exp.rb +60 -0
  101. data/spec/processor/from_self/test_on_with_exp.rb +22 -0
  102. data/spec/processor/merge/test_on_select_exp.rb +73 -0
  103. data/spec/processor/merge/test_on_with_exp.rb +56 -0
  104. data/spec/processor/order_by/test_on_select_exp.rb +24 -0
  105. data/spec/processor/rename/test_on_select_item.rb +30 -0
  106. data/spec/processor/rename/test_on_select_list.rb +22 -0
  107. data/spec/processor/reorder/test_on_select_list.rb +22 -0
  108. data/spec/processor/requalify/test_on_select_exp.rb +24 -0
  109. data/spec/processor/star/test_on_select_exp.rb +24 -0
  110. data/spec/processor/test_clip.rb +24 -0
  111. data/spec/processor/test_distinct.rb +24 -0
  112. data/spec/processor/test_on_select_exp.rb +28 -0
  113. data/spec/processor/test_on_set_operator.rb +28 -0
  114. data/spec/processor/test_rename.rb +24 -0
  115. data/spec/shared/compiled_examples.rb +13 -0
  116. data/spec/spec_helper.rb +14 -0
  117. data/spec/test_sql.rb +10 -0
  118. data/tasks/bench.rake +40 -0
  119. data/tasks/gem.rake +8 -0
  120. data/tasks/test.rake +6 -0
  121. metadata +235 -0
@@ -0,0 +1,30 @@
1
+ module Alf
2
+ module Sql
3
+ module OrderByTerm
4
+ include Expr
5
+
6
+ def qualified_name
7
+ self[1]
8
+ end
9
+
10
+ def qualifier
11
+ qualified_name.qualifier
12
+ end
13
+
14
+ def as_name
15
+ qualified_name.as_name
16
+ end
17
+
18
+ def direction
19
+ last
20
+ end
21
+
22
+ def to_sql(buffer = "")
23
+ self[1].to_sql(buffer)
24
+ buffer << SPACE << direction.upcase
25
+ buffer
26
+ end
27
+
28
+ end # module OrderByTerm
29
+ end # module Sql
30
+ end # module Alf
@@ -0,0 +1,32 @@
1
+ module Alf
2
+ module Sql
3
+ #
4
+ # [:qualified_name,
5
+ # [:range_var_name `qualifier`],
6
+ # [:column_name, `as_name`] ]
7
+ #
8
+ module QualifiedName
9
+ include Expr
10
+
11
+ def qualifier
12
+ self[1].qualifier
13
+ end
14
+
15
+ def as_name
16
+ last.as_name
17
+ end
18
+
19
+ def would_be_name
20
+ as_name
21
+ end
22
+
23
+ def to_sql(buffer = "")
24
+ self[1].to_sql(buffer)
25
+ buffer << '.'
26
+ self[2].to_sql(buffer)
27
+ buffer
28
+ end
29
+
30
+ end # module QualifiedName
31
+ end # module Sql
32
+ end # module Alf
@@ -0,0 +1,17 @@
1
+ module Alf
2
+ module Sql
3
+ module RangeVarName
4
+ include Expr
5
+
6
+ def qualifier
7
+ last
8
+ end
9
+
10
+ def to_sql(buffer = "")
11
+ buffer << last
12
+ buffer
13
+ end
14
+
15
+ end # module RangeVarName
16
+ end # module Sql
17
+ end # module Alf
@@ -0,0 +1,101 @@
1
+ module Alf
2
+ module Sql
3
+ module SelectExp
4
+ include Expr
5
+
6
+ SELECT_DISTINCT = "SELECT DISTINCT".freeze
7
+
8
+ SELECT = "SELECT".freeze
9
+
10
+ def set_quantifier
11
+ self[1]
12
+ end
13
+
14
+ def with_exp?
15
+ false
16
+ end
17
+
18
+ def distinct?
19
+ set_quantifier.distinct?
20
+ end
21
+
22
+ def all?
23
+ set_quantifier.all?
24
+ end
25
+
26
+ def join?
27
+ from_clause && from_clause.join?
28
+ end
29
+
30
+ def should_be_reused?
31
+ join? or distinct? or complex_clause?
32
+ end
33
+
34
+ def complex_clause?
35
+ where_clause or order_by_clause or limit_clause or offset_clause
36
+ end
37
+
38
+ def select_exp
39
+ self
40
+ end
41
+
42
+ def select_list
43
+ self[2]
44
+ end
45
+
46
+ def where_clause
47
+ find_child(:where_clause)
48
+ end
49
+
50
+ def predicate
51
+ where_clause && where_clause.predicate
52
+ end
53
+
54
+ def from_clause
55
+ find_child(:from_clause)
56
+ end
57
+
58
+ def table_spec
59
+ from_clause.table_spec
60
+ end
61
+
62
+ def order_by_clause
63
+ find_child(:order_by_clause)
64
+ end
65
+
66
+ def limit_clause
67
+ find_child(:limit_clause)
68
+ end
69
+
70
+ def offset_clause
71
+ find_child(:offset_clause)
72
+ end
73
+
74
+ def desaliaser
75
+ select_list.desaliaser
76
+ end
77
+
78
+ ### to_xxx
79
+
80
+ def to_attr_list
81
+ select_list.to_attr_list
82
+ end
83
+
84
+ ### to_sql
85
+
86
+ def to_sql(buffer = "", parenthesize = !buffer.empty?)
87
+ if parenthesize
88
+ sql_parenthesized(buffer){|b| to_sql(b, false) }
89
+ else
90
+ buffer << (distinct? ? SELECT_DISTINCT : SELECT)
91
+ each_child(1) do |elm,i|
92
+ buffer << SPACE
93
+ elm.to_sql(buffer)
94
+ end
95
+ buffer
96
+ end
97
+ end
98
+
99
+ end # module SelectExp
100
+ end # module Sql
101
+ end # module Alf
@@ -0,0 +1,37 @@
1
+ module Alf
2
+ module Sql
3
+ module SelectItem
4
+ include Expr
5
+
6
+ def left
7
+ self[1]
8
+ end
9
+
10
+ def right
11
+ self[2]
12
+ end
13
+
14
+ def qualifier
15
+ left.qualifier
16
+ end
17
+
18
+ def would_be_name
19
+ left.would_be_name
20
+ end
21
+
22
+ def as_name
23
+ last.as_name
24
+ end
25
+
26
+ def to_sql(buffer = "")
27
+ self[1].to_sql(buffer)
28
+ unless would_be_name == as_name
29
+ buffer << SPACE << AS << SPACE
30
+ last.to_sql(buffer)
31
+ end
32
+ buffer
33
+ end
34
+
35
+ end # module SelectItem
36
+ end # module Sql
37
+ end # module Alf
@@ -0,0 +1,31 @@
1
+ module Alf
2
+ module Sql
3
+ module SelectList
4
+ include Expr
5
+
6
+ def desaliaser
7
+ ->(a){
8
+ item = sexpr_body.find{|item| item.as_name.to_s == a.to_s }
9
+ item && item.left
10
+ }
11
+ end
12
+
13
+ def knows?(as_name)
14
+ find_child{|child| child.as_name == as_name }
15
+ end
16
+
17
+ def to_attr_list
18
+ AttrList.coerce(sexpr_body.map{|a| a.as_name })
19
+ end
20
+
21
+ def to_sql(buffer = "")
22
+ sexpr_body.each_with_index do |item,index|
23
+ buffer << ", " unless index == 0
24
+ item.to_sql(buffer)
25
+ end
26
+ buffer
27
+ end
28
+
29
+ end # module SelectList
30
+ end # module Sql
31
+ end # module Alf
@@ -0,0 +1,15 @@
1
+ module Alf
2
+ module Sql
3
+ module SelectStar
4
+ include Expr
5
+
6
+ STAR = "*".freeze
7
+
8
+ def to_sql(buffer = "")
9
+ buffer << STAR
10
+ buffer
11
+ end
12
+
13
+ end # module SelectStar
14
+ end # module Sql
15
+ end # module Alf
@@ -0,0 +1,64 @@
1
+ module Alf
2
+ module Sql
3
+ module SetOperator
4
+ include Expr
5
+
6
+ def left
7
+ self[2]
8
+ end
9
+
10
+ def right
11
+ self[3]
12
+ end
13
+
14
+ def set_quantifier
15
+ self[1]
16
+ end
17
+
18
+ def with_exp?
19
+ false
20
+ end
21
+
22
+ def set_operator?
23
+ true
24
+ end
25
+
26
+ def distinct?
27
+ set_quantifier.distinct?
28
+ end
29
+
30
+ def all?
31
+ set_quantifier.all?
32
+ end
33
+
34
+ def should_be_reused?
35
+ true
36
+ end
37
+
38
+ def order_by_clause
39
+ nil
40
+ end
41
+
42
+ def to_attr_list
43
+ self.last.to_attr_list
44
+ end
45
+
46
+ def to_sql(buffer = "", parenthesize = !buffer.empty?)
47
+ if parenthesize
48
+ sql_parenthesized(buffer){|b| to_sql(b, false) }
49
+ else
50
+ left.to_sql(buffer, true)
51
+ buffer << SPACE << keyword
52
+ unless distinct?
53
+ buffer << SPACE
54
+ set_quantifier.to_sql(buffer)
55
+ end
56
+ buffer << SPACE
57
+ right.to_sql(buffer, true)
58
+ buffer
59
+ end
60
+ end
61
+
62
+ end # module SetOperator
63
+ end # module Sql
64
+ end # module Alf
@@ -0,0 +1,20 @@
1
+ module Alf
2
+ module Sql
3
+ module SetQuantifier
4
+ include Expr
5
+
6
+ def all?
7
+ last == "all"
8
+ end
9
+
10
+ def distinct?
11
+ last == "distinct"
12
+ end
13
+
14
+ def to_sql(buffer = "")
15
+ buffer << self.last
16
+ end
17
+
18
+ end # module SetQuantifier
19
+ end # module Sql
20
+ end # module Alf
@@ -0,0 +1,28 @@
1
+ module Alf
2
+ module Sql
3
+ module SubqueryAs
4
+ include Expr
5
+
6
+ def left
7
+ self[1]
8
+ end
9
+ alias :subquery :left
10
+
11
+ def right
12
+ self[2]
13
+ end
14
+
15
+ def as_name
16
+ self[2].last
17
+ end
18
+
19
+ def to_sql(buffer = "")
20
+ left.to_sql(buffer)
21
+ buffer << " AS "
22
+ right.to_sql(buffer)
23
+ buffer
24
+ end
25
+
26
+ end # module SubqueryAs
27
+ end # module Sql
28
+ end # module Alf
@@ -0,0 +1,31 @@
1
+ module Alf
2
+ module Sql
3
+ module TableAs
4
+ include Expr
5
+
6
+ def left
7
+ self[1]
8
+ end
9
+
10
+ def right
11
+ self[2]
12
+ end
13
+
14
+ def table_name
15
+ self[1].last
16
+ end
17
+
18
+ def as_name
19
+ self[2].last
20
+ end
21
+
22
+ def to_sql(buffer = "")
23
+ self[1].to_sql(buffer)
24
+ buffer << " AS "
25
+ self[2].to_sql(buffer)
26
+ buffer
27
+ end
28
+
29
+ end # module TableAs
30
+ end # module Sql
31
+ end # module Alf
@@ -0,0 +1,17 @@
1
+ module Alf
2
+ module Sql
3
+ module TableName
4
+ include Expr
5
+
6
+ def value
7
+ last
8
+ end
9
+
10
+ def to_sql(buffer = "")
11
+ buffer << last.to_s
12
+ buffer
13
+ end
14
+
15
+ end # module TableName
16
+ end # module Sql
17
+ end # module Alf
@@ -0,0 +1,14 @@
1
+ module Alf
2
+ module Sql
3
+ module Union
4
+ include SetOperator
5
+
6
+ UNION = "UNION".freeze
7
+
8
+ def keyword
9
+ UNION
10
+ end
11
+
12
+ end # module Union
13
+ end # module Sql
14
+ end # module Alf