alf-core 0.13.1 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (200) hide show
  1. data/CHANGELOG.md +77 -0
  2. data/examples/operators/page.alf +4 -0
  3. data/lib/alf-adapter-fs/alf/adapter/folder.rb +4 -0
  4. data/lib/alf-adapter-fs/alf/adapter/folder/connection.rb +3 -2
  5. data/lib/alf-adapter/alf/adapter/connection.rb +1 -1
  6. data/lib/alf-algebra/alf/algebra/operand.rb +2 -2
  7. data/lib/alf-algebra/alf/algebra/operand/fake.rb +3 -3
  8. data/lib/alf-algebra/alf/algebra/operand/named.rb +1 -1
  9. data/lib/alf-algebra/alf/algebra/operand/proxy.rb +14 -0
  10. data/lib/alf-algebra/alf/algebra/operator.rb +4 -1
  11. data/lib/alf-algebra/alf/algebra/operator/clip.rb +7 -4
  12. data/lib/alf-algebra/alf/algebra/operator/frame.rb +22 -0
  13. data/lib/alf-algebra/alf/algebra/operator/hierarchize.rb +22 -0
  14. data/lib/alf-algebra/alf/algebra/operator/page.rb +22 -0
  15. data/lib/alf-algebra/alf/algebra/operator/project.rb +4 -9
  16. data/lib/alf-algebra/alf/algebra/operator/rank.rb +2 -2
  17. data/lib/alf-algebra/alf/algebra/support.rb +2 -0
  18. data/lib/alf-algebra/alf/algebra/support/signature.rb +2 -1
  19. data/lib/alf-algebra/alf/algebra/support/with_ordering.rb +11 -0
  20. data/lib/alf-core/ext/domain/heading_based.rb +16 -4
  21. data/lib/alf-core/facade.rb +5 -1
  22. data/lib/alf-core/version.rb +2 -2
  23. data/lib/alf-database/alf/database/connection.rb +2 -2
  24. data/lib/alf-database/alf/database/options.rb +0 -3
  25. data/lib/alf-engine/alf/engine.rb +4 -1
  26. data/lib/alf-engine/alf/engine/aggregate.rb +2 -1
  27. data/lib/alf-engine/alf/engine/autonum.rb +2 -1
  28. data/lib/alf-engine/alf/engine/clip.rb +2 -1
  29. data/lib/alf-engine/alf/engine/coerce.rb +2 -1
  30. data/lib/alf-engine/alf/engine/cog.rb +23 -0
  31. data/lib/alf-engine/alf/engine/compact.rb +3 -2
  32. data/lib/alf-engine/alf/engine/compact/set.rb +2 -1
  33. data/lib/alf-engine/alf/engine/compact/uniq.rb +2 -1
  34. data/lib/alf-engine/alf/engine/compiler.rb +60 -33
  35. data/lib/alf-engine/alf/engine/concat.rb +2 -1
  36. data/lib/alf-engine/alf/engine/defaults.rb +2 -1
  37. data/lib/alf-engine/alf/engine/filter.rb +4 -2
  38. data/lib/alf-engine/alf/engine/generator.rb +2 -1
  39. data/lib/alf-engine/alf/engine/group/hash.rb +4 -3
  40. data/lib/alf-engine/alf/engine/hierarchize.rb +87 -0
  41. data/lib/alf-engine/alf/engine/infer_heading.rb +2 -1
  42. data/lib/alf-engine/alf/engine/join.rb +5 -1
  43. data/lib/alf-engine/alf/engine/join/hash.rb +9 -2
  44. data/lib/alf-engine/alf/engine/leaf.rb +6 -1
  45. data/lib/alf-engine/alf/engine/materialize/array.rb +2 -1
  46. data/lib/alf-engine/alf/engine/materialize/hash.rb +2 -1
  47. data/lib/alf-engine/alf/engine/quota/cesure.rb +2 -1
  48. data/lib/alf-engine/alf/engine/rank/cesure.rb +2 -1
  49. data/lib/alf-engine/alf/engine/rename.rb +2 -1
  50. data/lib/alf-engine/alf/engine/semi/hash.rb +7 -1
  51. data/lib/alf-engine/alf/engine/set_attr.rb +4 -3
  52. data/lib/alf-engine/alf/engine/sort.rb +3 -2
  53. data/lib/alf-engine/alf/engine/sort/in_memory.rb +2 -1
  54. data/lib/alf-engine/alf/engine/summarize/cesure.rb +2 -1
  55. data/lib/alf-engine/alf/engine/summarize/hash.rb +3 -2
  56. data/lib/alf-engine/alf/engine/{cesure.rb → support/cesure.rb} +0 -0
  57. data/lib/alf-engine/alf/engine/take.rb +53 -0
  58. data/lib/alf-engine/alf/engine/to_array.rb +6 -5
  59. data/lib/alf-engine/alf/engine/type_safe.rb +2 -1
  60. data/lib/alf-engine/alf/engine/ungroup.rb +2 -1
  61. data/lib/alf-engine/alf/engine/unwrap.rb +2 -1
  62. data/lib/alf-engine/alf/engine/wrap.rb +2 -1
  63. data/lib/alf-io/alf/reader.rb +1 -1
  64. data/lib/alf-io/alf/reader/ruby.rb +23 -0
  65. data/lib/alf-io/alf/renderer/text.rb +22 -9
  66. data/lib/alf-lang/alf/lang/lispy.rb +41 -29
  67. data/lib/alf-lang/alf/lang/oo/algebra_methods.rb +17 -1
  68. data/lib/alf-optimizer/alf/optimizer/restrict.rb +7 -1
  69. data/lib/alf-predicate/alf/predicate.rb +11 -2
  70. data/lib/alf-relation/alf/relation.rb +21 -1
  71. data/lib/alf-relvar/alf/relvar.rb +21 -1
  72. data/lib/alf-relvar/alf/relvar/base.rb +11 -6
  73. data/lib/alf-relvar/alf/relvar/fake.rb +3 -2
  74. data/lib/alf-relvar/alf/relvar/virtual.rb +1 -2
  75. data/lib/alf-support/alf/support/bindable.rb +1 -1
  76. data/lib/alf-support/alf/support/config.rb +91 -18
  77. data/lib/alf-support/alf/support/tuple_scope.rb +8 -4
  78. data/lib/alf-types/alf/types.rb +2 -0
  79. data/lib/alf-types/alf/types/attr_list.rb +3 -1
  80. data/lib/alf-types/alf/types/heading.rb +4 -1
  81. data/lib/alf-types/alf/types/keys.rb +0 -4
  82. data/lib/alf-types/alf/types/ordering.rb +104 -18
  83. data/lib/alf-types/alf/types/selection.rb +18 -0
  84. data/lib/alf-types/alf/types/selector.rb +59 -0
  85. data/lib/alf-types/alf/types/tuple_computation.rb +2 -2
  86. data/lib/alf-types/alf/types/tuple_expression.rb +18 -2
  87. data/lib/alf-viewpoint/alf/viewpoint.rb +23 -8
  88. data/lib/alf-viewpoint/alf/viewpoint/metadata.rb +73 -0
  89. data/spec/integration/relation/test_extend.rb +20 -0
  90. data/spec/integration/relation/test_to_array.rb +1 -1
  91. data/spec/integration/test_examples.rb +18 -2
  92. data/spec/shared/a_cog.rb +36 -0
  93. data/spec/spec_helper.rb +8 -0
  94. data/spec/unit/alf-algebra/operand/test_proxy.rb +54 -0
  95. data/spec/unit/alf-algebra/operator/hierarchize/test_heading.rb +23 -0
  96. data/spec/unit/alf-algebra/operator/project/test_key_preserving.rb +3 -0
  97. data/spec/unit/alf-algebra/operator/project/test_keys.rb +54 -17
  98. data/spec/unit/alf-algebra/operator/rank/test_keys.rb +2 -2
  99. data/spec/unit/alf-algebra/operator/restrict/test_keys.rb +2 -2
  100. data/spec/unit/alf-algebra/operator/test_page.rb +30 -0
  101. data/spec/unit/alf-algebra/support/test_relational.rb +3 -0
  102. data/spec/unit/alf-algebra/support/with_ordering/test_total_ordering.rb +61 -0
  103. data/spec/unit/alf-database/connection/test_reconnect.rb +1 -1
  104. data/spec/unit/alf-database/options/test_new.rb +4 -4
  105. data/spec/unit/alf-database/shared_examples/a_facade_on_database_options.rb +1 -2
  106. data/spec/unit/alf-engine/cog/test_to_cog.rb +14 -0
  107. data/spec/unit/alf-engine/compiler/test_on_frame.rb +70 -0
  108. data/spec/unit/alf-engine/compiler/test_on_hierarchize.rb +33 -0
  109. data/spec/unit/alf-engine/compiler/test_on_page.rb +128 -0
  110. data/spec/unit/alf-engine/compiler/test_unsupported.rb +48 -0
  111. data/spec/unit/alf-engine/hierarchize/test_renamer.rb +18 -0
  112. data/spec/unit/alf-engine/test_filter.rb +43 -11
  113. data/spec/unit/alf-engine/test_hierarchize.rb +71 -0
  114. data/spec/unit/alf-engine/test_set_attr.rb +13 -0
  115. data/spec/unit/alf-engine/test_take.rb +46 -0
  116. data/spec/unit/alf-engine/test_to_array.rb +45 -28
  117. data/spec/unit/alf-io/reader/{input.rb → input.rash} +0 -0
  118. data/spec/unit/alf-io/reader/input.ruby +4 -0
  119. data/spec/unit/alf-io/reader/test_rash.rb +1 -1
  120. data/spec/unit/alf-io/reader/test_ruby.rb +25 -0
  121. data/spec/unit/alf-predicate/predicate/test_evaluate.rb +51 -13
  122. data/spec/unit/alf-relation/relation/class/test_recursive_type.rb +42 -0
  123. data/spec/unit/alf-relation/relation/test_equality.rb +19 -1
  124. data/spec/unit/alf-relation/relation/test_relops.rb +14 -2
  125. data/spec/unit/alf-relation/relation/test_to_hash.rb +31 -0
  126. data/spec/unit/alf-relvar/base/test_connection.rb +8 -2
  127. data/spec/unit/alf-relvar/base/test_delete.rb +2 -2
  128. data/spec/unit/alf-relvar/base/test_heading.rb +2 -2
  129. data/spec/unit/alf-relvar/base/test_insert.rb +3 -3
  130. data/spec/unit/alf-relvar/base/test_keys.rb +2 -2
  131. data/spec/unit/alf-relvar/base/test_lock.rb +2 -2
  132. data/spec/unit/alf-relvar/base/test_name.rb +3 -2
  133. data/spec/unit/alf-relvar/base/test_oo_lang.rb +2 -1
  134. data/spec/unit/alf-relvar/base/test_to_cog.rb +3 -3
  135. data/spec/unit/alf-relvar/base/test_to_lispy.rb +3 -2
  136. data/spec/unit/alf-relvar/base/test_to_relvar.rb +2 -1
  137. data/spec/unit/alf-relvar/base/test_to_s.rb +3 -2
  138. data/spec/unit/alf-relvar/base/test_update.rb +5 -4
  139. data/spec/unit/alf-relvar/virtual/test_connection.rb +3 -2
  140. data/spec/unit/alf-relvar/virtual/test_delete.rb +3 -4
  141. data/spec/unit/alf-relvar/virtual/test_expr.rb +3 -2
  142. data/spec/unit/alf-relvar/virtual/test_heading.rb +5 -4
  143. data/spec/unit/alf-relvar/virtual/test_insert.rb +2 -2
  144. data/spec/unit/alf-relvar/virtual/test_keys.rb +5 -4
  145. data/spec/unit/alf-relvar/virtual/test_oo_lang.rb +7 -2
  146. data/spec/unit/alf-relvar/virtual/test_to_cog.rb +4 -3
  147. data/spec/unit/alf-relvar/virtual/test_to_lispy.rb +3 -6
  148. data/spec/unit/alf-relvar/virtual/test_to_relvar.rb +2 -1
  149. data/spec/unit/alf-relvar/virtual/test_to_s.rb +3 -3
  150. data/spec/unit/alf-relvar/virtual/test_update.rb +4 -5
  151. data/spec/unit/alf-support/config/test_dup.rb +58 -0
  152. data/spec/unit/alf-support/config/test_freeze.rb +37 -0
  153. data/spec/unit/alf-support/config/test_hash_get.rb +41 -0
  154. data/spec/unit/alf-support/config/test_hash_set.rb +61 -0
  155. data/spec/unit/alf-support/config/test_new.rb +10 -0
  156. data/spec/unit/alf-support/config/test_option.rb +15 -0
  157. data/spec/unit/alf-support/config/test_option_setter.rb +72 -0
  158. data/spec/unit/alf-support/config/test_options.rb +22 -0
  159. data/spec/unit/alf-support/tuple_scope/test_hash_get.rb +20 -0
  160. data/spec/unit/alf-support/tuple_scope/test_respond_to.rb +6 -0
  161. data/spec/unit/alf-support/tuple_scope/test_to_s.rb +22 -0
  162. data/spec/unit/alf-types/keys/test_select.rb +57 -8
  163. data/spec/unit/alf-types/ordering/test_coerce.rb +46 -35
  164. data/spec/unit/alf-types/ordering/test_dive.rb +41 -0
  165. data/spec/unit/alf-types/ordering/test_hash_get.rb +20 -0
  166. data/spec/unit/alf-types/ordering/test_merge.rb +61 -0
  167. data/spec/unit/alf-types/ordering/test_reverse.rb +40 -0
  168. data/spec/unit/alf-types/ordering/test_selectors.rb +24 -0
  169. data/spec/unit/alf-types/ordering/test_sorter.rb +62 -8
  170. data/spec/unit/alf-types/ordering/test_to_attr_list.rb +16 -4
  171. data/spec/unit/alf-types/ordering/test_total.rb +56 -0
  172. data/spec/unit/alf-types/selection/test_coerce.rb +38 -0
  173. data/spec/unit/alf-types/selection/test_select.rb +34 -0
  174. data/spec/unit/alf-types/selector/test_coerce.rb +36 -0
  175. data/spec/unit/alf-types/selector/test_composite_q.rb +20 -0
  176. data/spec/unit/alf-types/selector/test_dive.rb +32 -0
  177. data/spec/unit/alf-types/selector/test_select.rb +40 -0
  178. data/spec/unit/alf-types/selector/test_simple_q.rb +20 -0
  179. data/spec/unit/alf-types/selector/test_to_a.rb +20 -0
  180. data/spec/unit/alf-types/selector/test_to_lispy.rb +20 -0
  181. data/spec/unit/alf-types/selector/test_to_ruby_literal.rb +20 -0
  182. data/spec/unit/alf-types/tuple_expression/test_evaluate.rb +38 -0
  183. data/spec/unit/alf-viewpoint/metadata/test_add_members.rb +38 -0
  184. data/spec/unit/alf-viewpoint/metadata/test_all_members.rb +33 -0
  185. data/spec/unit/alf-viewpoint/metadata/test_depends.rb +50 -0
  186. data/spec/unit/alf-viewpoint/metadata/test_dup.rb +32 -0
  187. data/spec/unit/alf-viewpoint/metadata/test_expand.rb +31 -0
  188. data/spec/unit/alf-viewpoint/metadata/test_expects.rb +38 -0
  189. data/spec/unit/alf-viewpoint/metadata/test_initialize.rb +40 -0
  190. data/spec/unit/alf-viewpoint/metadata/test_to_module.rb +37 -0
  191. data/spec/unit/alf-viewpoint/test_depends.rb +18 -0
  192. data/spec/unit/alf-viewpoint/test_expects.rb +18 -0
  193. data/spec/unit/alf-viewpoint/test_members.rb +33 -0
  194. data/spec/unit/alf-viewpoint/test_metadata.rb +27 -0
  195. data/spec/unit/alf-viewpoint/test_native_const.rb +6 -0
  196. metadata +125 -14
  197. data/spec/unit/alf-database/options/test_default_viewpoint.rb +0 -25
  198. data/spec/unit/alf-types/keys/test_compact.rb +0 -21
  199. data/spec/unit/alf-types/ordering/test_plus.rb +0 -27
  200. data/spec/unit/alf-viewpoint/test_namespace.rb +0 -23
@@ -111,8 +111,6 @@ module Alf
111
111
  "Alf::Database::Connection(#{adapter_connection})"
112
112
  end
113
113
 
114
- private
115
-
116
114
  def compile(expr)
117
115
  if df = options.debug_folder
118
116
  where, i = options.debug_naming.call(expr), 1
@@ -129,6 +127,8 @@ module Alf
129
127
  end
130
128
  end
131
129
 
130
+ private
131
+
132
132
  def optimizer
133
133
  Optimizer.new.register(Optimizer::Restrict.new, Algebra::Restrict)
134
134
  end
@@ -8,9 +8,6 @@ module Alf
8
8
  # What viewpoint to use by default?
9
9
  option :viewpoint, Module, Viewpoint::NATIVE
10
10
 
11
- alias :default_viewpoint :viewpoint
12
- alias :default_viewpoint= :viewpoint=
13
-
14
11
  # Path to a folder where debugging graphs can be found
15
12
  option :debug_folder, Path, nil
16
13
 
@@ -6,8 +6,9 @@ module Alf
6
6
  end # module Engine
7
7
  end # module Alf
8
8
  require_relative 'engine/cog'
9
+ require_relative 'engine/support/cesure'
10
+
9
11
  require_relative 'engine/leaf'
10
- require_relative 'engine/cesure'
11
12
  require_relative 'engine/autonum'
12
13
  require_relative 'engine/clip'
13
14
  require_relative 'engine/coerce'
@@ -17,6 +18,7 @@ require_relative 'engine/defaults'
17
18
  require_relative 'engine/sort'
18
19
  require_relative 'engine/set_attr'
19
20
  require_relative 'engine/filter'
21
+ require_relative 'engine/hierarchize'
20
22
  require_relative 'engine/concat'
21
23
  require_relative 'engine/aggregate'
22
24
  require_relative 'engine/rename'
@@ -29,6 +31,7 @@ require_relative 'engine/unwrap'
29
31
  require_relative 'engine/summarize'
30
32
  require_relative 'engine/rank'
31
33
  require_relative 'engine/quota'
34
+ require_relative 'engine/take'
32
35
  require_relative 'engine/ungroup'
33
36
  require_relative 'engine/infer_heading'
34
37
  require_relative 'engine/type_safe'
@@ -27,7 +27,8 @@ module Alf
27
27
  attr_reader :summarization
28
28
 
29
29
  # Creates an Aggregate instance
30
- def initialize(operand, summarization)
30
+ def initialize(operand, summarization, expr = nil)
31
+ super(expr)
31
32
  @operand = operand
32
33
  @summarization = summarization
33
34
  end
@@ -26,7 +26,8 @@ module Alf
26
26
  attr_reader :as
27
27
 
28
28
  # Creates an Autonum instance
29
- def initialize(operand, as)
29
+ def initialize(operand, as, expr = nil)
30
+ super(expr)
30
31
  @operand = operand
31
32
  @as = as
32
33
  end
@@ -35,7 +35,8 @@ module Alf
35
35
  attr_reader :allbut
36
36
 
37
37
  # Creates an Clip instance
38
- def initialize(operand, attributes, allbut)
38
+ def initialize(operand, attributes, allbut, expr = nil)
39
+ super(expr)
39
40
  @operand = operand
40
41
  @attributes = attributes
41
42
  @allbut = allbut
@@ -27,7 +27,8 @@ module Alf
27
27
  attr_reader :coercions
28
28
 
29
29
  # Creates an Coerce instance
30
- def initialize(operand, coercions)
30
+ def initialize(operand, coercions, expr = nil)
31
+ super(expr)
31
32
  @operand = operand
32
33
  @coercions = coercions
33
34
  end
@@ -3,6 +3,29 @@ module Alf
3
3
  module Cog
4
4
  include Enumerable
5
5
 
6
+ attr_reader :expr
7
+
8
+ def initialize(expr)
9
+ if expr && !expr.is_a?(Algebra::Operand)
10
+ raise "Operand expected as first cog argument"
11
+ end
12
+ @expr = expr
13
+ end
14
+
15
+ def heading
16
+ return expr.heading if expr
17
+ raise NotSupportedError, "Cog#heading without expr traceability"
18
+ end
19
+
20
+ def keys
21
+ return expr.keys if expr
22
+ raise NotSupportedError, "Cog#keys without expr traceability"
23
+ end
24
+
25
+ def to_cog
26
+ self
27
+ end
28
+
6
29
  def to_relation
7
30
  Relation.coerce(to_a)
8
31
  end
@@ -10,13 +10,14 @@ module Alf
10
10
  attr_reader :operand
11
11
 
12
12
  # Creates a Compact instance
13
- def initialize(operand)
13
+ def initialize(operand, expr = nil)
14
+ super(expr)
14
15
  @operand = operand
15
16
  end
16
17
 
17
18
  # (see Cog#each)
18
19
  def _each(&block)
19
- Compact::Uniq.new(operand).each(&block)
20
+ Compact::Uniq.new(operand, expr).each(&block)
20
21
  end
21
22
 
22
23
  end # class Compact
@@ -10,7 +10,8 @@ module Alf
10
10
  attr_reader :operand
11
11
 
12
12
  # Creates a Compact::Set instance
13
- def initialize(operand)
13
+ def initialize(operand, expr = nil)
14
+ super(expr)
14
15
  @operand = operand
15
16
  end
16
17
 
@@ -10,7 +10,8 @@ module Alf
10
10
  attr_reader :operand
11
11
 
12
12
  # Creates a Compact::Uniq instance
13
- def initialize(operand)
13
+ def initialize(operand, expr = nil)
14
+ super(expr)
14
15
  @operand = operand
15
16
  end
16
17
 
@@ -17,126 +17,153 @@ module Alf
17
17
  ### non relational
18
18
 
19
19
  def on_autonum(expr)
20
- Autonum.new(apply(expr.operand), expr.as)
20
+ Autonum.new(apply(expr.operand), expr.as, expr)
21
21
  end
22
22
 
23
23
  def on_clip(expr)
24
- Clip.new(apply(expr.operand), expr.attributes, expr.allbut)
24
+ Clip.new(apply(expr.operand), expr.attributes, expr.allbut, expr)
25
25
  end
26
26
 
27
27
  def on_coerce(expr)
28
- Coerce.new(apply(expr.operand), expr.coercions)
28
+ Coerce.new(apply(expr.operand), expr.coercions, expr)
29
29
  end
30
30
 
31
31
  def on_compact(expr)
32
- Compact.new(apply(expr.operand))
32
+ Compact.new(apply(expr.operand), expr)
33
33
  end
34
34
 
35
35
  def on_defaults(expr)
36
- op = Defaults.new(apply(expr.operand), expr.defaults)
37
- op = Clip.new(op, expr.defaults.to_attr_list, false) if expr.strict
36
+ op = Defaults.new(apply(expr.operand), expr.defaults, expr)
37
+ op = Clip.new(op, expr.defaults.to_attr_list, false, expr) if expr.strict
38
38
  op
39
39
  end
40
40
 
41
41
  def on_generator(expr)
42
- Generator.new(expr.as, 1, 1, expr.size)
42
+ Generator.new(expr.as, 1, 1, expr.size, expr)
43
43
  end
44
44
 
45
45
  def on_sort(expr)
46
- Sort.new(apply(expr.operand), expr.ordering)
46
+ Sort.new(apply(expr.operand), expr.ordering, expr)
47
47
  end
48
48
 
49
49
  def on_type_safe(expr)
50
50
  checker = TypeCheck.new(expr.heading, expr.strict)
51
- TypeSafe.new(apply(expr.operand), checker)
51
+ TypeSafe.new(apply(expr.operand), checker, expr)
52
52
  end
53
53
 
54
54
  ### relational
55
55
 
56
56
  def on_extend(expr)
57
- SetAttr.new(apply(expr.operand), expr.ext)
57
+ SetAttr.new(apply(expr.operand), expr.ext, expr)
58
+ end
59
+
60
+ def on_frame(expr)
61
+ offset, limit = expr.offset, expr.limit
62
+ ordering = unsupported(expr.ordering){ expr.total_ordering }
63
+ op = Sort.new(apply(expr.operand), ordering, expr)
64
+ op = Take.new(op, offset, limit, expr)
65
+ end
66
+
67
+ def on_page(expr)
68
+ index, size = expr.page_index, expr.page_size
69
+ ordering = unsupported(expr.ordering){ expr.total_ordering }
70
+ ordering = ordering.reverse if index < 0
71
+ op = Sort.new(apply(expr.operand), ordering, expr)
72
+ op = Take.new(op, (index.abs - 1) * size, size, expr)
58
73
  end
59
74
 
60
75
  def on_group(expr)
61
- Group::Hash.new(apply(expr.operand), expr.attributes, expr.as, expr.allbut)
76
+ Group::Hash.new(apply(expr.operand), expr.attributes, expr.as, expr.allbut, expr)
77
+ end
78
+
79
+ def on_hierarchize(expr)
80
+ Hierarchize.new(apply(expr.operand), expr.id, expr.parent, expr.as)
62
81
  end
63
82
 
64
83
  def on_infer_heading(expr)
65
- InferHeading.new(apply(expr.operand))
84
+ InferHeading.new(apply(expr.operand), expr)
66
85
  end
67
86
 
68
87
  def on_intersect(expr)
69
- Join::Hash.new(apply(expr.left), apply(expr.right))
88
+ Join::Hash.new(apply(expr.left), apply(expr.right), expr)
70
89
  end
71
90
 
72
91
  def on_join(expr)
73
- Join::Hash.new(apply(expr.left), apply(expr.right))
92
+ Join::Hash.new(apply(expr.left), apply(expr.right), expr)
74
93
  end
75
94
 
76
95
  def on_matching(expr)
77
- Semi::Hash.new(apply(expr.left), apply(expr.right), true)
96
+ Semi::Hash.new(apply(expr.left), apply(expr.right), true, expr)
78
97
  end
79
98
 
80
99
  def on_minus(expr)
81
- Semi::Hash.new(apply(expr.left), apply(expr.right), false)
100
+ Semi::Hash.new(apply(expr.left), apply(expr.right), false, expr)
82
101
  end
83
102
 
84
103
  def on_not_matching(expr)
85
- Semi::Hash.new(apply(expr.left), apply(expr.right), false)
104
+ Semi::Hash.new(apply(expr.left), apply(expr.right), false, expr)
86
105
  end
87
106
 
88
107
  def on_project(expr)
89
- op = Clip.new(apply(expr.operand), expr.attributes, expr.allbut)
90
- op = Compact.new(op)
108
+ op = Clip.new(apply(expr.operand), expr.attributes, expr.allbut, expr)
109
+ op = Compact.new(op, expr)
91
110
  op
92
111
  end
93
112
 
94
113
  def on_quota(expr)
95
- op = Sort.new(apply(expr.operand), expr.by.to_ordering + expr.order)
96
- op = Quota::Cesure.new(op, expr.by, expr.summarization)
114
+ op = Sort.new(apply(expr.operand), expr.by.to_ordering + expr.order, expr)
115
+ op = Quota::Cesure.new(op, expr.by, expr.summarization, expr)
97
116
  op
98
117
  end
99
118
 
100
119
  def on_rank(expr)
101
- op = Sort.new(apply(expr.operand), expr.order)
102
- op = Rank::Cesure.new(op, expr.order, expr.as)
120
+ op = Sort.new(apply(expr.operand), expr.order, expr)
121
+ op = Rank::Cesure.new(op, expr.order.to_attr_list, expr.as, expr)
103
122
  op
104
123
  end
105
124
 
106
125
  def on_rename(expr)
107
- Rename.new(apply(expr.operand), expr.renaming)
126
+ Rename.new(apply(expr.operand), expr.renaming, expr)
108
127
  end
109
128
 
110
129
  def on_restrict(expr)
111
- Filter.new(apply(expr.operand), expr.predicate)
130
+ Filter.new(apply(expr.operand), expr.predicate, expr)
112
131
  end
113
132
 
114
133
  def on_summarize(expr)
115
134
  if expr.allbut
116
- Summarize::Hash.new(apply(expr.operand), expr.by, expr.summarization, expr.allbut)
135
+ Summarize::Hash.new(apply(expr.operand), expr.by, expr.summarization, expr.allbut, expr)
117
136
  else
118
- op = Sort.new(apply(expr.operand), expr.by.to_ordering)
119
- op = Summarize::Cesure.new(op, expr.by, expr.summarization, expr.allbut)
137
+ op = Sort.new(apply(expr.operand), expr.by.to_ordering, expr)
138
+ op = Summarize::Cesure.new(op, expr.by, expr.summarization, expr.allbut, expr)
120
139
  op
121
140
  end
122
141
  end
123
142
 
124
143
  def on_ungroup(expr)
125
- Ungroup.new(apply(expr.operand), expr.attribute)
144
+ Ungroup.new(apply(expr.operand), expr.attribute, expr)
126
145
  end
127
146
 
128
147
  def on_union(expr)
129
- op = Concat.new([apply(expr.left), apply(expr.right)])
130
- op = Compact.new(op)
148
+ op = Concat.new([apply(expr.left), apply(expr.right)], expr)
149
+ op = Compact.new(op, expr)
131
150
  op
132
151
  end
133
152
 
134
153
  def on_unwrap(expr)
135
- Unwrap.new(apply(expr.operand), expr.attribute)
154
+ Unwrap.new(apply(expr.operand), expr.attribute, expr)
136
155
  end
137
156
 
138
157
  def on_wrap(expr)
139
- Wrap.new(apply(expr.operand), expr.attributes, expr.as, expr.allbut)
158
+ Wrap.new(apply(expr.operand), expr.attributes, expr.as, expr.allbut, expr)
159
+ end
160
+
161
+ protected
162
+
163
+ def unsupported(fallback, &bl)
164
+ bl.call
165
+ rescue NotSupportedError
166
+ fallback
140
167
  end
141
168
 
142
169
  end # class Compiler
@@ -10,7 +10,8 @@ module Alf
10
10
  attr_reader :operands
11
11
 
12
12
  # Creates a Concat instance
13
- def initialize(operands)
13
+ def initialize(operands, expr = nil)
14
+ super(expr)
14
15
  @operands = operands
15
16
  end
16
17
 
@@ -25,7 +25,8 @@ module Alf
25
25
  attr_reader :defaults
26
26
 
27
27
  # Creates a Defaults instance
28
- def initialize(operand, defaults)
28
+ def initialize(operand, defaults, expr = nil)
29
+ super(expr)
29
30
  @operand = operand
30
31
  @defaults = defaults
31
32
  end
@@ -24,7 +24,8 @@ module Alf
24
24
  attr_reader :predicate
25
25
 
26
26
  # Creates a Filter instance
27
- def initialize(operand, predicate)
27
+ def initialize(operand, predicate, expr = nil)
28
+ super(expr)
28
29
  @operand = operand
29
30
  @predicate = predicate
30
31
  end
@@ -33,7 +34,8 @@ module Alf
33
34
  def _each
34
35
  scope = tuple_scope
35
36
  operand.each do |tuple|
36
- yield(tuple) if @predicate.evaluate(scope.__set_tuple(tuple))
37
+ t, c = scope.__set_tuple(tuple), expr && expr.connection
38
+ yield(tuple) if @predicate.evaluate(t, c)
37
39
  end
38
40
  end
39
41
 
@@ -29,7 +29,8 @@ module Alf
29
29
  attr_reader :count
30
30
 
31
31
  # Creates an Generator instance
32
- def initialize(as, offset, step, count)
32
+ def initialize(as, offset, step, count, expr = nil)
33
+ super(expr)
33
34
  @as = as
34
35
  @offset = offset
35
36
  @step = step
@@ -19,7 +19,8 @@ module Alf
19
19
  attr_reader :allbut
20
20
 
21
21
  # Creates a Group::Hash instance
22
- def initialize(operand, attributes, as, allbut)
22
+ def initialize(operand, attributes, as, allbut, expr = nil)
23
+ super(expr)
23
24
  @operand = operand
24
25
  @attributes = attributes
25
26
  @as = as
@@ -29,9 +30,9 @@ module Alf
29
30
  # (see Cog#each)
30
31
  def _each(&block)
31
32
  atr, alb = @attributes, @allbut
32
- index = Materialize::Hash.new(operand, atr, !alb)
33
+ index = Materialize::Hash.new(operand, atr, !alb, expr)
33
34
  index.each_pair do |k,v|
34
- grouped = Clip.new(v, atr, alb).to_relation
35
+ grouped = Clip.new(v, atr, alb, expr).to_relation
35
36
  yield k.merge(@as => grouped)
36
37
  end
37
38
  end
@@ -0,0 +1,87 @@
1
+ module Alf
2
+ module Engine
3
+ class Hierarchize
4
+ include Cog
5
+
6
+ # @return [Enumerable] The operand
7
+ attr_reader :operand
8
+
9
+ # @return [AttrList] Attribute list of the id
10
+ attr_reader :id
11
+
12
+ # @return [AttrList] Attribute list for the parent
13
+ attr_reader :parent
14
+
15
+ # @return [AttrName] Attribute name for children
16
+ attr_reader :children
17
+
18
+ # @return [Class] the type of the children relation
19
+ attr_reader :relation_type
20
+
21
+ # @return [Class] the type of the children tuples
22
+ attr_reader :tuple_type
23
+
24
+ # Creates a Hierarchize instance
25
+ def initialize(operand, id, parent, children, expr = nil)
26
+ super(expr)
27
+ @operand = operand
28
+ @id = id
29
+ @parent = parent
30
+ @children = children
31
+ end
32
+
33
+ # (see Cog#each)
34
+ def _each(&block)
35
+ by_id = Hash.new{|h,k| h[k] = {children => nil} }
36
+ operand.each do |tuple|
37
+ tuple = tuple.to_hash
38
+ infer_types(tuple) unless @relation_type
39
+
40
+ # extract my key and my parent's key
41
+ tuple_key, parent_key = keys_of(tuple)
42
+
43
+ # this will be my tuple
44
+ by_id[tuple_key] = tuple.merge(by_id[tuple_key])
45
+
46
+ # add me to my parent unless same tuple
47
+ unless tuple_key==parent_key
48
+ my_tuple = tuple_type.new(by_id[tuple_key])
49
+ by_id[parent_key][children] ||= relation_type.new(Set.new)
50
+ by_id[parent_key][children].send(:reused_instance) << my_tuple
51
+ end
52
+ end
53
+
54
+ # Now output tuples that are their own parent
55
+ by_id.each_pair do |k,tuple|
56
+ tuple_key, parent_key = keys_of(tuple)
57
+ tuple[children] ||= relation_type.empty
58
+ yield(tuple) if tuple_key==parent_key
59
+ end
60
+ end
61
+
62
+ def to_relation
63
+ tuples = to_set
64
+ relation_type.new(tuples)
65
+ end
66
+
67
+ private
68
+
69
+ def infer_types(tuple)
70
+ heading = Tuple(tuple).heading
71
+ @relation_type = Relation.type(heading){|r| { children => r } }
72
+ @tuple_type = Tuple.type(heading){|r| { children => @relation_type } }
73
+ end
74
+
75
+ def renamer
76
+ @renamer ||= Renaming.new(Hash[parent.to_a.zip(id.to_a)])
77
+ end
78
+
79
+ def keys_of(tuple)
80
+ tuple_key = id.project_tuple(tuple)
81
+ parent_key = renamer.rename_tuple(parent.project_tuple(tuple))
82
+ [ tuple_key, parent_key ]
83
+ end
84
+
85
+ end # class Hierarchize
86
+ end # module Engine
87
+ end # module Alf