Show rows for all reads and confirm nextval()

SHOW, EXPLAIN, VALUES and TABLE count as reads now but their rows were
dropped and reported as a write; every read except SET now returns its
rows. nextval() advances a sequence, so it needs confirmation like
setval().
This commit is contained in:
2026-09-30 03:59:11 +02:00
parent 10055c9358
commit f89ced651b
3 changed files with 3 additions and 2 deletions
+1 -1
View File
@@ -174,7 +174,7 @@ class DbController extends Controller
$stmt = $this->db->prepare($query);
$stmt->execute();
if ($statementType === 'SELECT' || ($statementType === 'WITH' && SqlGuard::isReadOnly($query))) {
if ($statementType === 'SELECT' || ($statementType !== 'SET' && SqlGuard::isReadOnly($query))) {
// Read row by row and stop at MAX_ROWS, instead of
// fetchAll() + array_slice — otherwise a SELECT without
// LIMIT on a huge table would still pull everything into
+1 -1
View File
@@ -46,7 +46,7 @@ class SqlGuard
private const WRITES_INSIDE_READ = [
'/\b(INSERT|UPDATE|DELETE|MERGE|INTO|ANALYZE)\b/i',
'/^SET\s+(SESSION\s+|LOCAL\s+)?(ROLE|SESSION\s+AUTHORIZATION)\b/i',
'/\b(pg_terminate_backend|pg_cancel_backend|pg_reload_conf|set_config|setval|lo_create|lo_put|lo_unlink|pg_switch_wal|pg_create_restore_point|pg_advisory_lock)\s*\(/i',
'/\b(pg_terminate_backend|pg_cancel_backend|pg_reload_conf|set_config|setval|nextval|lo_create|lo_put|lo_unlink|pg_switch_wal|pg_create_restore_point|pg_advisory_lock)\s*\(/i',
];
/**
+1
View File
@@ -110,6 +110,7 @@ class SqlGuardTest extends TestCase
['SELECT pg_terminate_backend(123)'],
["SELECT set_config('x', 'y', false)"],
["SELECT setval('seq', 1)"],
["SELECT nextval('seq')"],
['MERGE INTO t USING s ON true WHEN MATCHED THEN DELETE'],
['VACUUM'],
["WITH a AS (SELECT '/*'), b AS (DELETE FROM t RETURNING 1) SELECT '*/'"],