@lotics/app-sdk 0.102.0 → 0.102.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/queries.md +17 -38
- package/package.json +1 -1
package/docs/queries.md
CHANGED
|
@@ -234,7 +234,7 @@ supports the full §5 operator matrix **except**: `traversal` nodes, `locked`, a
|
|
|
234
234
|
`record_id` works on any row-level derived query (rejected over a `group`, which has no row
|
|
235
235
|
identity). When a `filter` directly wraps a `union` of `project(from_table)` arms and every
|
|
236
236
|
condition targets bare passthrough columns, the engine pushes the predicate into each arm's
|
|
237
|
-
source filter automatically
|
|
237
|
+
source filter automatically, where it runs once per record; otherwise it evaluates post-union.
|
|
238
238
|
|
|
239
239
|
### `join` — combine two row sets
|
|
240
240
|
|
|
@@ -545,9 +545,9 @@ Negation-shaped inner operators (`has_none_of`, `not_equals`, `is_none_of`,
|
|
|
545
545
|
|
|
546
546
|
Traversals are **source-layer only** (rejected on derived columns — push them into
|
|
547
547
|
`from_table.filter`). Each hop reaches the linked rows by primary key from the ids in the link
|
|
548
|
-
cell. Under an OR beside column conditions a traversal runs once per row and takes
|
|
549
|
-
|
|
550
|
-
|
|
548
|
+
cell. Under an OR beside column conditions a traversal runs once per row and takes a membership
|
|
549
|
+
condition off its index with it; give it a `union` arm of its own when the other arms must keep
|
|
550
|
+
theirs. Two access classes:
|
|
551
551
|
|
|
552
552
|
- **Self-scoped** — inner operator `is_current_member` / `is_not_current_member`: tests only
|
|
553
553
|
the viewer's own membership on the linked row, leaks nothing, and is exempt from the linked
|
|
@@ -871,7 +871,7 @@ ordering and scoping into the template or its params.
|
|
|
871
871
|
Any other execution failure returns a generic `query execution failed` (the real error — which
|
|
872
872
|
may embed SQL — is server-logged only). Bind-time and validation errors are always specific.
|
|
873
873
|
|
|
874
|
-
###
|
|
874
|
+
### What a query reads, in plain terms
|
|
875
875
|
|
|
876
876
|
Records are stored partitioned by workspace, so a query reads only its own workspace's slice; a
|
|
877
877
|
`from_table` narrows that slice to the table's rows, and within them:
|
|
@@ -879,39 +879,18 @@ Records are stored partitioned by workspace, so a query reads only its own works
|
|
|
879
879
|
- **GIN-served (fast at any size):** *positive* exact-membership filters at the **source
|
|
880
880
|
layer** — `select`/`select_member`/`select_record_link` `has_any_of` / `has_all_of`, and
|
|
881
881
|
`is_current_member`. These compile to containment the JSONB GIN index serves.
|
|
882
|
-
- **Trigram-served:** `from_table.search` (§7).
|
|
883
|
-
- **
|
|
884
|
-
comparisons
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
template. Fine on thousands of rows; on very large tables these dominate latency and are the
|
|
895
|
-
usual timeout cause.
|
|
896
|
-
|
|
897
|
-
**Filter shape drives latency.** Equality/range/sort predicates in the bound template are
|
|
898
|
-
index-served; lead with those or a GIN-served membership filter / `search`, and let scan-shaped
|
|
899
|
-
predicates refine the already-narrowed set. Derived-layer filters run over the subquery result
|
|
900
|
-
(no index), so **filter at the source layer whenever the field exists there** — the runtime
|
|
901
|
-
filter is for caller-driven refinement, not for the main cut (a runtime-only field gets no
|
|
902
|
-
managed index). (The engine pushes eligible filter-over-union predicates down automatically,
|
|
903
|
-
but don't rely on that for other shapes.)
|
|
904
|
-
|
|
905
|
-
**A sorted page reads in its sort index — declare the order it is read in.** A page sorted by one
|
|
906
|
-
column that passes a number or date field unchanged (a bare `project` source with no `type`
|
|
907
|
-
override, an `unpivot` passthrough, or a row column that reads the same field in every row) reads
|
|
908
|
-
the table in that field's sort index and stops at the page, instead of reading every row and
|
|
909
|
-
sorting. Over a `union`, each arm is paged this way on its own and the arms are merged, so a
|
|
910
|
-
register over several tables or `unpivot` sides is fast at any size — don't hand-split it into
|
|
911
|
-
per-table queries you merge client-side. The index exists when a bound template sorts that field
|
|
912
|
-
in the same direction and blank position: give the query its default order as a top-level `sort`,
|
|
913
|
-
and a page the app sorts the same way is served. A text column, a computed, literal or cast column,
|
|
914
|
-
a sort on more than one key, and a cursor (`keyset`) page sort every row.
|
|
882
|
+
- **Trigram-served:** `from_table.search` (§7), within the one table.
|
|
883
|
+
- **Every row of the table:** everything else — text equality and `contains`, number and date
|
|
884
|
+
comparisons, sorts, negations, emptiness, files predicates. Fine on thousands of rows; the cost
|
|
885
|
+
grows with the table, and on very large tables these dominate latency and are the usual
|
|
886
|
+
timeout cause.
|
|
887
|
+
|
|
888
|
+
**Filter shape drives latency.** Lead with a GIN-served membership filter or `search`, which
|
|
889
|
+
narrow the table before its rows are read, and let the other conditions refine that set.
|
|
890
|
+
Derived-layer filters run over the subquery result, after any `unpivot` fan-out, so **filter at
|
|
891
|
+
the source layer whenever the field exists there** — the runtime filter is for caller-driven
|
|
892
|
+
refinement, not for the main cut. (The engine moves eligible filter-over-union predicates into
|
|
893
|
+
each arm's source automatically, but don't rely on that for other shapes.)
|
|
915
894
|
|
|
916
895
|
**An aggregate arm you cannot filter costs its whole table, every execution.** A `join` whose right
|
|
917
896
|
side is a `group` over entire tables, keyed on a value the LEFT side supplies at run time, has no
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lotics/app-sdk",
|
|
3
|
-
"version": "0.102.
|
|
3
|
+
"version": "0.102.1",
|
|
4
4
|
"description": "The SDK a Lotics custom-code app reads and writes through \u2014 typed hooks over the host bridge, cell readers, mount() and AppRouter",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|