Skip to content

Commit 4c211a8

Browse files
committed
Add VARCHAR support to vector_set_value_at
- Add DUCKDB_TYPE_VARCHAR case using duckdb_vector_assign_string_element_len() - Update type validation to allow :varchar in return types - Add test_scalar_function_varchar_return_type test - Update error test to use TIMESTAMP (now unsupported)
1 parent a9a8acc commit 4c211a8

File tree

3 files changed

+31
-6
lines changed

3 files changed

+31
-6
lines changed

ext/duckdb/scalar_function.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,14 @@ static void vector_set_value_at(duckdb_vector vector, duckdb_logical_type elemen
243243
case DUCKDB_TYPE_DOUBLE:
244244
((double *)vector_data)[index] = NUM2DBL(value);
245245
break;
246+
case DUCKDB_TYPE_VARCHAR: {
247+
// VARCHAR requires special API, not direct array assignment
248+
VALUE str = rb_obj_as_string(value);
249+
const char *str_ptr = StringValuePtr(str);
250+
idx_t str_len = RSTRING_LEN(str);
251+
duckdb_vector_assign_string_element_len(vector, index, str_ptr, str_len);
252+
break;
253+
}
246254
default:
247255
rb_raise(rb_eArgError, "Unsupported return type for scalar function");
248256
break;

lib/duckdb/scalar_function.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module DuckDB
44
# DuckDB::ScalarFunction encapsulates DuckDB's scalar function
55
class ScalarFunction
66
# Sets the return type for the scalar function.
7-
# Currently supports BOOLEAN, INTEGER, BIGINT, FLOAT, and DOUBLE types.
7+
# Currently supports BOOLEAN, INTEGER, BIGINT, FLOAT, DOUBLE, and VARCHAR types.
88
#
99
# @param logical_type [DuckDB::LogicalType] the return type
1010
# @return [DuckDB::ScalarFunction] self
@@ -13,8 +13,8 @@ def return_type=(logical_type)
1313
raise DuckDB::Error, 'logical_type must be a DuckDB::LogicalType' unless logical_type.is_a?(DuckDB::LogicalType)
1414

1515
# Check if the type is supported
16-
unless %i[boolean integer bigint float double].include?(logical_type.type)
17-
raise DuckDB::Error, 'Only BOOLEAN, INTEGER, BIGINT, FLOAT, and DOUBLE return types are currently supported'
16+
unless %i[boolean integer bigint float double varchar].include?(logical_type.type)
17+
raise DuckDB::Error, 'Only BOOLEAN, INTEGER, BIGINT, FLOAT, DOUBLE, and VARCHAR return types are currently supported'
1818
end
1919

2020
_set_return_type(logical_type)

test/duckdb_test/scalar_function_test.rb

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ def test_return_type_setter
3737

3838
def test_return_type_setter_raises_error_for_unsupported_type
3939
sf = DuckDB::ScalarFunction.new
40-
varchar_type = DuckDB::LogicalType.new(17) # DUCKDB_TYPE_VARCHAR
40+
timestamp_type = DuckDB::LogicalType.new(13) # DUCKDB_TYPE_TIMESTAMP (unsupported)
4141

4242
error = assert_raises(DuckDB::Error) do
43-
sf.return_type = varchar_type
43+
sf.return_type = timestamp_type
4444
end
4545

46-
assert_match(/only.*INTEGER.*supported/i, error.message)
46+
assert_match(/only.*supported/i, error.message)
4747
end
4848

4949
def test_set_function
@@ -214,5 +214,22 @@ def test_scalar_function_float_return_type # rubocop:disable Metrics/MethodLengt
214214

215215
assert_in_delta 3.0, result.first.first, 0.0001
216216
end
217+
218+
def test_scalar_function_varchar_return_type # rubocop:disable Metrics/MethodLength
219+
@con.execute('SET threads=1')
220+
@con.execute('CREATE TABLE test_table (name VARCHAR)')
221+
@con.execute("INSERT INTO test_table VALUES ('Alice'), ('Bob')")
222+
223+
sf = DuckDB::ScalarFunction.new
224+
sf.name = 'add_greeting'
225+
sf.add_parameter(DuckDB::LogicalType.new(17)) # VARCHAR (type ID 17)
226+
sf.return_type = DuckDB::LogicalType.new(17) # VARCHAR
227+
sf.set_function { |name| "Hello, #{name}!" }
228+
229+
@con.register_scalar_function(sf)
230+
result = @con.execute('SELECT add_greeting(name) FROM test_table ORDER BY name')
231+
232+
assert_equal [['Hello, Alice!'], ['Hello, Bob!']], result.to_a
233+
end
217234
end
218235
end

0 commit comments

Comments
 (0)