listcursorplan

package
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Sep 10, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package listcursorplan доказывает ПОВЕДЕНИЕМ, что страница курсорного списка берёт свой порядок из индекса, а не достраивает его сортировкой.

Зачем отдельная проба, если гейт уже зелёный

Гейт `internal/repohygiene` сводит текст миграции с текстом запроса. Это утверждение о СХЕМЕ: «объявлен индекс такой-то формы». Утверждение о ПОВЕДЕНИИ — другое: «планировщик Postgres берёт порядок отсюда». Между ними умещается всё, что гейт по построению не знает: тип индекса, класс операторов, сортировка колонки, версия сервера, порядок колонок, который человек прочитал иначе, чем читает база. Поэтому форма проверяется разбором, а действие — планом настоящего Postgres на настоящей схеме сервиса.

Что именно утверждается и почему без данных

Проба спрашивает у базы ПЛАН страницы:

EXPLAIN SELECT … FROM <схема>.<таблица> [WHERE <равенство>]
        ORDER BY <ключи курсора> LIMIT <размер+1>

и требует двух вещей сразу: план ИМЕНУЕТ ожидаемый индекс и НЕ содержит узла сортировки.

Выбор плана зависит от статистики, а статистика — от числа строк, которое проба сама и насыпала бы. Такая проба меряла бы не свойство схемы, а удачность подобранного объёма: на трёхстах строках вердикт один, на трёх тысячах другой, и оба «настоящие». Поэтому основной вопрос ставится ДЕТЕРМИНИРОВАННО — последовательное чтение и сортировка выключаются на время одного запроса (`SET LOCAL enable_seqscan/enable_sort = off`). Обе ручки МЯГКИЕ: они не запрещают план, а делают его дорогим. Значит база возьмёт упорядоченный путь по индексу тогда и только тогда, когда он СУЩЕСТВУЕТ, — а когда его нет, честно построит сортировку, и проба это увидит.

Один случай на сервис проверяется ВДОБАВОК реалистично — на насыпанных строках, с `ANALYZE` и БЕЗ единой ручки: там план выбирает сам планировщик по своей стоимости. Реалистичным сделан общий список операций: у его таблицы нет ни внешних ключей, ни триггеров учёта, поэтому строки насыпаются одним оператором и не тянут за собой фикстуру половины сервиса.

Контроль в обратную сторону обязателен

Утверждение «сортировки в плане нет» само по себе зеленело бы на пробе, которая ничего не читает. Поэтому каждый прогон обязан нести КОНТРОЛЬ: тот же запрос к той же таблице, упорядоченный по колонке, под которую индекса нет. Его план обязан содержать сортировку. Без контроля проба доказывает только то, что она выполнилась.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Run

func Run(t *testing.T, opts Options)

Run применяет цепочку миграций сервиса в пустую базу и проверяет план каждого случая.

func SeedOperations

func SeedOperations(schema string) string

SeedOperations — 5000 строк общей таблицы операций одним оператором.

Живёт здесь, а не у каждого сервиса: семь копий одного посева разошлись бы молча, и разошлись бы на составе колонок. Отметки времени расходятся, поэтому порядок по (created_at, id) не вырожден и ничьи не решают всё.

Types

type Case

type Case struct {
	// Table — таблица без схемы.
	Table string
	// Index — индекс, который план ОБЯЗАН назвать.
	Index string
	// Order — ключи курсора дословно, как их пишет репозиторий:
	// `created_at ASC, id ASC`.
	Order string
	// Where — равенство, которое несёт настоящий обход (`project_id = 'prj-plan'`).
	// Пусто, если у обхода обязательного равенства нет.
	Where string
	// Seed — оператор, насыпающий строки. Непуст ⇒ случай проверяется ВДОБАВОК
	// реалистично: `ANALYZE`, затем план БЕЗ единой ручки.
	Seed string
}

Case — один курсорный обход, чей план проверяется.

type Control

type Control struct {
	Table string
	Order string
}

Control — обратная половина: обход, под который индекса нет и быть не должно. Его план обязан содержать сортировку, иначе проба не доказывает ничего.

type Options

type Options struct {
	Service string
	Schema  string
	FS      fs.FS
	Cases   []Case
	Control Control
}

Options — что проверять у одного сервиса.

Jump to

Keyboard shortcuts

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