aminghadersohi opened a new pull request, #44714: URL: https://github.com/apache/superset/pull/44714
### SUMMARY Running a statement that returns no result set (CREATE, INSERT, UPDATE, DELETE) through SQL Lab fails after the statement has already executed on several engines, because `BaseEngineSpec.fetch_data` calls `fetchall()`/`fetchmany()` unconditionally and these DB-API drivers raise when there is nothing to fetch: | Engine | Driver | Error | |---|---|---| | MySQL (`mysql+mysqlconnector`) | mysql-connector-python | `No result set to fetch from` | | Db2 (`db2+ibm_db`) | ibm_db | `The last call to execute did not produce any result set` | | Exasol (`exa`, `exa+websocket`) | pyexasol / sqlalchemy-exasol | `Attempt to fetch from statement without result set` | | Impala | impyla | `Trying to fetch results on an operation with no results` | The Postgres, Oracle and MSSQL specs each already guarded on `cursor.description`. This moves that guard into `BaseEngineSpec.fetch_data` (inside the existing `try`, so errors raised while resolving the description are still mapped), and removes the three now-redundant copies. PEP 249 defines `description` as `None` for operations that do not return rows. The guard uses `not cursor.description` (as the existing per-engine guards did) because some drivers report `[]` instead of `None` in that state (e.g. pyexasol's DB-API 2 wrapper). I checked the drivers that compute `description` lazily (pyhive Presto/Hive, trino, pydruid, sqlalchemy-drill, shillelagh, clickhouse-connect, crate, databricks-sql, firebolt, snowflake, pyathena, elasticsearch-dbapi, pinotdb): each sets it at `execute()` time, or blocks until the columns are known, whenever rows can follow, so none of them returns rows with an empty description. Engines that already catch the fetch error themselves (Hive, Drill) keep working unchanged. Impala needs one more piece. `ImpalaEngineSpec.execute` uses `execute_async`, and `handle_cursor` only keeps polling while the operation is INITIALIZED/RUNNING. Right after submission an INSERT is typically still `PENDING_STATE` (description `None`, `has_result_set` False). `fetchall()` used to wait for the operation implicitly. With the early return, the INSERT was not complete when SQL Lab moved on, and a following SELECT saw 0 rows. An asynchronously failing statement would also have looked successful. `ImpalaEngineSpec.fetch_data` now waits for the operation first (impyla's own fetch-time wait, which raises the operation's error), then defers to the base class. Fixes #34208 (same defect, reported for mysql-connector). ### TESTING INSTRUCTIONS `pytest tests/unit_tests/db_engine_specs/test_base.py -k fetch_data` `pytest tests/unit_tests/db_engine_specs/test_impala.py -k fetch_data` `test_fetch_data_no_result_set` uses a cursor that raises on fetch like these drivers do, with `description` `None` and `[]`, with and without a limit, against the base, MySQL, Db2, Exasol, Impala, Postgres, Oracle and MSSQL specs. Without the change it fails 20 cases (every base/MySQL/Db2/Exasol/Impala case). The two Impala tests (waits for the operation; raises the operation's error) fail without the Impala change. Full `tests/unit_tests/db_engine_specs/`: 1672 passed, 3 skipped, 1 failed. The one failure is `test_databricks.py::test_dialect_supports_installed_sqlalchemy`, which fails identically on unmodified master in my environment (installed Databricks dialect version). I also ran `CREATE TABLE` + `INSERT` + `SELECT` (then a dataset and a chart on the table) through the SQL Lab REST API against local MySQL 8 (mysqlconnector), Db2 11.5, Exasol 2026.2 (`exa` and `exa+websocket`) and Impala 4.5 servers. The CREATE/INSERT failed with the errors above before the change. After it, every step passed with exact rows. Impala only passed once the wait was in place. MySQL (mysqlclient) and Postgres DDL/DML were unchanged (pass before and after). ### ADDITIONAL INFORMATION - [x] Has associated issue: #34208 - [ ] Required feature flags: - [ ] Changes UI - [ ] Includes DB Migration (follow approval process in [SIP-59](https://github.com/apache/superset/issues/13351)) - [ ] Migration is atomic, supports rollback & is backwards-compatible - [ ] Confirm DB migration upgrade and downgrade tested - [ ] Runtime estimates and downtime expectations provided - [ ] Introduces new feature or API - [ ] Removes existing feature or API 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
