-
-
Notifications
You must be signed in to change notification settings - Fork 697
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"Query parameters" form shows wrong input fields if query contains "03:31" style times #1421
Comments
Urgh, yeah I've seen this one before. Fixing it pretty much requires writing a full SQLite SQL syntax parser in Python, which is frustratingly complicated for solving this issue! You can work around this for a canned query by using the optional |
Marking this blocked because I don't have a way around the needing-a-SQLite-SQL-parser problem at the moment. |
I may have a way to work around this, using select * from facetable
where state = :state
and on_earth = :on_earth
and neighborhood not like '00:04' Datasette currently gets confused and shows three form fields: https://latest.datasette.io/fixtures?sql=select+*+from+facetable%0D%0Awhere+state+%3D+%3Astate%0D%0Aand+on_earth+%3D+%3Aon_earth%0D%0Aand+neighborhood+not+like+%2700%3A04%27&state=&on_earth=&04= But... if I run
Could it be as simple as pulling out those |
I hoped this would work: with foo as (
explain select * from facetable
where state = :state
and on_earth = :on_earth
and neighborhood not like '00:04'
)
select p4 from foo where opcode = 'Variable' But sadly it returns an error:
|
Relevant code: datasette/datasette/views/database.py Lines 225 to 231 in ad90a72
|
This may not work:
The I could try using the regex to pull out candidates and passing |
I think this works! _re_named_parameter = re.compile(":([a-zA-Z0-9_]+)")
async def derive_named_parameters(db, sql):
explain = 'explain {}'.format(sql.strip().rstrip(";"))
possible_params = _re_named_parameter.findall(sql)
try:
results = await db.execute(explain, {p: None for p in possible_params})
return [row["p4"].lstrip(":") for row in results if row["opcode"] == "Variable"]
except sqlite3.DatabaseError:
return [] |
One catch with this approach: if the SQL query is invalid, the parameters will not be extracted and shown as form fields. Maybe that's completely fine? Why display a form if it's going to break when the user actually runs the query? But it does bother me. I worry that someone who is still iterating on and editing their query before actually starting to use it might find the behaviour confusing. So maybe if the query raises an exception it could fall back on the regular expression results? |
Fixed! Fantastic, this one has been bothering me for years. |
SQLite carries a warning about using
I think that's OK here, because of the regular expression fallback. If the format changes in the future in a way that breaks the query the error should be caught and the regex-captured parameters should be returned instead. Hmmm... actually that's not entirely true: datasette/datasette/utils/__init__.py Lines 1084 to 1091 in b1fed48
If the format changes such that the same columns are returned but the I'm going to take that risk for the moment, but I'll actively watch out for problems in the future. If this does turn out to be bad I can always go back to the pure regular expression mechanism. |
Amusing edge-case: if you run this against a |
I suspect this has problem in sqlite 3.46.0(not works in datasette 0.64.6, and also not works on 1.0a13), after I reinstall sqlite 3.45.3, it works as normal. the error happens in 3.46.0.
|
Datasette version
0.58.1
.I'm guessing this is a bug in the code that looks for
:param
-style query parameters..The text was updated successfully, but these errors were encountered: