# Code quality
> The editor checks every statement as you type: syntax, unknown columns, aggregation mistakes, and the BigQuery cost traps a dry run won't tell you about. Problems get a squiggle, a hover explanation, and usually a one-keystroke fix.
Source: https://docs.querylab.io/writing-sql/code-quality/
**Query 1**
```sql
SELECT «warn:*»
FROM `ace-analytics.warehouse.fact_mot_test`
WHERE completed_date >= '2024-01-01'
LIMIT 10
```
SELECT * from large table 'ace-analytics.warehouse.fact_mot_test' (506.7GB).
Consider selecting specific columns to reduce costs.{" "}
sql-best-practices(select-star-large-table)
View Problem (Alt+F8) · Quick Fix… (Ctrl+.)
## Reading a squiggle
| Underline | Severity | Means |
| --------- | -------- | --------------------------------------------------------------- |
| Red | Error | BigQuery will reject this |
| Orange | Warning | Runs, but costs more or does something you probably didn't mean |
| Blue | Info | Worth knowing; no action required |
| None | Hint | Shown only in the quick-fix menu when the cursor is on the code |
Hover an underline for the message; every message ends with the rule id in parentheses. `⌥ F8` (`Alt F8` on Windows and Linux) jumps to the next problem. Hint-level rules draw nothing; the lightbulb in the gutter is the only sign of them.
Some problems are found as you type; others come back from BigQuery's dry run when you pause. Dry-run errors, like a missing required partition filter, also land in the status bar:
**Fix with AI** hands the error and the query to Prism AI; **Explain** asks it to explain the message. A syntax error shows the dry-run wording, `Syntax error: Unexpected identifier "SELEC" at [1:1]`, with _No quick fixes available_.
## Quick fixes
Put the cursor on the underlined code and press `⌘ .` (`Ctrl .` on Windows and Linux), or click the lightbulb. `Enter` applies the highlighted fix.
**Quick Fix**
```sql
WITH tests AS (
SELECT make, test_result
FROM `ace-analytics.warehouse.fact_mot_test`
),
vehicles AS (
SELECT make, «err:model»
FROM `ace-analytics.warehouse.dim_vehicle`
)
SELECT make, test_result
FROM tests
JOIN vehicles USING (make)
```
The menu always ends with two entries: **Disable '…' rule**, which switches that rule off in settings (not offered for syntax errors or rules your organization locks), and **Fix with Prism AI**, which sends the problems and their suggested fixes to the agent.
Fixes you'll meet most:
| Rule | Fix inserted |
| --------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| SELECT \* on Large Table | Expand SELECT \* to explicit columns |
| Missing Partition Filter / Missing Cluster Filter | Add `column` filter: a WHERE condition on the partition or cluster column |
| Missing LIMIT on Large Table | Add LIMIT 1000 (or `\|> LIMIT 1000` in pipe syntax) |
| Wildcard Table Scan Without Filter | Add `_TABLE_SUFFIX` filter: today only, last 7 days, last 30 days |
| Large Table Scan | Add TABLESAMPLE SYSTEM (1 PERCENT); see [TABLESAMPLE](https://docs.querylab.io/writing-sql/tablesample/) |
| Undefined Column / Table Alias / CTE | Did you mean '…'? (nearest name, STRUCT fields marked) |
| Ambiguous Column Reference | Qualify with 'alias.column' |
| Non-Aggregated Column | Add 'column' to GROUP BY · Use GROUP BY ALL |
| Aggregate in WHERE | Change WHERE to HAVING · Move aggregate condition to existing HAVING |
| NULL Comparison with Equals | Replace with IS NULL / IS DISTINCT FROM |
| COUNT(DISTINCT) Performance | Replace with APPROX_COUNT_DISTINCT |
| Cross Join Detected | Use explicit CROSS JOIN · Move condition to ON clause |
| Unused CTE | Remove unused CTE 'name' |
| Suggest QUALIFY / LIKE ANY / GROUP BY ALL / UNION BY NAME | Convert to QUALIFY clause · Replace with LIKE ANY · Use GROUP BY ALL · Use UNION BY NAME |
The same menu also lists refactorings that don't need a warning: expand `t.*`, extract a subquery to a CTE, inline a CTE, convert CROSS JOIN to INNER JOIN, flip JOIN sides, CASE → COALESCE / NULLIF, convert pipe syntax to standard SQL. Keyword casing and backtick cleanup live on the editor toolbar instead.
### Suggest QUALIFY
The `subquery + WHERE rn = 1` idiom has a shorter form. Offered for `ROW_NUMBER()`, `RANK()` and `DENSE_RANK()`:
```sql
SELECT * FROM (
SELECT vehicle_id, test_result,
ROW_NUMBER() OVER (PARTITION BY vehicle_id ORDER BY completed_date DESC) AS rn
FROM `ace-analytics.warehouse.fact_mot_test`
)
WHERE rn = 1
```
```sql
SELECT vehicle_id, test_result
FROM `ace-analytics.warehouse.fact_mot_test`
QUALIFY ROW_NUMBER() OVER (PARTITION BY vehicle_id ORDER BY completed_date DESC) = 1
```
### Suggest LIKE ANY
```sql
WHERE make LIKE 'FORD%' OR make LIKE 'VAUXHALL%' OR make LIKE 'MINI%'
```
becomes `WHERE make LIKE ANY ('FORD%', 'VAUXHALL%', 'MINI%')`. `NOT LIKE … AND NOT LIKE …` becomes `NOT LIKE ANY`.
## Thresholds and disabling rules
Settings → Code Quality (also listed under [Settings](https://docs.querylab.io/settings/#code-quality)). Two sections: **Cost Optimization** holds the thresholds, **Diagnostic Rules** the on/off switch for every rule.