@@ -1007,6 +1007,63 @@ jobs:
10071007 unset($pdo);
10081008 }
10091009
1010+ - name : Probe Turso PDO churn — does state accumulate that breaks later queries?
1011+ continue-on-error : true
1012+ env :
1013+ LD_PRELOAD : ${{ steps.preload.outputs.value }}
1014+ run : |
1015+ php <<'PHP'
1016+ <?php
1017+ // The 3 failing tests all pass in fresh-PDO probes but fail
1018+ // mid-suite. This probe simulates the suite's PDO churn:
1019+ // open N PDOs, run a smattering of operations on each, close.
1020+ // Then in a final fresh PDO, run the failing-test query shape
1021+ // and see whether the bug manifests.
1022+ //
1023+ // If the bug reproduces past some N, we have a minimal repro
1024+ // and can bisect what specifically accumulates.
1025+ function setup_and_run(int $churn_count): array {
1026+ for ($i = 0; $i < $churn_count; $i++) {
1027+ $p = new PDO('sqlite::memory:');
1028+ $p->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
1029+ $p->exec('CREATE TABLE t (id INT, v TEXT)');
1030+ $p->exec("INSERT INTO t VALUES (1, 'a'), (2, 'b'), (3, 'c')");
1031+ $p->query('SELECT * FROM t');
1032+ // CREATE TEMP TABLE on each — exercises temp pager
1033+ $p->exec('CREATE TEMPORARY TABLE t2 (id INT)');
1034+ $p->exec("INSERT INTO t2 VALUES (1)");
1035+ unset($p);
1036+ }
1037+ // Now in a fresh PDO, run the failing-test shape.
1038+ $p = new PDO('sqlite::memory:');
1039+ $p->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
1040+ $p->exec("CREATE TABLE _ist (table_schema TEXT, table_name TEXT)");
1041+ $p->exec("CREATE TABLE _isc (table_schema TEXT, table_name TEXT, column_name TEXT, extra TEXT)");
1042+ $p->exec("INSERT INTO _ist VALUES ('main','low'), ('main','high'), ('main','plain')");
1043+ $p->exec("INSERT INTO _isc VALUES ('main','low','id','auto_increment'), ('main','high','id','auto_increment'), ('main','plain','id','')");
1044+ $p->exec("CREATE TABLE sqlseq (name TEXT, seq INT)");
1045+ $p->exec("INSERT INTO sqlseq VALUES ('low',1), ('high',5)");
1046+ $derived = "(SELECT table_name AS NAME,
1047+ (SELECT COALESCE(s.seq + 1, 1) FROM _isc AS c LEFT JOIN sqlseq AS s ON s.name = c.table_name
1048+ WHERE c.extra = 'auto_increment' AND c.table_schema = t.table_schema AND c.table_name = t.table_name) AS AI
1049+ FROM _ist AS t)";
1050+ $rows1 = $p->query("SELECT NAME FROM $derived WHERE AI > 3")->fetchAll(PDO::FETCH_COLUMN);
1051+ // also run a temp-table sequence
1052+ $temp_ok = true;
1053+ $temp_err = null;
1054+ try {
1055+ $p->exec('CREATE TEMPORARY TABLE _ttest (id INTEGER PRIMARY KEY AUTOINCREMENT, v TEXT NOT NULL DEFAULT \'\')');
1056+ $p->exec('DROP TABLE _ttest');
1057+ } catch (Throwable $e) { $temp_ok = false; $temp_err = $e->getMessage(); }
1058+ return ['filter_rows' => $rows1, 'temp_ok' => $temp_ok, 'temp_err' => $temp_err];
1059+ }
1060+ foreach ([0, 1, 5, 20, 50, 100, 200, 500] as $n) {
1061+ $r = setup_and_run($n);
1062+ $rows = json_encode($r['filter_rows']);
1063+ $temp = $r['temp_ok'] ? 'temp OK' : 'temp FAIL: '.$r['temp_err'];
1064+ echo "churn=$n filter_rows=$rows $temp\n";
1065+ }
1066+
10101067 - name : Probe Turso correlated subquery in derived-table SELECT list
10111068 continue-on-error : true
10121069 env :
0 commit comments