Skip to content

Commit 44ab2aa

Browse files
authored
Merge pull request #480 from sparklemotion/freeze-result
Freeze results that come from the database
2 parents 718b47b + 839c288 commit 44ab2aa

File tree

4 files changed

+27
-4
lines changed

4 files changed

+27
-4
lines changed

ext/sqlite3/statement.c

+4
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,15 @@ step(VALUE self)
162162
if (internal_encoding) {
163163
val = rb_str_export_to_enc(val, internal_encoding);
164164
}
165+
rb_obj_freeze(val);
165166
}
166167
break;
167168
case SQLITE_BLOB: {
168169
val = rb_str_new(
169170
(const char *)sqlite3_column_blob(stmt, i),
170171
(long)sqlite3_column_bytes(stmt, i)
171172
);
173+
rb_obj_freeze(val);
172174
}
173175
break;
174176
case SQLITE_NULL:
@@ -192,6 +194,8 @@ step(VALUE self)
192194
CHECK(sqlite3_db_handle(ctx->st), value);
193195
}
194196

197+
rb_obj_freeze(list);
198+
195199
return list;
196200
}
197201

lib/sqlite3/database.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ def execute sql, bind_vars = [], *args, &block
210210
yield row
211211
end
212212
else
213-
stmt.to_a
213+
stmt.to_a.freeze
214214
end
215215
end
216216
end

test/test_encoding.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def test_blob_is_binary
9090

9191
string = @db.execute("select data from foo").first.first
9292
assert_equal Encoding.find("ASCII-8BIT"), string.encoding
93-
assert_equal str, string.force_encoding("UTF-8")
93+
assert_equal str, string.dup.force_encoding("UTF-8")
9494
end
9595

9696
def test_blob_is_ascii8bit
@@ -103,7 +103,7 @@ def test_blob_is_ascii8bit
103103

104104
string = @db.execute("select data from foo").first.first
105105
assert_equal Encoding.find("ASCII-8BIT"), string.encoding
106-
assert_equal str, string.force_encoding("UTF-8")
106+
assert_equal str, string.dup.force_encoding("UTF-8")
107107
end
108108

109109
def test_blob_with_eucjp
@@ -116,7 +116,7 @@ def test_blob_with_eucjp
116116

117117
string = @db.execute("select data from foo").first.first
118118
assert_equal Encoding.find("ASCII-8BIT"), string.encoding
119-
assert_equal str, string.force_encoding("EUC-JP")
119+
assert_equal str, string.dup.force_encoding("EUC-JP")
120120
end
121121

122122
def test_db_with_eucjp

test/test_statement.rb

+19
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,25 @@ def teardown
1212
@db.close
1313
end
1414

15+
def test_rows_should_be_frozen
16+
@db.execute 'CREATE TABLE "things" ("float" float, "int" int, "text" blob, "string" string, "nil" string)'
17+
stmt = @db.prepare "INSERT INTO things (float, int, text, string, nil) VALUES (?, ?, ?, ?, ?)"
18+
stmt.execute(1.2, 2, "blob", "string", nil)
19+
stmt.close
20+
21+
rows = @db.execute "SELECT float, int, text, string, nil FROM things"
22+
assert_predicate rows, :frozen?
23+
assert_equal 1, rows.length
24+
row = rows[0]
25+
assert_predicate row, :frozen?
26+
row.each { |item| assert_predicate item, :frozen? }
27+
28+
if defined?(Ractor)
29+
assert Ractor.shareable?(rows)
30+
assert Ractor.shareable?(row)
31+
end
32+
end
33+
1534
def test_double_close_does_not_segv
1635
@db.execute 'CREATE TABLE "things" ("number" float NOT NULL)'
1736

0 commit comments

Comments
 (0)