module Bmg::Sql

Constants

Grammar
VERSION

Private Instance Methods

_collect(sexpr, tables, joins, kind) click to toggle source
# File lib/bmg/sql/support/from_clause_orderer.rb, line 193
def _collect(sexpr, tables, joins, kind)
  case sexpr.first
  when :from_clause
    _collect(sexpr.table_spec, tables, joins, kind)
  when :table_as, :native_table_as, :subquery_as
    tables << [sexpr, kind]
  when :cross_join
    _collect(sexpr.left, tables, joins, :cross_join)
    _collect(sexpr.right, tables, joins, :cross_join)
  when :inner_join
    _collect_joins(sexpr.predicate, joins)
    _collect(sexpr.left, tables, joins, :inner_join)
    _collect(sexpr.right, tables, joins, :inner_join)
  when :left_join
    _collect_joins(sexpr.predicate, joins)
    _collect(sexpr.left, tables, joins, kind)
    _collect(sexpr.right, tables, joins, :left_join)
  end
end
_collect_joins(sexpr, joins) click to toggle source
# File lib/bmg/sql/support/from_clause_orderer.rb, line 213
def _collect_joins(sexpr, joins)
  case sexpr.first
  when :and
    _collect_joins(sexpr[1], joins)
    _collect_joins(sexpr[2], joins)
  when :eq
    joins << sexpr
  else
    raise NotImplementedError, "Unexpected predicate `#{sexpr.inspect}`"
  end
end
_constants(type, cs) click to toggle source
# File lib/bmg/sql/relation.rb, line 54
def _constants(type, cs)
  expr = before_use(self.expr)
  expr = Processor::Constants.new(cs, builder).call(expr)
  _instance(type, builder, expr)
end
_instance(type, builder, expr) click to toggle source

Build a new relation instance for some new type & expression

This method can be overriden by subclasses to provide their own class instance

# File lib/bmg/sql/relation.rb, line 181
def _instance(type, builder, expr)
  Relation.new(type, builder, expr)
end
_join(type, right, on) click to toggle source
Calls superclass method
# File lib/bmg/sql/relation.rb, line 60
def _join(type, right, on)
  if right_expr = extract_compatible_sexpr(right)
    right_expr = Processor::Requalify.new(builder).call(right_expr)
    expr = before_use(self.expr)
    expr = Processor::Join.new(right_expr, on, {}, builder).call(expr)
    _instance(type, builder, expr)
  else
    super
  end
end
_left_join(type, right, on, default_right_tuple) click to toggle source
Calls superclass method
# File lib/bmg/sql/relation.rb, line 71
def _left_join(type, right, on, default_right_tuple)
  if right_expr = extract_compatible_sexpr(right)
    right_expr = Processor::Requalify.new(builder).call(right_expr)
    expr = before_use(self.expr)
    expr = Processor::Join.new(right_expr, on, {
      kind: :left,
      default_right_tuple: default_right_tuple
    }, builder).call(expr)
    _instance(type, builder, expr)
  else
    super
  end
end
_matching(type, right, on) click to toggle source
Calls superclass method
# File lib/bmg/sql/relation.rb, line 85
def _matching(type, right, on)
  if right_expr = extract_compatible_sexpr(right)
    expr = before_use(self.expr)
    expr = Processor::SemiJoin.new(right_expr, on, false, builder).call(expr)
    _instance(type, builder, expr)
  else
    super
  end
end
_not_matching(type, right, on) click to toggle source
Calls superclass method
# File lib/bmg/sql/relation.rb, line 95
def _not_matching(type, right, on)
  if right_expr = extract_compatible_sexpr(right)
    expr = before_use(self.expr)
    expr = Processor::SemiJoin.new(right_expr, on, true, builder).call(expr)
    _instance(type, builder, expr)
  else
    super
  end
end
_page(type, ordering, page_index, options) click to toggle source
# File lib/bmg/sql/relation.rb, line 105
def _page(type, ordering, page_index, options)
  limit  = options[:page_size] || Operator::Page::DEFAULT_OPTIONS[:page_size]
  offset = (page_index - 1) * limit
  expr = before_use(self.expr)
  expr = Processor::OrderBy.new(ordering, builder).call(expr)
  expr = Processor::LimitOffset.new(limit, offset, builder).call(expr)
  _instance(type, builder, expr)
end
_project(type, attrlist) click to toggle source
# File lib/bmg/sql/relation.rb, line 114
def _project(type, attrlist)
  preserved_key = self.type.knows_keys? && self.type.keys.find{|k|
    k.all?{|a| attrlist.include?(a) }
  }
  expr = before_use(self.expr)
  expr = Processor::Clip.new(attrlist, false, :is_table_dee, builder).call(expr)
  expr = Processor::Distinct.new(builder).call(expr) unless preserved_key
  _instance(type, builder, expr)
end
_rename(type, renaming) click to toggle source
# File lib/bmg/sql/relation.rb, line 124
def _rename(type, renaming)
  expr = before_use(self.expr)
  expr = Processor::Rename.new(renaming, builder).call(expr)
  _instance(type, builder, expr)
end
_restrict(type, predicate) click to toggle source
# File lib/bmg/sql/relation.rb, line 130
def _restrict(type, predicate)
  expr = before_use(self.expr)
  expr = Processor::Where.new(predicate, builder).call(expr)
  _instance(type, builder, expr)
end
_summarize(type, by, defs) click to toggle source
Calls superclass method
# File lib/bmg/sql/relation.rb, line 136
def _summarize(type, by, defs)
  summarization = ::Bmg::Summarizer.summarization(defs)
  if can_compile_summarization?(summarization)
    expr = before_use(self.expr)
    expr = Processor::Summarize.new(by, summarization, builder).call(expr)
    _instance(type, builder, expr)
  else
    super
  end
end
_transform(type, transformation, options) click to toggle source
Calls superclass method
# File lib/bmg/sql/relation.rb, line 147
def _transform(type, transformation, options)
  expr = before_use(self.expr)
  sup, unsup = Processor::Transform.split_supported(transformation){|x|
    [String, Integer, Float, Date, DateTime].include?(x)
  }
  return super if sup.nil?
  expr = Processor::Transform.new(sup, options, builder).call(expr)
  result = _instance(type, builder, expr)
  result = result.transform(unsup, options) if unsup
  result
rescue Sql::NotSupportedError
  super
end
_union(type, right, options) click to toggle source
Calls superclass method
# File lib/bmg/sql/relation.rb, line 167
def _union(type, right, options)
  if right_expr = extract_compatible_sexpr(right)
    expr = before_use(self.expr)
    expr = Processor::Merge.new(:union, !!options[:all], right_expr, builder).call(expr)
    _instance(type, builder, expr)
  else
    super
  end
end
before_use(expr) click to toggle source

Provides subclasses with a chance to manipulate the expression before it is reused in another one, following an algebra method call

# File lib/bmg/sql/relation.rb, line 188
def before_use(expr)
  expr
end
can_compile_summarization?(summarization) click to toggle source
# File lib/bmg/sql/relation.rb, line 161
def can_compile_summarization?(summarization)
  summarization.values.all?{|s|
    [:avg, :count, :max, :min, :sum, :distinct_count].include?(s.to_summarizer_name)
  }
end
extract_compatible_sexpr(operand) click to toggle source

Given a Relation operand (typically a right operand in a binary expression), extract the associated `expr` if it is compatible with self for optimization (e.g. same underlying engine).

May return nil if operand should not be considered for further optimization

# File lib/bmg/sql/relation.rb, line 198
def extract_compatible_sexpr(operand)
  nil
end
inspect()
Alias for: to_s
to_ast() click to toggle source
# File lib/bmg/sql/relation.rb, line 208
def to_ast
  [:sql, to_sql]
end
to_s() click to toggle source
# File lib/bmg/sql/relation.rb, line 212
def to_s
  "(sql #{to_sql})"
end
Also aliased as: inspect
to_sql() click to toggle source
# File lib/bmg/sql/relation.rb, line 204
def to_sql
  expr.to_sql("", Dialect.default)
end