Quail
Architecture

Overview

Quail converts a SQL query into a plan, executes the plan, and returns the results. A plan describes the operations needed to answer the query.

How Quail executes a query

For example, imagine a reviews table with review identifiers in id and review text in body. A query classifies each review as positive or negative and returns the identifiers and labels of negative reviews. Quail processes this query in five steps:

%%{init: {"flowchart": {"rankSpacing": 20, "nodeSpacing": 15, "padding": 10}}}%%
flowchart LR
  logical["Build logical plan"]
  optimize["Optimize plan"]
  physical["Build physical plan"]
  execute["Execute plan"]
  collect["Collect rows"]
  logical --> optimize --> physical --> execute --> collect
  1. Build the logical plan. The logical plan describes the requested operations and their inputs. For this query, those operations are classification, filtering by label, and selecting result columns. See Logical plans.
  2. Optimize the plan. The optimizer applies rules that remove unnecessary work or compare ways to execute the query. When a rule compares execution time, it uses an estimate of GPU time. See Optimizer for the rules and estimates.
  3. Build the physical plan. The physical plan selects the operators that will execute the query and records their settings. An operator performs one part of the query. For this query, separate operators identify the input reviews, classify them, test their labels, and select the result columns. See Physical plans.
  4. Execute the plan. Quail runs each operator when its input is available. The model classifies the reviews on the GPU. The CPU tests the labels and selects result columns. See Execution.
  5. Read the results. Execution returns a QueryResult with timing and token counts. Calling collect() reads its result rows into an Arrow table. In this example, each result row contains a review identifier and the label negative. See Results.

For how Quail stores and reuses model data in GPU memory, see KV.

On this page