3.12.6
release: v3.12.6 — Python psycopg2 % substitution fix (issue #40)
Python-only behavioural fix; PHP / Ruby / Node ship the same version
stamp for parity but carry no functional changes.
Issue tina4-python#40: psycopg2 interprets % as parameter
placeholders whenever cursor.execute is called with a params arg —
even an empty list. So migration bodies with literal % chars (e.g.
RAISE EXCEPTION 'thing %', x in PL/pgSQL) blew up with the
misleading list index out of range, looking like a tina4 internal
bug rather than psycopg2's substitution engine misfiring.
Fix: new PostgreSQLAdapter._safe_execute(cursor, sql, params) helper
routes empty/None params through cursor.execute(sql) (no second arg),
which makes psycopg2 skip the substitution pass entirely. Literal %
chars flow through. Applied at every cursor.execute call site in the
adapter (5 spots across execute, fetch, fetch_one).
Tests: 5 unit + 3 live-PG regression tests
(test_postgres_percent_substitution.py, test_postgres_plpgsql_percent.py).
Live tests skip cleanly when no Postgres is reachable. Full suite
2453 passing (was 2448).
Parity check: PHP (pg_query vs pg_query_params) and Ruby (exec vs
exec_params) already branch correctly. Node uses $1 placeholders so
the same class of bug doesn't apply.
Closes tina4-python#40.