ResultSet fetch methods silently return empty after close instead of raising (PEP 249 §Cursor)
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 55/100
- Tipo di issue
- Bug
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Tranquilla
- Stack tecnologico
- python
- Ambito
- backend-api-design
Direzione di ricerca
Inizia da src/databricks/sql/result_set.py, quindi segui i metodi di fetch di ThriftResultSet, SeaResultSet e KernelResultSet. Riproduci prima l’esempio del cursore chiuso e verifica come close() imposta lo stato esistente e i flag di esaurimento. Il lavoro è completo quando ogni metodo di fetch elencato solleva InterfaceError dopo close() per tutti e tre i backend, il comportamento PEP 249 è verificato e la nota sulla compatibilità è stata presa in considerazione.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
PEP 249 §Cursor says fetch operations on a closed cursor should raise an exception. Today, all three result-set implementations (ThriftResultSet, SeaResultSet, KernelResultSet) silently return empty after close() rather than raising InterfaceError.
Repro
import databricks.sql
with databricks.sql.connect(...) as conn:
cur = conn.cursor()
cur.execute("SELECT 1")
cur.close()
cur.fetchall() # PEP 249 says raise; today returns [].
Root cause
# src/databricks/sql/result_set.py — base ResultSet.close():
def close(self) -> None:
...
finally:
self.has_been_closed_server_side = True
self.status = CommandState.CLOSED
The flag is set, but the fetch methods don't read it. They walk self.results (an internal queue) which has been closed; next_n_rows returns empty rather than raising. KernelResultSet has the same shape with self._exhausted = True in close, which short-circuits its fetch loop to empty.
Scope
All three backends. This is a project-wide PEP 249 compliance gap, not specific to the kernel backend.
Concurrent fetch-vs-close (related)
There is no _closed flag readable by concurrent threads — if one thread is mid-fetch while another calls close(), behaviour is undefined (likely AttributeError from a nulled handle). Cursors are documented as not thread-safe, so this is "not a bug" by design, but a single _closed flag would make accidental misuse fail cleanly with InterfaceError instead of AttributeError.
Suggested fix
In base ResultSet (src/databricks/sql/result_set.py):
- Add
self._closed: bool = False. Set toTrueinsideclose()after cleanup. - Add a private
_check_open()that raisesInterfaceError("Result set is closed")if_closed. - Call
_check_open()at the top of every fetch method (fetchone,fetchmany,fetchall,fetchmany_arrow,fetchall_arrow).
Backwards-compat note: any user code that defensively does cur.close(); cur.fetchall() expecting [] will start raising. Likely warrants a release note.
Surfaced by
Review of PR #787 (kernel backend). Documented as P1 #8 + #9 in https://github.com/databricks/databricks-sql-python/pull/787#issuecomment-4475165482 — but the gap is pre-existing on Thrift and SEA too, not specific to the kernel backend.
- Lingua principale
- Python
- Stelle
- 233
- Fork
- 152
- Merge medio
- 21h 5m
- PR unite (30g)
- 10
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di databricks/databricks-sql-python
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
Tutte le issue di databricks/databricks-sql-python
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 86/100
-
🐛 Bug 🔔 Pending processing
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
jumpserver/jumpserver#17584 ·