# The DynoStudio PartiQL dialect

DynoStudio's editor speaks a richer PartiQL than DynamoDB natively accepts. Everything the service can't run is **lowered** — translated into requests it can — and every lowering is **disclosed**: in the "Executes as" strip, in the editor's inline diagnostics, and in run status lines. Nothing executes in a way the UI doesn't explain.

If terms like partition key, sort key, GSI, Query, or Scan still feel slippery, read the [DynamoDB basics](https://www.kanject.com/docs/dynostudio-dynamodb-basics/) first. This series is easier when the database model is already in your head.

The dialect is **PartiQL-native**: it extends the query language DynamoDB itself speaks, rather than emulating SQL through a script layer running over scanned rows. Every statement compiles to the operations the service actually executes — `Query`, `BatchGetItem`, `TransactWriteItems` — so results, semantics, and costs are the database's own.

```sql
-- a first query: read a table
SELECT * FROM "stage.Users"

-- further in: move money atomically
BEGIN TRANSACTION;
UPDATE "stage.Accounts" SET balance = balance - 100 WHERE accountId = 'A1';
UPDATE "stage.Accounts" SET balance = balance + 100 WHERE accountId = 'B2';
INSERT INTO "stage.Ledger" VALUE {'ledgerId': 'TX#123', 'amount': 100};
COMMIT;
```

## Three words used on every page

Each capability in this reference is tagged with where it actually executes. The tags matter because they predict cost and behaviour:

- **Native** — DynamoDB executes it server-side. The statement you write is (or compiles directly to) the request the service runs.
- **Lowered** — The studio translates it into native requests; any client-side work is disclosed in the "Executes as" strip and run status lines.
- **Kanject** — A convention extension beyond the PartiQL spec — e.g. key templates like 'Customer#{CustomerId}' that understand your schema.

> **The one cost rule:** On DynamoDB the shape of your query is the shape of your bill. A **partition-key equality or `IN` list** stays a cheap **Query**; anything else is a **Scan** that reads — and **bills** — every item in the table. And *lowered* features (joins, aggregates, subqueries, set operations) do their work client-side **after** a read, so every row they match, filter, fold, or `OFFSET`-skip is still read and billed. The "Executes as" strip tells you which one you got, every time — internalise this rule and the rest of the series is about staying on the cheap side of it.

## Find your entry point

You don't have to read this reference front-to-back. Every page stands alone, so start from the question that brought you here — each card below is a job you might be trying to do:

- **["Show me my data"](https://www.kanject.com/docs/dynostudio-partiql-basics/)** — Your first SELECT against a table or a GSI, choosing and computing columns — and how to read the "Executes as" strip.
- **["Fetch exactly these items"](https://www.kanject.com/docs/dynostudio-partiql-reads/)** — The WHERE reference: key conditions vs filters, keeping a read a cheap Query instead of a full-table Scan, sorting and paging.
- **["Answer across two tables"](https://www.kanject.com/docs/dynostudio-partiql-joins/)** — Key-aware joins, IN (SELECT …) semi-joins and anti-joins, and UNION / INTERSECT / EXCEPT — reads DynamoDB can't run alone.
- **["How many? Top ten?"](https://www.kanject.com/docs/dynostudio-partiql-aggregates/)** — COUNT, SUM, AVG, MIN, MAX with GROUP BY and HAVING — plus PROFILE TABLE to discover an unknown table's shape.
- **["Change data — safely"](https://www.kanject.com/docs/dynostudio-partiql-writes/)** — INSERT, UPDATE, DELETE and ON CONFLICT upserts, preview-first bulk sweeps, clock functions, query parameters, and all-or-nothing transactions.
- **["Stand up a table or index"](https://www.kanject.com/docs/dynostudio-partiql-ddl/)** — Control-plane DDL: CREATE TABLE, CREATE GSI, S3 Tables analytics replicas, Kanject UNIQUE / COLLECTION / RANGE markers, ALTER, and guarded drops.

Prefer to build up from first principles instead? Read the cards **in order** — each guide builds on the ones before it, from a first `SELECT` to the control plane, and the prev/next links at the bottom of every page walk the same path. Already fluent? The [keyword reference](https://www.kanject.com/docs/dynostudio-partiql-keywords/) is the flat index — every keyword, operator, and function on one page — and each core statement has a **dedicated page** ([SELECT](https://www.kanject.com/docs/dynostudio-select/), [INSERT](https://www.kanject.com/docs/dynostudio-insert/), [UPDATE](https://www.kanject.com/docs/dynostudio-update/), [DELETE](https://www.kanject.com/docs/dynostudio-delete/), [PROFILE TABLE](https://www.kanject.com/docs/dynostudio-profile-table/), [transactions](https://www.kanject.com/docs/dynostudio-transactions/)) whose examples are **quotable**: every one carries a permanent deep link you can copy and share.

> **Or browse the Query Library — no memorising:** You don't have to keep any of this in your head. Inside the editor, the **Query Library** is a searchable catalogue of the queries in this series, grouped by what you're trying to do. Pick one and it drops into the editor against the table you're viewing, classified in the "Executes as" strip just like anything you type. On **Professional**, read snippets insert with fillable `{parameters}` — a reusable question you fill and re-run; the free tier inserts the same query with a literal example value.

## Guardrails, everywhere

Multi-request lowerings are capped, and every cap breach refuses with a named fix rather than running away with your bill. Each guide lists the caps for its own features — joins and subqueries in [Joins, subqueries & sets](https://www.kanject.com/docs/dynostudio-partiql-joins/), aggregates in [Aggregates & profiling](https://www.kanject.com/docs/dynostudio-partiql-aggregates/). Unknown tables, malformed subqueries and unbounded Scan subqueries are flagged in the editor before anything reaches the wire. On **Professional**, those caps are tunable per install (Settings → Querying) — raising one can increase a query's read cost. A couple of authoring conveniences (naming query parameters, tuning the caps themselves) are Professional features; *running* an already-saved parameterized function is free at every edition.

**AWS references behind this dialect**

- [PartiQL for DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html) — AWS docs: the native PartiQL surface that DynoStudio builds from.
- [Querying tables in DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html) — AWS docs: why key-based reads are the baseline for predictable DynamoDB access.
- [Scanning tables in DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html) — AWS docs: why Scan warnings matter before a statement reaches production data.

> **The disclosure rule:** Every lowering is visible: the "Executes as" strip shows the native request(s), the editor squiggles what won't run or will bill heavily, and run status lines report items and pages actually read. If the UI didn't explain it, DynoStudio didn't do it.

---
_Source: https://www.kanject.com/docs/dynostudio-partiql/ · Kanject Docs_
