Qwiratry — SQL-Features-Spitballing

Qwiratry language redesign for SQL-shaped features

Plan/Spec for version 0.10.2 (Language Redesign): how the Qwiratry language (Query AST, query slang, and operator surface) grows to cover the gaps listed in SQL-bits-missing.md — CrUD, Grouping, and Other — without turning Qwiratry into SQL.

Companion research: SQL-AST-Qwiratry-Mapping.md, SQL-AST-Comparison.md.Backend / Location / TaOP work stays out of scope here (see Qwiratry-TaOP-Basics.md and Qwiratry-TaOP-Plan.md for row sinks and Relation faces).

Status: Writing.Scope: Language only — operators, slang forms, AST nodes, pipeline semantics, and how those map conceptually to SQL.Non-scope: Postgres/Memory Location APIs, SQL string encoding, Walker pushdown strategy internals (except where the language must expose a hook).

1. Goals

  1. Make Create / Update / Delete first-class in the query language, tying mutation into Destination rather than inventing a second write vocabulary.

  2. Add real grouping (group-by + aggregates), window, and unique/distinct features/operators — not approximations via ReduceOperator.

  3. Cover transactions and paging (LIMIT/OFFSET) as language constructs that compose with pipelines.

  4. Keep Qwiratry’s design principles: declarative Query AST, Unicode/relational operators, chained pipelines, introspectable nodes, domain flexibility (tables and other models where the op makes sense).

2. Non-goals

  • Emitting or parsing SQL text in core.

  • A full SQL dialect grammar or keyword-for-keyword SQL slang.

  • Replacing TaOP Relation mutation APIs; pipelines and Relation remain complementary.

  • Replacing ReduceOperator (⌿) — it stays a fold; grouping/distinct are different nodes.

  • Row locking (FOR UPDATE, …) in the first cut (note only; see §8).

  • Backend capability matrices beyond “language must not assume every Location can do every mode”.

3. Design principles

  1. Pipeline position is semantics. σ before grouping ≈ WHERE; σ after grouping ≈ HAVING. Prefer that over a dedicated HAVING node unless pushdown later needs an explicit tag.

  2. One Destination glyph, many intents. Extend DestinationOperator with write modes/adverbs (insert/update/delete/schema), informed by the survey in §4.

4. Survey: Create / Update / Delete across languages

How existing languages and APIs express mutation intents. Cells are representative idioms, not exhaustive catalogues. — means that family does not really own that column (or treats it as out of scope).

Rows mix command families (SQL sublanguages), protocol surfaces (HTTP, GraphQL), shell/file idioms, host-language containers, and a few graph / document peers, plus algebraic analogies (sets, logic gates, joins). Use this when choosing Destination adverb / mode names and when deciding whether schema CrUD and record CrUD share one operator.

Column meanings

  • Create — Add a new thing that did not exist (row, object, file, privilege, graph, …). Fails or no-ops if identity already exists, depending on the language.

  • Update — Change an existing thing in place (partial or full), identified by key / URL / path / node. Does not create if missing (unless the idiom is really an upsert — then prefer the Upsert column).

  • Delete — Remove an existing thing (or mark it gone). Parent container may remain.

  • Upsert — Create-or-update by identity in one operation (MERGE, ON CONFLICT, REPLACE INTO, HTTP conditional put-with-create, …). Distinct from plain Create and plain Update.

  • Truncate parent + Create — Empty or replace the parent container, then populate it afresh (SQL TRUNCATE + INSERT; overwrite a whole file; replace an entire collection/document; PUT a whole resource body). The parent identity survives; the children are wiped and re-created. Not the same as Delete of the parent, and not the same as per-row Update.

Language / surfaceCreateUpdateDeleteUpsertTruncate parent + Create
SQL DDL (relations / schema objects)CREATE TABLE / VIEW / INDEX / …ALTER TABLE / ALTER VIEW / …DROP TABLE / VIEW / …— (no create-or-alter-object in one standard verb)DROP + CREATE; or CREATE OR REPLACE VIEW (views)
SQL DDL (columns)ALTER … ADD COLUMNALTER … ALTER/MODIFY COLUMN / RENAME COLUMNALTER … DROP COLUMN—drop all columns + re-add (rare; usually DROP TABLE + CREATE)
SQL DML (records)INSERT (+ INSERT … SELECT)UPDATEDELETEMERGE; INSERT … ON CONFLICT / REPLACE INTO (dialect)TRUNCATE then INSERT; DELETE all then INSERT
SQL DQL— (read-only; SELECT / WITH)————
SQL DCLGRANT—REVOKE— (GRANT often additive, not upsert)revoke all + re-grant (manual pattern)
SQL TCL— (wraps DML; does not create data)—— (ROLLBACK undoes uncommitted work)——
HTTP / REST (resources)POST (create); sometimes PUT to new URLPATCH (partial); PUT when resource must existDELETEPUT to URL (create-or-replace by URI)PUT full body (replace representation); delete-children + POST bulk
GraphQL (Mutation root)createX / addX / insertX fieldsupdateX / setX fieldsdeleteX / removeX fieldsschema-defined upsertX / saveX (convention only)custom replaceX / setCollection mutation (convention only)
GraphQL (Hasura-style CRUD)insert_* / insert_*_oneupdate_* / update_*_by_pkdelete_* / delete_*_by_pkinsert_* + on_conflict update columnsdelete-all (or truncate via SQL) + insert_*; no first-class “replace table”
GraphQL (Relay / input objects)…(input: Create…Input!)…(input: Update…Input!)…(input: Delete…Input!)…(input: Upsert…Input!) if schema defines itcustom replace/set mutation inputs
SPARQL Update (graph data)INSERT DATA / INSERT … WHERE; LOAD; CREATE GRAPHDELETE { } INSERT { } WHERE { }DELETE DATA / DELETE … WHERE; DROP GRAPHDELETE + INSERT in one update (pattern upsert)CLEAR GRAPH / DROP+CREATE then INSERT; LOAD into cleared graph
Cypher (Neo4j)CREATESET / REMOVE propertyDELETE / DETACH DELETEMERGE (+ ON CREATE / ON MATCH)match parent, delete children, CREATE anew; or recreate subgraph
MongoDB (shell / driver)insertOne / insertManyupdateOne / updateMany; $set / …deleteOne / deleteManyupdate* / replaceOne with upsert: true; bulkWrite upsertsdeleteMany({}) + insertMany; drop collection + recreate; replace root doc
XQuery Update Facilityinsert node … into/before/afterreplace node / replace value of; renamedelete node— (compose delete+insert / replace)delete all children + insert; replace node parent content
bash (files via redirect)> create; cat … > filesed -i / sponge edit-in-placerm— (no identity merge; overwrite is replace)> / cat … > file (truncate file + write); truncate then write
bash (tee)… | tee file (write/overwrite)… | tee -a file (append; not true field update)— (pair with rm)—… | tee file (truncate-via-open + write stream)
Raku (files / IO).IO.spurt; open :w / :createrewrite via temp+move; partial edit by hand.IO.unlink—.IO.spurt($content) / open :w (truncate + write); :truncate
Raku (Array / List building).push / .append@a[$i] = …; .splice.pop / .shift / .splice / .DELETE-POS— (assign-by-index is update, not upsert-by-key)@a = @new / .STORE (replace all elements)
Raku (Hash / Map)%h{$k} = $v when key absent%h{$k} = $v when key present%h{$k}:delete / .DELETE-KEY%h{$k} = $v (assign is upsert-by-key)%h = %new / .STORE (replace all pairs)
Raku (Set / BagHash)∪ / .set—∖ / (-) / .unset.set (add-if-absent; no payload update)assign new set / clear + add all
Raku (Bag)assignment / .STOREmutation methodsdrop last reference (GC)—re-bless / replace object identity (rare)
Raku (assignment / meta-assignment)//= / (double-vertical-bars blocked by Markdown)= (write only if absent/undefined — SQL INSERT-shaped); also append= / prepend= / ~= (always add new content).= (in-place method); otherwise no single “field update” metaop-= / ∖= (remove / subtract)+= / ∪= (merge into existing; may autovivify — SQL UPSERT-shaped)bare = (replace container contents / .STORE)
Qwiratry today (Destination ⮷)single write/sink (… ⮷ $loc); blob replace semantics———blob ⮷ often is truncate-parent+create (overwrite location)
Current Proposal (Destination operators, including composites)⮷// (Destination before // — insert-if-absent, cf. //=)⮷+ (Destination before + — Plus / Update)⮷- (Destination before -, cf. -=)⮷⊕ (Destination before Circled Plus ⊕ — Upsert)bare ⮷ (replace/overwrite location — Truncate parent + Create)
git (working tree / index)git add new paths; git commitedit + git add; commit --amendgit rm; discard via restore—replace file contents + add; orphan branch / reset patterns (heavy-handed)
Makefile / build artefactsrecipe creates targetrecipe rebuilds targetclean / rm—recipe always rebuilds target file from scratch
CSSOM / DOM (browser)createElement / appendChild; insertRuleset attrs / textContent / replaceChildremove() / deleteRule—replaceChildren(…) / set innerHTML; replace stylesheet content
LDAPaddmodify / modifyDNdelete— (no standard upsert; search then add/modify)delete subtree children + re-add; replace entry attrs via modify
IMAP (mailboxes / messages)CREATE mailbox; APPEND messageSTORE flags; RENAMEDELETE mailbox; EXPUNGE—empty mailbox (EXPUNGE all) + APPEND; recreate mailbox
Set theory (existing ⊕ new)∪ union (add members from new)— (no payload; approximate (A ∖ {x}) ∪ {x′})∖ / − difference (remove members in new); ∁ relative complement∪ (idempotent add-by-membership)replace with new: B, or ∅ ∪ B (discard existing)
Z Notation (sets / relations / schemas)∪ (set union); add maplets x ↦ y to a relationrelational override ⊕ on a known domain element; Δ-schema with primed after-stateset difference \; domain anti-restriction ⩤ (drop pairs by key)relational override ⊕ (add-or-replace by domain — classic Z “map update”)after-state replace S′ = T / S′ = ∅ ∪ T (discard prior binding)
Logic gates (existing ⊕ new bits)OR (set 1s from new)MUX / conditional assign (new ? new : old); XOR = toggleAND-NOT / inhibit (old ∧ ¬new)OR (same as Create for bits)replace with new (Y); FALSE ∨ Y
Joins (Qwiratry / RA: existing ⋈ new)⟕ left outer (keep existing, attach new); × cross (new combinations)⨝ / ▷=◁ / ≜ (match + enrich / overwrite joined attrs)antijoin ▷ / ◁ (drop matches or keep non-matches); semijoin ⋉ / ⋊ (keep only matches)⟗ full outer (keep identities from both; coalesce)take new side only: ⟖ then project right (or discard left + use right; not a pure join)

Notes for Qwiratry design:

  • Schema vs data: SQL splits DDL (relations/columns) from DML (records). GraphQL usually collapses both into Mutation fields. File/tee languages mostly only have blob create/overwrite/append/delete.

  • Append vs update: tee -a, Raku :a / .spurt(:append), and SQL INSERT are create-shaped; true update needs identity (key / URL / path / node).

  • Upsert and Truncate parent + Create are the two columns that most often collapse into today’s single Destination overwrite — the language redesign should split them from per-row Update/Delete.

  • Current Proposal: Destination forms are operators, not Raku metaoperators. Bare Destination is overwrite (Truncate parent + Create). The other glyphs are composite Destination operators: ⮷// = Create/Insert; ⮷+ = Update (Plus); ⮷⊕ = Upsert (Circled Plus); ⮷- = Delete. Related Raku assignment operators (=, //=, +=, -=) are an analogy only.

  • Qwiratry today only covers blob Create / Truncate-parent+Create via ⮷; record and schema CrUD (and true Upsert) are the language gap this plan targets.

5. Candidate Unicode symbols for mutation intents

There are no Unicode characters officially named Create, Update, Upsert, Replace, or Truncate for database work. The table lists the candidates from the survey discussion: usable glyphs whose names or conventional UI meaning are close enough to borrow for Qwiratry Destination modes (if we use glyphs at all rather than adverbs alone).

IntentSymbolCodeNameNotes
Create / insert➕U+2795HEAVY PLUS SIGNCommon “add” UI glyph
Create / insert⊞U+229ESQUARED PLUSMath-ish plus; pairs with ⊟
Create / insert⊕U+2295CIRCLED PLUSAlso usable as upsert/merge metaphor
Create / insert⎀U+2380INSERTION SYMBOLUnicode name is literally insertion
Create / insert∪U+222AUNIONSet-theory Create (union)
Create / insert🆕U+1F195SQUARED NEWEmoji; loud / informal
Update / edit✎U+270ELOWER RIGHT PENCILPencil = edit convention
Update / edit✏U+270FPENCILPencil = edit convention
Update / edit📝U+1F4DDMEMOEmoji memo
Update / edit↻U+21BBCLOCKWISE OPEN CIRCLE ARROWRefresh / rewrite metaphor
Update / edit🔄U+1F504ANTICLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWSEmoji refresh
Delete🗑U+1F5D1WASTEBASKETEmoji trash
Delete⌫U+232BERASE TO THE LEFTErase in name; keyboard backspace
Delete⌦U+2326ERASE TO THE RIGHTErase in name; keyboard delete
Delete␡U+2421SYMBOL FOR DELETEUnicode name is Symbol for Delete
Delete➖U+2796HEAVY MINUS SIGNPairs with ➕
Delete⊟U+229FSQUARED MINUSMath-ish minus; pairs with ⊞
Delete✖U+2716HEAVY MULTIPLICATION XHeavy X / cancel
Upsert / merge∪U+222AUNIONIdempotent add-by-membership
Upsert / merge⊎U+228EMULTISET UNIONMultiset union; “add with multiplicity” feel
Upsert / merge⊕U+2295CIRCLED PLUSCircled plus / XOR-adjacent family
Upsert / merge⇄U+21C4RIGHTWARDS ARROW OVER LEFTWARDS ARROWExchange / merge-in-both-directions metaphor
Upsert / merge≔U+2254COLON EQUALSAssignment; also fits Replace
Replace≔U+2254COLON EQUALS“becomes” / assign-new-value
Replace⇄U+21C4RIGHTWARDS ARROW OVER LEFTWARDS ARROWSwap metaphor
Replace↔U+2194LEFT RIGHT ARROWLeft-right exchange
Truncate / empty∅U+2205EMPTY SETEmpty the parent; keep container identity
Truncate / empty⎚U+239ACLEAR SCREEN SYMBOLClear screen; rare in fonts
Truncate / empty🗋U+1F5CBEMPTY DOCUMENTEmpty document emoji

A compact math-ish palette (if choosing glyphs): ⊞ Create, ✎ or ↻ Update, ⊟ Delete, ⊕/⊎ Upsert, ≔ Replace, ∅ Truncate.

6. Table of Proposed Destination Operators

Expanded form of the Current Proposal survey row. These are operators, not Raku metaoperators. Bare Destination is the overwrite operator. The other rows are composite Destination operators (Destination combined with another glyph). Related Raku assignment operators are an analogy only.

SymCodeUnicode NameSQL DML OperationQwiratry NameRelated Raku Assignment OperatorNotes
⮷U+2BB7RIBBON ARROW RIGHT DOWNTRUNCATE + INSERT (replace all rows / contents)Overwrite Destination=Truncate parent + Create — replace/overwrite location (today’s default Destination semantics)
⮷//U+2BB7 + U+002F U+002FRIBBON ARROW RIGHT DOWN + SOLIDUS + SOLIDUSINSERTInsert Destination//=insert-if-absent
⮷+U+2BB7 + U+002BRIBBON ARROW RIGHT DOWN + PLUS SIGNUPDATEUpdate Destination+=
⮷-U+2BB7 + U+002DRIBBON ARROW RIGHT DOWN + HYPHEN-MINUSDELETEDelete from Destination-=
⮷⊕U+2BB7 + U+2295RIBBON ARROW RIGHT DOWN + CIRCLED PLUSUPSERT / MERGEUpsert/Append Destination

Qwiratry v0.11.0

Declarative query and data-walking architecture for Raku, with transformers, molds, walkers, I/O pipelines, and aggregate functions.

Authors

  • Tim Nelson

License

Dependencies

SlangifyImplementation::Loader:ver<0.0.9+>Glob::Grammar

Test Dependencies

Provides

  • Qwiratry
  • Qwiratry::Aggregate::AggSub
  • Qwiratry::Aggregate::AggSub::Compiler
  • Qwiratry::Aggregate::Avg
  • Qwiratry::Aggregate::BodyRewrite
  • Qwiratry::Aggregate::Count
  • Qwiratry::Aggregate::DenseRank
  • Qwiratry::Aggregate::Driver
  • Qwiratry::Aggregate::Rank
  • Qwiratry::Aggregate::Sum
  • Qwiratry::AggregateFunction
  • Qwiratry::Context
  • Qwiratry::DatabaseStorage
  • Qwiratry::DatabaseStorage::CSVdemo
  • Qwiratry::DatabaseStorage::Location
  • Qwiratry::DatabaseStorage::Location::Tree
  • Qwiratry::DatabaseStorage::Memory
  • Qwiratry::FieldMode
  • Qwiratry::Format
  • Qwiratry::Format::Base
  • Qwiratry::Format::CSVdemo
  • Qwiratry::Format::HalfHuman
  • Qwiratry::Format::JSONdemo
  • Qwiratry::Format::NDJSONdemo
  • Qwiratry::Format::Textish::RenderWalkable
  • Qwiratry::Implementation::Loader
  • Qwiratry::Location
  • Qwiratry::Location::Base
  • Qwiratry::Location::File
  • Qwiratry::Mold
  • Qwiratry::Mold::Compiler
  • Qwiratry::Mold::Registry
  • Qwiratry::Mold::Slang
  • Qwiratry::MovingFrameAggregateFunction
  • Qwiratry::Operator::Capability
  • Qwiratry::Operator::IO
  • Qwiratry::Operator::MapReduce
  • Qwiratry::Operator::Navigation
  • Qwiratry::Operator::Set
  • Qwiratry::Query::Evaluator::Eager
  • Qwiratry::Query::Evaluator::Filter
  • Qwiratry::Query::Evaluator::Join
  • Qwiratry::Query::Evaluator::Lazy
  • Qwiratry::Query::Evaluator::MapReduce
  • Qwiratry::Query::Evaluator::Navigation
  • Qwiratry::Query::Evaluator::Relational
  • Qwiratry::Query::Evaluator::Row
  • Qwiratry::Query::Evaluator::Set
  • Qwiratry::Query::Evaluator::Union
  • Qwiratry::Query::Extract
  • Qwiratry::Query::NamedJoins
  • Qwiratry::Query::RelationCommon
  • Qwiratry::Query::Runtime
  • Qwiratry::Query::Selector
  • Qwiratry::Query::Slang
  • Qwiratry::Query::Slang::Ops
  • Qwiratry::Query::Slang::Topic
  • Qwiratry::Query::Specificity
  • Qwiratry::Query::Topic
  • Qwiratry::QueryCursor
  • Qwiratry::QueryIterator
  • Qwiratry::QueryMatch
  • Qwiratry::Setup
  • Qwiratry::Singleton
  • Qwiratry::Strategy
  • Qwiratry::Strategy::ControlSignal
  • Qwiratry::Strategy::FinishResult
  • Qwiratry::Strategy::RewriteSpec
  • Qwiratry::Strategy::Traversal
  • Qwiratry::Suggest
  • Qwiratry::TaOP
  • Qwiratry::Table
  • Qwiratry::Table::Schema
  • Qwiratry::Transformer
  • Qwiratry::Transformer::Copy
  • Qwiratry::Transformer::TreeRewrite
  • Qwiratry::Tree::Navigator
  • Qwiratry::Tree::Navigator::Base
  • Qwiratry::Tree::Navigator::Filesystem
  • Qwiratry::Tree::Navigator::Match
  • Qwiratry::Tree::Navigator::RakuAST
  • Qwiratry::Tree::Replace
  • Qwiratry::Walker
  • Qwiratry::Walker::Capabilities
  • Qwiratry::Walker::Factory
  • Qwiratry::Walker::Implementation::Table
  • Qwiratry::Walker::Implementation::Tree
  • Qwiratry::Walker::Implementation::TreeWithPath
  • Qwiratry::Walker::Master
  • Qwiratry::Walker::Providing
  • TypedIterator
  • WalkCursor
  • X::Qwiratry

The Camelia image is copyright 2009 by Larry Wall. "Raku" is a trademark of the Yet Another Society. All rights reserved.

Built with Podlite — the markup and publishing tools behind this site.