Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ext/sqlite3/database.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ define_function_with_flags(VALUE self, VALUE name, VALUE flags)

CHECK(ctx->db, status);

rb_hash_aset(rb_iv_get(self, "@functions"), name, block);
rb_ary_push(rb_iv_get(self, "@functions"), block);

return self;
}
Expand Down
4 changes: 3 additions & 1 deletion lib/sqlite3/database.rb
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def initialize file, options = {}, zvfs = nil
@authorizer = nil
@progress_handler = nil
@collations = {}
@functions = {}
@functions = []
@results_as_hash = options[:results_as_hash]
@readonly = mode & Constants::Open::READONLY != 0
@default_transaction_mode = options[:default_transaction_mode] || :deferred
Expand Down Expand Up @@ -398,6 +398,8 @@ def get_first_value(sql, *bind_vars)
# the FunctionProxy#result= method on the +func+ parameter and
# indicate the return value that way.
#
# A reference to the block will be kept for the lifetime of the database object.
#
# Example:
#
# db.create_function( "maim", 1 ) do |func, value|
Expand Down
8 changes: 8 additions & 0 deletions test/test_database.rb
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,14 @@ def test_define_function
assert_equal 10, called_with
end

def test_redefine_function_with_different_arity_does_not_use_freed_block
@db.define_function("f") { |a| "orig" }
@db.define_function("f") { |a, b| "new" }
GC.start(full_mark: true, immediate_sweep: true)

assert_equal ["orig"], @db.execute("select f(1)").first
end

def test_call_func_arg_type
called_with = nil
@db.define_function("hello") do |b, c, d|
Expand Down