mirror of
https://github.com/simonw/datasette.git
synced 2026-10-18 15:26:57 +02:00
Exact filters match integer columns without type affinity, closes #2073
This commit is contained in:
parent
c435a80030
commit
5fbc809417
2 changed files with 41 additions and 1 deletions
|
|
@ -259,6 +259,24 @@ class TemplatedFilter(Filter):
|
|||
return template.format(c=column, v=value)
|
||||
|
||||
|
||||
class ExactFilter(TemplatedFilter):
|
||||
def where_clause(self, table, column, value, param_counter):
|
||||
sql, param = super().where_clause(table, column, value, param_counter)
|
||||
try:
|
||||
as_int = int(value)
|
||||
except ValueError:
|
||||
return sql, param
|
||||
if str(as_int) != value:
|
||||
return sql, param
|
||||
# Columns without type affinity (such as expressions in a view) do not
|
||||
# convert "1" to 1 for the comparison, so match both representations
|
||||
quoted = _quote_sqlite_identifier(column)
|
||||
return (
|
||||
f"{quoted} in (:p{param_counter}, :p{param_counter + 1})",
|
||||
[value, as_int],
|
||||
)
|
||||
|
||||
|
||||
def _quote_sqlite_identifier(identifier):
|
||||
# Preserve the historic always-quoted SQL generated by TemplatedFilter.
|
||||
escaped = escape_sqlite(identifier)
|
||||
|
|
@ -305,7 +323,7 @@ class Filters:
|
|||
_filters = (
|
||||
[
|
||||
# key, display, sql_template, human_template, format=, numeric=, no_argument=
|
||||
TemplatedFilter(
|
||||
ExactFilter(
|
||||
"exact",
|
||||
"=",
|
||||
"{c} = :{p}",
|
||||
|
|
|
|||
|
|
@ -829,3 +829,25 @@ async def test_facet_only_considers_first_x_rows():
|
|||
assert data2["suggested_facets"] == []
|
||||
finally:
|
||||
Facet.suggest_consider = original_suggest_consider
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_facet_selection_against_integer_column_in_view():
|
||||
# https://github.com/simonw/datasette/issues/2073
|
||||
# View columns computed from expressions have no column affinity, so
|
||||
# comparing them to the string "1" from the querystring does not match 1
|
||||
ds = Datasette()
|
||||
db = ds.add_memory_database("test_facet_integer_view")
|
||||
await db.execute_write("create table t (id integer primary key, n integer)")
|
||||
await db.execute_write_many(
|
||||
"insert into t (n) values (:n)", [{"n": 1}, {"n": 1}, {"n": 2}]
|
||||
)
|
||||
await db.execute_write("create view v as select id, n + 0 as n from t")
|
||||
response = await ds.client.get(
|
||||
"/test_facet_integer_view/v.json?_facet=n&n=1&_extra=facet_results"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert [row["id"] for row in data["rows"]] == [1, 2]
|
||||
results = data["facet_results"]["results"]["n"]["results"]
|
||||
assert [(r["value"], r["count"], r["selected"]) for r in results] == [(1, 2, True)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue