tursodatabase/turso · error · SystemExit

no query finished on any engine

Error message

no query finished on any engine

What it means

The Figure constructor computes the y-axis range from the minimum 'low' timing across all series. Every series low is None when no query finished on any engine (all runs missing/timing data), so axis scaling would divide by nothing; the script exits with this message.

Source

Thrown at perf/tpc-h/plot/plot-tpch.py:142

                for x, (t, lo, hi) in enumerate(zip(self.times, self.lows, self.highs)) if t is not None]


def parse_time(text):
    text = text.strip()
    if not text or text.upper() == "NA":
        return None
    return float(text)


class Figure:
    def __init__(self, runs, columns, names):
        self.queries = [row["Query"] for row in runs[0].rows]
        self.series = [Series(c, i, self.queries, runs, names.get(c.lower())) for i, c in enumerate(columns)]
        self.whiskers = len(runs) > 1
        lows = [t for s in self.series for t in s.lows if t is not None]
        highs = [t for s in self.series for t in s.highs if t is not None]
        if not lows:
            raise SystemExit("no query finished on any engine")
        # A decade of headroom under the fastest run and over the slowest,
        # so the shortest bar still has height and the legend fits over the tallest.
        self.ymin = 10 ** np.floor(np.log10(min(lows)))
        self.ymax = 10 ** (np.ceil(np.log10(max(highs))) + 0.5)
        self.bar_width = GROUP_WIDTH / len(self.series)

    def offset(self, index):
        """How far the bars of the engine at `index` sit from the query's centre."""
        return (index - (len(self.series) - 1) / 2) * self.bar_width

    def matplotlib(self, output):
        import matplotlib

        matplotlib.use("Agg")
        import matplotlib.pyplot as plt
        import scienceplots  # noqa: F401  (registers the styles)
        from matplotlib.ticker import FuncFormatter, NullLocator

View on GitHub (pinned to 492c4a71cd)

Solutions

  1. Check the CSV timing columns contain numeric values: `head results.csv`; re-run the benchmark if all timings are missing.
  2. Fix engine crashes/errors that prevented any query from completing before plotting.
  3. Verify the column names expected by Series (e.g. 'Query', timing columns) match the CSV header.
  4. Plot a run where at least one query completed on one engine.

Example fix

// before
python plot-tpch.py --csv-files all_failed.csv -o out
// after
python plot-tpch.py --csv-files successful_run.csv -o out
Defensive patterns

Strategy: validation

Validate before calling

import csv
def has_any_timing(paths):
    for p in paths:
        with open(p, newline="") as f:
            for row in csv.DictReader(f):
                if row.get("low") not in (None, ""):
                    return True
    return False

Prevention

When it happens

Trigger: Building the Figure from runs whose rows have no valid timing values in the low/high columns — e.g. every query errored, timed out, or the timing columns are absent/None in all CSVs.

Common situations: Benchmark run where all engines failed on all TPC-H queries; plotting CSVs that contain rows but only error markers or empty timing cells; comparing against an engine that produced no completed measurements.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of tursodatabase/turso@492c4a71cd (2026-09-13). Data as JSON: /api/errors/57cfb95edcceefd0. Report an issue: GitHub.