Skip to content

Commit e06bf74

Browse files
author
Jim Fulton
authored
fix: in-operator literal binds not handled properly (#285)
1 parent 2cf05a0 commit e06bf74

File tree

5 files changed

+40
-6
lines changed

5 files changed

+40
-6
lines changed

sqlalchemy_bigquery/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ def visit_bindparam(
420420
)
421421

422422
type_ = bindparam.type
423-
if isinstance(type_, NullType):
423+
if literal_binds or isinstance(type_, NullType):
424424
return param
425425

426426
if (

testing/constraints-3.6.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
# e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev",
77
sqlalchemy==1.2.0
88
google-auth==1.25.0
9-
google-cloud-bigquery==2.19.0
9+
google-cloud-bigquery==2.24.1
1010
google-api-core==1.30.0

tests/system/test_sqlalchemy_bigquery.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ def test_record_content_from_raw_queries(engine, bigquery_dataset):
301301

302302

303303
def test_content_from_reflect(engine, table_one_row):
304-
rows = table_one_row.select().execute().fetchall()
304+
rows = table_one_row.select(use_labels=True).execute().fetchall()
305305
assert list(rows[0]) == ONE_ROW_CONTENTS_EXPANDED
306306

307307

@@ -505,21 +505,21 @@ def test_querying_wildcard_tables(engine):
505505
def test_dml(engine, session, table_dml):
506506
# test insert
507507
engine.execute(table_dml.insert(ONE_ROW_CONTENTS_DML))
508-
result = table_dml.select().execute().fetchall()
508+
result = table_dml.select(use_labels=True).execute().fetchall()
509509
assert len(result) == 1
510510

511511
# test update
512512
session.query(table_dml).filter(table_dml.c.string == "test").update(
513513
{"string": "updated_row"}, synchronize_session=False
514514
)
515-
updated_result = table_dml.select().execute().fetchone()
515+
updated_result = table_dml.select(use_labels=True).execute().fetchone()
516516
assert updated_result[table_dml.c.string] == "updated_row"
517517

518518
# test delete
519519
session.query(table_dml).filter(table_dml.c.string == "updated_row").delete(
520520
synchronize_session=False
521521
)
522-
result = table_dml.select().execute().fetchall()
522+
result = table_dml.select(use_labels=True).execute().fetchall()
523523
assert len(result) == 0
524524

525525

tests/unit/test_compliance.py

+16
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,19 @@ def test_group_by_composed(faux_conn):
200200
select([sqlalchemy.func.count(table.c.id), expr]).group_by(expr).order_by(expr)
201201
)
202202
assert_result(faux_conn, stmt, [(1, 3), (1, 5), (1, 7)])
203+
204+
205+
def test_cast_type_decorator(faux_conn, last_query):
206+
# [artial dup of:
207+
# sqlalchemy.testing.suite.test_types.CastTypeDecoratorTest.test_special_type
208+
# That test failes without code that's otherwise not covered by the unit tests.
209+
210+
class StringAsInt(sqlalchemy.TypeDecorator):
211+
impl = sqlalchemy.String(50)
212+
213+
def bind_expression(self, col):
214+
return sqlalchemy.cast(col, String(50))
215+
216+
t = setup_table(faux_conn, "t", Column("x", StringAsInt()))
217+
faux_conn.execute(t.insert(), [{"x": x} for x in [1, 2, 3]])
218+
last_query("INSERT INTO `t` (`x`) VALUES (CAST(%(x:STRING)s AS STRING))", {"x": 3})

tests/unit/test_select.py

+18
Original file line numberDiff line numberDiff line change
@@ -356,3 +356,21 @@ def test_select_notin_param_empty(faux_conn):
356356
else "SELECT (%(param_1:INT64)s NOT IN UNNEST([ ])) AS `anon_1`",
357357
{"param_1": 1},
358358
)
359+
360+
361+
def test_literal_binds_kwarg_with_an_IN_operator_252(faux_conn):
362+
table = setup_table(
363+
faux_conn,
364+
"test",
365+
sqlalchemy.Column("val", sqlalchemy.Integer),
366+
initial_data=[dict(val=i) for i in range(3)],
367+
)
368+
q = sqlalchemy.select([table.c.val]).where(table.c.val.in_([2]))
369+
370+
def nstr(q):
371+
return " ".join(str(q).strip().split())
372+
373+
assert (
374+
nstr(q.compile(faux_conn.engine, compile_kwargs={"literal_binds": True}))
375+
== "SELECT `test`.`val` FROM `test` WHERE `test`.`val` IN (2)"
376+
)

0 commit comments

Comments
 (0)