locomotive 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/lib/locomotive.rb +6 -0
  2. data/lib/locomotive/core_extensions.rb +6 -0
  3. data/lib/locomotive/core_extensions/array.rb +22 -0
  4. data/lib/locomotive/core_extensions/class.rb +47 -0
  5. data/lib/locomotive/core_extensions/hash.rb +7 -0
  6. data/lib/locomotive/core_extensions/inflector.rb +29 -0
  7. data/lib/locomotive/core_extensions/module.rb +77 -0
  8. data/lib/locomotive/core_extensions/symbol.rb +17 -0
  9. data/lib/locomotive/misc.rb +1 -0
  10. data/lib/locomotive/misc/type_check.rb +129 -0
  11. data/lib/locomotive/relational_algebra.rb +8 -0
  12. data/lib/locomotive/relational_algebra/attributes.rb +171 -0
  13. data/lib/locomotive/relational_algebra/operators.rb +15 -0
  14. data/lib/locomotive/relational_algebra/operators/abstraction.rb +2 -0
  15. data/lib/locomotive/relational_algebra/operators/abstraction/lambda.rb +83 -0
  16. data/lib/locomotive/relational_algebra/operators/abstraction/variable.rb +65 -0
  17. data/lib/locomotive/relational_algebra/operators/aggregation.rb +2 -0
  18. data/lib/locomotive/relational_algebra/operators/aggregation/aggr_builtin.rb +26 -0
  19. data/lib/locomotive/relational_algebra/operators/aggregation/aggregation.rb +76 -0
  20. data/lib/locomotive/relational_algebra/operators/basic_operators.rb +144 -0
  21. data/lib/locomotive/relational_algebra/operators/boolean.rb +4 -0
  22. data/lib/locomotive/relational_algebra/operators/boolean/and.rb +9 -0
  23. data/lib/locomotive/relational_algebra/operators/boolean/basic_boolean.rb +66 -0
  24. data/lib/locomotive/relational_algebra/operators/boolean/not.rb +56 -0
  25. data/lib/locomotive/relational_algebra/operators/boolean/or.rb +9 -0
  26. data/lib/locomotive/relational_algebra/operators/builtins.rb +3 -0
  27. data/lib/locomotive/relational_algebra/operators/builtins/arith_builtin.rb +37 -0
  28. data/lib/locomotive/relational_algebra/operators/builtins/basic_builtin.rb +20 -0
  29. data/lib/locomotive/relational_algebra/operators/builtins/function.rb +69 -0
  30. data/lib/locomotive/relational_algebra/operators/comparisons.rb +6 -0
  31. data/lib/locomotive/relational_algebra/operators/comparisons/basic_comparison.rb +65 -0
  32. data/lib/locomotive/relational_algebra/operators/comparisons/equal.rb +13 -0
  33. data/lib/locomotive/relational_algebra/operators/comparisons/greater.rb +13 -0
  34. data/lib/locomotive/relational_algebra/operators/comparisons/greater_equal.rb +14 -0
  35. data/lib/locomotive/relational_algebra/operators/comparisons/less.rb +21 -0
  36. data/lib/locomotive/relational_algebra/operators/comparisons/less_equal.rb +13 -0
  37. data/lib/locomotive/relational_algebra/operators/error.rb +1 -0
  38. data/lib/locomotive/relational_algebra/operators/error/error.rb +52 -0
  39. data/lib/locomotive/relational_algebra/operators/filter.rb +1 -0
  40. data/lib/locomotive/relational_algebra/operators/filter/select.rb +50 -0
  41. data/lib/locomotive/relational_algebra/operators/join.rb +5 -0
  42. data/lib/locomotive/relational_algebra/operators/join/basic_join.rb +9 -0
  43. data/lib/locomotive/relational_algebra/operators/join/cross.rb +28 -0
  44. data/lib/locomotive/relational_algebra/operators/join/equi_join.rb +61 -0
  45. data/lib/locomotive/relational_algebra/operators/join/predicates.rb +95 -0
  46. data/lib/locomotive/relational_algebra/operators/join/theta_join.rb +53 -0
  47. data/lib/locomotive/relational_algebra/operators/projections.rb +2 -0
  48. data/lib/locomotive/relational_algebra/operators/projections/attach.rb +67 -0
  49. data/lib/locomotive/relational_algebra/operators/projections/projection.rb +106 -0
  50. data/lib/locomotive/relational_algebra/operators/ranking.rb +6 -0
  51. data/lib/locomotive/relational_algebra/operators/ranking/basic_ranking.rb +67 -0
  52. data/lib/locomotive/relational_algebra/operators/ranking/rank.rb +9 -0
  53. data/lib/locomotive/relational_algebra/operators/ranking/rank_lists.rb +45 -0
  54. data/lib/locomotive/relational_algebra/operators/ranking/row_id.rb +24 -0
  55. data/lib/locomotive/relational_algebra/operators/ranking/row_number.rb +55 -0
  56. data/lib/locomotive/relational_algebra/operators/ranking/row_rank.rb +9 -0
  57. data/lib/locomotive/relational_algebra/operators/serialization.rb +2 -0
  58. data/lib/locomotive/relational_algebra/operators/serialization/basic_serialize.rb +9 -0
  59. data/lib/locomotive/relational_algebra/operators/serialization/serialize_relation.rb +105 -0
  60. data/lib/locomotive/relational_algebra/operators/set.rb +4 -0
  61. data/lib/locomotive/relational_algebra/operators/set/basic_set.rb +24 -0
  62. data/lib/locomotive/relational_algebra/operators/set/difference.rb +11 -0
  63. data/lib/locomotive/relational_algebra/operators/set/distinct.rb +35 -0
  64. data/lib/locomotive/relational_algebra/operators/set/union.rb +11 -0
  65. data/lib/locomotive/relational_algebra/operators/tables.rb +3 -0
  66. data/lib/locomotive/relational_algebra/operators/tables/literal_table.rb +95 -0
  67. data/lib/locomotive/relational_algebra/operators/tables/nil.rb +13 -0
  68. data/lib/locomotive/relational_algebra/operators/tables/ref_table.rb +75 -0
  69. data/lib/locomotive/relational_algebra/operators/typeing.rb +1 -0
  70. data/lib/locomotive/relational_algebra/operators/typeing/cast.rb +59 -0
  71. data/lib/locomotive/relational_algebra/ordering.rb +30 -0
  72. data/lib/locomotive/relational_algebra/query_information.rb +666 -0
  73. data/lib/locomotive/relational_algebra/rel_alg_ast_node.rb +51 -0
  74. data/lib/locomotive/relational_algebra/rel_alg_exceptions.rb +15 -0
  75. data/lib/locomotive/relational_algebra/schema.rb +87 -0
  76. data/lib/locomotive/relational_algebra/types.rb +86 -0
  77. data/lib/locomotive/tree_helpers.rb +3 -0
  78. data/lib/locomotive/tree_helpers/annotations.rb +58 -0
  79. data/lib/locomotive/tree_helpers/ast.rb +99 -0
  80. data/lib/locomotive/tree_helpers/ast_traversal.rb +43 -0
  81. data/lib/locomotive/utils.rb +2 -0
  82. data/lib/locomotive/utils/relalg2xml.rb +239 -0
  83. data/lib/locomotive/utils/xml.rb +47 -0
  84. metadata +157 -0
@@ -0,0 +1,51 @@
1
+ module Locomotive
2
+
3
+ module RelationalAlgebra
4
+
5
+ # Represents a Relational Algebra node
6
+ # Such a node has
7
+ # * the behaviour of a composite pattern
8
+ # * and node specific annotations
9
+ class RelAlgAstNode
10
+ include AstHelpers::AstNode
11
+ include AstHelpers::Annotations
12
+
13
+ [:project, :attach,
14
+ :or, :and, :not,
15
+ :aggr,
16
+ :select,
17
+ :difference, :union, :distinct,
18
+ :cross, :equi_join, :theta_join,
19
+ :equal, :greater_than,
20
+ :less_than, :less_equal_than,
21
+ :row_num, :row_id, :rank, :row_rank,
22
+ :cast,
23
+ :error,
24
+ :serialize_relation].each do |op|
25
+ define_method(op) do |*args|
26
+ ::Locomotive::RelationalAlgebra.const_get(op.classify).new(self, *args)
27
+ end
28
+ end
29
+
30
+ [:addition, :subtraction,
31
+ :multiplication, :division].each do |meth|
32
+ define_method(meth) do |*args|
33
+ Function.new(self,
34
+ ::Locomotive::RelationalAlgebra.const_get(meth.classify).instance,
35
+ *args)
36
+ end
37
+ end
38
+
39
+ [:max, :min, :count, :avg, :sum, :all].each do |meth|
40
+ define_method(meth) do |*args|
41
+ Aggr.new(self,
42
+ ::Locomotive::RelationalAlgebra.const_get(meth.classify).instance,
43
+ *args)
44
+ end
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+
@@ -0,0 +1,15 @@
1
+ module Locomotive
2
+
3
+ module RelationalAlgebra
4
+
5
+ class IdError < StandardError; end
6
+ class AbstractClassError < StandardError; end
7
+ class Duplicates < StandardError; end
8
+ class CorruptedSchema < StandardError; end
9
+ class ITblsNotEqual < StandardError; end
10
+
11
+ class ArgumentException < StandardError; end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,87 @@
1
+ module Locomotive
2
+
3
+ module RelationalAlgebra
4
+
5
+ #
6
+ # The Schema contains the attributes
7
+ # and its associated types.
8
+ # Each operator of the relational algebra
9
+ # contains a schema.
10
+ #
11
+ class Schema
12
+ include Locomotive::XML
13
+ def_node :_schema_, :col
14
+
15
+ protected
16
+
17
+ attr_accessor :schema
18
+ def_sig :schema=, { ConstAttribute => [RType] }
19
+
20
+ # check if there are duplicates in the schemas
21
+ def duplicates?(schema)
22
+ (self.attributes + schema.attributes).length >
23
+ (self.attributes + schema.attributes).uniq.length
24
+ end
25
+ def_sig :duplicates?, Schema
26
+
27
+ public
28
+
29
+ delegate :[],
30
+ :each,
31
+ :to => :schema
32
+
33
+ def initialize(hash)
34
+ self.schema = hash
35
+ end
36
+
37
+ def attributes
38
+ schema.keys
39
+ end
40
+
41
+ def attributes?(attributes)
42
+ attributes.all? { |attr| self.attributes.member? attr }
43
+ end
44
+ def_sig :attributes?, [ConstAttribute]
45
+
46
+ # merges two schemas, given that there are
47
+ # no duplicate keys
48
+ def +(schm)
49
+ if duplicates?(schm)
50
+ raise Duplicates,
51
+ "Found duplicates in #{self.attributes} " \
52
+ "and #{schm.attributes}."
53
+ end
54
+ # create a new schema
55
+ Schema.new(schema.merge(schm.schema))
56
+ end
57
+ def_sig :+, Schema
58
+
59
+ def []=(attr,types)
60
+ raise Duplicates,
61
+ "#{attr.inspect} results in duplicates " \
62
+ "in schema #{self.attributes}" unless self[attr].nil?
63
+ schema[attr] = types
64
+ end
65
+ def_sig :[]=, ConstAttribute, [RType]
66
+
67
+ def to_xml
68
+ _schema_ do
69
+ self.schema.collect do |attr,types|
70
+ col :name => attr.to_xml,
71
+ :type => types.collect { |ty| ty.to_xml }.join(",")
72
+ end.join
73
+ end
74
+ end
75
+
76
+ def inspect
77
+ "<Schema [#{schema.map { |s| s.inspect }.join(", ")}]>"
78
+ end
79
+
80
+ def clone
81
+ Schema.new( self.schema.clone )
82
+ end
83
+ end
84
+
85
+ end
86
+
87
+ end
@@ -0,0 +1,86 @@
1
+ module Locomotive
2
+
3
+ module RelationalAlgebra
4
+
5
+ class RType
6
+ include Singleton
7
+ include Locomotive::XML
8
+
9
+ class << self
10
+ alias :type :instance
11
+ end
12
+
13
+ def initialize()
14
+ if self.class == RType
15
+ raise AbstractClassError,
16
+ "#{self.class} is an abstract class"
17
+ end
18
+ end
19
+
20
+ def clone
21
+ # since all types are singletons
22
+ # we can return the object itself
23
+ self
24
+ end
25
+
26
+ def to_xml
27
+ self.class.to_s.split("::").last.downcase[1..-1]
28
+ end
29
+
30
+ def inspect
31
+ "<#{self.class.to_s.split('::').last}>"
32
+ end
33
+ end
34
+ class RDbl < RType; end
35
+ class RDec < RDbl; end
36
+ class RInt < RDec; end
37
+ class RNat < RInt; end
38
+
39
+ class RStr < RType; end
40
+
41
+ class RBool < RType; end
42
+
43
+ #
44
+ # An atomic value constists of a value an
45
+ # its associated type
46
+ #
47
+ class RAtomic
48
+ extend Locomotive::TypeChecking::Signature
49
+ include Locomotive::XML
50
+
51
+ def_node :_value_
52
+
53
+ attr_accessor :value,
54
+ :type
55
+ def_sig :type=, RType
56
+
57
+ def initialize(val, ty)
58
+ self.value,
59
+ self.type = val, ty
60
+ end
61
+
62
+ def to_xml
63
+ _value_ :type => type.to_xml do
64
+ value
65
+ end
66
+ end
67
+
68
+ def clone
69
+ RAtomic.new(self.value,
70
+ self.type)
71
+ end
72
+ end
73
+
74
+
75
+ [:r_dbl, :r_dec, :r_int, :r_nat, :r_str, :r_bool].each do |meth|
76
+ meth_ = meth.classify.to_sym
77
+ define_method(meth_) do |val|
78
+ RAtomic.new(val,
79
+ ::Locomotive::RelationalAlgebra.
80
+ const_get(meth_).type)
81
+ end
82
+ end
83
+
84
+ end
85
+
86
+ end
@@ -0,0 +1,3 @@
1
+ require 'locomotive/tree_helpers/annotations'
2
+ require 'locomotive/tree_helpers/ast'
3
+ require 'locomotive/tree_helpers/ast_traversal'
@@ -0,0 +1,58 @@
1
+ require 'pp'
2
+ module Locomotive
3
+
4
+ module AstHelpers
5
+
6
+ # The purpose of this module is to enhance
7
+ # an instance with accessors on special labeled
8
+ # methods.
9
+ #
10
+ # Each instance of a class (with this module included)
11
+ # has methods
12
+ # *. o.ann_\w+
13
+ # *. o.ann_\w+=
14
+ # to set and read the annotations.
15
+ module Annotations
16
+ public
17
+
18
+ # overwrite the respond_to method
19
+ # to pretend there are ann_-methods
20
+ def respond_to? sym
21
+ @annotations ||= {}
22
+ if @annotations.keys.member?( sym.to_s[-1,1] != "=" ?
23
+ sym :
24
+ sym.to_s[0..-2].to_sym )
25
+ true
26
+ else
27
+ super.respond_to? sym
28
+ end
29
+ end
30
+
31
+ # set method_missing to overwrite
32
+ # the behaviour of ann_-prefixed
33
+ # methods
34
+ def method_missing(key, *args)
35
+ key_str = key.to_s
36
+
37
+ # labeled ANN_PATTERN is not applicable in
38
+ # this case due to ?<data>
39
+ if /^ann_(?<data>\w+)=?/ =~ key_str
40
+ @annotations ||= {}
41
+
42
+ data_sym = "ann_#{data}".to_sym
43
+ if key_str[-1,1] == "=" then
44
+ @annotations[data_sym] = args[0]
45
+ else
46
+ @annotations[data_sym]
47
+ end
48
+
49
+ else
50
+ super.method_missing(key, *args)
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+
58
+ end
@@ -0,0 +1,99 @@
1
+ require "#{File.dirname(__FILE__)}/ast_traversal"
2
+
3
+
4
+ module Locomotive
5
+
6
+ module AstHelpers
7
+
8
+ # Implements the composite behaviour, thus a node with
9
+ # two children.
10
+ module AstNode
11
+ private
12
+
13
+ DEFAULT_TRAVERSE_STRATEGY = PreOrderTraverse
14
+
15
+ public
16
+
17
+ attr_accessor :kind,
18
+ :value,
19
+ :owner
20
+
21
+ attr_reader :left_child,
22
+ :right_child
23
+
24
+ # The owner denotes the parent
25
+ # of this node
26
+
27
+ # Initialize the node with values.</b>
28
+ # An <b>A</b>stract <b>S</b>yntax <b>T</b>ree-Node
29
+ # has a
30
+ # 1. kind
31
+ # 2. value
32
+ # 3. a left child
33
+ # 4. a right child
34
+ # 5. some node specific annotations
35
+ #
36
+ # The values 2. - 5. can be omitted because there can be
37
+ # some nodes with a kind only (e.g. separators).
38
+ # A node with neither left- nor right-child is a leaf-node.
39
+ def initialize(kind,
40
+ value = nil,
41
+ left = nil,
42
+ right = nil)
43
+ self.owner = nil
44
+ self.kind, self.value = kind, value
45
+ self.left_child = left if left != nil
46
+ self.right_child = right if right != nil
47
+ self.traverse_strategy = DEFAULT_TRAVERSE_STRATEGY
48
+ end
49
+
50
+ # Sets a new left child
51
+ # and sets the owner which is the
52
+ # actual instance
53
+ def left_child=(child)
54
+ child.owner = self
55
+ @left_child = child
56
+ end
57
+
58
+ # Sets a new right child
59
+ # and sets the owner which is the
60
+ # actual instance
61
+ def right_child=(child)
62
+ child.owner = self
63
+ @right_child = child
64
+ end
65
+
66
+ def has_left_child?
67
+ self.left_child != nil
68
+ end
69
+
70
+ def has_right_child?
71
+ self.right_child != nil
72
+ end
73
+
74
+ # checks whether the node is a leaf
75
+ # or not
76
+ def is_leaf?
77
+ self.left_child == nil and
78
+ self.right_child == nil
79
+ end
80
+
81
+ def traverse_strategy=(strategy)
82
+ @strategy = strategy
83
+ self.left_child.traverse_strategy = strategy if self.has_left_child?
84
+ self.right_child.traverse_strategy = strategy if self.has_right_child?
85
+ end
86
+
87
+ # Traverses the ast with a given
88
+ # strategy. If nothing given simple
89
+ # prefix-traversal is used
90
+ def traverse(strategy=nil, &block)
91
+ @strategy ||= strategy || DEFAULT_TRAVERSE_STRATEGY
92
+ @strategy.traverse(self, &block)
93
+ end
94
+
95
+ end
96
+
97
+ end
98
+
99
+ end
@@ -0,0 +1,43 @@
1
+ module Locomotive
2
+
3
+ module AstHelpers
4
+
5
+ class TraverseStrategy
6
+ def TraverseStrategy.traverse(ast, &block)
7
+ raise "Called abstract method traverse"
8
+ end
9
+ end
10
+
11
+ class PreOrderTraverse < TraverseStrategy
12
+ def PreOrderTraverse.traverse(ast, &block)
13
+ block.call(ast)
14
+ traverse(ast.left_child, &block) if ast.has_left_child?
15
+ traverse(ast.right_child, &block) if ast.has_right_child?
16
+ # return nothing
17
+ return
18
+ end
19
+ end
20
+
21
+ class PostOrderTraverse < TraverseStrategy
22
+ def PostOrderTraverse.traverse(ast, &block)
23
+ traverse(ast.left_child, &block) if ast.has_left_child?
24
+ traverse(ast.right_child, &block) if ast.has_right_child?
25
+ block.call(ast)
26
+ # return nothing
27
+ return
28
+ end
29
+ end
30
+
31
+ class InOrderTraverse < TraverseStrategy
32
+ def InOrderTraverse.traverse(ast, &block)
33
+ traverse(ast.left_child, &block) if ast.has_left_child?
34
+ block.call(ast)
35
+ traverse(ast.right_child, &block) if ast.has_right_child?
36
+ # return nothing
37
+ return
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ end