Physical plans
A physical plan specifies which operators execute a query, what data each operator receives, and what data it produces. An operator performs one part of the query, such as classifying reviews or selecting result columns. The plan also records execution settings, such as the attention path used by a model operator.
The optimizer builds the physical plan from a logical plan. The logical plan describes the requested operations. The physical plan specifies how Quail executes them.
Execute a review query
For example, imagine a reviews table with an id column for review
identifiers and a body column for review text. This query classifies
each review as positive or negative and returns only negative reviews:
SELECT r.id,
AI.CLASSIFY(
PROMPT('What sentiment does this review express? {0}', r.body),
ARRAY['positive', 'negative']) AS sentiment
FROM reviews r
WHERE AI.CLASSIFY(
PROMPT('What sentiment does this review express? {0}', r.body),
ARRAY['positive', 'negative']) IN ('negative');Before execution, Quail tokenizes the review text. During execution,
it identifies each review by its row position in the input table,
starting at zero. Quail calls this position a document ID. It is separate
from the value in reviews.id.
Quail uses four operators to execute this query. Each box represents an operator. Each arrow shows the data passed between operators.
flowchart TD
scan["Scan"]
classify["AiClassify"]
filter["Filter"]
project["Project"]
scan -->|Document IDs| classify
classify -->|Document IDs and labels| filter
filter -->|Document IDs for negative reviews| project
classify -->|Document IDs and labels| project
- Scan returns the document IDs for the
reviewsinput. - AiClassify receives these IDs and uses the model to classify the corresponding reviews. It produces a table of document IDs and labels.
- Filter reads that table and keeps the document IDs whose label is
negative. This comparison runs on the CPU. - Project receives the selected document IDs and the classification
table. It reads
reviews.idfor each selected review and adds the classification label. The result hasidandsentimentcolumns.
The SELECT and WHERE expressions use the same classification output.
Quail does not classify each review again for the SELECT expression.
The arrows show which inputs each operator needs. Compatible operators can pass batches to each other before they finish processing all rows. See Execution for how Quail groups and schedules these operators.
Inspect the plan
Call query.explain() to inspect the plan without running model inference.
The output shows the operators, their execution settings, and estimated work.
Editing a plan
Call query.plan() to get a plan that you can edit before execution.
Each edit returns a new plan. You can execute it with
query.run(plan=edited).
See Editing physical plans for a complete example that inspects a plan, inserts an operator, and removes it.
To implement an operator, see Custom operators. That guide explains how operator classes declare their inputs, outputs, and execution code.