Describe the bug
fetchone() and cursor iteration fail with InterfaceError on results from ODBC catalog methods (cursor.tables(), cursor.columns(), etc.), while fetchall() works correctly on the same result set.
The error is:
InterfaceError: Driver Error: Cannot increment rownumber: no active result set.; DDBC Error: No active result set.
After calling any catalog method (e.g., cursor.tables()):
cursor.description is correctly populated with column metadata
cursor.rownumber remains -1 (never gets set to 0)
fetchall() works and returns all expected rows
fetchone() raises InterfaceError
for row in cursor: also fails since it calls fetchone() internally
The root cause appears to be in _increment_rownumber() — it guards against rownumber == -1 assuming no active result set, but catalog functions don't initialize rownumber to 0 the way execute() does. fetchall() bypasses this guard, which is why it works.
To reproduce
import mssql_python
conn = mssql_python.connect(
"Server=localhost;Database=AdventureWorks2022;"
"UID=sa;PWD=YourPassword;TrustServerCertificate=yes"
)
# --- fetchall() works ---
cursor1 = conn.cursor()
cursor1.tables(table="Product", schema="Production")
print(f"description: {cursor1.description is not None}") # True
rows = cursor1.fetchall()
print(f"fetchall: {len(rows)} rows") # fetchall: 1 rows
print(f"table_name: {rows[0].table_name}") # table_name: Product
cursor1.close()
# --- fetchone() fails ---
cursor2 = conn.cursor()
cursor2.tables(table="Product", schema="Production")
print(f"description: {cursor2.description is not None}") # True
print(f"rownumber: {cursor2.rownumber}") # rownumber: -1 <-- should be 0
try:
row = cursor2.fetchone() # InterfaceError!
print(f"fetchone: {row.table_name}")
except Exception as e:
print(f"fetchone error: {e}")
cursor2.close()
# --- cursor iteration also fails ---
cursor3 = conn.cursor()
try:
for row in cursor3.tables(): # InterfaceError!
print(row.table_name)
except Exception as e:
print(f"iteration error: {e}")
cursor3.close()
conn.close()
Output:
description: True
fetchall: 1 rows
table_name: Product
description: True
rownumber: -1
fetchone error: Driver Error: Cannot increment rownumber: no active result set.; DDBC Error: No active result set.
iteration error: Driver Error: Cannot increment rownumber: no active result set.; DDBC Error: No active result set.
Expected behavior
fetchone() and cursor iteration should work on catalog method results the same way they work for execute() results. rownumber should be initialized to 0 after a catalog method call that produces results.
Further technical details
Python version: 3.14.0 (CPython, MSC v.1944 64 bit AMD64)
SQL Server version: SQL Server 2022
Operating system: Windows 11 (10.0.26200)
Additional context
All nine ODBC catalog methods are affected:
cursor.tables()
cursor.columns()
cursor.procedures()
cursor.primaryKeys()
cursor.foreignKeys()
cursor.statistics()
cursor.rowIdColumns()
cursor.rowVerColumns()
cursor.getTypeInfo()
Workaround: Use cursor.tables(); rows = cursor.fetchall() instead of for row in cursor.tables():.
Driver version: mssql-python 1.4.0
Describe the bug
fetchone()and cursor iteration fail withInterfaceErroron results from ODBC catalog methods (cursor.tables(),cursor.columns(), etc.), whilefetchall()works correctly on the same result set.The error is:
After calling any catalog method (e.g.,
cursor.tables()):cursor.descriptionis correctly populated with column metadatacursor.rownumberremains-1(never gets set to0)fetchall()works and returns all expected rowsfetchone()raisesInterfaceErrorfor row in cursor:also fails since it callsfetchone()internallyThe root cause appears to be in
_increment_rownumber()— it guards againstrownumber == -1assuming no active result set, but catalog functions don't initializerownumberto0the wayexecute()does.fetchall()bypasses this guard, which is why it works.To reproduce
Output:
Expected behavior
fetchone()and cursor iteration should work on catalog method results the same way they work forexecute()results.rownumbershould be initialized to0after a catalog method call that produces results.Further technical details
Python version: 3.14.0 (CPython, MSC v.1944 64 bit AMD64)
SQL Server version: SQL Server 2022
Operating system: Windows 11 (10.0.26200)
Additional context
All nine ODBC catalog methods are affected:
cursor.tables()cursor.columns()cursor.procedures()cursor.primaryKeys()cursor.foreignKeys()cursor.statistics()cursor.rowIdColumns()cursor.rowVerColumns()cursor.getTypeInfo()Workaround: Use
cursor.tables(); rows = cursor.fetchall()instead offor row in cursor.tables():.Driver version: mssql-python 1.4.0