Qwiratry β€” Qwiratry-TaOP-Prerequisites

Qwiratry TaOP Prerequisites

Specification for Qwiratry core changes required before rebuilding TaOP on Qwiratry. This document is not the TaOP product surface.

Parent plan: Qwiratry-TaOP-Plan.md.TaOP layer (Relation, Memory, Postgres, Tables, anonymous Table front-end): Qwiratry-TaOP-Basics.md.

Status: Prerequisites substantially complete (post-0.0.9 / toward 0.10.0). Landed: text-chunk walkable/pull; sector vocabulary; WalkCursor / QueryCursor tree; Topic slang; TypedIterator (File .of = Str); text-adaptor checks; QueryIterator does TypedIterator. Remaining doc polish may trail in Extending; row sinks / table Locations β†’ Basics.Scope (prerequisites only): Streaming-shaped Location I/O; TypedIterator as the common element-kind face (I/O pull and query match streams); WalkCursor tree contract; no Qwiratry::Storage::*.

1. Goals

  1. Streaming-shaped Location I/O (walkable + optional pull/sink) so adaptors can carry Iterators without always materialising a giant Str.

  2. TypedIterator so pull streams advertise element kind (Location chunks today; query matches via QueryIterator; later rows in Basics) without parallel read-rows APIs.

  3. WalkCursor tree contract as the movement API TOP/SQL cursors will reuse. (WalkCursor itself does not return an Iterator; QueryCursor.iterator is the optional match-stream bridge.)

  4. No parallel Storage hierarchy β€” when TaOP lands, table backends extend Location (see Basics); Qwiratry core must not ship a competing Storage tree.

  5. Adaptor operators that do not assume every pull stream is text (no blind .Str coerce).

  6. SourceOperator stays walkable-shaped β€” it does not return an Iterator; Location pull is composed by Parse (or, later, by Basics when a table Source is used in a pipeline that needs rows). Dirs/globs keep current return shapes.

2. Non-goals (TaOP work β€” see Basics)

These are out of scope for prerequisites. Spec and acceptance live in Qwiratry-TaOP-Basics.md:

  • Relation / use-table / live Table handles

  • Memory Location (and anonymous default storage)

  • Postgres (and other SQL) Location

  • Tables / Database / Field / Tuple front-end, FieldMode plugins as TaOP API

  • CSV Location, HalfHuman, WithBorders (plan sequencing)

  • Multi-dialect / Red-style SQL encoding (plan Β§12)

  • Graduating CSVdemo into a production Format

  • Full Format push (Supply) edges β€” not needed for TaOP Basics; destination text sinks suffice for blob streaming today (see Streaming proposal v2 later)

  • Interim row .of type and Destination row sinks β€” Basics (table Locations not in prerequisites)

  • Making bare SourceOperator return a pull Iterator β€” rejected for now; walkable evaluate is intentional

3. Current baseline (after 0.0.9 β†’ Unreleased / 0.10.0)

PieceBehaviour
Qwiratry::Location::Base::SourceWalkableread-walkable(Str $location --> Mu) β€” whole payload
Qwiratry::Location::Base::DestinationWalkablewrite-walkable(Str $location, Mu $content --> Mu)
Qwiratry::Location::Base::SourcePullOptional read-pull(--> Iterator); prefer TypedIterator
Qwiratry::Location::Base::DestinationPushOptional open-sink-push β†’ sink with write-chunk / close
Qwiratry::Format::Base::ParseWalkable / RenderWalkableparse-walkable / render-walkable
Qwiratry::Format::Base::ParsePull / RenderPullOptional parse-pull / render-pull
SourceOperatorAlways whole-value read-walkable (dirs/globs/return shapes). Does not return an Iterator. Pull composition is chosen by ParseOperator when both source and parser support pull.
DestinationOperatorPrefer open-sink-push when upstream is a text-chunk Iterator; else join and write-walkable. Rejects non-text .of / non-Str untyped elements.
ParseOperator / RenderOperatorPrefer pull when format (and source, for parse) advertise it; else walkable fallback. Same text-kind checks as Destination.
FileWalkable + SourcePull + DestinationPush; read-pull β†’ TypedIterator with .of = Str
HTTPWalkable only (sibling package)
NDJSONdemoWalkable + ParsePull / RenderPull
Qwiratry::Location factoryDiscovers ::Source / ::Destination; validates against Walkable bases
Qwiratry::Table::Catalog / SchemaExisting FK-aware navigation over named collections / row lists (not TaOP Table front-end)
Navigation vocabularyFormer β€œaxis” naming β†’ sector
WalkCursor / Sector / AxisGeneric position/fetch-*/move-* (lib/WalkCursor.rakumod) β€” not an Iterator factory
Qwiratry::QueryCursorTree specialization; Plan.cursor; optional Strategy :cursor; .iterator β†’ QueryIterator (match bridge)
Qwiratry::QueryIteratorQuery match pull stream (+ Context); does TypedIterator (default .of = Mu)
Tree NavigatorMulti-step sector helpers; walk-local caches
Qwiratry::Query::Slang + ::Ops + ::TopicTopic slang after Slang for given / bare nav / universe ops
TypedIteratorTop-level role + TypedIterator::Wrapper; .of default Mu

Still missing for TaOP to plug in cleanly: Basics Locations (Memory, …) that yield row TypedIterators, plus Destination row sinks / Parse skip for structured .of β€” specified in Basics, not here.

4. Pipeline face (prerequisite concern)

SourceOperator and DestinationOperator remain the adaptor pipeline operators:

  • Source = pull data from a location into the pipeline.

  • Destination = push pipeline data out to a location.

Location capabilitySource yields (via Location APIs)Destination accepts
Blob (File, HTTP, …)read-walkable, or read-pull β†’ TypedIterator with .of = Str (used when Parse composes pull)write-walkable, or text-chunk sink
Structured / table-capable (TaOP Locations)Same read-pull surface with row .of β€” BasicsRow sink when elements are rows β€” Basics

SourceOperator.evaluate always uses read-walkable. It does not return an Iterator. That keeps directory/glob shapes stable. Pull is an optional Location capability consumed by ParseOperator today (and by Basics pipelines that call read-pull / structured adaptors later).

Parse/Render stay on Format when the pipeline deals with encoded text. When a pipeline already has structured values, Parse may be skipped (Basics).

The object face (Relation / Table.new) is TaOP Basics, not a prerequisite module. Both faces SHOULD eventually share row I/O on the same backend β€” that sharing rule is specified in Basics.

Adaptor operators MUST NOT assume every Location is Str-only.

5. Prerequisite A0 β€” Streaming-shaped Location I/O

5.1 Why first

TOP table Sources are only honest if the Location and operator stack can carry Iterators (chunks or later rows) without forcing full materialisation. Text walkable/pull has landed. QueryIterator does TypedIterator and Extending .of docs are landed. Row sinks / table Locations are Basics.

Align names with Streaming-Qwiratry-Proposal.md.

5.2 Landed contracts (text / blob)

class Qwiratry::Location::Base::SourceWalkable {
    method read-walkable(Str $location --> Mu) { ... }
}
class Qwiratry::Location::Base::DestinationWalkable {
    method write-walkable(Str $location, Mu $content --> Mu) { ... }
}
role Qwiratry::Location::Base::SourcePull {
    method read-pull(Str:D $location --> Iterator:D) { ... }
}
role Qwiratry::Location::Base::DestinationPush {
    method open-sink-push(Str:D $location --> Mu) { ... }  # write-chunk / close
}

class Qwiratry::Format::Base::ParseWalkable {
    method parse-walkable(Str $input-string --> Mu) { ... }
}
class Qwiratry::Format::Base::RenderWalkable {
    method render-walkable(Mu $data, Associative :%options --> Str) { ... }
}
role Qwiratry::Format::Base::ParsePull {
    method parse-pull(Iterator:D $chunks, *%options --> Mu) { ... }
}
role Qwiratry::Format::Base::RenderPull {
    method render-pull(Mu $data, Associative :%options --> Iterator:D) { ... }
}

Operators choose pull when both sides advertise it; otherwise walkable fallback. Full Supply push roles are deferred.

5.3 TypedIterator (element kind on pull streams)

Decision: one Location pull/sink surface (SourcePull / DestinationPush), not parallel read-rows APIs. Advertise element kind with TypedIterator.

Same role is the element-kind face for query match streams:

# lib/TypedIterator.rakumod
role TypedIterator does Iterator {
    method of(--> Mu:U) { Mu }   # default = untyped / per-element
}
# TypedIterator::Wrapper β€” wrap a foreign Iterator with an explicit :of

role QueryIterator does TypedIterator { ... }  # match streams + Context
# QueryCursor.iterator / Plan.iterator β†’ QueryIterator β‡’ also TypedIterator
# Default .of = Mu (heterogeneous matches); walkers may override later

.of means β€œelement kind of this pull stream,” whether the producer is Location I/O (chunks/rows) or a query match bridge β€” not I/O-only.

.ofBehaviour
StrText-chunk path: Parse may consume; Destination may write-chunk (landed)
Row / Associative / TupleStructured path: skip text Parse; Destination row sink β€” Basics (no interim row type until table Locations)
Mu or plain IteratorPer-element; text adaptors require Str or error (no blind .Str) (landed for text)

Landed: File .of = Str; text adaptors raise X::Qwiratry::IO::ElementType; QueryIterator does TypedIterator.Basics: row .of, row sinks, Parse skip for structured streams.

Do not invent a second Storage tree; do not require a Format round-trip as the only way to get rows out of a future table Location.

5.4 Operator requirements (settled for prerequisites)

  • SourceOperator does not return an Iterator (walkable evaluate only).

  • Location read-pull SHOULD return a TypedIterator whose .of matches the payload (File: Str).

  • Text Parse/Destination MUST NOT treat every Iterator as text chunks (landed).

  • Blob Destination + non-text .of β†’ clear error (landed via ElementType); structured sinks are Basics.

  • They SHOULD NOT force a lazy Seq into a full List unless required downstream.

5.5 Acceptance criteria

Text-chunk / walkable-pull (done):

  • Walkable + optional pull/sink roles on Format and Location bases.

  • File implements read-pull and open-sink-push.

  • Parse / Render / Destination compose pull without forcing full materialisation where both sides support it.

  • NDJSONdemo reference format with walkable + pull.

  • Documented rename map / Extending docs for walkable method names.

  • Unit coverage in t/unit/streaming-io.rakutest.

TypedIterator readiness:

  • TypedIterator with .of(--> Mu:U) (default Mu); plain Iterator = untyped.

  • File pull returns TypedIterator with .of = Str.

  • Destination / Parse text path: non-text .of β†’ error; .of = Mu β†’ per-element Str or error.

  • SourceOperator remains walkable-only (does not return Iterator) β€” settled.

  • QueryIterator does TypedIterator (default .of = Mu); QueryCursor.iterator / Plan.iterator are then TypedIterators.

  • Extending docs describe .of for Location pull and for query match streams.

  • Pull vs walkable discovery: ~~ SourcePull / ~~ DestinationPush (document in Extending); element kind lives on the Iterator via .of.

Row sink / Parse skip when .of is structured β†’ Basics.

5.6 Soft foundation β€” WalkCursor / QueryCursor (tree done)

Normative design: Cursor-Proposal.md. Tree first landing shipped. Memory/Postgres/Relation cursor backends are TaOP Basics.

Done (Tree proof):

  • Generic WalkCursor + Sector / Axis in lib/WalkCursor.rakumod.

  • Qwiratry::QueryCursor; Plan.cursor; walk-local Navigator.

  • Strategy optional WalkCursor :$cursor; Navigation Evaluator delegation.

  • QueryCursor.iterator match bridge β†’ QueryIterator (not a visit-every-node stream).

  • Extending docs; t/unit/query-cursor.rakutest.

  • Sector vocabulary; Cursor Axis = bidirectional sector pair.

  • Postgres-style fetch-* / move-* documented for later TaOP backends.

Settled: WalkCursor has no Iterator factory. Optional pull from a cursor is QueryCursor.iterator only. That bridge returns a QueryIterator, which does TypedIterator (default .of = Mu; still typed as QueryIterator in signatures).

Do not force Location Source Iterators through QueryCursor.

6. Implementation order (prerequisites)

  1. Text-chunk streaming β€” landed (Β§5.2 / Β§5.5).

  2. WalkCursor tree landing β€” landed (Β§5.6).

  3. Sector vocabulary + Topic slang β€” landed.

  4. TypedIterator + File .of = Str + text-adaptor checks β€” landed (Β§5.3).

  5. SourceOperator stays walkable-only β€” settled (Β§5.4).

  6. QueryIterator does TypedIterator + Extending docs β€” landed (Β§5.3 / Β§5.5).

  7. Then Qwiratry-TaOP-Basics.md: Relation, Memory, Tables, Postgres, row sinks, row .of, …

7. Open points (prerequisite)

  • Whether specific Tree/Table QueryIterators should override .of soon, or leave Mu until Basics (default leave Mu).

Moved to Basics / deferred: interim row .of type; Destination row sink + Parse skip; full Supply push; bare Source returning Iterator.

8. References

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.