Skip to content

Commit d5aa7d0

Browse files
committed
Add TASK and TRIGGER documentation
Subject: Add new reference documentation for TASK and TRIGGER statements
1 parent d5d75d6 commit d5aa7d0

7 files changed

Lines changed: 363 additions & 3 deletions

File tree

docs-site/nav.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@
126126
{
127127
"ALTER TABLE": "reference/sql/statements/alter-table.md"
128128
},
129+
{
130+
"ALTER TRIGGER": "reference/sql/statements/alter-trigger.md"
131+
},
129132
{
130133
"ALTER VIEW": "reference/sql/statements/alter-view.md"
131134
},
@@ -147,6 +150,12 @@
147150
{
148151
"CREATE TABLE": "reference/sql/statements/create-table.md"
149152
},
153+
{
154+
"CREATE TASK": "reference/sql/statements/create-task.md"
155+
},
156+
{
157+
"CREATE TRIGGER": "reference/sql/statements/create-trigger.md"
158+
},
150159
{
151160
"CREATE VIEW": "reference/sql/statements/create-view.md"
152161
},
@@ -168,6 +177,9 @@
168177
{
169178
"DROP TABLE": "reference/sql/statements/drop-table.md"
170179
},
180+
{
181+
"DROP TASK": "reference/sql/statements/drop-task.md"
182+
},
171183
{
172184
"DROP TRIGGER": "reference/sql/statements/drop-trigger.md"
173185
},
@@ -177,6 +189,9 @@
177189
{
178190
"DROP WORKSPACE": "reference/sql/statements/drop-workspace.md"
179191
},
192+
{
193+
"EXECUTE": "reference/sql/statements/execute.md"
194+
},
180195
{
181196
"EXPLAIN": "reference/sql/statements/explain.md"
182197
},

docs-site/reference/sql/statements.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,22 @@ Materialized views store a query's result as a physical table and refresh it aut
102102
| [ALTER MATERIALIZED VIEW](statements/alter-materialized-view) | Change a view's refresh owner, or suspend and resume its refresh |
103103
| [DROP MATERIALIZED VIEW](statements/drop-materialized-view) | Remove a materialized view and its refresh triggers |
104104
| [REFRESH MATERIALIZED VIEW](statements/refresh-materialized-view) | Rebuild a materialized view from its defining SELECT |
105-
| [DROP TRIGGER](statements/drop-trigger) | Remove one refresh trigger from a table |
106-
| [SHOW TRIGGERS FOR](statements/show-triggers) | List the refresh triggers attached to a table |
105+
| [SHOW TRIGGERS FOR](statements/show-triggers) | List the triggers attached to a table |
106+
107+
A materialized view's refresh triggers are created and maintained by `CREATE MATERIALIZED VIEW` itself — they are not authored by hand.
108+
109+
## Tasks & Triggers
107110

108-
There is no `CREATE TRIGGER` — triggers only come into existence through `CREATE MATERIALIZED VIEW`.
111+
A task is a statement the platform runs for you, on demand or when a table changes. Where a materialized view rebuilds one `SELECT` in full, a task runs any statement — typically appending only what changed, which suits tables too large to rebuild:
112+
113+
| Statement | Purpose |
114+
|-----------|---------|
115+
| [CREATE TASK](statements/create-task) | Define a statement the platform can run, optionally fired by a table |
116+
| [EXECUTE](statements/execute) | Run a task now, supplying its parameters |
117+
| [DROP TASK](statements/drop-task) | Remove a task |
118+
| [CREATE TRIGGER](statements/create-trigger) | Fire a task when a table changes |
119+
| [ALTER TRIGGER](statements/alter-trigger) | Suspend or resume a trigger |
120+
| [DROP TRIGGER](statements/drop-trigger) | Remove a trigger from a table |
109121

110122
## Workspace Management
111123

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
title: ALTER TRIGGER Statement — Opteryx Reference
3+
description: SQL ALTER TRIGGER statement syntax and examples for suspending and resuming a trigger in Opteryx
4+
---
5+
6+
# ALTER TRIGGER
7+
8+
The `ALTER TRIGGER` statement suspends or resumes one trigger.
9+
10+
A suspended trigger still exists and is still reached when its table commits; it simply
11+
enqueues nothing and records that it was suppressed. Prefer this to
12+
[DROP TRIGGER](drop-trigger) when pausing: a dropped trigger is indistinguishable from one
13+
that was never created, whereas a suspended one shows that it was switched off
14+
deliberately, when, and by whom.
15+
16+
## Syntax
17+
18+
~~~sql
19+
ALTER TRIGGER <trigger_name>
20+
ON <table_name>
21+
{ SUSPEND | RESUME };
22+
~~~
23+
24+
## Parameters
25+
26+
- **`<trigger_name>`** — the trigger to change. Use
27+
[SHOW TRIGGERS FOR](show-triggers) to list the triggers on a table.
28+
- **`<table_name>`** — the table the trigger is attached to, fully qualified as
29+
`<workspace>.<collection>.<table_name>`.
30+
- `SUSPEND` — stop the trigger firing, keeping it in place.
31+
- `RESUME` — let it fire again.
32+
33+
## Examples
34+
35+
### Suspend a Trigger
36+
~~~sql
37+
ALTER TRIGGER ingest_on_events ON my_workspace.raw.events SUSPEND;
38+
~~~
39+
40+
### Resume It
41+
~~~sql
42+
ALTER TRIGGER ingest_on_events ON my_workspace.raw.events RESUME;
43+
~~~
44+
45+
## Notes
46+
47+
- Requires the `writer` role on the table the trigger is attached to, the same as creating
48+
one.
49+
- Suspension is recorded on the **trigger**, not the task. A task fired by several tables
50+
can be paused on one of them and left running on the others.
51+
- A suspended trigger's table continues to accept commits normally; only the reaction is
52+
suppressed.
53+
- What a trigger runs cannot be altered in place — repoint it with
54+
[CREATE OR REPLACE TRIGGER](create-trigger).
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
---
2+
title: CREATE TASK Statement — Opteryx Reference
3+
description: SQL CREATE TASK statement syntax and examples for defining a statement the platform runs for you in Opteryx
4+
---
5+
6+
# CREATE TASK
7+
8+
The `CREATE TASK` statement records a statement the platform can run on your behalf, either
9+
on demand with [EXECUTE](execute) or automatically when a table changes.
10+
11+
A task is the general form of the machinery behind a materialized view. Where a view
12+
re-runs one `SELECT` into its own backing table, a task runs any statement the engine can
13+
plan — typically an `INSERT` that appends only what changed, which is what makes it
14+
suitable for tables too large to rebuild.
15+
16+
A task runs as its owner, so creating one is not merely registering some SQL: it creates
17+
something that executes with an identity. What you may define is therefore bounded by what
18+
you could already run yourself — see [Notes](#notes).
19+
20+
## Syntax
21+
22+
~~~sql
23+
CREATE [ OR REPLACE ] TASK <task_name>
24+
[ ON <table_name> ]
25+
AS <statement>;
26+
~~~
27+
28+
## Parameters
29+
30+
- **`<task_name>`** — the name of the task, fully qualified as
31+
`<workspace>.<collection>.<task_name>`. A task shares its namespace with tables and
32+
views, so the name must be free.
33+
- **`<table_name>`** — a table whose commits fire this task. Supplying it creates the
34+
trigger alongside the task, so one statement leaves nothing half-wired. Omit it and the
35+
task is defined but nothing fires it, which is what a backfill or a replay wants; add
36+
triggers later with [CREATE TRIGGER](create-trigger).
37+
- **`<statement>`** — the SQL the task runs. It may contain `:name` placeholders, which are
38+
supplied when the task is executed rather than now.
39+
- `OR REPLACE` — redefine an existing task instead of refusing. The previous statement is
40+
kept as an earlier version, and the task's owner is **not** changed.
41+
42+
## Examples
43+
44+
### Define a Task Run on Demand
45+
~~~sql
46+
CREATE TASK my_workspace.ops.rebuild_summary AS
47+
INSERT INTO my_workspace.ops.summary
48+
SELECT category, COUNT(*) FROM my_workspace.sales.orders GROUP BY category;
49+
~~~
50+
51+
### Define a Task Fired by a Table
52+
~~~sql
53+
CREATE TASK my_workspace.ops.ingest_events
54+
ON my_workspace.raw.events
55+
AS INSERT INTO my_workspace.ops.event_log
56+
SELECT * FROM my_workspace.raw.events VERSION AS OF :current_version;
57+
~~~
58+
59+
### Parameterize the Window
60+
A task fired by a table is passed the committing snapshot and the one before it, so it can
61+
process only what that commit added:
62+
63+
~~~sql
64+
CREATE TASK my_workspace.ops.ingest_new
65+
ON my_workspace.raw.events
66+
AS INSERT INTO my_workspace.ops.event_log
67+
SELECT c.*
68+
FROM my_workspace.raw.events VERSION AS OF :current_version AS c
69+
LEFT ANTI JOIN my_workspace.raw.events VERSION AS OF :parent_version AS p
70+
ON c.event_id = p.event_id;
71+
~~~
72+
73+
### Redefine an Existing Task
74+
~~~sql
75+
CREATE OR REPLACE TASK my_workspace.ops.ingest_events AS
76+
SELECT 1;
77+
~~~
78+
79+
## Notes
80+
81+
- **You may only create a task you could run yourself.** Creating one requires `reader` on
82+
everything the statement reads and `writer` where it writes, checked against you at the
83+
time you create it and again every time you redefine it. Without that, a task would let
84+
anyone define work over data they cannot see and have a privileged identity run it.
85+
- **The task runs as you.** There is no syntax for naming another principal — an argument
86+
that could is the escalation above, written out. Ownership survives `OR REPLACE`, so
87+
editing a task never quietly transfers whose authority it runs with.
88+
- **Platform identities cannot own tasks.** They can read a great deal but have no billing
89+
account, so a task pinned to one would run on a schedule forever and land on nobody's
90+
bill. Own a task as a user or a service account.
91+
- The statement is parsed when the task is created, so SQL that could never run is refused
92+
now rather than discovered when it fires. It is not fully planned — a task's placeholders
93+
have no values yet, and planning would demand them.
94+
- A task cannot create, drop, or run another task.
95+
- Relations inside the statement must be **fully qualified**. A task is planned with no
96+
implicit workspace, so a two-part name cannot be resolved.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
---
2+
title: CREATE TRIGGER Statement — Opteryx Reference
3+
description: SQL CREATE TRIGGER statement syntax and examples for firing a task when a table changes in Opteryx
4+
---
5+
6+
# CREATE TRIGGER
7+
8+
The `CREATE TRIGGER` statement attaches a trigger to a table so that committing to that
9+
table runs a [task](create-task).
10+
11+
Use this when the firing condition is not simply "the table the task reads" — a task can be
12+
fired by several tables, or by a table it does not itself read. Where the two do coincide,
13+
`CREATE TASK ... ON <table>` creates the trigger for you in one statement.
14+
15+
Triggers that refresh a **materialized view** are still created automatically by
16+
[CREATE MATERIALIZED VIEW](create-materialized-view) and are not authored with this
17+
statement.
18+
19+
## Syntax
20+
21+
~~~sql
22+
CREATE [ OR REPLACE ] TRIGGER <trigger_name>
23+
ON <table_name>
24+
EXECUTE <task_name>;
25+
~~~
26+
27+
## Parameters
28+
29+
- **`<trigger_name>`** — a name for the trigger, unique among the triggers on that table.
30+
- **`<table_name>`** — the table whose commits fire it, fully qualified as
31+
`<workspace>.<collection>.<table_name>`. Only commits that write data fire a trigger;
32+
housekeeping such as compaction and expiration does not.
33+
- **`<task_name>`** — the task to run, fully qualified.
34+
- `OR REPLACE` — repoint an existing trigger of this name. Without it, a trigger already
35+
pointing at a different task is left alone and the statement is refused, so one trigger
36+
cannot silently steal another's name.
37+
38+
## Examples
39+
40+
### Fire a Task When a Table Changes
41+
~~~sql
42+
CREATE TRIGGER ingest_on_events
43+
ON my_workspace.raw.events
44+
EXECUTE my_workspace.ops.ingest_new;
45+
~~~
46+
47+
### Fire One Task From Several Tables
48+
~~~sql
49+
CREATE TRIGGER ingest_on_events ON my_workspace.raw.events
50+
EXECUTE my_workspace.ops.reconcile;
51+
52+
CREATE TRIGGER ingest_on_returns ON my_workspace.raw.returns
53+
EXECUTE my_workspace.ops.reconcile;
54+
~~~
55+
56+
### Repoint an Existing Trigger
57+
~~~sql
58+
CREATE OR REPLACE TRIGGER ingest_on_events
59+
ON my_workspace.raw.events
60+
EXECUTE my_workspace.ops.ingest_v2;
61+
~~~
62+
63+
## Notes
64+
65+
- Requires the `writer` role on the **table** the trigger is attached to — landing a
66+
trigger is an update to that table. It does not require any permission on the task: a
67+
trigger confers no authority of its own, and what the task may do was settled against its
68+
author when the task was created.
69+
- A fired task is passed the committing snapshot and its parent, as `:current_version` and
70+
`:parent_version`. The window is fixed when the trigger fires, so a run means the same
71+
thing however long afterwards it is picked up.
72+
- Only **catalog events** — a commit to a table — can fire a trigger. Clock schedules and
73+
application signals are refused rather than stored, because nothing dispatches them yet
74+
and a trigger nothing fires is worse than none: the table it maintains stops updating
75+
while the trigger record still looks healthy.
76+
- To stop a trigger without losing it, use
77+
[ALTER TRIGGER ... SUSPEND](alter-trigger).
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
title: DROP TASK Statement — Opteryx Reference
3+
description: SQL DROP TASK statement syntax and examples for removing a task in Opteryx
4+
---
5+
6+
# DROP TASK
7+
8+
The `DROP TASK` statement removes a task. A task owns no storage, so nothing is reclaimed
9+
and the drop is fully reversible by re-creating it.
10+
11+
## Syntax
12+
13+
~~~sql
14+
DROP TASK [ IF EXISTS ] <task_name>;
15+
~~~
16+
17+
## Parameters
18+
19+
- **`<task_name>`** — the task to remove, fully qualified as
20+
`<workspace>.<collection>.<task_name>`.
21+
- `IF EXISTS` — skip the operation without error if the task does not exist, instead of
22+
refusing the statement.
23+
24+
## Examples
25+
26+
### Drop a Task
27+
~~~sql
28+
DROP TASK my_workspace.ops.ingest_events;
29+
~~~
30+
31+
### Drop Only If It Exists
32+
~~~sql
33+
DROP TASK IF EXISTS my_workspace.ops.ingest_events;
34+
~~~
35+
36+
## Notes
37+
38+
- Requires the `writer` role on the task.
39+
- **Triggers that fire the task are not removed.** A trigger lives on the table that fires
40+
it, and deleting other tables' records from this statement is how a partial failure
41+
leaves a trigger nobody can see. Remove them with [DROP TRIGGER](drop-trigger).
42+
- `DROP TASK` takes no other options — with no storage behind it, there is nothing for
43+
`CASCADE` or `RESTRICT` to decide.

0 commit comments

Comments
 (0)