"""End-to-end SELECT benchmarks. Measure the full PREPARE → EXECUTE → FETCH → CLOSE → RELEASE round-trip for representative query shapes. The codec micro-benchmarks set the *ceiling* (best-case CPU); these tell you how much of that ceiling the wire protocol + server response time eats. Layered comparison: - ``select_one_row`` — protocol-overhead floor (single tiny round-trip) - ``select_systables_first`` — small server-side query (~10 rows) - ``select_bench_table_all`` — full 1k-row table fetch (sustained throughput) """ from __future__ import annotations import pytest import informix_db pytestmark = [pytest.mark.benchmark, pytest.mark.integration] def test_select_one_row(benchmark, bench_conn: informix_db.Connection) -> None: """Single-row round-trip — protocol-overhead floor.""" def run() -> object: cur = bench_conn.cursor() cur.execute("SELECT 1 FROM systables WHERE tabid = 1") row = cur.fetchone() cur.close() return row benchmark(run) def test_select_systables_first_10(benchmark, bench_conn: informix_db.Connection) -> None: """Small server-side query — describes 4 columns, returns ~10 rows.""" def run() -> list: cur = bench_conn.cursor() cur.execute( "SELECT FIRST 10 tabname, owner, tabid, ncols FROM systables" ) rows = cur.fetchall() cur.close() return rows benchmark(run) def test_select_bench_table_all( benchmark, bench_conn: informix_db.Connection, bench_table: str ) -> None: """1000-row sustained fetch — covers the typical reporting query.""" def run() -> list: cur = bench_conn.cursor() cur.execute(f"SELECT * FROM {bench_table}") rows = cur.fetchall() cur.close() return rows benchmark(run) def test_select_with_param( benchmark, bench_conn: informix_db.Connection, bench_table: str ) -> None: """Parameterized SELECT — exercises the BIND path.""" def run() -> list: cur = bench_conn.cursor() cur.execute( f"SELECT id, name FROM {bench_table} WHERE counter > ?", (5000,), ) rows = cur.fetchall() cur.close() return rows benchmark(run)