module Sequel::Postgres::AutoParameterizeInArray
Enable automatically parameterizing queries.
Public Instance Methods
Source
# File lib/sequel/extensions/pg_auto_parameterize_in_array.rb 47 def complex_expression_sql_append(sql, op, args) 48 case op 49 when :IN, :"NOT IN" 50 l, r = args 51 if auto_param?(sql) && (type = _bound_variable_type_for_array(r)) 52 if op == :IN 53 op = :"=" 54 func = :ANY 55 else 56 op = :!= 57 func = :ALL 58 end 59 args = [l, Sequel.function(func, Sequel.pg_array(r, type))] 60 end 61 end 62 63 super 64 end
Transform column IN (…) expressions into column = ANY($) and column NOT IN (…) expressions into column != ALL($) using an array bound variable for the ANY/ALL argument, if all values inside the predicate are of the same type and the type is handled by the extension. This is the same optimization PostgreSQL performs internally, but this reduces the number of bound variables.
Calls superclass method
Private Instance Methods
Source
# File lib/sequel/extensions/pg_auto_parameterize_in_array.rb 70 def _bound_variable_type_for_array(r) 71 return unless Array === r && r.size > 1 72 classes = r.map(&:class) 73 classes.uniq! 74 classes.delete(NilClass) 75 return unless classes.size == 1 76 77 klass = classes[0] 78 if klass == Integer 79 # This branch is not taken on Ruby <2.4, because of the Fixnum/Bignum split. 80 # However, that causes no problems as pg_auto_parameterize handles integer 81 # arrays natively (though the SQL used is different) 82 "int8" 83 elsif klass == String 84 "text" if db.typecast_value(:boolean, db.opts[:treat_string_list_as_text_array]) 85 elsif klass == BigDecimal 86 "numeric" 87 elsif klass == Date 88 "date" 89 elsif klass == Time 90 @db.cast_type_literal(Time) 91 elsif klass == Float 92 # PostgreSQL treats literal floats as numeric, not double precision 93 # But older versions of PostgreSQL don't handle Infinity/NaN in numeric 94 r.all?{|v| v.nil? || v.finite?} ? "numeric" : "double precision" 95 elsif klass == Sequel::SQLTime 96 "time" 97 elsif klass == DateTime 98 @db.cast_type_literal(DateTime) 99 elsif klass == Sequel::SQL::Blob 100 "bytea" 101 end 102 end
The bound variable type string to use for the bound variable array. Returns nil if a bound variable should not be used for the array.