Rules

Eighteen rules, none of them about formatting

A rule earns its place by knowing something the query text does not say, or by being about damage rather than tidiness. Style filler is a formatter's job, and the fastest way to get the whole thing switched off. This page is rendered from packages/gripes — the catalogue, the severities and the wording below are the ones the app runs, not a copy of them.

delete.no-where

Delete with no where clause. That is the table, not the row.

blockerstatement · all engines

grant.default-privileges-untrusted

Default privileges grant every new {objects} to {role}. Nothing yet exists.

blockeraccess · postgres

grant.definer-public-reach

Security definer, and {role} can call it. It runs as {owner}, not them.

blockeraccess · postgres

grant.public-execute

PUBLIC can execute {routine}, so {role} can call it. That is the default.

blockeraccess · postgres

grant.untrusted-write

{role} can {privileges} {relation}. Anonymous callers, writing.

blockeraccess · postgres

join.no-condition

This join has no condition. I'll allow it. I won't forget it.

blockerstatement · all engines

routine.definer-no-search-path

Security definer, no search_path. Anyone who can add a schema owns this.

blockerobject · all engines

update.no-where

Update with no where clause. Every row gets this, not just yours.

blockerstatement · all engines

column.nullable-inequality

{column} can be null, and null is not <> anything. Those rows vanish here.

warningstatement + schema · all engines

grant.rls-no-policy

RLS on {relation}, zero policies. Every row is denied, silently.

warningaccess · postgres

grant.untrusted-read-no-rls

{role} reads every row of {relation}. Row-level security is off.

warningaccess · postgres

grant.view-owner-bypass

{view} is not security_invoker. {role} reads {relation} as {owner}.

warningaccess · postgres

index.not-concurrent

No concurrently. Writes to this table queue up until the index is built.

warningstatement · postgres

subquery.not-in

not in against a subquery. One null in there and you get zero rows, silently.

warningstatement · all engines

table.no-primary-key

No primary key on {table}. Every row is indistinguishable from its twin.

warningobject · all engines

view.select-star

The star in this view is expanded once, at creation. New columns never appear.

warningstatement · all engines

index.duplicate

{index} is already covered by {covering}. It costs writes and buys nothing.

styleobject · all engines

routine.volatile-but-readonly

{routine} only reads, yet claims volatile. The planner takes you at your word.

styleobject · all engines

Each line is the finding at warning, the default. The same finding is re-worded at four levels — see gripe levels. Every one of them is dismissable, and a new one is a file, an entry, four strings and three fixtures. The ones that are written down and not built are on the roadmap.