Untyped queries¶
Some queries return rows whose type sqlty cannot infer: columns of tables without a schema,
an expression it has no rule for (a function the schema doesn't declare, a bare NULL), and
SELECT statements sqlty cannot parse. One untyped column leaves the whole row untyped. By
default sqlty rewrite leaves them as plain strings, so nothing marks them as untyped:
The UNTYPED sentinel¶
Set untyped = "sentinel" to wrap them as SQL[UNTYPED](...) instead:
pairs = "--sql\nSELECT x, y FROM pairs"
users = "--sql\nSELECT id::INTEGER FROM users"
# rewritten-file: from sqlty import SQL
# rewritten-file: from sqlty import UNTYPED
# rewritten-file: pairs = SQL[UNTYPED]("--sql\nSELECT x, y FROM pairs")
# rewritten-file: users = SQL[tuple[int]]("--sql\nSELECT id::INTEGER FROM users")
untyped-query reports each SQL[UNTYPED]
with what could not be typed: the unknown function or expression, or the untyped
columns. check --statistics counts the partially typed queries the default mode
leaves unwrapped.
UNTYPED is a PEP 661 sentinel, not
Any. mypy, pyright and ty reject using an UNTYPED row as a concrete type,
so code that relies on the row's shape fails type checking until the query is
typed.
Statements without rows¶
Statements that return no rows stay plain strings in both modes: DML without
RETURNING, DDL and transaction control. So does the "--sql SELECT ..."
form, which is a SQL comment.
purge = "--sql\nDELETE FROM users WHERE id = 1"
table = "--sql\nCREATE TABLE users (id INTEGER)"
deleted = "--sql\nDELETE FROM users RETURNING id::INTEGER"
# rewritten: purge = "--sql\nDELETE FROM users WHERE id = 1"
# rewritten: table = "--sql\nCREATE TABLE users (id INTEGER)"
# rewritten: deleted = SQL[tuple[int]]("--sql\nDELETE FROM users RETURNING id::INTEGER")
sqlty check reports nothing for them:
stale-rewrite covers only strings
that rewrite would wrap.
The untyped-query rule¶
sqlty check reports every SQL[UNTYPED] query as
untyped-query (warning by default).
Once casts or a schema make the type known, the message names it:
# error: [untyped-query] "SQL[UNTYPED] has no inferable row type: columns `x`, `y` are untyped; add casts (for example id::INTEGER) or a schema"
pairs = SQL[UNTYPED]("--sql\nSELECT x, y FROM pairs")
# error: [untyped-query] "SQL[UNTYPED] can now be SQL[tuple[int]]; run sqlty check --fix"
users = SQL[UNTYPED]("--sql\nSELECT id::INTEGER FROM users")
sqlty rewrite does not replace an existing wrapper; sqlty check --fix
does. See Editing queries.