Skip to content
This repository was archived by the owner on Jul 11, 2021. It is now read-only.

Commit e3b2134

Browse files
author
Simone Mosciatti
committed
fix bug when different returns types are product for the same column, which is possible using the JSON1 module
1 parent 5824666 commit e3b2134

File tree

3 files changed

+38
-22
lines changed

3 files changed

+38
-22
lines changed

src/community_statement.rs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ use std::ffi::{CString, CStr};
66
use sqlite::ffi;
77

88
use sqlite::StatementTrait;
9-
use sqlite::{SQLite3Error, Cursor, EntityType, RawConnection,
10-
SQLiteOK};
9+
use sqlite::{SQLite3Error, Cursor, RawConnection, SQLiteOK};
1110
use sqlite::generate_sqlite3_error;
1211

1312
#[cfg(feature = "pro")]
@@ -163,23 +162,9 @@ impl<'a> StatementTrait<'a> for Statement<'a> {
163162
unsafe {
164163
ffi::sqlite3_column_count(self.stmt)
165164
} as i32;
166-
let mut types: Vec<EntityType> = Vec::new();
167-
for i in 0..n_columns {
168-
types.push(match unsafe {
169-
ffi::sqlite3_column_type(self.stmt, i)
170-
} {
171-
ffi::SQLITE_INTEGER => EntityType::Integer,
172-
ffi::SQLITE_FLOAT => EntityType::Float,
173-
ffi::SQLITE_TEXT => EntityType::Text,
174-
ffi::SQLITE_BLOB => EntityType::Blob,
175-
ffi::SQLITE_NULL => EntityType::Null,
176-
_ => EntityType::Null,
177-
})
178-
}
179165
Ok(Cursor::RowsCursor {
180166
stmt: self,
181167
num_columns: n_columns,
182-
types: types,
183168
previous_status: ffi::SQLITE_ROW,
184169
to_replicate: self.to_replicate(),
185170
modified_rows: 0,

src/sqlite.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,6 @@ pub enum Cursor<'a> {
180180
},
181181
RowsCursor {
182182
num_columns: i32,
183-
types: Vec<EntityType>,
184183
previous_status: i32,
185184
stmt: &'a Statement<'a>,
186185
modified_rows: i32,
@@ -221,6 +220,20 @@ impl<'a> FromIterator<Cursor<'a>> for Cursor<'a> {
221220
}
222221
}
223222

223+
fn get_entity_type(stmt: *mut ffi::sqlite3_stmt,
224+
i: i32)
225+
-> EntityType {
226+
let entity_type = unsafe { ffi::sqlite3_column_type(stmt, i) };
227+
match entity_type {
228+
ffi::SQLITE_INTEGER => EntityType::Integer,
229+
ffi::SQLITE_FLOAT => EntityType::Float,
230+
ffi::SQLITE_TEXT => EntityType::Text,
231+
ffi::SQLITE_BLOB => EntityType::Blob,
232+
ffi::SQLITE_NULL => EntityType::Null,
233+
_ => EntityType::Null,
234+
235+
}
236+
}
224237

225238
impl<'a> Iterator for Cursor<'a> {
226239
type Item = Row;
@@ -243,42 +256,48 @@ impl<'a> Iterator for Cursor<'a> {
243256
Cursor::RowsCursor {
244257
ref stmt,
245258
num_columns,
246-
ref types,
247259
ref mut previous_status,
248260
..
249261
} => {
250262
match *previous_status {
251263
ffi::SQLITE_ROW => {
252264
let mut result = vec![];
253265
for i in 0..num_columns {
254-
let entity_value = match types[i as
255-
usize] {
266+
let entity_value = match get_entity_type(stmt.get_raw_stmt(), i) {
256267
EntityType::Integer => {
257268
let value =
258269
unsafe {
259270
ffi::sqlite3_column_int(stmt.get_raw_stmt(), i)
260271
};
272+
debug!("Got integer: {:?}",
273+
value);
261274
Entity::Integer { int: value }
262275
}
263276
EntityType::Float => {
264277
let value = unsafe {
265278
ffi::sqlite3_column_double(stmt.get_raw_stmt(), i)
266279
};
280+
debug!("Got float: {:?}", value);
267281
Entity::Float { float: value }
268282
}
269283
EntityType::Text => {
270284
let value = unsafe {
271285
CStr::from_ptr(ffi::sqlite3_column_text(stmt.get_raw_stmt(), i) as *const i8).to_string_lossy().into_owned()
272286
};
287+
debug!("Got text: {:?}", value);
273288
Entity::Text { text: value }
274289
}
275290
EntityType::Blob => {
276291
let value = unsafe {
277292
CStr::from_ptr(ffi::sqlite3_column_blob(stmt.get_raw_stmt(), i) as *const i8).to_string_lossy().into_owned()
278293
};
294+
debug!("Got blob: {:?}", value);
279295
Entity::Blob { blob: value }
280296
}
281-
EntityType::Null => Entity::Null {},
297+
EntityType::Null => {
298+
debug!("Got null");
299+
Entity::Null {}
300+
}
282301
};
283302
result.push(entity_value);
284303
}

test/correctness/test.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,19 @@ def test_multi_insert_same_statement(self):
216216
COMMIT;""")
217217
self.assertEquals(done, ["DONE", 6L])
218218

219-
219+
class TestJSON(TestRediSQLWithExec):
220+
def test_multiple_insert_on_different_types(self):
221+
with DB(self.client, "H"):
222+
with Table(self.client, "j1", "(A text, B int)", key = "H"):
223+
done = self.exec_naked("REDISQL.EXEC", "H", """BEGIN;
224+
INSERT INTO j1 VALUES ('{\"foo\" : \"bar\"}', 1);
225+
INSERT INTO j1 VALUES ('{\"foo\" : 3}', 2);
226+
INSERT INTO j1 VALUES ('{\"foo\" : [1, 2, 3]}', 3);
227+
INSERT INTO j1 VALUES ('{\"foo\" : {\"baz\" : [1, 2, 3]}}', 4);
228+
COMMIT;""")
229+
self.assertEquals(done, ["DONE", 4L])
230+
result = self.exec_naked("REDISQL.EXEC", "H", "SELECT json_extract(A, '$.foo') FROM j1 ORDER BY B;")
231+
self.assertEquals(result, [["bar"], [3], ["[1,2,3]"], ['{"baz":[1,2,3]}']])
220232

221233

222234
class TestStatements(TestRediSQLWithExec):

0 commit comments

Comments
 (0)