SQL Reconstructionο
Adjusting a LIMIT
ο
This adjustment only takes place if ConstraintValidator.max_limit
in
your validator subclass returns an integer.
If a query has no LIMIT
clause, one will be added. For example:
SELECT p.date
FROM purchases p
JOIN users u ON u.id=p.user_id
WHERE u.id=:user_id
Will become:
SELECT p.date
FROM purchases p
JOIN users u ON u.id=p.user_id
WHERE u.id=:user_id
LIMIT 100
Similarly, if an existing LIMIT
is too high, it will be lowered to the maximum
returned by your validator.
Disallowed column removalο
This adjustment takes place if a column appears in the result returned from
SQLConstraintValidator.select_column_allowed
The prompt envelope (and consequently,
the LLM) isnβt told what columns are allowlisted. This means that an LLM may produce a
SELECT
query that selects columns that are not allowed. For example, most of the
time, you probably donβt want your users to see a id-like column:
SELECT p.id, u.id, p.date
FROM purchases p
JOIN users u ON u.id=p.user_id
WHERE u.id=:user_id
In a soft-validation pass, HeimdaLLM will test all selected columns and remove any disallowed columns by modifying the parse tree directly, so that the resulting query will pass validation:
SELECT p.date
FROM purchases p
JOIN users u ON u.id=p.user_id
WHERE u.id=:user_id
Note
Only selected columns are examined for reconstruction in this soft-validation pass.
Other clauses of the query where columns are referenced, like the WHERE
clause,
are left alone until the hard-validation pass, where they could cause a failure.
Fully-qualifying columnsο
Despite efforts to convince the LLM to fully-qualify columns, it may still produce queries that use columns that are not prefixed by a table name or table alias:
SELECT u.email
FROM users u
WHERE id=:user_id
The LLM typically produces these queries when the column is unambiguous because a single table is being selected. In these cases, the reconstructor will fully-qualify the column based on the name of the selected table, so that the above query becomes:
SELECT u.email
FROM users u
WHERE users.id=:user_id