This is an automated email from the ASF dual-hosted git repository.
lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git
The following commit(s) were added to refs/heads/main by this push:
new 5ead7bb42 fix(c/driver/sqlite): don't rely on double-quoted strings
feature (#2555)
5ead7bb42 is described below
commit 5ead7bb42a65187cede638ed800ddb9ea56f6df9
Author: David Li <[email protected]>
AuthorDate: Mon Feb 24 22:27:44 2025 -0500
fix(c/driver/sqlite): don't rely on double-quoted strings feature (#2555)
A recent update to the conda-forge feedstock disabled double-quoted
strings, which we were accidentally relying on.
Ref:
https://github.com/conda-forge/sqlite-feedstock/commit/302e685b984ea3a36a333a453e75b547007d0f88
Fixes #2554.
---
c/driver/sqlite/sqlite.cc | 4 ++--
c/driver/sqlite/sqlite_test.cc | 20 +++++++++++---------
python/adbc_driver_manager/tests/test_dbapi.py | 18 +++++++++---------
3 files changed, 22 insertions(+), 20 deletions(-)
diff --git a/c/driver/sqlite/sqlite.cc b/c/driver/sqlite/sqlite.cc
index 6348b5ce3..543428963 100644
--- a/c/driver/sqlite/sqlite.cc
+++ b/c/driver/sqlite/sqlite.cc
@@ -312,7 +312,7 @@ struct SqliteGetObjectsHelper : public
driver::GetObjectsHelper {
// XXX: because we're saving the SqliteQuery, we also need to save the
string builder
columns_query.Reset();
columns_query.Append(
- R"(SELECT cid, name, type, "notnull", dflt_value FROM
pragma_table_info("%w" , "%w") WHERE NAME LIKE ?)",
+ R"(SELECT cid, name, type, 'notnull', dflt_value FROM
pragma_table_info(%Q, %Q) WHERE NAME LIKE ?)",
table.data(), catalog.data());
UNWRAP_RESULT(auto query, columns_query.GetString());
assert(!query.empty());
@@ -343,7 +343,7 @@ struct SqliteGetObjectsHelper : public
driver::GetObjectsHelper {
{
SqliteStringBuilder builder;
builder.Append(
- R"(SELECT name FROM pragma_table_info("%w" , "%w") WHERE pk > 0
ORDER BY pk ASC)",
+ R"(SELECT name FROM pragma_table_info(%Q, %Q) WHERE pk > 0 ORDER BY
pk ASC)",
table.data(), catalog.data());
UNWRAP_RESULT(auto pk_query, builder.GetString());
std::vector<std::string> pk;
diff --git a/c/driver/sqlite/sqlite_test.cc b/c/driver/sqlite/sqlite_test.cc
index 8ceb747ac..6f47b8812 100644
--- a/c/driver/sqlite/sqlite_test.cc
+++ b/c/driver/sqlite/sqlite_test.cc
@@ -443,8 +443,10 @@ class SqliteReaderTest : public ::testing::Test {
}
void Exec(const std::string& query) {
- ASSERT_EQ(SQLITE_OK, sqlite3_prepare_v2(db, query.c_str(), query.size(),
&stmt,
- /*pzTail=*/nullptr));
+ SCOPED_TRACE(query);
+ int rc = sqlite3_prepare_v2(db, query.c_str(), query.size(), &stmt,
+ /*pzTail=*/nullptr);
+ ASSERT_EQ(SQLITE_OK, rc) << "Failed to prepare query: " <<
sqlite3_errmsg(db);
ASSERT_EQ(SQLITE_DONE, sqlite3_step(stmt));
sqlite3_finalize(stmt);
stmt = nullptr;
@@ -526,7 +528,7 @@ TEST_F(SqliteReaderTest, IntsFloatsNulls) {
TEST_F(SqliteReaderTest, IntsNullsStrsNullsInts) {
adbc_validation::StreamReader reader;
ASSERT_NO_FATAL_FAILURE(ExecSelect(
- R"((NULL), (1), (NULL), (-1), ("foo"), (NULL), (""), (24))", kInferRows,
&reader));
+ R"((NULL), (1), (NULL), (-1), ('foo'), (NULL), (''), (24))", kInferRows,
&reader));
ASSERT_EQ(NANOARROW_TYPE_STRING, reader.fields[0].type);
ASSERT_NO_FATAL_FAILURE(reader.Next());
@@ -552,7 +554,7 @@ TEST_F(SqliteReaderTest, IntExtremes) {
TEST_F(SqliteReaderTest, IntExtremesStrs) {
adbc_validation::StreamReader reader;
ASSERT_NO_FATAL_FAILURE(ExecSelect(
- R"((NULL), (9223372036854775807), (-9223372036854775808), (""),
(9223372036854775807), (-9223372036854775808))",
+ R"((NULL), (9223372036854775807), (-9223372036854775808), (''),
(9223372036854775807), (-9223372036854775808))",
kInferRows, &reader));
ASSERT_EQ(NANOARROW_TYPE_STRING, reader.fields[0].type);
@@ -587,7 +589,7 @@ TEST_F(SqliteReaderTest, FloatExtremes) {
TEST_F(SqliteReaderTest, IntsFloatsStrs) {
adbc_validation::StreamReader reader;
ASSERT_NO_FATAL_FAILURE(
- ExecSelect(R"((1), (1.0), (""), (9e999), (-9e999))", kInferRows,
&reader));
+ ExecSelect(R"((1), (1.0), (''), (9e999), (-9e999))", kInferRows,
&reader));
ASSERT_EQ(NANOARROW_TYPE_STRING, reader.fields[0].type);
ASSERT_NO_FATAL_FAILURE(reader.Next());
@@ -629,7 +631,7 @@ TEST_F(SqliteReaderTest, InferIntRejectFloat) {
TEST_F(SqliteReaderTest, InferIntRejectStr) {
adbc_validation::StreamReader reader;
ASSERT_NO_FATAL_FAILURE(
- ExecSelect(R"((1), (NULL), (""), (NULL))", /*infer_rows=*/2, &reader));
+ ExecSelect(R"((1), (NULL), (''), (NULL))", /*infer_rows=*/2, &reader));
ASSERT_EQ(NANOARROW_TYPE_INT64, reader.fields[0].type);
ASSERT_NO_FATAL_FAILURE(reader.Next());
ASSERT_NO_FATAL_FAILURE(
@@ -678,7 +680,7 @@ TEST_F(SqliteReaderTest, InferFloatReadIntFloat) {
TEST_F(SqliteReaderTest, InferFloatRejectStr) {
adbc_validation::StreamReader reader;
- ASSERT_NO_FATAL_FAILURE(ExecSelect(R"((1E0), (NULL), (2E0), (3), (""),
(NULL))",
+ ASSERT_NO_FATAL_FAILURE(ExecSelect(R"((1E0), (NULL), (2E0), (3), (''),
(NULL))",
/*infer_rows=*/2, &reader));
ASSERT_EQ(NANOARROW_TYPE_DOUBLE, reader.fields[0].type);
ASSERT_NO_FATAL_FAILURE(reader.Next());
@@ -716,7 +718,7 @@ TEST_F(SqliteReaderTest, InferFloatRejectBlob) {
TEST_F(SqliteReaderTest, InferStrReadAll) {
adbc_validation::StreamReader reader;
- ASSERT_NO_FATAL_FAILURE(ExecSelect(R"((""), (NULL), (2), (3E0), ("foo"),
(NULL))",
+ ASSERT_NO_FATAL_FAILURE(ExecSelect(R"((''), (NULL), (2), (3E0), ('foo'),
(NULL))",
/*infer_rows=*/2, &reader));
ASSERT_EQ(NANOARROW_TYPE_STRING, reader.fields[0].type);
ASSERT_NO_FATAL_FAILURE(reader.Next());
@@ -799,7 +801,7 @@ TEST_F(SqliteReaderTest, InferTypedParams) {
ASSERT_NO_FATAL_FAILURE(Exec("CREATE TABLE foo (idx, value)"));
ASSERT_NO_FATAL_FAILURE(
- Exec(R"(INSERT INTO foo VALUES (0, "foo"), (1, NULL), (2, 4), (3,
1E2))"));
+ Exec(R"(INSERT INTO foo VALUES (0, 'foo'), (1, NULL), (2, 4), (3,
1E2))"));
ASSERT_THAT(adbc_validation::MakeSchema(&schema.value, {{"",
NANOARROW_TYPE_INT64}}),
IsOkErrno());
diff --git a/python/adbc_driver_manager/tests/test_dbapi.py
b/python/adbc_driver_manager/tests/test_dbapi.py
index fbc785183..2db92388f 100644
--- a/python/adbc_driver_manager/tests/test_dbapi.py
+++ b/python/adbc_driver_manager/tests/test_dbapi.py
@@ -201,10 +201,10 @@ def test_partitions(sqlite):
@pytest.mark.sqlite
def test_query_fetch_py(sqlite):
with sqlite.cursor() as cur:
- cur.execute('SELECT 1, "foo", 2.0')
+ cur.execute("SELECT 1, 'foo' AS foo, 2.0")
assert cur.description == [
("1", dbapi.NUMBER, None, None, None, None, None),
- ('"foo"', dbapi.STRING, None, None, None, None, None),
+ ("foo", dbapi.STRING, None, None, None, None, None),
("2.0", dbapi.NUMBER, None, None, None, None, None),
]
assert cur.rownumber == 0
@@ -212,26 +212,26 @@ def test_query_fetch_py(sqlite):
assert cur.rownumber == 1
assert cur.fetchone() is None
- cur.execute('SELECT 1, "foo", 2.0')
+ cur.execute("SELECT 1, 'foo', 2.0")
assert cur.fetchmany() == [(1, "foo", 2.0)]
assert cur.fetchmany() == []
- cur.execute('SELECT 1, "foo", 2.0')
+ cur.execute("SELECT 1, 'foo', 2.0")
assert cur.fetchall() == [(1, "foo", 2.0)]
assert cur.fetchall() == []
- cur.execute('SELECT 1, "foo", 2.0')
+ cur.execute("SELECT 1, 'foo', 2.0")
assert list(cur) == [(1, "foo", 2.0)]
@pytest.mark.sqlite
def test_query_fetch_arrow(sqlite):
with sqlite.cursor() as cur:
- cur.execute('SELECT 1, "foo", 2.0')
+ cur.execute("SELECT 1, 'foo' AS foo, 2.0")
assert cur.fetch_arrow_table() == pyarrow.table(
{
"1": [1],
- '"foo"': ["foo"],
+ "foo": ["foo"],
"2.0": [2.0],
}
)
@@ -240,13 +240,13 @@ def test_query_fetch_arrow(sqlite):
@pytest.mark.sqlite
def test_query_fetch_df(sqlite):
with sqlite.cursor() as cur:
- cur.execute('SELECT 1, "foo", 2.0')
+ cur.execute("SELECT 1, 'foo' AS foo, 2.0")
assert_frame_equal(
cur.fetch_df(),
pandas.DataFrame(
{
"1": [1],
- '"foo"': ["foo"],
+ "foo": ["foo"],
"2.0": [2.0],
}
),