ResultSet fetch methods silently return empty after close instead of raising (PEP 249 §Cursor)
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Facilidade para iniciantes
- 55/100
- Tipo de issue
- Bug
- Clareza
- Razoavelmente clara
- Status de atividade
- Pouca atividade
- Stack de tecnologia
- python
- Domínio
- backend-api-design
Direção de pesquisa
Comece em src/databricks/sql/result_set.py e, em seguida, rastreie os métodos de fetch de ThriftResultSet, SeaResultSet e KernelResultSet. Reproduza primeiro o exemplo de cursor fechado e inspecione como close() define o estado existente e os flags de esgotamento. O trabalho estará concluído quando todos os métodos de fetch listados gerarem InterfaceError após close() para os três backends, o comportamento do PEP 249 estiver verificado e a observação de compatibilidade tiver sido considerada.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
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.
- Linguagem predominante
- Python
- Estrelas
- 233
- Forks
- 152
- Merge médio
- 21h 5min
- PRs com merge (30d)
- 10
Guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de databricks/databricks-sql-python
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 76/100
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 84/100
Todas as issues de databricks/databricks-sql-python
Issues semelhantes
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 84/100
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 86/100
-
🐛 Bug 🔔 Pending processing
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 84/100
jumpserver/jumpserver#17584 ·