File tree Expand file tree Collapse file tree 2 files changed +44
-12
lines changed Expand file tree Collapse file tree 2 files changed +44
-12
lines changed Original file line number Diff line number Diff line change @@ -277,32 +277,34 @@ last_insert_row_id(VALUE self)
277277VALUE
278278sqlite3val2rb (sqlite3_value * val )
279279{
280+ VALUE rb_val ;
281+
280282 switch (sqlite3_value_type (val )) {
281283 case SQLITE_INTEGER :
282- return LL2NUM (sqlite3_value_int64 (val ));
284+ rb_val = LL2NUM (sqlite3_value_int64 (val ));
283285 break ;
284286 case SQLITE_FLOAT :
285- return rb_float_new (sqlite3_value_double (val ));
287+ rb_val = rb_float_new (sqlite3_value_double (val ));
286288 break ;
287- case SQLITE_TEXT :
288- return rb_str_new2 ((const char * )sqlite3_value_text (val ));
289+ case SQLITE_TEXT : {
290+ rb_val = rb_utf8_str_new_cstr ((const char * )sqlite3_value_text (val ));
291+ rb_obj_freeze (rb_val );
289292 break ;
293+ }
290294 case SQLITE_BLOB : {
291- /* Sqlite warns calling sqlite3_value_bytes may invalidate pointer from sqlite3_value_blob,
292- so we explicitly get the length before getting blob pointer.
293- Note that rb_str_new apparently create string with ASCII-8BIT (BINARY) encoding,
294- which is what we want, as blobs are binary
295- */
296295 int len = sqlite3_value_bytes (val );
297- return rb_str_new ((const char * )sqlite3_value_blob (val ), len );
296+ rb_val = rb_str_new ((const char * )sqlite3_value_blob (val ), len );
297+ rb_obj_freeze (rb_val );
298298 break ;
299299 }
300300 case SQLITE_NULL :
301- return Qnil ;
301+ rb_val = Qnil ;
302302 break ;
303303 default :
304- rb_raise (rb_eRuntimeError , "bad type" ); /* FIXME */
304+ rb_raise (rb_eRuntimeError , "bad type" );
305305 }
306+
307+ return rb_val ;
306308}
307309
308310void
Original file line number Diff line number Diff line change @@ -15,6 +15,36 @@ def teardown
1515 @db . close unless @db . closed?
1616 end
1717
18+ def test_custom_function_encoding
19+ @db . execute ( "CREATE TABLE
20+ sourceTable(
21+ sourceData TEXT);" )
22+ @db . execute ( "INSERT INTO sourceTable
23+ VALUES ('abcde');" )
24+
25+ @db . create_function ( "GetCopy" , 1 ) { |func , value |
26+ func . result = value
27+ }
28+
29+ @db . transaction { |t |
30+ t . execute ( "CREATE TABLE
31+ afterTable(
32+ beforeData TEXT,
33+ afterData TEXT);" . squeeze ( " " ) )
34+
35+ t . execute ( "INSERT INTO afterTable
36+ SELECT
37+ sourceData,
38+ GetCopy(sourceData)
39+ FROM sourceTable;" )
40+ }
41+
42+ assert_equal ( 1 , @db . get_first_value ( "SELECT 1
43+ FROM afterTable
44+ WHERE beforeData = afterData
45+ LIMIT 1;" ) )
46+ end
47+
1848 def test_segv
1949 assert_raises { SQLite3 ::Database . new 1 } # rubocop:disable Minitest/UnspecifiedException
2050 end
You can’t perform that action at this time.
0 commit comments