fix(datasources): MySQL browser race + slow row counts

When switching source engine, the sample effect fired with the previous
engine selected object (e.g. public.sales_orders against MySQL), surfacing
"Table hr.sales_orders doesn't exist". Track which engine the selected
object belongs to and only sample when it matches the active engine, plus
guard against stale responses overwriting newer ones.

Row-count for the browser used an exact count(*) which full-scanned huge
tables (~30s on 24M rows). Use planner/statistics estimates and only run a
time-bounded exact count for small (<=50k) tables.
This commit is contained in:
mo
2026-06-28 10:10:17 +00:00
parent 1432a8429a
commit d05fe403a2
2 changed files with 42 additions and 10 deletions
+30 -4
View File
@@ -693,8 +693,20 @@ def _table_row_count(engine: str, object_name: str) -> int | None:
)
try:
cur = conn.cursor()
cur.execute(f'SELECT count(*) FROM "{schema}"."{table}"')
return int(cur.fetchone()[0])
# Planner estimate first; only do a (bounded) exact count for small
# tables so huge tables don't trigger a slow full scan.
cur.execute("SELECT reltuples::bigint FROM pg_class WHERE oid = %s::regclass", (f'"{schema}"."{table}"',))
row = cur.fetchone()
est = int(row[0]) if row and row[0] is not None and row[0] >= 0 else 0
if est <= 50000:
try:
cur.execute("SET LOCAL statement_timeout = 4000")
cur.execute(f'SELECT count(*) FROM "{schema}"."{table}"')
return int(cur.fetchone()[0])
except Exception:
conn.rollback()
return est
return est
finally:
conn.close()
if engine == "mysql":
@@ -705,8 +717,22 @@ def _table_row_count(engine: str, object_name: str) -> int | None:
)
try:
cur = conn.cursor()
cur.execute(f"SELECT count(*) FROM `{table}`")
return int(cur.fetchone()[0])
# Fast estimate from statistics; only do a (bounded) exact count for
# small tables to avoid full scans on huge ones (e.g. 24M rows).
cur.execute(
"SELECT table_rows FROM information_schema.tables WHERE table_schema=%s AND table_name=%s",
(schema, table),
)
row = cur.fetchone()
est = int(row[0]) if row and row[0] is not None else 0
if est <= 50000:
try:
cur.execute("SET SESSION MAX_EXECUTION_TIME=4000")
cur.execute(f"SELECT count(*) FROM `{table}`")
return int(cur.fetchone()[0])
except Exception:
return est
return est
finally:
conn.close()
if engine == "mongodb":