Read-only enforcement

How trend guarantees it never writes to your warehouse.

trend is read-only by construction. The guarantee holds at three independent layers — even if two fail, the third would still stop a write.

Layer 1 — Customer database role

We recommend creating a dedicated SELECT-only role for the trend connection. See Postgres, MySQL, Snowflake, or BigQuery for the SQL or gcloud commands. For Postgres/MySQL/Snowflake we probe the credentials on save: if the role can write, you see an amber warning instead of the green Read-only verified badge. For BigQuery, read-only is enforced by IAM (the dataViewer role has no write scope), so a passing test always shows the green badge.

Layer 2 — SQL validator

Every query passes through our SQL validator before it reaches a warehouse. The validator rejects:

  • Any leading keyword that isn’t SELECT or WITH (INSERT, UPDATE, DELETE, DROP, ALTER, CREATE, TRUNCATE, GRANT, REVOKE, CALL, EXEC, COPY, PUT, GET, USE, SET, LOCK, REPLACE, RENAME, COMMENT, ANALYZE, VACUUM, CLUSTER, REFRESH, REINDEX, LOAD, UNLOAD, BACKUP, RESTORE).
  • Multi-statement input (any ; followed by non-blank text).
  • CTE-wrapped writes (WITH ... AS (INSERT ...)).
  • Oversized SQL (>50KB).

It also injects a row cap (LIMIT 10000) if you don’t set one explicitly.

Layer 3 — Database session flag

Every connection trend opens sets the most restrictive session flag the engine supports:

  • Postgres: SET default_transaction_read_only = on + SET statement_timeout = 55000
  • MySQL: SET SESSION TRANSACTION READ ONLY + SET SESSION MAX_EXECUTION_TIME = 55000
  • Snowflake: ALTER SESSION SET STATEMENT_TIMEOUT_IN_SECONDS = 55
  • BigQuery: no session-level flag exists; the SA's IAM role is what enforces read-only. Job timeout is set to 55s to match the others.

Even if a write somehow slipped past the validator, the warehouse itself would refuse it.