collide

package
v0.18.49 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2026 License: AGPL-3.0 Imports: 2 Imported by: 0

Documentation

Overview

Package collide is the COLLIDING-BARE-NAME fixture: three relations whose columns are all called c0, c1, c2, the way SQLancer names every schema it generates.

It exists because every other corpus in this repository prefixes its column names per table — TPC-H's `l_`, `o_`, `c_`, `n_`; the type matrix's `c_i32`, `c_str`; multikey's shared `s`, `n`, `d` across four tables of ONE schema — so no two DIFFERENT relations in one query ever share a bare column name that means different things. That is the blind spot #843 lived in for twelve releases: inside a derived table with two or more UNALIASED relations, every base scan was re-aliased to the derived table's alias, so `t0.c1` bound to whichever relation was planned last and the query answered another table's column with no error at all. A fixture whose bare names collide is the only shape that can see it, and it belongs in the corpora whether or not any particular defect is fixed.

Every Want here was measured on live postgres:17-alpine over these exact rows.

Index

Constants

View Source
const (
	T0 = "clt0"
	T1 = "clt1"
	T2 = "clt2"
	// T4 and T5 carry ONE column whose names differ only by CASE. Since an
	// unquoted reference folds (#731) those two names are one name to every
	// resolver, so a qualified reference to either is only resolvable through
	// its RELATION — the identity is (relation, folded name) and never the
	// bare folded name (ADR-0026). Without them nothing in any corpus made
	// that distinction: the arc's round-0 review found `SELECT clt4.MixedCol,
	// clt5.mixedcol FROM clt4, clt5` answering clt5's value TWICE on all four
	// arms.
	T4 = "clt4"
	T5 = "clt5"
	// T6 is the THIRD spelling of that one folded name, all upper case, so a
	// query can name all three relations at once and each reference has two
	// wrong answers available to it rather than one. Round 1's review found
	// single and dag DISAGREEING on exactly that shape.
	T6 = "clt6"
	// TCam is a CamelCase SCHEMA — the shape a parquet-registered table has,
	// and ClickBench's `hits` exactly. It is here because no DAG or worker
	// gate put one through `batch.resolveFoldedIndex`'s case-insensitive arm:
	// the two-path corpora all run on all-lower-case fixtures, so the half of
	// #731 that keeps ClickBench working never executed on a worker.
	TCam = "cltcam"
)

The three relations. SQLancer's own names, kept, so a dump from it can be replayed against this fixture without renaming anything.

Variables

This section is empty.

Functions

func CamelData

func CamelData() []map[string]any

CamelData is TCam's rows.

func CamelSchema

func CamelSchema() parquet.Schema

CamelSchema is TCam's: names a parquet file would carry, not names a DDL would fold.

func CaseData

func CaseData(table string) []map[string]any

CaseData is one case-colliding relation's rows. The three relations' value ranges do not overlap, so a reference bound to the wrong one cannot answer the right number by accident.

func CaseSchema

func CaseSchema(col string) parquet.Schema

CaseSchema is T4's and T5's, parameterized by the case-carrying column's spelling: `MixedCol` in one relation, `mixedcol` in the other.

func Data

func Data(table string) []map[string]any

Data is one relation's rows. The values are chosen so that a reference bound to the WRONG relation cannot answer the right number by accident: the three tables' c1 ranges do not overlap, and t0 carries the NULL that makes the headline shape's `IS NOT NULL` predicate mean something.

func Schema

func Schema() parquet.Schema

Schema is shared by all three: bare names that mean a DIFFERENT column in each table.

Types

type Case

type Case struct {
	Name    string
	SQL     string
	Want    []string
	Ordered bool
	// PGSQL is the spelling PostgreSQL needs for the same question, when the
	// wadjet spelling is one PostgreSQL cannot resolve. It is filled in
	// automatically for every entry naming a CamelCase column of this fixture
	// — see pgSpelling — because that unquoted spelling IS the divergence
	// ADR-0012 records: PostgreSQL matches a folded name exactly against the
	// catalog, so `clt4.MixedCol` is 42703 there and `clt4."MixedCol"` is the
	// question it can answer. Every value this corpus asserts is therefore
	// PostgreSQL's answer to the quoted spelling, which is the contract that
	// entry states.
	PGSQL string
	// Ref is the same question with DISTINCT output names, for the entries
	// whose own names collide. A result read BY NAME cannot represent two
	// columns of one name, so the duplicate spelling is compared against its
	// reference — which is positional by construction and works on the DAG,
	// where no positional accessor reaches the caller.
	Ref string
	// KnownBug pins a divergence from Want. The comparison still runs and
	// Want stays exactly as PostgreSQL wrote it, so a pinned entry that
	// starts AGREEING fails and deleting the pin is the proof of a fix
	// (ADR-0013 §Pins).
	KnownBug string
	Issue    string
	// KnownBugArms narrows the pin to the EXECUTION ARMS that diverge, by
	// the two-path gate's own names ("single", "spilled", "dag",
	// "dag-shuffled"). Empty means every arm, which is what a pin meant
	// before this existed.
	//
	// A divergence that is real on ONE arm is the most dangerous kind — two
	// engines answering one query differently — and pinning it everywhere
	// would stop asserting the arms that are RIGHT, which is how a fix on
	// three arms silently regresses on the fourth. With the arms named, an
	// unlisted arm is asserted normally and a listed one still fails the day
	// it agrees. The single-process PostgreSQL oracle ignores an entry whose
	// pin does not name "single": that comparison is not the divergent path.
	KnownBugArms []string
}

Case is one corpus entry. Want is the ROW LIST PostgreSQL 17 answers, rendered one string per row, in the entry's own ORDER when Ordered is set.

func Corpus

func Corpus() []Case

Corpus is the shape list. Each entry names a way two relations that share a bare column name can be confused for one another.

func DuplicateNameCorpus

func DuplicateNameCorpus() []Case

DuplicateNameCorpus is the part of this fixture whose answer cannot be read through a map keyed by column NAME, so it is kept apart from Corpus(): both of these project two columns called `c0`, and `map[string]any` holds one of them. That losing map is not an accident of the harness — it is the same mistake the ENGINE makes in #844, where a UNION ALL branch projecting two columns of one bare name binds the first to the LAST one's value. A gate that reads rows by name cannot tell the two apart, which is why these entries are gated POSITIONALLY (wadjet.QueryResult.Cells) instead.

Want here is one string per row, cells joined by "|", in the entry's own ORDER. Measured on live postgres:17-alpine.

func (Case) PinnedOn

func (c Case) PinnedOn(arm string) bool

PinnedOn reports whether this entry's KnownBug applies to the named execution arm.

type FixtureTable

type FixtureTable struct {
	Name   string
	Schema parquet.Schema
	Rows   []map[string]any
}

FixtureTable is one loadable table. Every consumer loads Tables(), so a relation cannot be added to the corpus and forgotten in one of the gates.

func Tables

func Tables() []FixtureTable

Tables is the whole fixture.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL