Skip to content

docs: document audited views and declared IN lists - #561

Draft
puzpuzpuz wants to merge 4 commits into
mainfrom
docs/audited-views
Draft

puzpuzpuz wants to merge 4 commits into
mainfrom
docs/audited-views

Conversation

@puzpuzpuz

@puzpuzpuz puzpuzpuz commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

Documents two features that ship together: audited views (QuestDB Enterprise) and declared value lists for IN (open source). The code is in questdb/questdb#7602 and questdb/questdb-enterprise#1203, neither merged yet, so this stays a draft until they are.

What goes where

  • security/audited-views.md (new, after RBAC in the sidebar): creating an audited view, the AUDITED modifier, the sys.view_audit schema and the params JSON per type, querying and retaining the trail, what counts as a read, audited views read through other audited views, the bounded queue and when it drops rows, permissions, replicas and readonly=true, and limitations
  • configuration/audited-views.md (new): view.audit.queue.capacity and view.audit.storage.policy
  • query/sql/declare.md: AUDITED in the syntax, and a "Value lists" section with the misuse errors. It removes the old "bracket lists are not allowed" limitation, which the OSS PR lifts
  • query/sql/create-view.md: the WITH AUDIT clause, and OWNED BY in the syntax block
  • query/sql/alter-view.md, query/sql/drop-view.md, security/rbac.md: an audited view stays audited through ALTER VIEW; altering or dropping one needs AUDIT VIEW; the new permission's row
  • concepts/views.md: short "List parameters" and "Audited views" subsections that link to the pages above
  • configuration/overview.md, sidebars.js, changelog.mdx: index entries. The changelog entries sit under September 2026 and may need to move to the month this merges

Limitations the page states

Three limitations came out of review and are spelled out under "Limitations":

  • Auditing is lossy, and there is no lossless mode. A read never waits for its row to be recorded, so a row can be lost: when the queue is full, when a batch write fails, when the audit table's schema is rejected, or when the server stops with rows still queued. The "Delivery" section lists each case and the log line it leaves.
  • A materialized view over an audited view takes that view's data out of the trail. Creating it, refreshing it and reading it all record nothing.
  • An UPDATE of a WAL table that reads an audited view records nothing, because the read happens during WAL apply. The same statement on a non-WAL table is recorded.

The page also states that statements which open a query only to check it (CREATE VIEW, CREATE MATERIALIZED VIEW, ALTER VIEW, CREATE OR REPLACE VIEW) record nothing when the check passes and an error row when it fails, and that a shadowed inner view's fixed AUDITED parameters are not on the outer view's row.

It also follows the Enterprise review fixes: redefining an audited view needs AUDIT VIEW, a CSV import with overwrite=true cannot replace sys.view_audit, and a replica takes the audit table, and its storage policy, from the primary rather than creating its own.

A later round follows the latest fixes. A new "Values that cannot be audited" section lists what a read refuses rather than record: a type the table does not list, a sub-query anywhere in the value, and a value that can change during the query. CREATE VIEW ... WITH AUDIT, ALTER VIEW and CREATE OR REPLACE VIEW refuse the same declarations. A read whose AUDITED value fails to evaluate is refused too, even when the query never uses the variable, and records an error row with NULL in params, which the schema table now mentions. ALTER TABLE can no longer change the audit table's columns or deduplication, which replaces the earlier advice that you can add columns of your own. declare.md says a bracketed (DECLARE ... SELECT ...) is a sub-query, not a list.

Not verified

  • No yarn build. The sidebar config was loaded with node, and a link and anchor check over the changed files found no broken targets among the new links.
  • The example SQL was not run against a server. The error messages quoted in the tables were checked against the source.
  • "Reloadable: no" for the two settings comes from the code (neither key is in the dynamic properties), not from SHOW PARAMETERS on a running server.

🤖 Generated with Claude Code

Adds a Security page for QuestDB Enterprise audited views (CREATE VIEW
... WITH AUDIT, the AUDITED modifier, sys.view_audit and its params JSON,
what counts as a read, audited views read through other audited views,
delivery, permissions, replication, limitations) and a configuration
page for view.audit.queue.capacity and view.audit.storage.policy.

Documents declared value lists for IN in DECLARE, replacing the old
"bracket lists are not allowed" limitation, and links the feature from
the views, CREATE VIEW, ALTER VIEW, DROP VIEW and RBAC pages.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 19, 2026 •

Copy link
Copy Markdown

🚀 Build success!

Latest successful preview: https://preview-561--questdb-documentation.netlify.app/docs/

Commit SHA: fdb47ee

📦 Build generates a preview & updates the link on each commit.

puzpuzpuz and others added 3 commits September 19, 2026 16:43
Audited views have one delivery mode, lossy: a read never waits for its
row to be recorded, and a row can be lost. The Delivery section now
says so up front and lists every case in which a read goes unrecorded:
a full queue, a failed batch write, a rejected table schema, and rows
still queued when the server stops. The Limitations entry and the
queue capacity setting point to it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Redefining an audited view with ALTER VIEW or CREATE OR REPLACE VIEW
  now needs AUDIT VIEW, not just ALTER VIEW on the view.
- A statement's check of its query records an error row when the check
  fails, since the error can carry values from the rows it read.
- The audit table cannot be overwritten by a CSV import either.
- A replica takes the audit table from the primary instead of creating
  its own, and holds its rows until the definition arrives.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A read whose AUDITED value fails to evaluate is refused and recorded as
an error row with NULL params, even when the query never uses the
variable. A sub-query in an AUDITED value is refused as a CURSOR, and a
new section lists every value the audit refuses, and where.

The audit table's columns and deduplication can no longer be changed
with ALTER TABLE, which replaces the advice to add columns of your own.

A bracketed (DECLARE ... SELECT ...) is a sub-query, not a value list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant