All Files (97.56% covered at 2120.67 hits/line)
143 files in total.
2911 relevant lines.
2840 lines covered and
71 lines missed
- 5
require_relative './enhance/node'
- 5
require_relative './enhance/path'
- 5
require_relative './enhance/path_node'
- 5
require_relative './enhance/query'
- 5
require_relative './enhance/query_methods'
- 5
require_relative './enhance/visitor'
- 5
module Arel
- 5
module Enhance
end
- 5
def self.enhance(object, context_enhancers = Arel::Enhance::Visitor::DEFAULT_CONTEXT_ENHANCERS)
- 3606
return object if object.is_a?(Arel::Enhance::Node)
- 3591
Arel::Enhance::Visitor.new.accept(object, context_enhancers)
end
end
- 5
module Arel
- 5
module Enhance
- 5
module ContextEnhancer
- 5
class ArelTable
# rubocop:disable Metrics/PerceivedComplexity
# rubocop:disable Metrics/CyclomaticComplexity
# rubocop:disable Metrics/AbcSize
- 5
def self.call(node)
- 2121
context = node.context.merge!(
range_variable: false, column_reference: false, alias: false,
)
- 2121
parent_object = node.parent.object
# Using Arel::Table as SELECT ... FROM <table>
- 2121
if parent_object.is_a?(Arel::Nodes::JoinSource)
- 536
context[:range_variable] = true
# NOTE: only applies to ActiveRecord generated Arel
# which does not use Arel::Table#alias but Arel::TableAlias instead
# Using Arel::Table as SELECT ... FROM <table> AS alias
- 1585
elsif parent_object.is_a?(Arel::Nodes::TableAlias) &&
node.parent.parent.object.is_a?(Arel::Nodes::JoinSource)
- 5
context[:range_variable] = true
- 1580
elsif parent_object.is_a?(Arel::Nodes::TableAlias) &&
node.parent.parent.parent.object.is_a?(Arel::Nodes::JoinSource)
- 10
context[:range_variable] = true
# Using Arel::Table as SELECT ... FROM [<table>]
- 1570
elsif parent_object.is_a?(Array) &&
node.parent.parent.object.is_a?(Arel::Nodes::JoinSource)
- 30
context[:range_variable] = true
# NOTE: only applies to ActiveRecord generated Arel
# which does not use Arel::Table#alias but Arel::TableAlias instead
# Using Arel::Table as SELECT ... FROM [<table> AS alias]
- 1540
elsif parent_object.is_a?(Arel::Nodes::TableAlias) &&
node.parent.parent.object.is_a?(Array) &&
node.parent.parent.parent.object.is_a?(Arel::Nodes::JoinSource)
context[:range_variable] = true
- 1540
elsif parent_object.is_a?(Arel::Nodes::TableAlias) &&
node.parent.parent.object.is_a?(Arel::Attributes::Attribute)
context[:column_reference] = true
- 1540
elsif parent_object.is_a?(Arel::Nodes::TableAlias) &&
node.parent.parent.parent.object.is_a?(Arel::Attributes::Attribute)
context[:column_reference] = true
# Using Arel::Table as SELECT ... INNER JOIN <table> ON TRUE
- 1540
elsif parent_object.is_a?(Arel::Nodes::Join)
- 124
context[:range_variable] = true
- 1416
elsif parent_object.is_a?(Arel::Nodes::TableAlias) &&
node.parent.parent.object.is_a?(Arel::Nodes::Join)
context[:range_variable] = true
- 1416
elsif parent_object.is_a?(Arel::Nodes::TableAlias) &&
node.parent.parent.parent.object.is_a?(Arel::Nodes::Join)
context[:range_variable] = true
# Using Arel::Table as an attribute SELECT <table>.id ...
- 1416
elsif parent_object.is_a?(Arel::Attributes::Attribute)
- 1127
context[:column_reference] = true
# Using Arel::Table in an INSERT INTO <table>
- 289
elsif parent_object.is_a?(Arel::Nodes::InsertStatement)
- 86
context[:range_variable] = true
# Using Arel::Table in an UPDATE <table> ...
- 203
elsif parent_object.is_a?(Arel::Nodes::UpdateStatement)
- 52
context[:range_variable] = true
# Arel::Table in UPDATE ... FROM [<table>]
- 151
elsif parent_object.is_a?(Array) &&
node.parent.parent.object.is_a?(Arel::Nodes::UpdateStatement)
- 20
context[:range_variable] = true
# Using Arel::Table in an DELETE FROM <table>
- 131
elsif parent_object.is_a?(Arel::Nodes::DeleteStatement)
- 45
context[:range_variable] = true
# Arel::Table in DELETE ... USING [<table>]
- 86
elsif parent_object.is_a?(Array) &&
node.parent.parent.object.is_a?(Arel::Nodes::DeleteStatement)
- 20
context[:range_variable] = true
# Using Arel::Table as an "alias" for WITH <table> AS (SELECT 1) SELECT 1
- 66
elsif parent_object.is_a?(Arel::Nodes::As) &&
node.parent.parent.parent.object.is_a?(Arel::Nodes::With)
- 41
context[:alias] = true
# Using Arel::Table as an "alias" for WITH RECURSIVE <table> AS (SELECT 1) SELECT 1
- 25
elsif parent_object.is_a?(Arel::Nodes::As) &&
node.parent.parent.parent.object.is_a?(Arel::Nodes::WithRecursive)
context[:alias] = true
# Using Arel::Table as an "alias" for SELECT INTO <table> ...
- 25
elsif parent_object.is_a?(Arel::Nodes::Into)
- 20
context[:alias] = true
else
- 5
raise "Unknown AST location for table #{node.inspect}, #{node.root_node.to_sql}"
end
end
# rubocop:enable Metrics/PerceivedComplexity
# rubocop:enable Metrics/CyclomaticComplexity
# rubocop:enable Metrics/AbcSize
end
end
end
end
- 5
module Arel
- 5
module Enhance
- 5
class Node
- 5
attr_reader :local_path
- 5
attr_reader :object
- 5
attr_reader :parent
- 5
attr_reader :root_node
- 5
def initialize(object)
- 125754
@object = object
- 125754
@root_node = self
- 125754
@dirty = false
end
- 5
def inspect
- 15
recursive_inspect('')
end
- 5
def value
- 250
return unless value?
- 250
fields.first
end
- 5
def each(&block)
- 16812
return enum_for(:each) unless block_given?
- 16386
yield self
- 16386
children.each_value do |child|
- 15960
child.each(&block)
end
end
- 5
def value?
- 855
children.empty?
end
- 5
def dirty?
- 171
root_node.instance_values.fetch('dirty')
end
- 5
def remove
- 30
mutate(nil, remove: true)
end
- 5
def replace(new_arel_node)
- 131
mutate(new_arel_node)
end
- 5
def add(path_node, node)
- 122319
node.local_path = path_node
- 122319
node.parent = self
- 122319
node.root_node = root_node
- 122319
children[path_node.value.to_s] = node
end
- 5
def to_sql(engine = Table.engine)
- 796
return nil if children.empty?
- 561
if object.respond_to?(:to_sql)
- 441
object.to_sql(engine)
else
- 120
collector = Arel::Collectors::SQLString.new
- 120
collector = engine.connection.visitor.accept object, collector
- 120
collector.value
end
end
- 5
def to_sql_and_binds(engine = Table.engine)
- 226
object.to_sql_and_binds(engine)
end
- 5
def method_missing(name, *args, &block)
- 71
child = children[name.to_s]
- 71
return super if child.nil?
- 66
child
end
- 5
def respond_to_missing?(method, include_private = false)
- 20
child = children[method.to_s]
- 20
child.present? || super
end
- 5
def [](key)
- 1406
children.fetch(key.to_s)
end
- 5
def child_at_path(path_items)
- 155
selected_node = self
- 155
path_items.each do |path_item|
- 745
selected_node = selected_node[path_item]
- 745
return nil if selected_node.nil?
end
- 155
selected_node
end
- 5
def query(**kwargs)
- 391
Arel::Enhance::Query.call(self, kwargs)
end
- 5
def full_path
- 395
the_path = [local_path]
- 395
current_parent = parent
- 395
while current_parent
- 2070
the_path.unshift current_parent.local_path
- 2070
current_parent = current_parent.parent
end
- 395
the_path.compact
end
- 5
def children
- 148223
@children ||= {}
end
- 5
def fields
- 69452
@fields ||= []
end
- 5
def context
- 5601
@context ||= {}
end
- 5
protected
- 5
attr_writer :local_path
- 5
attr_writer :parent
- 5
attr_writer :root_node
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/CyclomaticComplexity
# rubocop:disable Metrics/PerceivedComplexity
- 5
def recursive_inspect(string, indent = 1)
- 370
string << "<#{inspect_name} #{full_path.inspect}\n"
- 370
string << "#{spacing(indent)}sql = #{to_sql}\n" unless to_sql.nil?
- 370
string << "#{spacing(indent)}parent = #{parent.nil? ? nil.inspect : parent.inspect_name}"
- 370
string << "\n" unless children.length.zero?
- 370
children.each do |key, child|
- 355
string << "#{spacing(indent)}#{key} =\n"
- 355
string << spacing(indent + 1)
- 355
child.recursive_inspect(string, indent + 2)
end
- 370
string << "\n" if children.length.zero? && value?
- 370
string << "#{spacing(indent)}value = #{value.inspect}" if value?
- 370
string << if children.length.zero?
- 235
">\n"
else
- 135
"#{spacing(indent - 1)}>\n"
end
end
# rubocop:enable Metrics/AbcSize
# rubocop:enable Metrics/CyclomaticComplexity
# rubocop:enable Metrics/PerceivedComplexity
- 5
attr_writer :object
- 5
def inspect_name
- 730
"Node(#{object.class.name})"
end
- 5
def spacing(indent)
- 1585
indent.times.reduce('') do |memo|
- 17275
memo << ' '
- 17275
memo
end
end
- 5
def deep_copy_object
# https://github.com/mvgijssel/arel_toolkit/issues/97
- 141
new_object = Marshal.load(Marshal.dump(object))
- 141
self.object = new_object
- 141
recursive_update_object(new_object)
end
- 5
def recursive_update_object(arel_tree)
- 4890
children.each_value do |child|
- 4749
tree_child = arel_tree.send(*child.local_path.method)
- 4749
child.object = tree_child
- 4749
child.recursive_update_object(tree_child)
end
end
- 5
def mark_as_dirty
- 161
return if dirty?
- 141
@dirty = true
- 141
deep_copy_object
end
- 5
private
# rubocop:disable Metrics/PerceivedComplexity
# rubocop:disable Metrics/CyclomaticComplexity
# rubocop:disable Metrics/AbcSize
- 5
def mutate(new_node, remove: false)
- 161
root_node.mark_as_dirty
- 161
parent_object = parent.object
- 161
new_arel_node = new_node.is_a?(Arel::Enhance::Node) ? new_node.object : new_node
- 161
new_arel_node = [] if remove && object.is_a?(Array)
- 161
if parent_object.respond_to?("#{local_path.value}=")
- 141
parent_object.send("#{local_path.value}=", new_arel_node)
- 20
elsif parent_object.instance_values.key?(local_path.value)
- 5
parent_object.instance_variable_set("@#{local_path.value}", new_arel_node)
- 15
elsif local_path.arguments? && parent_object.respond_to?(local_path.method[0])
- 15
if remove
- 10
parent_object.delete_at(local_path.value)
else
- 5
parent_object[local_path.value] = new_arel_node
end
elsif parent_object.is_a?(Arel::Nodes::TableAlias) && local_path.value == 'relation'
parent_object.instance_variable_set('@left', new_arel_node)
else
raise "Don't know how to replace `#{local_path.value}` in #{parent_object.inspect}"
end
- 161
if new_node.is_a?(Arel::Enhance::Node)
- 5
parent.add(local_path, new_node)
- 5
parent[local_path.value]
else
- 156
new_parent_tree = Visitor.new.accept_with_root(parent_object, parent)
- 151
parent.parent.add(parent.local_path, new_parent_tree)
- 151
new_parent_tree[local_path.value]
end
end
# rubocop:enable Metrics/PerceivedComplexity
# rubocop:enable Metrics/CyclomaticComplexity
# rubocop:enable Metrics/AbcSize
end
end
end
- 5
module Arel
- 5
module Enhance
- 5
class Path
- 5
attr_reader :nodes
- 5
def initialize(nodes = [])
@nodes = nodes
end
- 5
def append(path_node)
Path.new(nodes + [path_node])
end
- 5
def dig_send(object)
selected_object = object
nodes.each do |path_node|
selected_object = selected_object.send(*path_node.method)
end
selected_object
end
- 5
def to_a
nodes.map(&:value)
end
- 5
def current
nodes.last
end
- 5
def inspect
nodes.inspect
string = '['
string << nodes.map(&:inspect).join(', ')
string << ']'
end
end
end
end
- 5
module Arel
- 5
module Enhance
- 5
class PathNode
- 5
attr_reader :method
- 5
attr_reader :value
- 5
def initialize(method, value)
- 122163
@method = method
- 122163
@value = value
end
- 5
def arguments?
- 15
method.is_a?(Array)
end
- 5
def inspect
- 1960
case value
when String
- 1320
"'#{value}'"
else
- 640
value.inspect
end
end
end
end
end
- 5
module Arel
- 5
module Enhance
- 5
class Query
- 5
def self.call(node, kwargs)
- 391
node_attributes = %i[context parent]
- 391
node_args = kwargs.slice(*node_attributes)
- 391
object_args = kwargs.except(*node_attributes)
- 391
node.each.select do |child_node|
- 15451
next unless matches?(child_node, node_args)
- 12041
matches?(child_node.object, object_args)
end
end
- 5
def self.matches?(object, test)
- 43118
case test
when Hash
- 31107
case object
when Hash
- 3375
test <= object
else
- 27732
test.all? do |test_key, test_value|
- 15876
next false unless object.respond_to?(test_key)
- 15626
object_attribute_value = object.public_send(test_key)
- 15626
matches? object_attribute_value, test_value
end
end
when Arel::Enhance::QueryMethods::QueryMethod
- 2535
test.matches?(object)
else
- 9476
object == test
end
end
end
end
end
- 5
module Arel
- 5
module Enhance
- 5
module QueryMethods
- 5
class QueryMethod
- 5
attr_reader :subject
- 5
def initialize(subject)
- 75
@subject = subject
end
end
- 5
class Ancestors < QueryMethod
- 5
def matches?(other)
- 2535
other <= subject
end
end
- 5
def self.in_ancestors?(object)
- 75
Ancestors.new(object)
end
end
end
end
- 5
require_relative './context_enhancer/arel_table'
- 5
module Arel
- 5
module Enhance
# rubocop:disable Naming/MethodName
- 5
class Visitor < Arel::Visitors::Dot
- 5
DEFAULT_CONTEXT_ENHANCERS = {
Arel::Table => Arel::Enhance::ContextEnhancer::ArelTable,
}.freeze
- 5
attr_reader :context_enhancers
- 5
def accept(object, context_enhancers = DEFAULT_CONTEXT_ENHANCERS)
- 3591
@context_enhancers = context_enhancers
- 3591
root_node = Arel::Enhance::Node.new(object)
- 3591
accept_with_root(object, root_node, context_enhancers)
end
- 5
def accept_with_root(object, root_node, context_enhancers = DEFAULT_CONTEXT_ENHANCERS)
- 3747
@context_enhancers = context_enhancers
- 3747
with_node(root_node) do
- 3747
visit object
end
- 3742
root_node
end
- 5
private
- 5
def visit_edge(object, method)
- 109305
arel_node = object.send(method)
- 109305
process_node(arel_node, Arel::Enhance::PathNode.new(method, method))
end
- 5
def nary(object)
- 343
visit_edge(object, 'children')
end
- 5
alias visit_Arel_Nodes_And nary
- 5
def visit_Hash(object)
- 5
object.each do |key, child|
- 5
process_node(child, Arel::Enhance::PathNode.new([:[], key], key))
end
end
- 5
def visit_Array(object)
- 26178
object.each_with_index do |child, index|
- 12853
process_node(child, Arel::Enhance::PathNode.new([:[], index], index))
end
end
- 5
def process_node(arel_node, path_node)
- 122163
node = Arel::Enhance::Node.new(arel_node)
- 122163
current_node.add(path_node, node)
- 122163
update_context(node)
- 122158
with_node node do
- 122158
visit arel_node
end
end
# rubocop:disable Metrics/AbcSize
# arel/lib/arel/visitors/visitor.rb:29
- 5
def visit(object)
- 127652
dispatch_method = dispatch[object.class]
- 127652
send dispatch_method, object
rescue NoMethodError => e
- 1747
raise e if respond_to?(dispatch_method, true)
- 1747
superklass = object.class.ancestors.find do |klass|
- 3801
respond_to?(dispatch[klass], true)
end
- 1747
raise(TypeError, "Cannot visit #{object.class}") unless superklass
- 1747
dispatch[object.class] = dispatch[superklass]
- 1747
retry
end
# rubocop:enable Metrics/AbcSize
- 5
def current_node
- 122163
@node_stack.last
end
- 5
def update_context(node)
- 122163
enhancer = context_enhancers[node.object.class]
- 122163
return if enhancer.nil?
- 2121
enhancer.call(node)
end
end
# rubocop:enable Naming/MethodName
end
end
- 5
require 'arel/extensions/dot'
- 5
require 'arel/extensions/unknown'
- 5
require 'arel/extensions/time_with_precision'
- 5
require 'arel/extensions/current_time'
- 5
require 'arel/extensions/current_date'
- 5
require 'arel/extensions/current_timestamp'
- 5
require 'arel/extensions/local_time'
- 5
require 'arel/extensions/local_timestamp'
- 5
require 'arel/extensions/current_role'
- 5
require 'arel/extensions/current_user'
- 5
require 'arel/extensions/session_user'
- 5
require 'arel/extensions/user'
- 5
require 'arel/extensions/current_catalog'
- 5
require 'arel/extensions/current_schema'
- 5
require 'arel/extensions/array'
- 5
require 'arel/extensions/indirection'
- 5
require 'arel/extensions/bit_string'
- 5
require 'arel/extensions/natural_join'
- 5
require 'arel/extensions/cross_join'
- 5
require 'arel/extensions/lateral'
- 5
require 'arel/extensions/range_function'
- 5
require 'arel/extensions/with_ordinality'
- 5
require 'arel/extensions/table'
- 5
require 'arel/extensions/attributes_attribute'
- 5
require 'arel/extensions/row'
- 5
require 'arel/extensions/ordering'
- 5
require 'arel/extensions/all'
- 5
require 'arel/extensions/any'
- 5
require 'arel/extensions/array_subselect'
- 5
require 'arel/extensions/type_cast'
- 5
require 'arel/extensions/distinct_from'
- 5
require 'arel/extensions/not_distinct_from'
- 5
require 'arel/extensions/null_if'
- 5
require 'arel/extensions/similar'
- 5
require 'arel/extensions/not_similar'
- 5
require 'arel/extensions/not_between'
- 5
require 'arel/extensions/between_symmetric'
- 5
require 'arel/extensions/not_between_symmetric'
- 5
require 'arel/extensions/function'
- 5
require 'arel/extensions/factorial'
- 5
require 'arel/extensions/square_root'
- 5
require 'arel/extensions/cube_root'
- 5
require 'arel/extensions/modulo'
- 5
require 'arel/extensions/absolute'
- 5
require 'arel/extensions/bitwise_xor'
- 5
require 'arel/extensions/exponentiation'
- 5
require 'arel/extensions/contains'
- 5
unless Gem.loaded_specs.key?('postgres_ext')
- 4
require 'arel/extensions/contained_within_equals'
- 4
require 'arel/extensions/contains_equals'
- 4
require 'arel/extensions/overlap'
end
- 5
require 'arel/extensions/contained_by'
- 5
require 'arel/extensions/select_statement'
- 5
require 'arel/extensions/insert_statement'
- 5
require 'arel/extensions/default_values'
- 5
require 'arel/extensions/conflict'
- 5
require 'arel/extensions/infer'
- 5
require 'arel/extensions/set_to_default'
- 5
require 'arel/extensions/update_statement'
- 5
require 'arel/extensions/current_of_expression'
- 5
require 'arel/extensions/delete_statement'
- 5
require 'arel/extensions/least'
- 5
require 'arel/extensions/greatest'
- 5
require 'arel/extensions/coalesce'
- 5
require 'arel/extensions/not_equal'
- 5
require 'arel/extensions/equality'
- 5
require 'arel/extensions/named_function'
- 5
require 'arel/extensions/intersect_all'
- 5
require 'arel/extensions/except_all'
- 5
require 'arel/extensions/select_manager'
- 5
require 'arel/extensions/insert_manager'
- 5
require 'arel/extensions/update_manager'
- 5
require 'arel/extensions/delete_manager'
- 5
require 'arel/extensions/at_time_zone'
- 5
require 'arel/extensions/extract_from'
- 5
require 'arel/extensions/json_get_object'
- 5
require 'arel/extensions/json_get_field'
- 5
require 'arel/extensions/json_path_get_object'
- 5
require 'arel/extensions/json_path_get_field'
- 5
require 'arel/extensions/jsonb_key_exists'
- 5
require 'arel/extensions/jsonb_any_key_exists'
- 5
require 'arel/extensions/jsonb_all_key_exists'
- 5
require 'arel/extensions/transaction'
- 5
require 'arel/extensions/assignment'
- 5
require 'arel/extensions/variable_set'
- 5
require 'arel/extensions/variable_show'
- 5
require 'arel/extensions/position'
- 5
require 'arel/extensions/overlay'
- 5
require 'arel/extensions/substring'
- 5
require 'arel/extensions/overlaps'
- 5
require 'arel/extensions/trim'
- 5
require 'arel/extensions/named_argument'
- 5
require 'arel/extensions/tree_manager'
- 5
require 'arel/extensions/into'
- 5
require 'arel/extensions/select_core'
- 5
require 'arel/extensions/unary'
- 5
require 'arel/extensions/binary'
- 5
require 'arel/extensions/unary_operation'
- 5
require 'arel/extensions/infix_operation'
- 5
require 'arel/extensions/values_list'
- 5
require 'arel/extensions/case'
- 5
require 'arel/extensions/current_row'
- 5
require 'arel/extensions/false'
- 5
require 'arel/extensions/true'
- 5
require 'arel/extensions/to_sql'
- 5
require 'arel/extensions/prepare'
- 5
require 'arel/extensions/dealocate'
- 5
require 'arel/extensions/active_record_type_caster_map'
- 5
require 'arel/extensions/active_record_type_caster_connection'
- 5
require 'arel/extensions/active_record_relation_query_attribute'
- 5
require 'arel/extensions/active_model_attribute_with_cast_value'
- 5
require 'arel/extensions/exists'
- 5
require 'arel/extensions/bind_param'
- 5
require 'arel/extensions/node'
- 5
require 'arel/extensions/top'
- 5
module Arel
- 5
module Extensions
end
end
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.4/functions-math.html
- 5
class Absolute < Arel::Nodes::UnaryOperation
- 5
def initialize(operand)
- 10
super('@', operand)
end
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class Dot
- 5
def visit_ActiveModel_Attribute_WithCastValue(o)
- 149
visit_edge o, 'name'
- 149
visit_edge o, 'value_before_type_cast'
end
end
- 5
class ToSql
- 5
def visit_ActiveModel_Attribute_WithCastValue(_o, collector)
collector
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class Dot
- 5
def visit_ActiveRecord_Relation_QueryAttribute(o)
- 235
visit_edge o, 'name'
- 235
visit_edge o, 'value_before_type_cast'
end
end
- 5
class ToSql
- 5
def visit_ActiveRecord_Relation_QueryAttribute(_o, collector)
collector
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class Dot
- 5
alias visit_ActiveRecord_TypeCaster_Connection terminal
end
end
end
- 5
module Arel
- 5
module Visitors
- 5
class Dot
- 5
alias visit_ActiveRecord_TypeCaster_Map terminal
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# Postgres: https://www.postgresql.org/docs/8.1/sql-select.html
- 5
class All < Arel::Nodes::Unary
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_All(o, collector)
- 15
collector << 'ALL('
- 15
visit o.expr, collector
- 15
collector << ')'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# Postgres: https://www.postgresql.org/docs/9.1/functions-comparisons.html
- 5
class Any < Arel::Nodes::Unary
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Any(o, collector)
- 35
collector << 'ANY('
- 35
visit o.expr, collector
- 35
collector << ')'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class Array < Arel::Nodes::Unary
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Array(o, collector)
- 100
collector << 'ARRAY['
- 100
inject_join(o.expr, collector, ', ')
- 100
collector << ']'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# Postgres: https://www.postgresql.org/docs/9.1/functions-comparisons.html
- 5
class ArraySubselect < Arel::Nodes::Unary
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_ArraySubselect(o, collector)
- 5
collector << 'ARRAY('
- 5
visit o.expr, collector
- 5
collector << ')'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Assignment(o, collector)
- 201
collector = visit o.left, collector
- 201
collector << ' = '
- 201
case o.right
when Arel::Nodes::Node, Arel::Attributes::Attribute
- 170
visit o.right, collector
else
- 31
collector << quote(o.right).to_s
end
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.2/functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT
- 5
class AtTimeZone < Arel::Nodes::Node
- 5
attr_reader :timezone
- 5
attr_reader :expr
- 5
def initialize(expr, timezone)
- 60
@expr = expr
- 60
@timezone = timezone
end
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_AtTimeZone(o, collector)
- 30
visit o.expr, collector
- 30
collector << ' AT TIME ZONE '
- 30
visit o.timezone, collector
end
end
- 5
class Dot
- 5
def visit_Arel_Nodes_AtTimeZone(o)
- 30
visit_edge o, 'expr'
- 30
visit_edge o, 'timezone'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Attributes
- 5
class Attribute
- 5
module AttributeExtension
# postgres only: https://www.postgresql.org/docs/10/ddl-schemas.html
- 5
attr_accessor :schema_name
- 5
attr_accessor :database
end
- 5
prepend AttributeExtension
end
end
- 5
module Visitors
- 5
class ToSql
- 5
module AttributesAttributeExtension
- 5
def visit_Arel_Attributes_Attribute(o, collector)
- 2006
collector << "#{quote_table_name(o.database)}." if o.database
- 2006
collector << "#{quote_table_name(o.schema_name)}." if o.schema_name
- 2006
super
end
end
- 5
prepend AttributesAttributeExtension
end
- 5
class Dot
- 5
module AttributesAttributeExtension
- 5
def visit_Arel_Attributes_Attribute(o)
- 2086
super
- 2086
visit_edge o, 'schema_name'
- 2086
visit_edge o, 'database'
end
end
- 5
prepend AttributesAttributeExtension
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# Postgres: https://www.postgresql.org/docs/9.1/functions-comparison.html
- 5
class BetweenSymmetric < Arel::Nodes::Between
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_BetweenSymmetric(o, collector)
- 5
collector = visit o.left, collector
- 5
collector << ' BETWEEN SYMMETRIC '
- 5
visit o.right, collector
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class Dot
- 5
alias visit_Arel_Nodes_Binary binary
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class Dot
- 5
def visit_Arel_Nodes_BindParam(o)
- 449
visit_edge o, 'value'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class BitString < Arel::Nodes::Unary
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_BitString(o, collector)
- 5
collector << "B'#{o.expr[1..-1]}'"
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://github.com/mvgijssel/arel_toolkit/issues/45
- 5
class BitwiseXor < InfixOperation
- 5
def initialize(left, right)
- 20
super('#', left, right)
end
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class Dot
- 5
def visit_Arel_Nodes_Case(o)
- 10
visit_edge o, 'case'
- 10
visit_edge o, 'conditions'
- 10
visit_edge o, 'default'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/10/functions-conditional.html
- 5
class Coalesce < Arel::Nodes::Unary
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Coalesce(o, collector)
- 31
collector << 'COALESCE('
- 31
collector = inject_join(o.expr, collector, ', ')
- 31
collector << ')'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.5/sql-insert.html
- 5
class Conflict < Arel::Nodes::Node
- 5
attr_accessor :action
- 5
attr_accessor :infer
- 5
attr_accessor :values
- 5
attr_accessor :wheres
end
end
- 5
module Visitors
- 5
class ToSql
# rubocop:disable Metrics/AbcSize
- 5
def visit_Arel_Nodes_Conflict(o, collector)
- 22
collector << ' ON CONFLICT '
- 22
visit(o.infer, collector) if o.infer
- 22
case o.action
when :ONCONFLICT_NOTHING
- 5
collector << 'DO NOTHING'
when :ONCONFLICT_UPDATE
- 17
collector << 'DO UPDATE SET '
else
raise "Unknown conflict clause `#{o.action}`"
end
- 22
o.values.any? && (inject_join o.values, collector, ', ')
- 22
if o.wheres.any?
- 6
collector << ' WHERE '
- 6
collector = inject_join o.wheres, collector, ' AND '
end
- 22
collector
end
# rubocop:enable Metrics/AbcSize
end
- 5
class Dot
- 5
def visit_Arel_Nodes_Conflict(o)
- 22
visit_edge o, 'action'
- 22
visit_edge o, 'infer'
- 22
visit_edge o, 'values'
- 22
visit_edge o, 'wheres'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.1/functions-array.html
- 5
class ContainedBy < InfixOperation
- 5
def initialize(left, right)
- 40
super('<@', left, right)
end
end
end
end
- 4
module Arel
- 4
module Nodes
# https://www.postgresql.org/docs/9.3/functions-net.html
- 4
class ContainedWithinEquals < Arel::Nodes::InfixOperation
- 4
def initialize(left, right)
- 16
super(:'<<=', left, right)
end
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
if Gem.loaded_specs.key?('postgres_ext')
- 1
module Visitors
- 1
module ContainsPatch
- 1
def visit_Arel_Nodes_Contains(o, collector)
- 4
if o.left.is_a?(Arel::Attribute)
super
else
- 4
infix_value o, collector, ' @> '
end
end
end
- 1
PostgreSQL.prepend(ContainsPatch)
end
else
- 4
module Nodes
# https://www.postgresql.org/docs/9.1/functions-array.html
- 4
class Contains < Arel::Nodes::InfixOperation
- 4
def initialize(left, right)
- 32
super(:'@>', left, right)
end
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 4
module Arel
- 4
module Nodes
# https://www.postgresql.org/docs/9.3/functions-net.html
- 4
class ContainsEquals < Arel::Nodes::InfixOperation
- 4
def initialize(left, right)
- 16
super(:'>>=', left, right)
end
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class CrossJoin < Arel::Nodes::Join
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_CrossJoin(o, collector)
- 5
collector << 'CROSS JOIN '
- 5
visit o.left, collector
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.4/functions-math.html
- 5
class CubeRoot < Arel::Nodes::UnaryOperation
- 5
def initialize(operand)
- 10
super('||/', operand)
end
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class CurrentCatalog < Arel::Nodes::Node
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_CurrentCatalog(_o, collector)
- 5
collector << 'current_catalog'
end
end
- 5
class Dot
- 5
alias visit_Arel_Nodes_CurrentCatalog terminal
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class CurrentDate < Arel::Nodes::Node
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_CurrentDate(_o, collector)
- 10
collector << 'current_date'
end
end
- 5
class Dot
- 5
alias visit_Arel_Nodes_CurrentDate terminal
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/10/sql-update.html
- 5
class CurrentOfExpression < Arel::Nodes::Unary
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_CurrentOfExpression(o, collector)
- 10
collector << 'CURRENT OF '
- 10
collector << o.expr
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class CurrentRole < Arel::Nodes::Node
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_CurrentRole(_o, collector)
- 5
collector << 'current_role'
end
end
- 5
class Dot
- 5
alias visit_Arel_Nodes_CurrentRole terminal
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class Dot
- 5
alias visit_Arel_Nodes_CurrentRow terminal
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class CurrentSchema < Arel::Nodes::Node
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_CurrentSchema(_o, collector)
- 5
collector << 'current_schema'
end
end
- 5
class Dot
- 5
alias visit_Arel_Nodes_CurrentSchema terminal
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class CurrentTime < TimeWithPrecision
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_CurrentTime(o, collector)
- 15
collector << 'current_time'
- 15
collector << "(#{o.precision.to_i})" if o.precision
- 15
collector
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class CurrentTimestamp < TimeWithPrecision
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_CurrentTimestamp(o, collector)
- 30
collector << 'current_timestamp'
- 30
collector << "(#{o.precision.to_i})" if o.precision
- 30
collector
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class CurrentUser < Arel::Nodes::Node
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_CurrentUser(_o, collector)
- 5
collector << 'current_user'
end
end
- 5
class Dot
- 5
alias visit_Arel_Nodes_CurrentUser terminal
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class Dot
- 5
def visit_Arel_Nodes_Dealocate(o)
- 10
visit_edge o, 'name'
end
end
- 5
class ToSql
- 5
def visit_Arel_Nodes_Dealocate(o, collector)
- 10
collector << 'DEALLOCATE ' << (o.name || 'ALL')
end
end
end
- 5
module Nodes
- 5
class Dealocate < Node
- 5
attr_reader :name
- 5
def initialize(name)
- 20
@name = name
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.5/sql-insert.html
- 5
class DefaultValues < Arel::Nodes::Node
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_DefaultValues(_o, collector)
- 5
collector << 'DEFAULT VALUES'
end
end
- 5
class Dot
- 5
alias visit_Arel_Nodes_DefaultValues terminal
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
class DeleteManager < Arel::TreeManager
- 5
def ==(other)
- 15
other.is_a?(self.class) && @ast == other.ast && @ctx == other.ctx
end
- 5
protected
- 5
attr_reader :ctx
end
- 5
module Visitors
- 5
class Dot
- 5
def visit_Arel_DeleteManager(o)
- 45
visit_edge o, 'ast'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/10/sql-delete.html
- 5
class DeleteStatement
- 5
module DeleteStatementExtension
- 5
attr_accessor :using
- 5
attr_accessor :with
- 5
attr_accessor :returning
- 5
attr_accessor :orders
- 5
def initialize(relation = nil, wheres = [])
- 125
super
- 125
@returning = []
- 125
@orders = []
- 125
@using = []
end
end
- 5
prepend DeleteStatementExtension
end
end
- 5
module Visitors
- 5
class ToSql
# rubocop:disable Metrics/AbcSize
- 5
def visit_Arel_Nodes_DeleteStatement(o, collector)
- 80
if o.with
- 5
collector = visit o.with, collector
- 5
collector << ' '
end
- 80
if Gem.loaded_specs['activerecord'].version >= Gem::Version.new('6.0.0')
- 48
o = prepare_delete_statement(o)
- 48
if has_join_sources?(o)
collector << 'DELETE '
visit o.relation.left, collector
collector << ' FROM '
else
- 48
collector << 'DELETE FROM '
end
else
- 32
collector << 'DELETE FROM '
end
- 80
collector = visit o.relation, collector
- 80
collect_nodes_for o.using, collector, ' USING ', ', '
- 80
collect_nodes_for o.wheres, collector, ' WHERE ', ' AND '
- 80
collect_nodes_for o.returning, collector, ' RETURNING ', ', '
- 80
collect_nodes_for o.orders, collector, ' ORDER BY '
- 80
maybe_visit o.limit, collector
end
# rubocop:enable Metrics/AbcSize
end
- 5
class Dot
- 5
module DeleteStatementExtension
- 5
def visit_Arel_Nodes_DeleteStatement(o)
- 45
super
- 45
visit_edge o, 'using'
- 45
visit_edge o, 'with'
- 45
visit_edge o, 'returning'
end
end
- 5
prepend(DeleteStatementExtension)
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class DistinctFrom < Arel::Nodes::InfixOperation
- 5
def initialize(left, right)
- 10
super(:'IS DISTINCT FROM', left, right)
end
end
end
end
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class Dot
- 5
def terminal(_o); end
end
end
end
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Equality(o, collector)
- 983
right = o.right
- 983
collector = visit o.left, collector
- 983
if [Arel::Nodes::Unknown, Arel::Nodes::False, Arel::Nodes::True].include?(right.class)
- 15
collector << ' IS '
- 15
visit right, collector
- 968
elsif right.nil?
- 10
collector << ' IS NULL'
else
- 958
collector << ' = '
- 958
visit right, collector
end
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class ExceptAll < Binary
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_ExceptAll(o, collector)
- 5
collector << '( '
- 5
infix_value(o, collector, ' EXCEPT ALL ') << ' )'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# This is a copy of https://github.com/rails/arel/blob/v9.0.0/lib/arel/nodes/function.rb
# Only difference is the superclass, because EXISTS is not a function but a subquery expression.
# Semantic meaning is important when transforming the Arel using the enhanced AST,
# because EXISTS cannot be processed as a function. For example it does not have a schema
# like a normal function.
#
# To change the superclass we're removing the existing Exists class `Arel::Nodes::Exists`
# and recreating it extending from `Arel::Nodes::Unary`.
- 5
remove_const(:Exists)
# https://www.postgresql.org/docs/10/functions-subquery.html
- 5
class Exists < Arel::Nodes::Unary
- 5
include Arel::Predications
- 5
include Arel::WindowPredications
- 5
include Arel::OrderPredications
- 5
attr_accessor :expressions, :alias, :distinct
- 5
def initialize(expr, aliaz = nil)
- 40
@expressions = expr
- 40
@alias = aliaz && SqlLiteral.new(aliaz)
- 40
@distinct = false
end
- 5
def as(aliaz)
- 5
self.alias = SqlLiteral.new(aliaz)
- 5
self
end
- 5
def hash
- 10
[@expressions, @alias, @distinct].hash
end
- 5
def eql?(other)
- 5
self.class == other.class &&
expressions == other.expressions &&
self.alias == other.alias &&
distinct == other.distinct
end
- 5
alias == eql?
end
end
- 5
module Visitors
- 5
class Dot
- 5
def visit_Arel_Nodes_Exists(o)
- 10
visit_edge o, 'expressions'
- 10
visit_edge o, 'alias'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.1/functions-array.html
- 5
class Exponentiation < InfixOperation
- 5
def initialize(left, right)
- 10
super(:^, left, right)
end
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.1/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT
- 5
class ExtractFrom < Arel::Nodes::Binary
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_ExtractFrom(o, collector)
- 20
collector << 'extract('
- 20
visit o.right, collector
- 20
collector << ' from '
- 20
visit o.left, collector
- 20
collector << ')'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.4/functions-math.html
- 5
class Factorial < Arel::Nodes::Node
- 5
attr_accessor :prefix
- 5
attr_accessor :expr
- 5
def initialize(expr, prefix)
- 30
@expr = expr
- 30
@prefix = prefix
end
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Factorial(o, collector)
- 15
if o.prefix
- 10
collector << '!! '
- 10
visit o.expr, collector
else
- 5
visit o.expr, collector
- 5
collector << ' !'
end
end
end
- 5
class Dot
- 5
def visit_Arel_Nodes_Factorial(o)
- 15
visit_edge o, 'expr'
- 15
visit_edge o, 'prefix'
end
end
end
end
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:enable Naming/MethodName
- 5
module Arel
- 5
module Visitors
- 5
class Dot
- 5
alias visit_Arel_Nodes_False terminal
end
end
end
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# Postgres: https://www.postgresql.org/docs/9.1/functions-comparison.html
- 5
class Function
- 5
module FunctionExtension
# postgres only: https://www.postgresql.org/docs/9.5/functions-aggregate.html
- 5
attr_accessor :orders
- 5
attr_accessor :filter
- 5
attr_accessor :within_group
- 5
attr_accessor :variardic
# postgres only: https://www.postgresql.org/docs/10/ddl-schemas.html
- 5
attr_accessor :schema_name
- 5
def initialize(expr, aliaz = nil)
- 3192
super
- 3192
@expressions = expr
- 3192
@alias = aliaz && SqlLiteral.new(aliaz)
- 3192
@distinct = false
- 3192
@orders = []
end
end
- 5
prepend FunctionExtension
end
end
- 5
module Visitors
- 5
class ToSql
# rubocop:disable Metrics/PerceivedComplexity
# rubocop:disable Metrics/CyclomaticComplexity
# rubocop:disable Metrics/AbcSize
- 5
def aggregate(name, o, collector)
- 1707
collector << "#{o.schema_name}." if o.schema_name
- 1707
collector << "#{name}("
- 1707
collector << 'DISTINCT ' if o.distinct
- 1707
collector << 'VARIADIC ' if o.variardic
- 1707
collector = inject_join(o.expressions, collector, ', ')
- 1707
if o.within_group
- 5
collector << ')'
- 5
collector << ' WITHIN GROUP ('
end
- 1707
if o.orders.any?
- 15
collector << ' ' unless o.within_group
- 15
collector << 'ORDER BY '
- 15
collector = inject_join o.orders, collector, ', '
end
- 1707
collector << ')'
- 1707
if o.filter
- 5
collector << ' FILTER(WHERE '
- 5
visit o.filter, collector
- 5
collector << ')'
end
- 1707
if o.alias
collector << ' AS '
visit o.alias, collector
else
- 1707
collector
end
end
# rubocop:enable Metrics/PerceivedComplexity
# rubocop:enable Metrics/CyclomaticComplexity
# rubocop:enable Metrics/AbcSize
end
- 5
class Dot
- 5
module FunctionExtension
- 5
def function(o)
- 1642
super
- 1642
visit_edge o, 'orders'
- 1642
visit_edge o, 'filter'
- 1642
visit_edge o, 'within_group'
- 1642
visit_edge o, 'variardic'
- 1642
visit_edge o, 'schema_name'
end
- 5
alias visit_Arel_Nodes_Min function
- 5
alias visit_Arel_Nodes_Max function
- 5
alias visit_Arel_Nodes_Avg function
- 5
alias visit_Arel_Nodes_Sum function
- 5
alias visit_Arel_Nodes_Count function
end
- 5
prepend FunctionExtension
end
end
end
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/10/functions-conditional.html
- 5
class Greatest < Arel::Nodes::Unary
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Greatest(o, collector)
- 10
collector << 'GREATEST('
- 10
collector = inject_join(o.expr, collector, ', ')
- 10
collector << ')'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class Indirection < Arel::Nodes::Binary
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Indirection(o, collector)
- 15
visit(o.left, collector)
- 15
collector << '['
- 15
visit(o.right, collector)
- 15
collector << ']'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.5/sql-insert.html
- 5
class Infer < Arel::Nodes::Binary
- 5
alias name left
- 5
alias indexes right
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Infer(o, collector)
- 12
if o.name.present?
- 5
collector << 'ON CONSTRAINT '
- 5
collector << o.left
- 5
collector << ' '
end
- 12
if o.right.present?
- 7
collector << '('
- 7
inject_join o.right, collector, ', '
- 7
collector << ') '
end
- 12
collector
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class Dot
- 5
def visit_Arel_Nodes_InfixOperation(o)
- 481
visit_edge o, 'operator'
- 481
visit_edge o, 'left'
- 481
visit_edge o, 'right'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
class InsertManager < Arel::TreeManager
- 5
def ==(other)
- 15
other.is_a?(self.class) && @ast == other.ast
end
end
- 5
module Visitors
- 5
class Dot
- 5
def visit_Arel_InsertManager(o)
- 86
visit_edge o, 'ast'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class InsertStatement
# https://www.postgresql.org/docs/9.5/sql-insert.html
- 5
module InsertStatementExtension
- 5
attr_accessor :with
- 5
attr_accessor :conflict
- 5
attr_accessor :override
- 5
attr_accessor :returning
- 5
def initialize
- 454
super
- 454
@returning = []
end
end
- 5
prepend(InsertStatementExtension)
end
end
- 5
module Visitors
- 5
class ToSql
# rubocop:disable Metrics/CyclomaticComplexity
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/PerceivedComplexity
- 5
def visit_Arel_Nodes_InsertStatement(o, collector)
- 399
if o.with
- 5
collector = visit o.with, collector
- 5
collector << ' '
end
- 399
collector << 'INSERT INTO '
- 399
collector = visit o.relation, collector
- 399
if o.columns.any?
- 364
collector << " (#{o.columns.map do |x|
- 906
quote_column_name x.name
end.join ', '})"
end
- 399
case o.override
when :OVERRIDING_KIND_UNDEFINED, :OVERRIDING_NOT_SET, nil
- 389
collector << ''
when :OVERRIDING_USER_VALUE
- 5
collector << ' OVERRIDING USER VALUE'
when :OVERRIDING_SYSTEM_VALUE
- 5
collector << ' OVERRIDING SYSTEM VALUE'
else
raise "Unknown override `#{o.override}`"
end
- 399
collector = if o.values
- 399
maybe_visit o.values, collector
elsif o.select
maybe_visit o.select, collector
else
collector
end
- 399
visit(o.conflict, collector) if o.conflict
- 399
unless o.returning.empty?
- 71
collector << ' RETURNING '
- 71
collector = inject_join o.returning, collector, ', '
end
- 399
collector
end
# rubocop:enable Metrics/CyclomaticComplexity
# rubocop:enable Metrics/AbcSize
# rubocop:enable Metrics/PerceivedComplexity
end
- 5
class Dot
- 5
module InsertStatementExtension
- 5
def visit_Arel_Nodes_InsertStatement(o)
- 86
super
- 86
visit_edge o, 'with'
- 86
visit_edge o, 'conflict'
- 86
visit_edge o, 'override'
- 86
visit_edge o, 'returning'
end
end
- 5
prepend(InsertStatementExtension)
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class IntersectAll < Binary
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_IntersectAll(o, collector)
- 5
collector << '( '
- 5
infix_value(o, collector, ' INTERSECT ALL ') << ' )'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class Into < Arel::Nodes::Unary
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Into(o, collector)
- 15
collector << 'INTO '
- 15
visit o.expr, collector
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.4/functions-json.html#FUNCTIONS-JSON-OP-TABLE
- 5
class JsonGetField < Arel::Nodes::InfixOperation
- 5
def initialize(left, right)
- 20
super(:'->>', left, right)
end
end
end
end
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.4/functions-json.html#FUNCTIONS-JSON-OP-TABLE
- 5
class JsonGetObject < Arel::Nodes::InfixOperation
- 5
def initialize(left, right)
- 20
super(:'->', left, right)
end
end
end
end
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.4/functions-json.html#FUNCTIONS-JSON-OP-TABLE
- 5
class JsonPathGetField < Arel::Nodes::InfixOperation
- 5
def initialize(left, right)
- 10
super(:'#>>', left, right)
end
end
end
end
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.4/functions-json.html#FUNCTIONS-JSON-OP-TABLE
- 5
class JsonPathGetObject < Arel::Nodes::InfixOperation
- 5
def initialize(left, right)
- 10
super(:'#>', left, right)
end
end
end
end
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.4/functions-json.html#FUNCTIONS-JSONB-OP-TABLE
- 5
class JsonbAllKeyExists < Arel::Nodes::InfixOperation
- 5
def initialize(left, right)
- 10
super(:'?&', left, right)
end
end
end
end
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.4/functions-json.html#FUNCTIONS-JSONB-OP-TABLE
- 5
class JsonbAnyKeyExists < Arel::Nodes::InfixOperation
- 5
def initialize(left, right)
- 20
super(:'?|', left, right)
end
end
end
end
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.4/functions-json.html#FUNCTIONS-JSONB-OP-TABLE
- 5
class JsonbKeyExists < Arel::Nodes::InfixOperation
- 5
def initialize(left, right)
- 10
super(:'?', left, right)
end
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://github.com/mvgijssel/arel_toolkit/issues/46
- 5
class Lateral < Arel::Nodes::Unary
end
end
- 5
module Visitors
- 5
class ToSql
# https://github.com/mvgijssel/arel_toolkit/issues/46
- 5
def visit_Arel_Nodes_Lateral(o, collector)
- 4
collector << 'LATERAL '
- 4
grouping_parentheses o, collector
end
# https://github.com/mvgijssel/arel_toolkit/issues/46
- 5
def grouping_parentheses(o, collector)
- 4
if o.expr.is_a? Nodes::SelectStatement
collector << '('
visit o.expr, collector
collector << ')'
else
- 4
visit o.expr, collector
end
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/10/functions-conditional.html
- 5
class Least < Arel::Nodes::Unary
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Least(o, collector)
- 10
collector << 'LEAST('
- 10
collector = inject_join(o.expr, collector, ', ')
- 10
collector << ')'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class LocalTime < TimeWithPrecision
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_LocalTime(o, collector)
- 15
collector << 'localtime'
- 15
collector << "(#{o.precision.to_i})" if o.precision
- 15
collector
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class LocalTimestamp < TimeWithPrecision
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_LocalTimestamp(o, collector)
- 15
collector << 'localtimestamp'
- 15
collector << "(#{o.precision.to_i})" if o.precision
- 15
collector
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.4/functions-math.html
- 5
class Modulo < Arel::Nodes::InfixOperation
- 5
def initialize(left, right)
- 10
super(:%, left, right)
end
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class NamedArgument < Arel::Nodes::Binary
- 5
alias name left
- 5
alias value right
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_NamedArgument(o, collector)
- 5
collector << o.name
- 5
collector << ' => '
- 5
visit(o.value, collector)
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_NamedFunction(o, collector)
- 1542
aggregate(o.name, o, collector)
end
end
- 5
class Dot
- 5
def visit_Arel_Nodes_NamedFunction(o)
- 1492
visit_edge o, 'name'
- 1492
function(o)
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class NaturalJoin < Arel::Nodes::Join
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_NaturalJoin(o, collector)
- 5
collector << 'NATURAL JOIN '
- 5
visit o.left, collector
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class Node
- 5
def to_sql_and_binds(engine = Arel::Table.engine)
- 230
collector = engine.connection.send(:collector)
- 230
engine.connection.visitor.accept(self, collector).value
end
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class NotBetween < Arel::Nodes::Between
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_NotBetween(o, collector)
- 5
collector = visit o.left, collector
- 5
collector << ' NOT BETWEEN '
- 5
visit o.right, collector
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# Postgres: https://www.postgresql.org/docs/9.1/functions-comparison.html
- 5
class NotBetweenSymmetric < Arel::Nodes::BetweenSymmetric
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_NotBetweenSymmetric(o, collector)
- 5
collector = visit o.left, collector
- 5
collector << ' NOT BETWEEN SYMMETRIC '
- 5
visit o.right, collector
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class NotDistinctFrom < Arel::Nodes::InfixOperation
- 5
def initialize(left, right)
- 10
super(:'IS NOT DISTINCT FROM', left, right)
end
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_NotEqual(o, collector)
- 50
right = o.right
- 50
collector = visit o.left, collector
- 50
if [Arel::Nodes::Unknown, Arel::Nodes::False, Arel::Nodes::True].include?(right.class)
- 15
collector << ' IS NOT '
- 15
visit right, collector
- 35
elsif right.nil?
- 10
collector << ' IS NOT NULL'
else
- 25
collector << ' != '
- 25
visit right, collector
end
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# Postgres: https://www.postgresql.org/docs/9/functions-matching.html
- 5
class NotSimilar < Arel::Nodes::Similar
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_NotSimilar(o, collector)
- 10
visit o.left, collector
- 10
collector << ' NOT SIMILAR TO '
- 10
visit o.right, collector
- 10
if o.escape
- 5
collector << ' ESCAPE '
- 5
visit o.escape, collector
else
- 5
collector
end
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class NullIf < Arel::Nodes::Binary
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_NullIf(o, collector)
- 15
collector << 'NULLIF('
- 15
visit o.left, collector
- 15
collector << ', '
- 15
visit o.right, collector
- 15
collector << ')'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class Ordering
- 5
module OrderingExtension
# Postgres: https://www.postgresql.org/docs/9.4/queries-order.html
- 5
attr_accessor :nulls
- 5
def initialize(expr, nulls = 0)
- 248
super(expr)
- 248
@nulls = nulls
end
end
- 5
prepend OrderingExtension
end
end
- 5
module Visitors
- 5
class ToSql
- 5
alias old_visit_Arel_Nodes_Ascending visit_Arel_Nodes_Ascending
- 5
def visit_Arel_Nodes_Ascending(o, collector)
- 109
old_visit_Arel_Nodes_Ascending(o, collector)
- 109
apply_ordering_nulls(o, collector)
end
- 5
alias old_visit_Arel_Nodes_Descending visit_Arel_Nodes_Descending
- 5
def visit_Arel_Nodes_Descending(o, collector)
- 44
old_visit_Arel_Nodes_Descending(o, collector)
- 44
apply_ordering_nulls(o, collector)
end
- 5
def apply_ordering_nulls(o, collector)
- 153
case o.nulls
when 1
- 5
collector << ' NULLS FIRST'
when 2
- 5
collector << ' NULLS LAST'
else
- 143
collector
end
end
end
- 5
class Dot
- 5
module OrderingExtension
- 5
def visit_Arel_Nodes_Ordering(o)
- 128
super
- 128
visit_edge o, 'nulls'
end
end
- 5
prepend OrderingExtension
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 4
module Arel
- 4
module Nodes
# https://www.postgresql.org/docs/9.1/functions-array.html
- 4
class Overlap < Arel::Nodes::InfixOperation
- 4
def initialize(left, right)
- 40
super(:'&&', left, right)
end
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/10/functions-string.html
- 5
inheritance_class = if Gem.loaded_specs['activerecord'].version < Gem::Version.new('6.1.0')
- 3
Arel::Nodes::Node
else
- 2
Arel::Nodes::InfixOperation
end
- 5
class Overlaps < inheritance_class
- 5
attr_reader :start1
- 5
attr_reader :end1
- 5
attr_reader :start2
- 5
attr_reader :end2
- 5
def initialize(start1, end1, start2, end2)
- 10
@start1 = start1
- 10
@end1 = end1
- 10
@start2 = start2
- 10
@end2 = end2
end
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Overlaps(o, collector)
- 5
collector << '('
- 5
visit o.start1, collector
- 5
collector << ', '
- 5
visit o.end1, collector
- 5
collector << ') OVERLAPS ('
- 5
visit o.start2, collector
- 5
collector << ', '
- 5
visit o.end2, collector
- 5
collector << ')'
end
end
- 5
class Dot
- 5
def visit_Arel_Nodes_Overlaps(o)
- 5
visit_edge o, 'start1'
- 5
visit_edge o, 'end1'
- 5
visit_edge o, 'start2'
- 5
visit_edge o, 'end2'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
# rubocop:disable Metrics/AbcSize
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/10/functions-string.html
- 5
class Overlay < Arel::Nodes::Node
- 5
attr_reader :string
- 5
attr_reader :substring
- 5
attr_reader :start
- 5
attr_reader :length
- 5
def initialize(string, substring, start, length = nil)
- 40
@string = string
- 40
@substring = substring
- 40
@start = start
- 40
@length = length
end
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Overlay(o, collector)
- 20
collector << 'overlay('
- 20
visit o.string, collector
- 20
collector << ' placing '
- 20
visit o.substring, collector
- 20
collector << ' from '
- 20
visit o.start, collector
- 20
unless o.length.nil?
- 15
collector << ' for '
- 15
visit o.length, collector
end
- 20
collector << ')'
end
end
- 5
class Dot
- 5
def visit_Arel_Nodes_Overlay(o)
- 20
visit_edge o, 'string'
- 20
visit_edge o, 'substring'
- 20
visit_edge o, 'start'
- 20
visit_edge o, 'length'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:enable Metrics/AbcSize
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.1/functions-string.html#FUNCTIONS-STRING-SQL
- 5
class Position < Arel::Nodes::Binary
- 5
alias substring left
- 5
alias string right
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Position(o, collector)
- 15
collector << 'position('
- 15
visit o.substring, collector
- 15
collector << ' in '
- 15
visit o.string, collector
- 15
collector << ')'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class Dot
- 5
def visit_Arel_Nodes_Prepare(o)
- 10
visit_edge o, 'name'
- 10
visit_edge o, 'argtypes'
- 10
visit_edge o, 'query'
end
end
- 5
class ToSql
- 5
def visit_Arel_Nodes_Prepare(o, collector)
- 10
collector << "PREPARE #{o.name}"
- 10
collector << " (#{o.argtypes.join(', ')})" if o.argtypes
- 10
collector << ' AS ('
- 10
visit(o.query, collector)
- 10
collector << ')'
end
end
end
- 5
module Nodes
- 5
class Prepare < Node
- 5
attr_reader :name, :query, :argtypes
- 5
def initialize(name, argtypes, query)
- 20
@name = name
- 20
@query = query
- 20
@argtypes = argtypes
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# Postgres: https://www.postgresql.org/docs/9.4/sql-select.html
- 5
class RangeFunction < Arel::Nodes::Unary
- 5
attr_reader :is_rowsfrom
- 5
def initialize(*args, is_rowsfrom:, **kwargs)
- 30
@is_rowsfrom = is_rowsfrom
- 30
super(*args, **kwargs)
end
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_RangeFunction(o, collector)
- 15
collector << 'ROWS FROM (' if o.is_rowsfrom
- 15
visit o.expr, collector
- 15
collector << ')' if o.is_rowsfrom
- 15
collector
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# Postgres: https://www.postgresql.org/docs/9.2/sql-expressions.html
- 5
class Row < Arel::Nodes::Binary
- 5
alias expr left
- 5
alias row_format right
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Row(o, collector)
- 10
collector << 'ROW('
- 10
visit o.expr, collector
- 10
collector << ')'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
# rubocop:disable Metrics/AbcSize
- 5
module Arel
- 5
module Nodes
- 5
class SelectCore < Arel::Nodes::Node
- 5
attr_accessor :into
- 5
attr_accessor :top
- 5
private
- 5
def hash
[
@source, @set_quantifier, @projections, @optimizer_hints,
@wheres, @groups, @havings, @windows, @comment, @top, @into
].hash
end
- 5
def eql?(other)
super &&
top == other.top &&
into == other.into
end
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_SelectCore(o, collector)
- 3749
collector << 'SELECT'
- 3749
collector = maybe_visit o.set_quantifier, collector
- 3749
collect_nodes_for o.projections, collector, ' '
- 3749
maybe_visit o.into, collector
- 3749
if o.source && !o.source.empty?
- 904
collector << ' FROM '
- 904
collector = visit o.source, collector
end
- 3749
collect_nodes_for o.wheres, collector, ' WHERE ', ' AND '
- 3749
collect_nodes_for o.groups, collector, ' GROUP BY '
- 3749
unless o.havings.empty?
- 5
collector << ' HAVING '
- 5
inject_join o.havings, collector, ' AND '
end
- 3749
collect_nodes_for o.windows, collector, ' WINDOW '
- 3749
collector
end
end
- 5
class Dot
- 5
module SelectCoreExtension
- 5
def visit_Arel_Nodes_SelectCore(o)
- 3451
super
- 3451
visit_edge o, 'into'
- 3451
visit_edge o, 'top'
end
end
- 5
prepend SelectCoreExtension
end
end
end
# rubocop:enable Metrics/AbcSize
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
class SelectManager
- 5
def ==(other)
- 15
other.is_a?(self.class) && @ast == other.ast && @ctx == other.ctx
end
- 5
protected
- 5
attr_reader :ctx
end
- 5
module Visitors
- 5
class Dot
- 5
def visit_Arel_SelectManager(o)
- 3208
visit_edge(o, 'ast')
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class SelectStatement
- 5
module SelectStatementExtension
# For INSERT statements
- 5
attr_accessor :values_lists
- 5
attr_accessor :union
- 5
attr_writer :cores
end
- 5
prepend SelectStatementExtension
end
end
- 5
module Visitors
- 5
class ToSql
- 5
module SelectStatementExtension
- 5
def visit_Arel_Nodes_SelectStatement(o, collector)
- 3739
visit(o.union, collector) if o.union
- 3739
super
end
end
- 5
prepend SelectStatementExtension
end
- 5
class Dot
- 5
module SelectStatementExtension
- 5
def visit_Arel_Nodes_SelectStatement(o)
- 3446
super
- 3441
visit_edge o, 'lock'
- 3441
visit_edge o, 'with'
- 3441
visit_edge o, 'union'
- 3441
visit_edge o, 'values_lists'
end
end
- 5
prepend SelectStatementExtension
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class SessionUser < Arel::Nodes::Node
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_SessionUser(_o, collector)
- 5
collector << 'session_user'
end
end
- 5
class Dot
- 5
alias visit_Arel_Nodes_SessionUser terminal
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.5/sql-insert.html
- 5
class SetToDefault < Arel::Nodes::Node
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_SetToDefault(_o, collector)
- 15
collector << 'DEFAULT'
end
end
- 5
class Dot
- 5
alias visit_Arel_Nodes_SetToDefault terminal
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# Postgres: https://www.postgresql.org/docs/9/functions-matching.html
- 5
class Similar < Arel::Nodes::Matches
- 5
def initialize(left, right, escape = nil)
- 40
super(left, right, escape, false)
end
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Similar(o, collector)
- 10
visit o.left, collector
- 10
collector << ' SIMILAR TO '
- 10
visit o.right, collector
- 10
if o.escape
- 5
collector << ' ESCAPE '
- 5
visit o.escape, collector
else
- 5
collector
end
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.4/functions-math.html
- 5
class SquareRoot < Arel::Nodes::UnaryOperation
- 5
def initialize(operand)
- 10
super('|/', operand)
end
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/10/functions-string.html
- 5
class Substring < Arel::Nodes::Node
- 5
attr_reader :string
- 5
attr_reader :pattern
- 5
attr_reader :escape
- 5
def initialize(string, pattern, escape)
- 70
@string = string
- 70
@pattern = pattern
- 70
@escape = escape
end
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Substring(o, collector)
- 35
collector << 'substring('
- 35
visit o.string, collector
- 35
collector << ' from '
- 35
visit o.pattern, collector
- 35
unless o.escape.nil?
- 25
collector << ' for '
- 25
visit o.escape, collector
end
- 35
collector << ')'
end
end
- 5
class Dot
- 5
def visit_Arel_Nodes_Substring(o)
- 35
visit_edge o, 'string'
- 35
visit_edge o, 'pattern'
- 35
visit_edge o, 'escape'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
# rubocop:disable Metrics/ParameterLists
- 5
module Arel
- 5
class Table
- 5
module TableExtension
# postgres only: https://www.postgresql.org/docs/9.5/sql-select.html
- 5
attr_accessor :only
# postgres only: https://www.postgresql.org/docs/10/ddl-schemas.html
- 5
attr_accessor :schema_name
# postgres only: https://www.postgresql.org/docs/9.1/catalog-pg-class.html
- 5
attr_accessor :relpersistence
- 5
def initialize(
name,
as: nil,
klass: nil,
type_caster: klass&.type_caster,
only: false,
schema_name: nil,
relpersistence: 'p'
)
- 2353
@only = only
- 2353
@schema_name = schema_name
- 2353
@relpersistence = relpersistence
- 2353
if Gem.loaded_specs['activerecord'].version < Gem::Version.new('6.1.0')
- 1549
super(name, as: as, type_caster: type_caster)
else
- 804
super(name, klass: klass, as: as, type_caster: type_caster)
end
end
end
- 5
prepend TableExtension
end
- 5
module Visitors
- 5
class ToSql
- 5
module TableExtension
- 5
def visit_Arel_Table(o, collector)
- 1722
collector << 'ONLY ' if o.only
- 1722
case o.relpersistence
when 'p'
- 1712
collector << ''
when 'u'
- 5
collector << 'UNLOGGED '
when 't'
- 5
collector << 'TEMPORARY '
else
raise "Unknown relpersistence `#{o.relpersistence}`"
end
- 1722
collector << "\"#{o.schema_name}\"." if o.schema_name
- 1722
super
end
end
- 5
prepend TableExtension
end
- 5
class Dot
- 5
module TableExtension
- 5
def visit_Arel_Table(o)
- 2171
super
- 2171
visit_edge o, 'only'
- 2171
visit_edge o, 'schema_name'
- 2171
visit_edge o, 'relpersistence'
- 2171
visit_edge o, 'type_caster'
end
end
- 5
prepend TableExtension
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:enable Metrics/ParameterLists
- 5
module Arel
- 5
module Nodes
- 5
class TimeWithPrecision < Arel::Nodes::Node
- 5
attr_reader :precision
- 5
def initialize(precision: nil)
- 150
super()
- 150
@precision = precision
end
end
end
- 5
module Visitors
- 5
class Dot
- 5
alias visit_Arel_Nodes_TimeWithPrecision terminal
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Attributes_Attribute(o, collector)
- 2006
if o.relation
- 1986
join_name = o.relation.table_alias || o.relation.name
- 1986
collector << "#{quote_table_name join_name}.#{quote_column_name o.name}"
else
- 20
visit_Arel_Nodes_UnqualifiedColumn o, collector
end
end
- 5
alias visit_Arel_Attributes_Integer visit_Arel_Attributes_Attribute
- 5
alias visit_Arel_Attributes_Float visit_Arel_Attributes_Attribute
- 5
alias visit_Arel_Attributes_Decimal visit_Arel_Attributes_Attribute
- 5
alias visit_Arel_Attributes_String visit_Arel_Attributes_Attribute
- 5
alias visit_Arel_Attributes_Time visit_Arel_Attributes_Attribute
- 5
alias visit_Arel_Attributes_Boolean visit_Arel_Attributes_Attribute
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# frozen_string_literal: true
- 5
module Arel # :nodoc: all
- 5
module Nodes
- 5
class Top < Unary
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
# rubocop:disable Metrics/CyclomaticComplexity
# rubocop:disable Metrics/AbcSize
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/8.3/tutorial-transactions.html
- 5
class Transaction < Arel::Nodes::Binary
- 5
alias type left
- 5
alias options right
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Transaction(o, collector)
- 170
case o.type
when 1
- 10
collector << 'BEGIN'
when 3
- 10
collector << 'COMMIT'
when 4
- 5
collector << 'ROLLBACK'
when 5
- 70
collector << 'SAVEPOINT '
- 70
collector << o.right
when 6
- 70
collector << 'RELEASE SAVEPOINT '
- 70
collector << o.right
when 7
- 5
collector << 'ROLLBACK TO '
- 5
collector << o.right
else
raise "Unknown transaction type `#{o.type}`"
end
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:enable Metrics/CyclomaticComplexity
# rubocop:enable Metrics/AbcSize
- 5
module Arel
- 5
class TreeManager
# Iterate through AST, nodes will be yielded depth-first
- 5
def to_sql_and_binds(engine = Arel::Table.engine)
- 3157
collector = engine.connection.send(:collector)
- 3157
engine.connection.visitor.accept(@ast, collector).value
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/10/functions-string.html
- 5
class Trim < Arel::Nodes::Node
- 5
attr_reader :type
- 5
attr_reader :substring
- 5
attr_reader :string
- 5
def initialize(type, substring, string)
- 60
@type = type
- 60
@substring = substring
- 60
@string = string
end
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Trim(o, collector)
- 30
collector << "trim(#{o.type} "
- 30
if o.substring
- 25
visit o.substring, collector
- 25
collector << ' from '
end
- 30
visit o.string, collector
- 30
collector << ')'
end
end
- 5
class Dot
- 5
def visit_Arel_Nodes_Trim(o)
- 30
visit_edge o, 'type'
- 30
visit_edge o, 'substring'
- 30
visit_edge o, 'string'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class Dot
- 5
alias visit_Arel_Nodes_True terminal
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# Postgres: https://www.postgresql.org/docs/9.1/sql-expressions.html
- 5
class TypeCast < Arel::Nodes::Node
- 5
attr_reader :arg
- 5
attr_reader :type_name
- 5
def initialize(arg, type_name)
- 2944
@arg = arg
- 2944
@type_name = type_name
end
- 5
def ==(other)
arg == other.arg && type_name == other.type_name
end
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_TypeCast(o, collector)
- 1524
visit o.arg, collector
- 1524
collector << '::'
- 1524
collector << o.type_name
end
end
- 5
class Dot
- 5
def visit_Arel_Nodes_TypeCast(o)
- 1524
visit_edge(o, 'arg')
- 1524
visit_edge(o, 'type_name')
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class Dot
- 5
alias visit_Arel_Nodes_Unary unary
end
end
end
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class Dot
- 5
def visit_Arel_Nodes_UnaryOperation(o)
- 55
visit_edge o, 'operator'
- 55
visit_edge o, 'expr'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class Unknown < Arel::Nodes::Node
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_Unknown(_o, collector)
- 10
collector << 'UNKNOWN'
end
end
- 5
class Dot
- 5
alias visit_Arel_Nodes_Unknown terminal
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
class UpdateManager < Arel::TreeManager
- 5
def ==(other)
- 15
other.is_a?(self.class) && @ast == other.ast && @ctx == other.ctx
end
- 5
protected
- 5
attr_reader :ctx
end
- 5
module Visitors
- 5
class Dot
- 5
def visit_Arel_UpdateManager(o)
- 52
visit_edge o, 'ast'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class UpdateStatement
- 5
module UpdateStatementExtension
# https://www.postgresql.org/docs/10/sql-update.html
- 5
attr_accessor :with
- 5
attr_accessor :froms
- 5
attr_accessor :returning
- 5
def initialize
- 131
super
- 131
@froms = []
- 131
@returning = []
end
end
- 5
prepend UpdateStatementExtension
end
end
- 5
module Visitors
- 5
class ToSql
# rubocop:disable Metrics/AbcSize
- 5
def visit_Arel_Nodes_UpdateStatement(o, collector)
- 86
if o.with
- 5
collector = visit o.with, collector
- 5
collector << ' '
end
- 86
wheres = if Gem.loaded_specs['activerecord'].version >= Gem::Version.new('6.0.0')
- 42
o = prepare_update_statement(o)
- 42
o.wheres
- 44
elsif o.orders.empty? && o.limit.nil?
- 44
o.wheres
else
[Nodes::In.new(o.key, [build_subselect(o.key, o)])]
end
- 86
collector << 'UPDATE '
- 86
collector = visit o.relation, collector
- 86
collect_nodes_for o.values, collector, ' SET '
- 86
collect_nodes_for o.froms, collector, ' FROM ', ', '
- 86
collect_nodes_for wheres, collector, ' WHERE ', ' AND '
- 86
collect_nodes_for o.returning, collector, ' RETURNING ', ', '
- 86
collector
end
# rubocop:enable Metrics/AbcSize
end
- 5
class Dot
- 5
module UpdateStatementExtension
- 5
def visit_Arel_Nodes_UpdateStatement(o)
- 52
super
- 52
visit_edge o, 'with'
- 52
visit_edge o, 'froms'
- 52
visit_edge o, 'returning'
end
end
- 5
prepend UpdateStatementExtension
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
- 5
class User < Arel::Nodes::Node
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_User(_o, collector)
- 5
collector << 'user'
end
end
- 5
class Dot
- 5
alias visit_Arel_Nodes_User terminal
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Visitors
- 5
class Dot
- 5
def visit_Arel_Nodes_ValuesList(o)
- 81
visit_edge o, 'rows'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.3/sql-set.html
- 5
class VariableSet < Arel::Nodes::Node
- 5
attr_reader :type
- 5
attr_reader :args
- 5
attr_reader :name
- 5
attr_reader :local
- 5
def initialize(type, args, name, local)
- 60
@type = type
- 60
@args = args
- 60
@name = name
- 60
@local = local
end
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_VariableSet(o, collector)
- 30
collector << 'SET '
- 30
collector << 'LOCAL ' if o.local
- 30
if o.name == 'timezone'
- 10
collector << 'TIME ZONE '
else
- 20
collector << o.name
- 20
collector << ' TO '
end
- 30
if o.args.empty?
- 10
collector << 'DEFAULT'
else
- 20
inject_join(o.args, collector, ', ')
end
end
end
- 5
class Dot
- 5
def visit_Arel_Nodes_VariableSet(o)
- 30
visit_edge o, 'type'
- 30
visit_edge o, 'args'
- 30
visit_edge o, 'name'
- 30
visit_edge o, 'local'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# https://www.postgresql.org/docs/9.1/sql-show.html
- 5
class VariableShow < Arel::Nodes::Unary
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_VariableShow(o, collector)
- 10
collector << 'SHOW '
- 10
collector << if o.expr == 'timezone'
- 5
'TIME ZONE'
else
- 5
o.expr
end
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
# rubocop:disable Naming/MethodName
# rubocop:disable Naming/UncommunicativeMethodParamName
- 5
module Arel
- 5
module Nodes
# Postgres: https://paquier.xyz/postgresql-2/postgres-9-4-feature-highlight-with-ordinality/
- 5
class WithOrdinality < Arel::Nodes::Unary
end
end
- 5
module Visitors
- 5
class ToSql
- 5
def visit_Arel_Nodes_WithOrdinality(o, collector)
- 5
visit o.expr, collector
- 5
collector << ' WITH ORDINALITY'
end
end
end
end
# rubocop:enable Naming/MethodName
# rubocop:enable Naming/UncommunicativeMethodParamName
- 5
require_relative './middleware/active_record_extension'
- 5
require_relative './middleware/railtie'
- 5
require_relative './middleware/chain'
- 5
require_relative './middleware/database_executor'
- 5
require_relative './middleware/to_sql_executor'
- 5
require_relative './middleware/to_sql_middleware'
- 5
require_relative './middleware/result'
- 5
require_relative './middleware/postgresql_adapter'
- 5
module Arel
- 5
module Middleware
- 5
class << self
- 5
def current_chain
- 28964
Thread.current[:arel_toolkit_middleware_current_chain] ||=
Arel::Middleware::Chain.new
end
- 5
def current_chain=(new_chain)
- 598
Thread.current[:arel_toolkit_middleware_current_chain] = new_chain
end
end
end
- 5
def self.middleware
- 998
Arel::Middleware.current_chain
end
end
- 5
module Arel
- 5
module Middleware
- 5
module ActiveRecordExtension
- 5
def load_schema!
# Prevent Rails from memoizing an empty response when using `Arel.middleware.to_sql`.
# Re-applying the middleware will use the database executor to fetch the actual data.
- 22
Arel.middleware.apply(Arel.middleware.current) do
- 22
super
end
end
end
end
end
- 5
module Arel
- 5
module Middleware
- 5
class CacheAccessor
- 5
attr_reader :cache
- 5
def initialize(cache)
- 162
@cache = cache
end
- 5
def read(original_sql)
- 356
cache.read cache_key(original_sql)
end
- 5
def write(transformed_sql:, transformed_binds:, original_sql:, original_binds:)
# To play it safe, the order of binds was changed and therefore we won't reuse the query
- 216
return if transformed_binds != original_binds
- 216
cache.write(cache_key(original_sql), transformed_sql)
end
- 5
def cache_key_for_sql(sql)
- 552
Digest::SHA256.hexdigest(sql)
end
- 5
def cache_key(sql)
# An important aspect of this cache key method is that it includes hashes of all active
# middlewares. If multiple Arel middleware chains that are using the same cache backend,
# this cache key mechanism will prevent cache entries leak in the wrong chain.
- 572
active_middleware_cache_key = Arel.middleware.current.map(&:hash).join('&') || 0
- 572
active_middleware_cache_key + '|' + cache_key_for_sql(sql)
end
end
end
end
- 5
require_relative './no_op_cache'
- 5
require_relative './cache_accessor'
- 5
module Arel
- 5
module Middleware
- 5
class Chain
- 5
attr_reader :executing_middleware_depth
- 5
attr_reader :executor
- 5
attr_reader :cache
- 5
MAX_RECURSION_DEPTH = 10
- 5
def initialize(
internal_middleware = [],
internal_context = {},
executor_class = Arel::Middleware::DatabaseExecutor,
cache: nil
)
- 324
@internal_middleware = internal_middleware
- 324
@internal_context = internal_context
- 324
@executor = executor_class.new(internal_middleware)
- 324
@executing_middleware_depth = 0
- 324
@cache = cache || NoOpCache
end
- 5
def cache_accessor
- 707
@cache_accessor ||= CacheAccessor.new @cache
end
- 5
def execute(sql, binds = [], &execute_sql)
- 27672
return execute_sql.call(sql, binds).to_casted_result if internal_middleware.length.zero?
- 356
if (cached_sql = cache_accessor.read(sql))
return execute_sql.call(cached_sql, binds).to_casted_result
end
- 356
execute_with_middleware(sql, binds, execute_sql).to_casted_result
rescue ::PgQuery::ParseError
- 5
execute_sql.call(sql, binds)
ensure
- 27672
@executing_middleware_depth -= 1
end
- 5
def current
- 669
internal_middleware.dup
end
- 5
def apply(middleware, cache: @cache, &block)
- 204
new_middleware = Array.wrap(middleware)
- 204
continue_chain(new_middleware, internal_context, cache: cache, &block)
end
- 5
alias only apply
- 5
def none(&block)
- 15
continue_chain([], internal_context, cache: cache, &block)
end
- 5
def except(without_middleware, cache: @cache, &block)
- 10
without_middleware = Array.wrap(without_middleware)
- 10
new_middleware = internal_middleware - without_middleware
- 10
continue_chain(new_middleware, internal_context, cache: cache, &block)
end
- 5
def insert_before(new_middleware, existing_middleware, cache: @cache, &block)
- 5
new_middleware = Array.wrap(new_middleware)
- 5
index = internal_middleware.index(existing_middleware)
- 5
updated_middleware = internal_middleware.insert(index, *new_middleware)
- 5
continue_chain(updated_middleware, internal_context, cache: cache, &block)
end
- 5
def prepend(new_middleware, cache: @cache, &block)
- 5
new_middleware = Array.wrap(new_middleware)
- 5
updated_middleware = new_middleware + internal_middleware
- 5
continue_chain(updated_middleware, internal_context, cache: cache, &block)
end
- 5
def insert_after(new_middleware, existing_middleware, cache: @cache, &block)
- 5
new_middleware = Array.wrap(new_middleware)
- 5
index = internal_middleware.index(existing_middleware)
- 5
updated_middleware = internal_middleware.insert(index + 1, *new_middleware)
- 5
continue_chain(updated_middleware, internal_context, cache: cache, &block)
end
- 5
def append(new_middleware, cache: @cache, &block)
- 10
new_middleware = Array.wrap(new_middleware)
- 10
updated_middleware = internal_middleware + new_middleware
- 10
continue_chain(updated_middleware, internal_context, cache: cache, &block)
end
- 5
def context(new_context = nil, &block)
- 391
if new_context.nil? && !block.nil?
- 5
raise 'You cannot do a block statement while calling context without arguments'
end
- 386
return internal_context if new_context.nil?
- 15
continue_chain(internal_middleware, new_context, cache: @cache, &block)
end
- 5
def to_sql(type, &block)
- 35
middleware = Arel::Middleware::ToSqlMiddleware.new(type)
- 35
new_chain = Arel::Middleware::Chain.new(
internal_middleware + [middleware],
internal_context,
Arel::Middleware::ToSqlExecutor,
)
- 35
maybe_execute_block(new_chain, &block)
- 35
middleware.sql
end
- 5
protected
- 5
attr_reader :internal_middleware
- 5
attr_reader :internal_context
- 5
private
- 5
def execute_with_middleware(sql, binds, execute_sql)
- 356
check_middleware_recursion(sql)
- 351
updated_context = context.merge(
original_sql: sql,
original_binds: binds,
cache_accessor: cache_accessor,
)
- 351
arel = Arel.sql_to_arel(sql, binds: binds)
- 346
enhanced_arel = Arel.enhance(arel)
- 346
executor.run(enhanced_arel, updated_context, execute_sql)
end
- 5
def continue_chain(middleware, context, cache:, &block)
- 269
new_chain = Arel::Middleware::Chain.new(middleware, context, cache: cache)
- 269
maybe_execute_block(new_chain, &block)
end
- 5
def maybe_execute_block(new_chain, &block)
- 304
return new_chain if block.nil?
- 294
previous_chain = Middleware.current_chain
- 294
Arel::Middleware.current_chain = new_chain
- 294
yield block
ensure
- 304
Arel::Middleware.current_chain = previous_chain
end
- 5
def check_middleware_recursion(sql)
- 356
if executing_middleware_depth > MAX_RECURSION_DEPTH
- 5
message = <<~ERROR
Middleware is being called from within middleware, aborting execution
to prevent endless recursion. You can do the following if you want to execute SQL
inside middleware:
- Set middleware context before entering the middleware
- Use `Arel.middleware.none { ... }` to temporarily disable middleware
SQL that triggered the error:
#{sql}
ERROR
- 5
raise message
else
- 351
@executing_middleware_depth += 1
end
end
end
end
end
- 5
module Arel
- 5
module Middleware
- 5
class DatabaseExecutor
- 5
attr_reader :middleware
- 5
attr_accessor :index
- 5
attr_reader :context
- 5
attr_reader :final_block
- 5
def initialize(middleware)
- 324
@middleware = middleware
end
- 5
def run(arel, context, final_block)
- 346
@index = 0
- 346
@context = context
- 346
@final_block = final_block
- 346
result = call(arel)
- 286
check_return_type result
- 281
result
ensure
- 346
@index = 0
- 346
@context = nil
- 346
@final_block = nil
end
- 5
def call(next_arel)
- 647
check_argument_type next_arel
- 642
current_middleware = middleware[index]
- 642
return execute_sql(next_arel) if current_middleware.nil?
- 361
self.index += 1
- 361
case current_middleware.method(:call).arity
when 2
- 265
current_middleware.call(next_arel, self)
else
- 96
current_middleware.call(next_arel, self, context.dup)
end
end
- 5
private
- 5
def execute_sql(next_arel)
- 216
sql, binds = next_arel.to_sql_and_binds
- 216
context[:cache_accessor].write(
transformed_sql: sql,
transformed_binds: binds,
original_sql: context[:original_sql],
original_binds: context[:original_binds],
)
- 216
sql_result = final_block.call(sql, binds)
- 216
check_return_type sql_result
- 216
sql_result
end
- 5
def check_argument_type(next_arel)
- 647
return if next_arel.is_a?(Arel::Enhance::Node)
- 5
raise "Only `Arel::Enhance::Node` is valid for middleware, passed `#{next_arel.class}`"
end
- 5
def check_return_type(return_object)
- 502
return if return_object.is_a?(Arel::Middleware::Result)
- 5
raise 'Object returned from middleware needs to be wrapped in `Arel::Middleware::Result`' \
" for object `#{return_object}`"
end
end
end
end
- 5
module Arel
- 5
module Middleware
- 5
module NoOpCache
- 5
def self.read(key); end
- 5
def self.write(key, sql); end
end
end
end
- 5
module Arel
- 5
module Middleware
- 5
module PostgreSQLAdapter
- 5
def initialize(*args)
- 5
Arel.middleware.none do
- 5
super(*args)
end
end
- 5
def execute(sql, name = nil)
- 26867
super(sql, name)
end
- 5
alias parent_execute execute
# rubocop:disable Lint/DuplicateMethods
- 5
def execute(sql, name = nil)
- 26807
Arel::Middleware.current_chain.execute(sql) do |processed_sql|
- 26777
Arel::Middleware::Result.create(
data: parent_execute(processed_sql, name),
from: Arel::Middleware::PGResult,
to: Arel::Middleware::PGResult,
)
end
end
# rubocop:enable Lint/DuplicateMethods
- 5
def query(sql, name = nil)
- 95
Arel::Middleware.current_chain.execute(sql) do |processed_sql|
# NOTE: we're not calling `super` here, but execute.
# The `query` super does not return the columns, like the other methods.
# As we want the result objects to be the same, we call execute instead.
- 90
Arel::Middleware::Result.create(
data: parent_execute(processed_sql, name),
from: Arel::Middleware::PGResult,
to: Arel::Middleware::ArrayResult,
)
end
end
- 5
def exec_no_cache(sql, name, binds)
- 451
Arel::Middleware.current_chain.execute(sql, binds) do |processed_sql, processed_binds|
- 411
Arel::Middleware::Result.create(
data: super(processed_sql, name, processed_binds),
from: Arel::Middleware::PGResult,
to: Arel::Middleware::PGResult,
)
end
end
- 5
def exec_cache(sql, name, binds)
- 319
Arel::Middleware.current_chain.execute(sql, binds) do |processed_sql, processed_binds|
- 259
Arel::Middleware::Result.create(
data: super(processed_sql, name, processed_binds),
from: Arel::Middleware::PGResult,
to: Arel::Middleware::PGResult,
)
end
end
end
end
end
- 5
module Arel
- 5
module Middleware
- 5
if defined? Rails::Railtie
- 1
class Railtie < Rails::Railtie
- 1
initializer 'arel.middleware.insert' do
- 1
ActiveSupport.on_load :active_record do
- 1
Arel::Middleware::Railtie.insert
end
end
end
end
- 5
class Railtie
- 5
def self.insert
- 5
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(
Arel::Middleware::PostgreSQLAdapter,
)
- 5
ActiveRecord::Base.singleton_class.prepend(
Arel::Middleware::ActiveRecordExtension,
)
end
end
end
end
- 5
module Arel
- 5
module Middleware
- 5
class Column
- 5
attr_reader :name
- 5
attr_reader :metadata
- 5
def initialize(name, metadata)
- 10
@name = name
- 10
@metadata = metadata
end
end
# Class is very similar to ActiveRecord::Result
# activerecord/lib/active_record/result.rb
- 5
class Result
- 5
attr_reader :original_data
- 5
def self.create(from:, to:, data:)
- 27587
Result.new from, to, data
end
- 5
def initialize(from_caster, to_caster, original_data)
- 27587
@from_caster = from_caster
- 27587
@to_caster = to_caster
- 27587
@original_data = original_data
- 27587
@modified = false
end
- 5
def columns
- 15
@columns ||= column_objects.map(&:name)
end
- 5
def column_objects
- 20
@column_objects ||= from_caster.column_objects(original_data)
end
- 5
def rows
- 105
@rows ||= from_caster.rows(original_data)
end
- 5
def remove_column(column_name)
- 5
column_index = columns.index(column_name)
- 5
raise "Unknown column `#{column_name}`. Existing columns: `#{columns}`" if column_index.nil?
- 5
@hash_rows = nil
- 5
@columns = nil
- 5
@modified = true
- 5
column_objects.delete_at(column_index)
- 5
deleted_rows = []
- 5
rows.map! do |row|
- 5
deleted_rows << row.delete_at(column_index)
- 5
row
end
- 5
deleted_rows
end
- 5
def hash_rows
- 5
@hash_rows ||=
begin
- 5
rows.map do |row|
- 5
hash = {}
- 5
index = 0
- 5
length = columns.length
- 5
while index < length
- 5
hash[columns[index]] = row[index]
- 5
index += 1
end
- 5
hash
end
end
end
- 5
def to_casted_result
- 27587
to_caster.cast_to(self)
end
- 5
def modified?
- 27432
@modified
end
- 5
private
- 5
attr_reader :to_caster, :from_caster
end
- 5
class PGResult
- 5
class << self
- 5
def column_objects(pg_result)
- 5
pg_result.fields.each_with_index.map do |field, index|
- 10
Column.new(
field,
tableid: pg_result.ftable(index),
columnid: pg_result.ftablecol(index),
format: pg_result.fformat(index),
typid: pg_result.ftype(index),
typlen: pg_result.fsize(index),
atttypmod: pg_result.fmod(index),
)
end
end
- 5
def rows(data)
- 95
data.values
end
- 5
def cast_to(result)
- 27432
return result.original_data unless result.modified?
- 5
pg_columns = result_to_columns(result)
- 5
conn = ActiveRecord::Base.connection.raw_connection
- 5
new_result = PgResultInit.create(conn, result.original_data, pg_columns, result.rows)
- 5
result.original_data.clear
- 5
new_result
end
- 5
private
- 5
def result_to_columns(result)
- 5
result.column_objects.map do |column|
- 5
{
name: column.name,
tableid: column.metadata.fetch(:tableid, 0),
columnid: column.metadata.fetch(:columnid, 0),
format: column.metadata.fetch(:format, 0),
typid: column.metadata.fetch(:typid),
typlen: column.metadata.fetch(:typlen),
atttypmod: column.metadata.fetch(:atttypmod, -1),
}
end
end
end
end
- 5
class EmptyPGResult < PGResult
- 5
class << self
- 5
def cast_to(_result)
- 65
ActiveRecord::Base.connection.raw_connection.make_empty_pgresult(2)
end
end
end
- 5
class ArrayResult
- 5
def self.cast_to(result)
- 90
result.rows
end
end
- 5
class StringResult
- 5
class << self
- 5
def column_objects(_string)
[]
end
- 5
def rows(_string)
[]
end
- 5
def cast_to(result)
result.original_data
end
end
end
end
end
- 5
module Arel
- 5
module Middleware
- 5
class ToSqlExecutor < DatabaseExecutor
- 5
private
- 5
def execute_sql(next_arel)
- 65
Arel::Middleware::Result.create(
data: next_arel.to_sql,
from: Arel::Middleware::StringResult,
to: Arel::Middleware::EmptyPGResult,
)
end
end
end
end
- 5
module Arel
- 5
module Middleware
- 5
class ToSqlMiddleware
- 5
attr_reader :sql, :type, :query_class
- 5
def initialize(type)
- 35
@sql = []
- 35
@type = type
- 35
@query_class = class_from_type
end
- 5
def call(next_arel, next_middleware)
- 70
sql << next_arel.to_sql unless next_arel.query(class: query_class).empty?
- 70
next_middleware.call(next_arel)
end
- 5
private
- 5
def class_from_type
- 35
case type
when :insert
- 5
Arel::Nodes::InsertStatement
when :select
- 10
Arel::Nodes::SelectStatement
when :update
- 10
Arel::Nodes::UpdateStatement
when :delete
- 10
Arel::Nodes::DeleteStatement
end
end
end
end
end
- 5
require_relative './sql_to_arel/result'
- 5
require_relative './sql_to_arel/error'
- 5
require_relative './sql_to_arel/pg_query_visitor'
- 5
module Arel
- 5
module SqlToArel
end
- 5
def self.sql_to_arel(sql, binds: [])
- 6411
SqlToArel::PgQueryVisitor.new.accept(sql, binds)
end
end
- 5
module Arel
- 5
module SqlToArel
- 5
class Error < StandardError
end
end
end
# rubocop:disable Metrics/PerceivedComplexity
# rubocop:disable Naming/MethodName
# rubocop:disable Metrics/CyclomaticComplexity
# rubocop:disable Metrics/AbcSize
- 5
require 'pg_query'
- 5
require_relative './pg_query_visitor/frame_options'
- 5
module Arel
- 5
module SqlToArel
- 5
class PgQueryVisitor
- 5
PG_CATALOG = 'pg_catalog'.freeze
- 5
MIN_MAX_EXPR = 'MinMaxExpr'.freeze
- 5
attr_reader :object
- 5
attr_reader :binds
- 5
attr_reader :sql
- 5
def accept(sql, binds = [])
- 6416
tree = PgQuery.parse(sql).tree
- 6411
@object = tree
- 6411
@binds = binds
- 6411
@sql = sql
- 6411
Result.new visit(object.stmts, :top)
rescue ::PgQuery::ParseError => e
- 5
new_error = ::PgQuery::ParseError.new(e.message, __FILE__, __LINE__, -1)
- 5
raise new_error, e.message, e.backtrace
rescue ::StandardError => e
- 10
raise e.class, e.message, e.backtrace if e.is_a?(Arel::SqlToArel::Error)
- 5
boom e.message, e.backtrace
end
- 5
private
- 5
def visit_A_ArrayExpr(attribute)
- 200
Arel::Nodes::Array.new visit(attribute.elements)
end
- 5
def visit_A_Const(attribute)
- 10089
visit(attribute.val, :const)
end
- 5
def visit_A_Expr(attribute)
- 2165
case attribute.kind
when :AEXPR_OP
- 1916
left = visit(attribute.lexpr) if attribute.lexpr
- 1916
right = visit(attribute.rexpr) if attribute.rexpr
- 1916
operator = visit(attribute.name[0], :operator)
- 1916
generate_operator(left, right, operator)
when :AEXPR_OP_ANY
- 30
left = visit(attribute.lexpr)
- 30
right = visit(attribute.rexpr)
- 30
right = Arel::Nodes::Any.new right
- 30
operator = visit(attribute.name[0], :operator)
- 30
generate_operator(left, right, operator)
when :AEXPR_OP_ALL
- 20
left = visit(attribute.lexpr)
- 20
right = visit(attribute.rexpr)
- 20
right = Arel::Nodes::All.new right
- 20
operator = visit(attribute.name[0], :operator)
- 20
generate_operator(left, right, operator)
when :AEXPR_DISTINCT
- 10
left = visit(attribute.lexpr)
- 10
right = visit(attribute.rexpr)
- 10
Arel::Nodes::DistinctFrom.new(left, right)
when :AEXPR_NOT_DISTINCT
- 10
left = visit(attribute.lexpr)
- 10
right = visit(attribute.rexpr)
- 10
Arel::Nodes::NotDistinctFrom.new(left, right)
when :AEXPR_NULLIF
- 25
left = visit(attribute.lexpr)
- 25
right = visit(attribute.rexpr)
- 25
Arel::Nodes::NullIf.new(left, right)
when :AEXPR_IN
- 24
left = visit(attribute.lexpr)
- 24
right = visit(attribute.rexpr)
- 24
operator = visit(attribute.name[0], :operator)
- 24
if operator == '<>'
- 10
Arel::Nodes::NotIn.new(left, right)
else
- 14
Arel::Nodes::In.new(left, right)
end
when :AEXPR_LIKE, :AEXPR_ILIKE
- 45
left = visit(attribute.lexpr) if attribute.lexpr
- 45
right = visit(attribute.rexpr)
- 45
escape = nil
- 45
if right.is_a?(Array)
- 20
boom "Don't know how to handle length `#{right.length}`" if right.length != 2
- 20
right, escape = right
end
- 45
operator = visit(attribute.name[0], :operator)
- 45
if %w[~~ ~~*].include?(operator)
- 25
Arel::Nodes::Matches.new(left, right, escape, attribute.kind == :AEXPR_LIKE)
else
- 20
Arel::Nodes::DoesNotMatch.new(left, right, escape, attribute.kind == :AEXPR_LIKE)
end
when :AEXPR_SIMILAR
- 40
left = visit(attribute.lexpr) if attribute.lexpr
- 40
right = visit(attribute.rexpr)
- 40
escape = nil
- 40
right, escape = right if right.is_a?(Array)
- 40
operator = visit(attribute.name[0], :operator)
- 40
if operator == '~'
- 20
Arel::Nodes::Similar.new(left, right, escape)
else
- 20
Arel::Nodes::NotSimilar.new(left, right, escape)
end
when :AEXPR_BETWEEN
- 10
left = visit(attribute.lexpr) if attribute.lexpr
- 10
right = visit(attribute.rexpr)
- 10
Arel::Nodes::Between.new left, Arel::Nodes::And.new(right)
when :AEXPR_NOT_BETWEEN
- 10
left = visit(attribute.lexpr) if attribute.lexpr
- 10
right = visit(attribute.rexpr)
- 10
Arel::Nodes::NotBetween.new left, Arel::Nodes::And.new(right)
when :AEXPR_BETWEEN_SYM
- 10
left = visit(attribute.lexpr) if attribute.lexpr
- 10
right = visit(attribute.rexpr)
- 10
Arel::Nodes::BetweenSymmetric.new left, Arel::Nodes::And.new(right)
when :AEXPR_NOT_BETWEEN_SYM
- 10
left = visit(attribute.lexpr) if attribute.lexpr
- 10
right = visit(attribute.rexpr)
- 10
Arel::Nodes::NotBetweenSymmetric.new left, Arel::Nodes::And.new(right)
else
- 5
boom "Unknown Expr type `#{attribute.kind}`"
end
end
- 5
def visit_A_Indices(attribute, context)
- 25
visit attribute.uidx, context
end
- 5
def visit_A_Indirection(attribute)
- 25
Arel::Nodes::Indirection.new(visit(attribute.arg), visit(attribute.indirection, :operator))
end
- 5
def visit_A_Star(_attribute)
- 321
Arel.star
end
- 5
def visit_Alias(attribute)
- 264
aliasname = if attribute.respond_to?(:aliasname)
- 176
attribute.aliasname
- 88
elsif attribute.is_a?(Hash)
- 88
attribute[:aliasname]
end
- 264
return if aliasname.nil?
- 264
Arel.sql visit_String(aliasname, nil)
end
- 5
def visit_BitString(attribute)
- 10
Arel::Nodes::BitString.new(attribute.str)
end
- 5
def visit_BoolExpr(attribute, context = false)
- 110
args = visit(attribute.args, context || true)
- 110
result = case attribute.boolop
when :AND_EXPR
- 80
Arel::Nodes::And.new(args)
when :OR_EXPR
- 10
generate_boolean_expression(args, Arel::Nodes::Or)
when :NOT_EXPR
- 20
Arel::Nodes::Not.new(args)
else
boom "? Boolop -> #{boolop}"
end
- 110
if context
- 75
Arel::Nodes::Grouping.new(result)
else
- 35
result
end
end
- 5
def visit_BooleanTest(attribute)
- 60
arg = visit(attribute.arg)
- 60
case attribute.booltesttype
when :IS_TRUE
- 10
Arel::Nodes::Equality.new(arg, Arel::Nodes::True.new)
when :IS_NOT_TRUE
- 10
Arel::Nodes::NotEqual.new(arg, Arel::Nodes::True.new)
when :IS_FALSE
- 10
Arel::Nodes::Equality.new(arg, Arel::Nodes::False.new)
when :IS_NOT_FALSE
- 10
Arel::Nodes::NotEqual.new(arg, Arel::Nodes::False.new)
when :IS_UNKNOWN
- 10
Arel::Nodes::Equality.new(arg, Arel::Nodes::Unknown.new)
when :IS_NOT_UNKNOWN
- 10
Arel::Nodes::NotEqual.new(arg, Arel::Nodes::Unknown.new)
else
boom '?'
end
end
- 5
def visit_CaseExpr(attribute)
- 20
Arel::Nodes::Case.new.tap do |kees|
- 20
kees.case = visit(attribute.arg) if attribute.arg
- 20
kees.conditions = visit attribute.args
- 20
if attribute.defresult
- 20
default_result = visit(attribute.defresult, :sql)
- 20
kees.default = Arel::Nodes::Else.new default_result
end
end
end
- 5
def visit_CaseWhen(attribute)
- 40
expr = visit(attribute.expr)
- 40
result = visit(attribute.result)
- 40
Arel::Nodes::When.new(expr, result)
end
- 5
def visit_CoalesceExpr(attribute)
- 41
args = visit(attribute.args)
- 41
Arel::Nodes::Coalesce.new args
end
- 5
def visit_ColumnRef(attribute)
- 2330
fields = attribute.fields.reverse
- 2330
column = visit(fields[0], :operator)
- 2330
table = visit(fields[1], :operator) if fields[1]
- 2330
schema_name = visit(fields[2], :operator) if fields[2]
- 2330
database = visit(fields[3], :operator) if fields[3]
- 2330
table = Arel::Table.new(table) if table
- 2330
attribute = Arel::Attribute.new(table, column)
- 2330
attribute.schema_name = schema_name
- 2330
attribute.database = database
- 2330
return attribute if table
- 1341
Arel::Nodes::UnqualifiedColumn.new Arel::Attribute.new(nil, column)
end
- 5
def visit_CommonTableExpr(attribute)
- 71
cte_table = Arel::Table.new(attribute.ctename)
- 71
cte_definition = visit(attribute.ctequery)
- 71
Arel::Nodes::As.new(cte_table, Arel::Nodes::Grouping.new(cte_definition))
end
- 5
def visit_CurrentOfExpr(attribute)
- 20
Arel::Nodes::CurrentOfExpression.new(attribute.cursor_name)
end
- 5
def visit_DeallocateStmt(attribute)
- 20
Arel::Nodes::Dealocate.new attribute.name.presence
end
- 5
def visit_DefElem(attribute)
case attribute.defname
when 'savepoint_name'
visit(attribute.arg)
else
boom "Unknown defname `#{attribute.defname}` with defaction `#{attribute.defaction}`"
end
end
- 5
def visit_DeleteStmt(attribute)
- 70
relation = visit(attribute.relation)
- 70
delete_manager = Arel::DeleteManager.new
- 70
delete_statement = delete_manager.ast
- 70
delete_statement.relation = relation
- 70
delete_statement.using = visit(attribute.using_clause) if attribute.using_clause
- 70
delete_statement.wheres = attribute.where_clause ? [visit(attribute.where_clause)] : []
- 70
delete_statement.with = visit(attribute.with_clause) if attribute.with_clause
- 70
delete_statement.returning = visit(attribute.returning_list, :select)
- 70
delete_manager
end
- 5
def visit_Float(attribute)
- 625
Arel::Nodes::SqlLiteral.new attribute.str
end
# https://github.com/postgres/postgres/blob/REL_10_1/src/include/nodes/parsenodes.h
- 5
def visit_FuncCall(attribute)
- 3512
args = if attribute.args.present?
- 3372
visit attribute.args
- 140
elsif attribute.agg_star
- 15
[Arel.star]
else
- 125
[]
end
- 3512
function_names = visit(attribute.funcname, :operator)
- 3512
func = case function_names
when ['sum']
- 200
Arel::Nodes::Sum.new args
when ['count']
- 25
Arel::Nodes::Count.new args
when ['max']
- 10
Arel::Nodes::Max.new args
when ['min']
- 10
Arel::Nodes::Min.new args
when ['avg']
- 40
Arel::Nodes::Avg.new args
when [PG_CATALOG, 'like_escape']
- 20
args
when [PG_CATALOG, 'similar_to_escape']
- 40
args
when [PG_CATALOG, 'date_part']
- 40
field, expression = args
- 40
[Arel::Nodes::ExtractFrom.new(expression, field)]
when [PG_CATALOG, 'timezone']
- 60
timezone, expression = args
- 60
[Arel::Nodes::AtTimeZone.new(maybe_add_grouping(expression), timezone)]
# https://www.postgresql.org/docs/10/functions-string.html
when [PG_CATALOG, 'position']
- 30
string, substring = args
- 30
[Arel::Nodes::Position.new(substring, string)]
when [PG_CATALOG, 'overlay']
- 40
string, substring, start, length = args
- 40
[Arel::Nodes::Overlay.new(string, substring, start, length)]
when [PG_CATALOG, 'ltrim']
- 10
string, substring = args
- 10
[Arel::Nodes::Trim.new('leading', substring, string)]
when [PG_CATALOG, 'rtrim']
- 10
string, substring = args
- 10
[Arel::Nodes::Trim.new('trailing', substring, string)]
when [PG_CATALOG, 'btrim']
- 40
string, substring = args
- 40
[Arel::Nodes::Trim.new('both', substring, string)]
when [PG_CATALOG, 'substring']
- 70
string, pattern, escape = args
- 70
[Arel::Nodes::Substring.new(string, pattern, escape)]
when [PG_CATALOG, 'overlaps']
- 10
start1, end1, start2, end2 = args
- 10
[Arel::Nodes::Overlaps.new(start1, end1, start2, end2)]
else
- 2857
case function_names.length
when 2
- 30
func = Arel::Nodes::NamedFunction.new(function_names.last, args)
- 30
func.schema_name = function_names.first
- 30
func
when 1
- 2827
Arel::Nodes::NamedFunction.new(function_names.first, args)
else
boom "Don't know how to handle function names length `#{function_names.length}`"
end
end
- 3512
func.distinct = attribute.agg_distinct unless func.is_a?(::Array)
- 3142
func.orders = (attribute.agg_order ? visit(attribute.agg_order) : []) unless
- 3512
func.is_a?(::Array)
- 3142
func.filter = (attribute.agg_filter ? visit(attribute.agg_filter) : nil) unless
- 3512
func.is_a?(::Array)
- 3512
func.within_group = attribute.agg_within_group unless func.is_a?(::Array)
- 3512
func.variardic = attribute.func_variadic unless func.is_a?(::Array)
- 3512
if attribute.over
- 170
Arel::Nodes::Over.new(func, visit(attribute.over))
else
- 3342
func
end
end
- 5
def visit_InferClause(attribute)
- 22
left = Arel.sql(attribute.conname) if attribute.conname
- 22
right = visit(attribute.index_elems) if attribute.index_elems.present?
- 22
Arel::Nodes::Infer.new left, right
end
- 5
def visit_IndexElem(attribute)
- 22
boom "Unknown ordering `#{attribute.ordering}`" unless attribute.ordering == :SORTBY_DEFAULT
boom "Unknown nulls ordering `#{attribute.nulls_ordering}`" unless
- 22
attribute.nulls_ordering == :SORTBY_NULLS_DEFAULT
- 22
Arel.sql visit_String(attribute.name)
end
- 5
def visit_InsertStmt(attribute)
- 131
relation = visit(attribute.relation)
- 131
cols = visit(attribute.cols, :insert).map do |col|
- 178
Arel::Attribute.new(relation, col)
end
- 131
insert_manager = Arel::InsertManager.new
- 131
insert_statement = insert_manager.ast
- 131
insert_statement.relation = relation
- 131
insert_statement.columns = cols
- 131
insert_statement.override = attribute.override
- 131
insert_statement.with = visit(attribute.with_clause) if attribute.with_clause
- 131
insert_statement.values = if attribute.select_stmt.present?
- 121
select_stmt = visit(attribute.select_stmt)
insert_statement.values = select_stmt.values_lists if
- 121
select_stmt.present?
else
- 10
insert_statement.values = Arel::Nodes::DefaultValues.new
end
- 131
insert_statement.returning = visit(attribute.returning_list, :select)
insert_statement.conflict = visit(attribute.on_conflict_clause) if
- 131
attribute.on_conflict_clause
- 131
insert_manager
end
- 5
def visit_Integer(attribute)
- 3420
attribute.ival
end
- 5
def visit_IntoClause(attribute)
raise "Unknown on_commit `#{attribute.on_commit}`" unless
- 35
attribute.on_commit == :ONCOMMIT_NOOP
- 35
Arel::Nodes::Into.new(visit(attribute.rel))
end
- 5
def visit_JoinExpr(attribute)
- 170
join_class = case attribute.jointype
when :JOIN_INNER
- 93
if attribute.is_natural
- 10
Arel::Nodes::NaturalJoin
- 83
elsif attribute.quals.nil?
- 10
Arel::Nodes::CrossJoin
else
- 73
Arel::Nodes::InnerJoin
end
when :JOIN_LEFT
- 57
Arel::Nodes::OuterJoin
when :JOIN_FULL
- 10
Arel::Nodes::FullOuterJoin
when :JOIN_RIGHT
- 10
Arel::Nodes::RightOuterJoin
end
- 170
larg = visit(attribute.larg)
- 170
rarg = visit(attribute.rarg)
- 170
join = if attribute.quals
- 150
join_class.new(rarg, Arel::Nodes::On.new(visit(attribute.quals)))
else
- 20
join_class.new(rarg, nil)
end
- 170
if larg.is_a?(Array)
- 47
larg.concat([join])
else
- 123
[larg, join]
end
end
- 5
def visit_LockingClause(attribute)
- 50
strength_clause = {
LCS_FORKEYSHARE: 'FOR KEY SHARE',
LCS_FORSHARE: 'FOR SHARE',
LCS_FORNOKEYUPDATE: 'FOR NO KEY UPDATE',
LCS_FORUPDATE: 'FOR UPDATE',
}.fetch(attribute.strength)
- 50
wait_policy_clause = {
LockWaitBlock: '',
LockWaitSkip: ' SKIP LOCKED',
LockWaitError: ' NOWAIT',
}.fetch(attribute.wait_policy)
- 50
Arel::Nodes::Lock.new Arel.sql("#{strength_clause}#{wait_policy_clause}")
end
- 5
def visit_MinMaxExpr(attribute)
- 30
case attribute.op
when :IS_GREATEST
- 15
Arel::Nodes::Greatest.new visit(attribute.args)
when :IS_LEAST
- 15
Arel::Nodes::Least.new visit(attribute.args)
else
boom "Unknown Op -> #{attribute.op}"
end
end
- 5
def visit_NamedArgExpr(attribute)
- 10
arg = visit(attribute.arg)
- 10
boom '' unless attribute.argnumber == -1
- 10
Arel::Nodes::NamedArgument.new(attribute.name, arg)
end
- 5
def visit_Node(attribute, context = nil)
- 366
return attribute.list.items.map { |item| visit_Node(item, context) } if
- 61250
attribute.node == :list
- 61065
visit(attribute[attribute.node.to_s], context)
end
- 5
def visit_Null(_attribute)
- 125
Arel.sql 'NULL'
end
- 5
def visit_NullTest(attribute)
- 20
arg = visit(attribute.arg)
- 20
case attribute.nulltesttype
when :IS_NULL
- 10
Arel::Nodes::Equality.new(arg, nil)
when :IS_NOT_NULL
- 10
Arel::Nodes::NotEqual.new(arg, nil)
end
end
- 5
def visit_OnConflictClause(attribute)
- 42
conflict = Arel::Nodes::Conflict.new
- 42
conflict.action = attribute.action
- 42
conflict.infer = visit(attribute.infer) if attribute.infer
- 42
conflict.values = attribute.target_list ? visit(attribute.target_list, :update) : []
- 42
conflict.wheres = attribute.where_clause ? [visit(attribute.where_clause)] : []
- 42
conflict
end
- 5
def visit_ParamRef(attribute)
- 484
value = (binds[attribute.number - 1] unless binds.empty?)
- 484
Arel::Nodes::BindParam.new(value)
end
- 5
def visit_PrepareStmt(attribute)
- 20
Arel::Nodes::Prepare.new(
attribute.name,
attribute.argtypes.present? && visit(attribute.argtypes),
visit(attribute.query),
)
end
- 5
def visit_RangeFunction(attribute)
- 30
functions = attribute.functions.map do |function_array|
- 40
function, _empty_node = function_array.list.items
- 40
visit(function)
end
- 30
node = Arel::Nodes::RangeFunction.new functions, is_rowsfrom: attribute.is_rowsfrom
- 30
node = attribute.lateral ? Arel::Nodes::Lateral.new(node) : node
- 30
node = attribute.ordinality ? Arel::Nodes::WithOrdinality.new(node) : node
- 30
attribute.alias.nil? ? node : Arel::Nodes::As.new(node, visit(attribute.alias))
end
- 5
def visit_RangeSubselect(attribute)
- 41
aliaz = visit(attribute.alias)
- 41
subquery = visit(attribute.subquery)
- 41
node = Arel::Nodes::As.new(Arel::Nodes::Grouping.new(subquery), aliaz)
- 41
attribute.lateral ? Arel::Nodes::Lateral.new(node) : node
end
- 5
def visit_RangeVar(attribute)
- 1122
Arel::Table.new(
attribute.relname,
- 1122
as: (visit(attribute.alias) if attribute.alias),
only: !attribute.inh,
relpersistence: attribute.relpersistence,
- 1122
schema_name: attribute.schemaname.blank? ? nil : attribute.schemaname,
)
end
- 5
def visit_RawStmt(attribute, context)
- 6516
visit(attribute.stmt, context)
end
- 5
def visit_ResTarget(attribute, context)
- 7144
case context
when :select
- 6738
val = visit(attribute.val)
- 6733
if attribute.name.blank?
- 6645
val
else
- 88
aliaz = visit_Alias(aliasname: attribute.name)
- 88
Arel::Nodes::As.new(val, aliaz)
end
when :insert
- 178
attribute.name
when :update
- 228
relation = nil
- 228
column = Arel::Attribute.new(relation, attribute.name)
- 228
value = visit(attribute.val)
- 228
Nodes::Assignment.new(Nodes::UnqualifiedColumn.new(column), value)
else
boom "Unknown context `#{context}`"
end
end
- 5
def visit_RowExpr(attribute)
- 20
Arel::Nodes::Row.new(visit(attribute.args), attribute.row_format)
end
- 5
def visit_SelectStmt(attribute, context = nil)
- 6461
select_manager = Arel::SelectManager.new
- 6461
select_core = select_manager.ast.cores.last
- 6461
select_statement = select_manager.ast
- 6461
froms, join_sources = generate_sources(attribute.from_clause)
- 6461
if froms
- 575
froms = froms.first if froms.length == 1
- 575
select_core.froms = froms
end
- 6461
select_core.from = froms if froms
- 6461
select_core.source.right = join_sources
- 6461
select_core.projections = visit(attribute.target_list, :select) if attribute.target_list
- 6451
if attribute.where_clause
- 187
where_clause = visit(attribute.where_clause, :select)
- 187
where_clause = if where_clause.is_a?(Arel::Nodes::And)
where_clause
else
- 187
Arel::Nodes::And.new([where_clause])
end
- 187
select_core.wheres = [where_clause]
end
- 6451
select_core.groups = visit(attribute.group_clause) if attribute.group_clause
- 6451
select_core.havings = [visit(attribute.having_clause)] if attribute.having_clause
- 6451
select_core.windows = visit(attribute.window_clause) if attribute.window_clause
- 6451
select_core.into = visit(attribute.into_clause) if attribute.into_clause
select_core.top = ::Arel::Nodes::Top.new visit(attribute.limit_count) if
- 6451
attribute.limit_count
- 6451
if attribute.distinct_clause == []
- 6421
select_core.set_quantifier = nil
- 30
elsif attribute.distinct_clause.is_a?(Google::Protobuf::RepeatedField)
- 30
select_core.set_quantifier = if attribute.distinct_clause.size == 1 &&
attribute.distinct_clause.first.to_h.compact.length.zero?
- 20
Arel::Nodes::Distinct.new
else
- 10
Arel::Nodes::DistinctOn.new(
visit(attribute.distinct_clause),
)
end
elsif attribute.distinct_clause.nil?
select_core.set_quantifier = nil
else
boom "Unknown distinct clause `#{attribute.distinct_clause}`"
end
- 6451
if attribute.limit_count
- 97
select_statement.limit = ::Arel::Nodes::Limit.new visit(attribute.limit_count)
end
- 6451
if attribute.limit_offset
- 10
select_statement.offset = ::Arel::Nodes::Offset.new visit(attribute.limit_offset)
end
- 6451
select_statement.orders = visit(attribute.sort_clause.to_a)
- 6451
select_statement.with = visit(attribute.with_clause) if attribute.with_clause
- 6451
select_statement.lock = visit(attribute.locking_clause) if attribute.locking_clause.present?
- 6451
if attribute.values_lists.present?
- 121
values_lists = visit(attribute.values_lists).map do |values_list|
- 121
values_list.map do |value|
- 258
case value
when String
- 10
value
when Integer
- 75
Arel.sql(value.to_s)
when Arel::Nodes::TypeCast, Arel::Nodes::UnqualifiedColumn
- 25
Arel.sql(value.to_sql)
when Arel::Nodes::BindParam
- 138
value
when Arel::Nodes::Quoted
- 10
value.value
else
boom "Unknown value `#{value}`"
end
end
end
- 121
select_statement.values_lists = Arel::Nodes::ValuesList.new(values_lists)
end
- 6451
union = case attribute.op
when :SET_OPERATION_UNDEFINED, :SETOP_NONE
- 6391
nil
when :SETOP_UNION
- 20
if attribute.all
- 10
Arel::Nodes::UnionAll.new(visit(attribute.larg), visit(attribute.rarg))
else
- 10
Arel::Nodes::Union.new(visit(attribute.larg), visit(attribute.rarg))
end
when :SETOP_INTERSECT
- 20
if attribute.all
- 10
Arel::Nodes::IntersectAll.new(visit(attribute.larg), visit(attribute.rarg))
else
- 10
Arel::Nodes::Intersect.new(visit(attribute.larg), visit(attribute.rarg))
end
when :SETOP_EXCEPT
- 20
if attribute.all
- 10
Arel::Nodes::ExceptAll.new(visit(attribute.larg), visit(attribute.rarg))
else
- 10
Arel::Nodes::Except.new(visit(attribute.larg), visit(attribute.rarg))
end
else
# https://www.postgresql.org/docs/10/queries-union.html
boom "Unknown combining queries op `#{attribute.op}`"
end
- 6451
unless union.nil?
- 60
select_statement.cores = []
- 60
select_statement.union = union
end
- 6451
if context == :top
- 5938
select_manager
else
- 513
select_statement
end
end
- 5
def visit_SetToDefault(_args)
- 30
Arel::Nodes::SetToDefault.new
end
- 5
def visit_SortBy(attribute)
- 213
result = visit(attribute.node)
- 213
case attribute.sortby_dir
when :SORTBY_ASC
- 99
Arel::Nodes::Ascending.new(
result,
PgQuery::SortByNulls.descriptor.to_h[attribute.sortby_nulls] - 1,
)
when :SORTBY_DESC
- 54
Arel::Nodes::Descending.new(
result,
PgQuery::SortByNulls.descriptor.to_h[attribute.sortby_nulls] - 1,
)
else
- 60
result
end
end
- 5
def visit_SQLValueFunction(attribute)
{
- 20
SVFOP_CURRENT_DATE: -> { Arel::Nodes::CurrentDate.new },
- 20
SVFOP_CURRENT_TIME: -> { Arel::Nodes::CurrentTime.new },
- 10
SVFOP_CURRENT_TIME_N: -> { Arel::Nodes::CurrentTime.new(precision: attribute.typmod) },
- 50
SVFOP_CURRENT_TIMESTAMP: -> { Arel::Nodes::CurrentTimestamp.new },
SVFOP_CURRENT_TIMESTAMP_N: lambda {
- 10
Arel::Nodes::CurrentTimestamp.new(precision: attribute.typmod)
},
- 20
SVFOP_LOCALTIME: -> { Arel::Nodes::LocalTime.new },
- 10
SVFOP_LOCALTIME_N: -> { Arel::Nodes::LocalTime.new(precision: attribute.typmod) },
- 20
SVFOP_LOCALTIMESTAMP: -> { Arel::Nodes::LocalTimestamp.new },
SVFOP_LOCALTIMESTAMP_N: lambda {
- 10
Arel::Nodes::LocalTimestamp.new(precision: attribute.typmod)
},
- 10
SVFOP_CURRENT_ROLE: -> { Arel::Nodes::CurrentRole.new },
- 10
SVFOP_CURRENT_USER: -> { Arel::Nodes::CurrentUser.new },
- 10
SVFOP_USER: -> { Arel::Nodes::User.new },
- 10
SVFOP_SESSION_USER: -> { Arel::Nodes::SessionUser.new },
- 10
SVFOP_CURRENT_CATALOG: -> { Arel::Nodes::CurrentCatalog.new },
- 10
SVFOP_CURRENT_SCHEMA: -> { Arel::Nodes::CurrentSchema.new },
- 230
}[attribute.op].call
end
- 5
def visit_String(attribute, context = nil)
- 18971
case context
when :operator
- 12586
attribute.str
when :const
- 5929
Arel::Nodes.build_quoted attribute.str
else
- 456
"\"#{attribute}\""
end
end
- 5
def visit_SubLink(attribute)
- 140
subselect = visit(attribute.subselect)
- 140
testexpr = visit(attribute.testexpr) if attribute.testexpr
- 140
operator = if attribute.oper_name
- 140
operator = visit(attribute.oper_name, :operator)
- 140
boom 'Unable to handle operator length > 1' if operator.length > 1
- 140
operator.first
end
- 140
generate_sublink(attribute.sub_link_type, subselect, testexpr, operator)
end
- 5
def visit_TransactionStmt(attribute)
- 170
Arel::Nodes::Transaction.new(
PgQuery::TransactionStmtKind.descriptor.to_h[attribute.kind],
visit_String(attribute.savepoint_name),
)
end
- 5
def visit_TypeCast(attribute)
- 2944
arg = visit(attribute.arg)
- 2944
type_name = visit(attribute.type_name)
- 2944
Arel::Nodes::TypeCast.new(maybe_add_grouping(arg), type_name)
end
- 5
def visit_TypeName(attribute)
- 2954
array_bounds = visit(attribute.array_bounds)
- 2954
names = attribute.names.map do |name|
- 3541
visit(name, :operator)
end
- 6495
names = names.reject { |name| name == PG_CATALOG }
- 2954
boom 'https://github.com/mvgijssel/arel_toolkit/issues/40' if attribute.typemod != -1
- 2954
boom 'https://github.com/mvgijssel/arel_toolkit/issues/41' if names.length > 1
- 2954
if array_bounds != [] && array_bounds != [-1]
boom 'https://github.com/mvgijssel/arel_toolkit/issues/86'
end
- 2954
type_name = names.first
- 2954
type_name = case type_name
when 'int4'
- 45
'integer'
when 'float4'
- 10
'real'
when 'float8'
- 30
'double precision'
when 'timestamptz'
- 40
'timestamp with time zone'
else
- 2829
type_name
end
- 2954
type_name += '[]' if array_bounds == [-1]
- 2954
type_name
end
- 5
def visit_UpdateStmt(attribute)
- 77
relation = visit(attribute.relation)
- 77
target_list = visit(attribute.target_list, :update)
- 77
update_manager = Arel::UpdateManager.new
- 77
update_statement = update_manager.ast
- 77
update_statement.relation = relation
- 77
update_statement.froms = visit(attribute.from_clause)
- 77
update_statement.values = target_list
- 77
update_statement.wheres = attribute.where_clause ? [visit(attribute.where_clause)] : []
- 77
update_statement.with = visit(attribute.with_clause) if attribute.with_clause
- 77
update_statement.returning = visit(attribute.returning_list, :select)
- 77
update_manager
end
- 5
def visit_VariableSetStmt(attribute)
- 60
Arel::Nodes::VariableSet.new(
attribute.kind,
visit(attribute.args),
attribute.name,
attribute.is_local,
)
end
- 5
def visit_VariableShowStmt(attribute)
- 20
Arel::Nodes::VariableShow.new(attribute.name)
end
- 5
def visit_WindowDef(attribute)
- 200
if attribute.name.present? &&
attribute.partition_clause.empty? &&
attribute.order_clause.empty?
- 30
return Arel::Nodes::SqlLiteral.new(attribute.name)
end
- 170
instance = if attribute.name.blank?
- 140
Arel::Nodes::Window.new
else
- 30
Arel::Nodes::NamedWindow.new(attribute.name)
end
- 170
instance.tap do |window|
- 170
window.orders = visit attribute.order_clause
- 170
window.partitions = visit attribute.partition_clause
- 170
if attribute.frame_options
- 170
window.framing = FrameOptions.arel(
attribute.frame_options,
- 170
(visit(attribute.start_offset) if attribute.start_offset),
- 170
(visit(attribute.end_offset) if attribute.end_offset),
)
end
end
end
- 5
def visit_WithClause(attribute)
- 71
if attribute.recursive
- 25
Arel::Nodes::WithRecursive.new visit(attribute.ctes)
else
- 46
Arel::Nodes::With.new visit(attribute.ctes)
end
end
- 5
def generate_operator(left, right, operator)
- 1996
left = maybe_add_grouping(left)
- 1996
right = maybe_add_grouping(right)
- 1996
case operator
# https://www.postgresql.org/docs/10/functions-math.html
when '+'
- 120
Arel::Nodes::Addition.new(left, right)
when '-'
- 170
if left.nil?
- 10
Arel::Nodes::UnaryOperation.new(:'-', right)
else
- 160
Arel::Nodes::Subtraction.new(left, right)
end
when '*'
- 50
Arel::Nodes::Multiplication.new(left, right)
when '/'
- 30
Arel::Nodes::Division.new(left, right)
when '%'
- 10
Arel::Nodes::Modulo.new(left, right)
when '^'
- 10
Arel::Nodes::Exponentiation.new(left, right)
when '|/'
- 10
Arel::Nodes::SquareRoot.new(right)
when '||/'
- 10
Arel::Nodes::CubeRoot.new(right)
when '!'
- 10
Arel::Nodes::Factorial.new(left || right, false)
when '!!'
- 20
Arel::Nodes::Factorial.new(right, true)
when '@'
- 10
Arel::Nodes::Absolute.new(right)
when '&'
- 20
Arel::Nodes::BitwiseAnd.new(left, right)
when '|'
- 20
Arel::Nodes::BitwiseOr.new(left, right)
when '#'
- 30
if left.nil?
- 10
Arel::Nodes::UnaryOperation.new(:'#', right)
else
- 20
Arel::Nodes::BitwiseXor.new(left, right)
end
when '~'
- 40
if left.nil?
- 20
Arel::Nodes::BitwiseNot.new(right)
else
- 20
Arel::Nodes::Regexp.new(left, right, true)
end
when '<<'
- 30
Arel::Nodes::BitwiseShiftLeft.new(left, right)
when '>>'
- 30
Arel::Nodes::BitwiseShiftRight.new(left, right)
# https://www.postgresql.org/docs/9.0/functions-comparison.html
when '<'
- 31
Arel::Nodes::LessThan.new(left, right)
when '>'
- 50
Arel::Nodes::GreaterThan.new(left, right)
when '<='
- 30
Arel::Nodes::LessThanOrEqual.new(left, right)
when '>='
- 20
Arel::Nodes::GreaterThanOrEqual.new(left, right)
when '='
- 511
Arel::Nodes::Equality.new(left, right)
when '<>'
- 30
Arel::Nodes::NotEqual.new(left, right)
# https://www.postgresql.org/docs/9.1/functions-array.html
when '@>'
- 40
Arel::Nodes::Contains.new(left, right)
when '<@'
- 40
Arel::Nodes::ContainedBy.new(left, right)
when '&&'
- 52
Arel::Nodes::Overlap.new(left, right)
when '||'
- 138
Arel::Nodes::Concat.new(left, right)
# https://www.postgresql.org/docs/9.3/functions-net.html
when '<<='
- 20
Arel::Nodes::ContainedWithinEquals.new(left, right)
when '>>='
- 20
Arel::Nodes::ContainsEquals.new(left, right)
# https://www.postgresql.org/docs/9.4/functions-json.html
when '->'
- 20
Arel::Nodes::JsonGetObject.new(left, right)
when '->>'
- 20
Arel::Nodes::JsonGetField.new(left, right)
when '#>'
- 10
Arel::Nodes::JsonPathGetObject.new(left, right)
when '#>>'
- 10
Arel::Nodes::JsonPathGetField.new(left, right)
# https://www.postgresql.org/docs/9.4/functions-json.html#FUNCTIONS-JSONB-OP-TABLE
when '?'
- 10
Arel::Nodes::JsonbKeyExists.new(left, right)
when '?|'
- 30
if left.nil?
- 10
Arel::Nodes::UnaryOperation.new(:'?|', right)
else
- 20
Arel::Nodes::JsonbAnyKeyExists.new(left, right)
end
when '?&'
- 10
Arel::Nodes::JsonbAllKeyExists.new(left, right)
# https://www.postgresql.org/docs/9.3/functions-matching.html#FUNCTIONS-POSIX-TABLE
when '~*'
- 20
Arel::Nodes::Regexp.new(left, right, false)
when '!~'
- 20
Arel::Nodes::NotRegexp.new(left, right, true)
when '!~*'
- 20
Arel::Nodes::NotRegexp.new(left, right, false)
else
- 224
if left.nil?
- 30
Arel::Nodes::UnaryOperation.new(operator, right)
else
- 194
Arel::Nodes::InfixOperation.new(operator, left, right)
end
end
end
- 5
def visit(attribute, context = nil)
- 25695
return attribute.map { |attr| visit(attr, context) } if
- 185959
attribute.is_a?(Google::Protobuf::RepeatedField) || attribute.is_a?(Array)
- 132358
dispatch_method = "visit_#{attribute.class.name.demodulize}"
- 132358
if context.present?
- 80812
method = method(dispatch_method)
- 80812
if method.parameters.include?(%i[opt context]) ||
method.parameters.include?(%i[req context])
- 75371
send dispatch_method, attribute, context
else
- 5441
send dispatch_method, attribute
end
else
- 51546
send dispatch_method, attribute
end
end
- 5
def generate_boolean_expression(args, boolean_class)
- 10
chain = boolean_class.new(nil, nil)
- 10
args.each_with_index.reduce(chain) do |c, (arg, index)|
- 20
if args.length - 1 == index
- 10
c.right = arg
- 10
c
else
- 10
new_chain = boolean_class.new(arg, nil)
- 10
c.right = new_chain
- 10
new_chain
end
end
- 10
chain.right
end
- 5
def generate_sources(clause)
- 6461
froms = []
- 6461
join_sources = []
- 6461
if (from_clauses = clause)
- 6461
results = visit(from_clauses).flatten
- 6461
results.each do |result|
- 820
case result
when Arel::Table
- 595
froms << result
else
- 225
join_sources << result
end
end
end
- 6461
if froms.empty?
- 5886
[nil, join_sources]
else
- 575
[froms, join_sources]
end
end
- 5
def generate_sublink(sub_link_type, subselect, testexpr, operator)
- 140
case sub_link_type
when :EXISTS_SUBLINK
- 15
Arel::Nodes::Exists.new subselect
when :ALL_SUBLINK
- 10
generate_operator(testexpr, Arel::Nodes::All.new(subselect), operator)
when :ANY_SUBLINK
- 60
if operator.nil?
- 40
Arel::Nodes::In.new(testexpr, subselect)
else
- 20
generate_operator(testexpr, Arel::Nodes::Any.new(subselect), operator)
end
when :ROWCOMPARE_SUBLINK
boom 'https://github.com/mvgijssel/arel_toolkit/issues/42'
when :EXPR_SUBLINK
- 45
Arel::Nodes::Grouping.new(subselect)
when :MULTIEXPR_SUBLINK
boom 'https://github.com/mvgijssel/arel_toolkit/issues/43'
when :ARRAY_SUBLINK
- 10
Arel::Nodes::ArraySubselect.new(subselect)
when :CTE_SUBLINK
boom 'https://github.com/mvgijssel/arel_toolkit/issues/44'
else
boom "Unknown sublinktype: #{type}"
end
end
- 5
def maybe_add_grouping(node)
- 6996
case node
when Arel::Nodes::Binary
- 111
Arel::Nodes::Grouping.new(node)
else
- 6885
node
end
end
- 5
def boom(message, backtrace = nil)
- 10
new_message = <<~STRING
SQL: #{sql}
BINDS: #{binds}
message: #{message}
STRING
- 10
raise(Arel::SqlToArel::Error, new_message, backtrace) if backtrace
- 5
raise Arel::SqlToArel::Error, new_message
end
end
end
end
# rubocop:enable Metrics/PerceivedComplexity
# rubocop:enable Naming/MethodName
# rubocop:enable Metrics/CyclomaticComplexity
# rubocop:enable Metrics/AbcSize
- 5
module Arel
- 5
module SqlToArel
- 5
class PgQueryVisitor
- 5
class FrameOptions
- 5
class << self
- 5
def arel(frame_options, start_offset, end_offset)
- 170
frame_option_names = calculate_frame_option_names(frame_options)
- 170
return unless frame_option_names.include?('FRAMEOPTION_NONDEFAULT')
- 120
range_klass = if frame_option_names.include?('FRAMEOPTION_RANGE')
- 50
Arel::Nodes::Range
else
- 70
Arel::Nodes::Rows
end
- 120
start_node = calculate_frame_node(
'FRAMEOPTION_START_',
frame_option_names,
start_offset,
)
- 120
end_node = calculate_frame_node(
'FRAMEOPTION_END_',
frame_option_names,
end_offset,
)
- 120
if frame_option_names.include?('FRAMEOPTION_BETWEEN')
- 100
Arel::Nodes::Between.new(
range_klass.new,
Arel::Nodes::And.new([start_node, end_node]),
)
else
- 20
range_klass.new start_node
end
end
- 5
private
# always NONDEFAULT
# RANGE or ROWS
# mandatory BETWEEN
# RANGE only unbounded
# ROWS all
# https://github.com/postgres/postgres/blob/REL_10_1/src/include/nodes/parsenodes.h
- 5
FRAMEOPTIONS_V10 = {
'FRAMEOPTION_NONDEFAULT' => 0x00001,
'FRAMEOPTION_RANGE' => 0x00002,
'FRAMEOPTION_ROWS' => 0x00004,
'FRAMEOPTION_BETWEEN' => 0x00008,
'FRAMEOPTION_START_UNBOUNDED_PRECEDING' => 0x00010,
'FRAMEOPTION_END_UNBOUNDED_PRECEDING' => 0x00020,
'FRAMEOPTION_START_UNBOUNDED_FOLLOWING' => 0x00040,
'FRAMEOPTION_END_UNBOUNDED_FOLLOWING' => 0x00080,
'FRAMEOPTION_START_CURRENT_ROW' => 0x00100,
'FRAMEOPTION_END_CURRENT_ROW' => 0x00200,
'FRAMEOPTION_START_VALUE_PRECEDING' => 0x00400,
'FRAMEOPTION_END_VALUE_PRECEDING' => 0x00800,
'FRAMEOPTION_START_VALUE_FOLLOWING' => 0x01000,
'FRAMEOPTION_END_VALUE_FOLLOWING' => 0x02000,
}.freeze
- 5
FRAMEOPTIONS_V11_AND_UP = {
'FRAMEOPTION_NONDEFAULT' => 0x00001, # any specified? */
'FRAMEOPTION_RANGE' => 0x00002, # RANGE behavior */
'FRAMEOPTION_ROWS' => 0x00004, # ROWS behavior */
'FRAMEOPTION_GROUPS' => 0x00008, # GROUPS behavior */
'FRAMEOPTION_BETWEEN' => 0x00010, # BETWEEN given? */
'FRAMEOPTION_START_UNBOUNDED_PRECEDING' => 0x00020, # start is U. P. */
'FRAMEOPTION_END_UNBOUNDED_PRECEDING' => 0x00040, # (disallowed) */
'FRAMEOPTION_START_UNBOUNDED_FOLLOWING' => 0x00080, # (disallowed) */
'FRAMEOPTION_END_UNBOUNDED_FOLLOWING' => 0x00100, # end is U. F. */
'FRAMEOPTION_START_CURRENT_ROW' => 0x00200, # start is C. R. */
'FRAMEOPTION_END_CURRENT_ROW' => 0x00400, # end is C. R. */
'FRAMEOPTION_START_OFFSET_PRECEDING' => 0x00800, # start is O. P. */
'FRAMEOPTION_END_OFFSET_PRECEDING' => 0x01000, # end is O. P. */
'FRAMEOPTION_START_OFFSET_FOLLOWING' => 0x02000, # start is O. F. */
'FRAMEOPTION_END_OFFSET_FOLLOWING' => 0x04000, # end is O. F. */
'FRAMEOPTION_EXCLUDE_CURRENT_ROW' => 0x08000, # omit C.R. */
'FRAMEOPTION_EXCLUDE_GROUP' => 0x10000, # omit C.R. & peers */
'FRAMEOPTION_EXCLUDE_TIES' => 0x20000, # omit C.R.'s peers */
}.freeze
- 5
def frameoptions
- 1460
case PG.library_version.to_s[0, 2]
when '09', '10'
FRAMEOPTIONS_V10
when '11', '12', '13', '14'
- 1460
FRAMEOPTIONS_V11_AND_UP
else
boom "Version #{PG.library_version.to_s[0, 2]} not supported"
end
end
- 5
def biggest_detractable_number(number, candidates)
- 30660
high_to_low_candidates = candidates.sort { |a, b| b <=> a }
- 730
high_to_low_candidates.find do |candidate|
- 9510
number - candidate >= 0
end
end
- 5
def calculate_frame_option_names(frame_options, names = [])
- 900
return names if frame_options.zero?
- 730
number = biggest_detractable_number(frame_options, frameoptions.values)
- 730
name = frameoptions.key(number)
- 730
calculate_frame_option_names(
frame_options - number, names + [name]
)
end
- 5
def calculate_frame_node(pattern, frame_option_names, offset)
- 1400
node_name = frame_option_names.select { |n| n.start_with?(pattern) }
- 240
raise "Don't know how to handle multiple nodes" if node_name.length > 1
- 240
node_name = node_name.first.gsub(/FRAMEOPTION_(START|END)_/, '')
- 240
name_to_node(node_name, offset)
end
- 5
def name_to_node(node_name, offset)
- 240
case node_name
when 'UNBOUNDED_PRECEDING'
- 40
Arel::Nodes::Preceding.new
when 'UNBOUNDED_FOLLOWING'
- 40
Arel::Nodes::Following.new
when 'CURRENT_ROW'
- 90
Arel::Nodes::CurrentRow.new
when 'VALUE_PRECEDING', 'OFFSET_PRECEDING'
- 40
Arel::Nodes::Preceding.new offset
when 'VALUE_FOLLOWING', 'OFFSET_FOLLOWING'
- 30
Arel::Nodes::Following.new offset
else
raise "Unknown start / end frame node `#{node_name}`"
end
end
end
end
end
end
end
- 5
module Arel
- 5
module SqlToArel
- 5
class Result < Array
- 5
def to_sql(engine = Arel::Table.engine)
- 3106
sql, _binds = to_sql_and_binds(engine)
- 3106
sql
end
- 5
def to_sql_and_binds(engine = Arel::Table.engine)
- 3327
sql_collection = []
- 3327
binds_collection = []
- 3327
each do |item|
- 3382
sql, binds = item.to_sql_and_binds(engine)
- 3382
sql_collection << sql
- 3382
binds_collection.concat(binds)
end
- 3327
[
sql_collection.join('; '),
binds_collection,
]
end
- 5
def map(&block)
- 5
Result.new super
end
end
end
end
- 5
require_relative './transformer/prefix_schema_name'
- 5
require_relative './transformer/replace_table_with_subquery'
- 5
module Arel
- 5
module Transformer
end
end
- 5
module Arel
- 5
module Transformer
- 5
class PrefixSchemaName
- 5
PG_CATALOG = 'pg_catalog'.freeze
- 5
DEFAULT_SCHEMA_PRIORITY = ['public', PG_CATALOG].freeze
- 5
attr_reader :object_mapping
- 5
attr_reader :schema_priority
- 5
def initialize(
schema_priority = DEFAULT_SCHEMA_PRIORITY,
override_object_mapping = {}
)
- 85
@schema_priority = schema_priority
- 85
@object_mapping = database_object_mapping.merge(override_object_mapping)
end
- 5
def call(arel, next_middleware)
- 85
tree = Arel.enhance(arel)
- 85
update_arel_tables(tree)
- 80
update_typecasts(tree)
- 75
update_functions(tree)
- 75
next_middleware.call tree
end
- 5
private
- 5
def update_arel_tables(tree)
tree.query(
class: Arel::Table,
schema_name: nil,
context: { range_variable: true },
- 85
).each do |node|
- 50
schema_name = schema_name_from_object_name(node['name'].object.to_s)
- 45
node['schema_name'].replace(schema_name)
end
end
- 5
def update_typecasts(tree)
tree.query(
class: Arel::Nodes::TypeCast,
type_name: 'regclass',
- 80
).each do |node|
- 20
update_typecast_node(node)
end
end
- 5
def update_typecast_node(node)
- 20
table_name = table_name_from_arel_node(node['arg'].object)
- 20
reference_parts = table_name.split('.')
- 20
case reference_parts.length
when 1
- 10
schema_name = schema_name_from_object_name(table_name)
- 10
reference_parts.unshift(schema_name)
- 10
node['arg']['expr'].replace(reference_parts.join('.'))
when 2
- 5
node # Do nothing
else
- 5
raise "Don't know how to handle `#{reference_parts.length}` parts in " \
"`#{reference_parts}` for sql `#{node.to_sql}`"
end
end
- 5
def update_functions(tree)
tree.query(
class: Arel::Enhance::QueryMethods.in_ancestors?(Arel::Nodes::Function),
schema_name: nil,
- 75
).each do |node|
- 15
update_function_node(node)
end
end
- 5
def update_function_node(node)
- 15
object_name = if node.object.is_a?(Arel::Nodes::NamedFunction)
- 10
node['name'].object.downcase
else
- 5
node.object.class.to_s.demodulize.underscore
end
- 15
schema_name = schema_name_from_object_name(object_name)
- 15
node['schema_name'].replace(schema_name)
end
- 5
def table_name_from_arel_node(arel_node)
- 20
case arel_node
when Arel::Nodes::Quoted
- 20
arel_node.expr
else
raise "Unknown node `#{table_name}` for `#{node.inspect}`"
end
end
- 5
def schema_name_from_object_name(table_name)
- 75
table_name = unquote_string(table_name)
- 75
possible_schemas = object_mapping[table_name]
- 75
if possible_schemas.nil?
- 5
raise "Object `#{table_name}` does not exist in the object_mapping and cannot be prefixed"
end
- 70
schema_name = schema_priority.find do |possible_schema_name|
- 90
possible_schemas.include?(possible_schema_name)
end
- 70
if schema_name.nil?
raise "Could not find a schema name for table `#{table_name}`.\n" \
"Current schema priority is `#{schema_priority}`.\n" \
"Possible schemas are `#{possible_schemas}`."
end
# We don't need to prefix nodes with `pg_catalog`, because that's the default
# even if the search_path does not include `pg_catalog`.
- 70
return nil if schema_name == PG_CATALOG
- 60
schema_name
end
# https://www.rubydoc.info/github/rubyworks/facets/String:unquote
- 5
def unquote_string(string)
- 75
s = string.dup
- 75
case string[0, 1]
when "'", '"', '`'
- 5
s[0] = ''
end
- 75
case string[-1, 1]
when "'", '"', '`'
- 5
s[-1] = ''
end
- 75
s
end
- 5
def database_object_mapping
- 85
mapping = {}
- 85
update_mapping mapping, database_tables
- 85
update_mapping mapping, database_views
- 85
update_mapping mapping, database_materialized_views
- 85
update_mapping mapping, database_functions
- 85
mapping
end
- 5
def update_mapping(mapping, objects)
- 340
objects.each do |object|
- 263041
name = object.fetch('object_name').to_s.downcase
- 263041
mapping[name] ||= []
- 263041
mapping[name] << object.fetch('schema_name').to_s
end
end
- 5
def database_tables
- 85
connection.execute(
'SELECT tablename AS object_name, schemaname AS schema_name FROM pg_tables',
)
end
- 5
def database_views
- 85
connection.execute(
'SELECT viewname AS object_name, schemaname AS schema_name FROM pg_views',
)
end
- 5
def database_materialized_views
- 85
connection.execute(
'SELECT matviewname AS object_name, schemaname AS schema_name FROM pg_matviews',
)
end
- 5
def database_functions
- 85
connection.execute(
'SELECT pg_proc.proname AS object_name, pg_namespace.nspname AS schema_name ' \
'FROM pg_proc INNER JOIN pg_namespace ON pg_proc.pronamespace = pg_namespace.oid',
)
end
- 5
def connection
- 340
Arel::Table.engine.connection
end
end
end
end
- 5
module Arel
- 5
module Transformer
- 5
class ReplaceTableWithSubquery
- 5
attr_reader :subquery_for_table
- 5
def initialize(subquery_for_table)
- 10
@subquery_for_table = subquery_for_table
end
- 5
def call(arel, next_middleware)
- 10
tree = Arel.enhance(arel)
- 10
update_arel_tables(tree)
- 10
next_middleware.call tree
end
- 5
private
- 5
def update_arel_tables(tree)
tree.query(
class: Arel::Table,
context: { range_variable: true },
schema_name: nil,
- 10
).each do |node|
- 10
if (subquery = subquery_for_table.call(node.name.value))
- 5
node.replace subquery.as(node.name.value)
end
end
end
end
end
end
# Make sure the gems are loaded before ArelToolkit
- 5
require 'postgres_ext' if Gem.loaded_specs.key?('postgres_ext')
- 5
require 'active_record_upsert' if Gem.loaded_specs.key?('active_record_upsert')
- 5
require 'pg_search' if Gem.loaded_specs.key?('pg_search')
- 5
require 'rails/railtie' if Gem.loaded_specs.key?('railties')
- 5
require 'arel'
- 5
require 'active_record'
- 5
require 'active_record/connection_adapters/postgresql_adapter'
- 5
require 'arel_toolkit/version'
- 5
require 'pg'
- 5
require 'arel_toolkit/pg_result_init'
- 5
require 'arel/extensions'
- 5
require 'arel/sql_to_arel'
- 5
require 'arel/middleware'
- 5
require 'arel/enhance'
- 5
require 'arel/transformer'
- 5
module ArelToolkit
end