Skip to content

Commit ac6e988

Browse files
jahnvi480Copilot
andcommitted
FIX: Match single-row tests to native profiler and bind errors
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 4c43081 commit ac6e988

2 files changed

Lines changed: 29 additions & 24 deletions

File tree

‎profiler/README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,12 @@ separately from prefix `SQLGetData` metadata. Direct `DDBCSQLNumResultCols` call
152152
remain uncached. `fetchval()` still calls `fetchone()` and constructs the full
153153
row, including converters for columns beyond the first.
154154
155-
`FetchSingleRow::SQL_UNBIND` counts attempted unbinds in that helper. A successful
155+
`ddbc::FetchSingleRow::SQL_UNBIND` counts attempted unbinds in that helper. A successful
156156
unbind can be reused within the same generation, but does not certify row-array
157157
attributes. Binding (including Arrow and partial binds), cleanup, and generation
158158
changes invalidate reuse.
159159
160-
`FetchMany::single_numeric_row` identifies the native `fetchmany(1)` route for
160+
`ddbc::FetchMany::single_numeric_row` identifies the native `fetchmany(1)` route for
161161
all-numeric results (integer, bit, real, float/double). It retains eager count/name
162162
validation, row-array configuration and cleanup, and uses `SQLFetchScroll` plus
163163
per-column `SQLGetData`. Mixed INT/NVARCHAR, text, LOB, decimal, temporal, UUID and

‎tests/test_fetch_single_row.py‎

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -258,63 +258,63 @@ def test_single_row_native_transitions_in_subprocess(conn_str):
258258
assert retained[0] == 1
259259
assert next(cursor)[0] == 2
260260
assert cursor.fetchval() == 3
261-
assert p.get_stats()["FetchSingleRow::SQL_UNBIND"]["calls"] == 1
261+
assert p.get_stats()["ddbc::FetchSingleRow::SQL_UNBIND"]["calls"] == 1
262262
assert cursor.fetchmany(1)[0][0] == 4
263-
assert "SQLBindColums" not in p.get_stats()
264-
assert p.get_stats()["FetchMany::single_numeric_row"]["calls"] == 1
263+
assert "ddbc::SQLBindColums" not in p.get_stats()
264+
assert p.get_stats()["ddbc::FetchMany::single_numeric_row"]["calls"] == 1
265265
# Cleanup deliberately forgets the unbound marker.
266266
assert cursor.fetchone()[0] == 5
267-
assert p.get_stats()["FetchSingleRow::SQL_UNBIND"]["calls"] == 2
267+
assert p.get_stats()["ddbc::FetchSingleRow::SQL_UNBIND"]["calls"] == 2
268268
assert [r[0] for r in cursor.fetchmany(2)] == [6, 7]
269-
assert p.get_stats()["SQLBindColums"]["calls"] == 1
269+
assert p.get_stats()["ddbc::SQLBindColums"]["calls"] == 1
270270
assert cursor.fetchone()[0] == 8
271271
assert cursor.fetchone() is None
272272
assert cursor.fetchone() is None
273-
assert p.get_stats()["FetchSingleRow::SQL_UNBIND"]["calls"] == 3
273+
assert p.get_stats()["ddbc::FetchSingleRow::SQL_UNBIND"]["calls"] == 3
274274
assert tuple(retained) == (1, 11)
275275
assert retained.a == 1
276276
assert not cursor.messages
277277
278278
cursor.execute(query)
279279
assert cursor.fetchone()[0] == 1
280-
assert p.get_stats()["FetchSingleRow::SQL_UNBIND"]["calls"] == 4
280+
assert p.get_stats()["ddbc::FetchSingleRow::SQL_UNBIND"]["calls"] == 4
281281
# Public statement-attribute changes must invalidate the marker.
282282
assert ddbc.DDBCSQLSetStmtAttr(cursor.hstmt, 0, 0) == 0 # SQL_ATTR_QUERY_TIMEOUT
283283
assert cursor.fetchone()[0] == 2
284-
assert p.get_stats()["FetchSingleRow::SQL_UNBIND"]["calls"] == 5
284+
assert p.get_stats()["ddbc::FetchSingleRow::SQL_UNBIND"]["calls"] == 5
285285
cursor.execute("SELECT 21 AS a; SELECT 22 AS a")
286286
assert cursor.fetchone()[0] == 21
287287
assert cursor.nextset()
288288
assert cursor.fetchone()[0] == 22
289-
assert p.get_stats()["FetchSingleRow::SQL_UNBIND"]["calls"] == 7
289+
assert p.get_stats()["ddbc::FetchSingleRow::SQL_UNBIND"]["calls"] == 7
290290
291291
cursor.execute("SELECT CAST(N'text' AS NVARCHAR(10)) AS a")
292292
assert cursor.fetchmany(1)[0][0] == "text"
293-
assert p.get_stats()["SQLBindColums"]["calls"] == 2
293+
assert p.get_stats()["ddbc::SQLBindColums"]["calls"] == 2
294294
cursor.execute(query)
295295
assert cursor.fetchone()[0] == 1
296296
cursor.skip(1)
297-
before = p.get_stats()["FetchSingleRow::SQL_UNBIND"]["calls"]
297+
before = p.get_stats()["ddbc::FetchSingleRow::SQL_UNBIND"]["calls"]
298298
assert cursor.fetchone()[0] == 3
299-
assert p.get_stats()["FetchSingleRow::SQL_UNBIND"]["calls"] == before + 1
299+
assert p.get_stats()["ddbc::FetchSingleRow::SQL_UNBIND"]["calls"] == before + 1
300300
batch = cursor.arrow_batch(2)
301301
assert batch.to_pydict() == {"a": [4, 5], "b": [14, 15]}
302-
before = p.get_stats()["FetchSingleRow::SQL_UNBIND"]["calls"]
302+
before = p.get_stats()["ddbc::FetchSingleRow::SQL_UNBIND"]["calls"]
303303
assert cursor.fetchone()[0] == 6
304-
assert p.get_stats()["FetchSingleRow::SQL_UNBIND"]["calls"] == before + 1
304+
assert p.get_stats()["ddbc::FetchSingleRow::SQL_UNBIND"]["calls"] == before + 1
305305
assert batch.to_pydict() == {"a": [4, 5], "b": [14, 15]}
306306
# Cancel invalidates the result generation; execute recovers the handle.
307307
cursor.hstmt._cancel()
308308
cursor.execute(query)
309-
before = p.get_stats()["FetchSingleRow::SQL_UNBIND"]["calls"]
309+
before = p.get_stats()["ddbc::FetchSingleRow::SQL_UNBIND"]["calls"]
310310
assert cursor.fetchone()[0] == 1
311-
assert p.get_stats()["FetchSingleRow::SQL_UNBIND"]["calls"] == before + 1
311+
assert p.get_stats()["ddbc::FetchSingleRow::SQL_UNBIND"]["calls"] == before + 1
312312
cursor.close()
313313
with connection.cursor() as replacement:
314314
replacement.execute(query)
315-
before = p.get_stats()["FetchSingleRow::SQL_UNBIND"]["calls"]
315+
before = p.get_stats()["ddbc::FetchSingleRow::SQL_UNBIND"]["calls"]
316316
assert replacement.fetchone()[0] == 1
317-
assert p.get_stats()["FetchSingleRow::SQL_UNBIND"]["calls"] == before + 1
317+
assert p.get_stats()["ddbc::FetchSingleRow::SQL_UNBIND"]["calls"] == before + 1
318318
p.disable()
319319
""")
320320
environment = os.environ.copy()
@@ -569,8 +569,13 @@ def warning(handle_type, handle, record, state, native, message, capacity, size)
569569
cursor.fetchone()
570570
else:
571571
cursor.fetchmany(2 if failure == "partial_bind" else 1)
572-
except (mssql_python.Error, UnicodeError) as error:
573-
if failure == "column_name":
572+
except (mssql_python.Error, UnicodeError, RuntimeError) as error:
573+
if failure == "partial_bind":
574+
assert type(error) is RuntimeError
575+
assert str(error) == (
576+
"Failed to bind column - b, Type - 4, column ID - 2"
577+
)
578+
elif failure == "column_name":
574579
assert isinstance(error, UnicodeError)
575580
else:
576581
assert isinstance(error, mssql_python.Error)
@@ -587,9 +592,9 @@ def warning(handle_type, handle, record, state, native, message, capacity, size)
587592
2 if failure in ("cleanup", "rows_fetched_cleanup", "getdata") else 1
588593
)
589594
assert cursor.fetchone()[0] == expected, failure
590-
before = ddbc.profiling.get_stats()["FetchSingleRow::SQL_UNBIND"]["calls"]
595+
before = ddbc.profiling.get_stats()["ddbc::FetchSingleRow::SQL_UNBIND"]["calls"]
591596
assert cursor.fetchone()[0] == expected + 1
592-
assert ddbc.profiling.get_stats()["FetchSingleRow::SQL_UNBIND"]["calls"] == before
597+
assert ddbc.profiling.get_stats()["ddbc::FetchSingleRow::SQL_UNBIND"]["calls"] == before
593598
ddbc.profiling.disable()
594599
""")
595600
environment = os.environ.copy()

0 commit comments

Comments
 (0)