module ThinkingSphinx class PostgreSQLAdapter < AbstractAdapter class << self def setup create_array_accum_function create_crc32_function end private def execute(command, output_error = false) connection.execute "begin" connection.execute "savepoint ts" begin connection.execute command rescue StandardError => err puts err if output_error connection.execute "rollback to savepoint ts" end connection.execute "release savepoint ts" connection.execute "commit" end def create_array_accum_function if connection.raw_connection.server_version > 80200 execute <<-SQL CREATE AGGREGATE array_accum (anyelement) ( sfunc = array_append, stype = anyarray, initcond = '{}' ); SQL else execute <<-SQL CREATE AGGREGATE array_accum ( basetype = anyelement, sfunc = array_append, stype = anyarray, initcond = '{}' ); SQL end end def create_crc32_function execute "CREATE LANGUAGE 'plpgsql';" function = <<-SQL CREATE OR REPLACE FUNCTION crc32(word text) RETURNS bigint AS $$ DECLARE tmp bigint; DECLARE i int; DECLARE j int; DECLARE word_array bytea; BEGIN i = 0; tmp = 4294967295; word_array = decode(replace(word, E'\\\\', E'\\\\\\\\'), 'escape'); LOOP tmp = (tmp # get_byte(word_array, i))::bigint; i = i + 1; j = 0; LOOP tmp = ((tmp >> 1) # (3988292384 * (tmp & 1)))::bigint; j = j + 1; IF j >= 8 THEN EXIT; END IF; END LOOP; IF i >= char_length(word) THEN EXIT; END IF; END LOOP; return (tmp # 4294967295); END $$ IMMUTABLE STRICT LANGUAGE plpgsql; SQL execute function, true end end end end