Skip to content

Commit 7d0e21f

Browse files
committed
More tests
1 parent f7ab2a0 commit 7d0e21f

File tree

1 file changed

+124
-7
lines changed

1 file changed

+124
-7
lines changed

tests/test_004_cursor.py

Lines changed: 124 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10760,24 +10760,141 @@ def test_multi_statement_query(cursor, db_connection):
1076010760
try:
1076110761
# Single SQL with multiple statements - tests pyODBC-style buffering
1076210762
multi_statement_sql = """
10763-
CREATE TABLE #TestData (id INT, name NVARCHAR(50), value INT);
10764-
INSERT INTO #TestData VALUES (1, 'Test1', 100), (2, 'Test2', 200);
10765-
SELECT COALESCE(name, 'DEFAULT') as result_name, SUM(value) as total_value INTO #TempResult FROM #TestData GROUP BY name;
10766-
SELECT result_name, total_value, 'SUCCESS' as status FROM #TempResult ORDER BY result_name;
10763+
SELECT 1 as col1, 'test' as col2 INTO #temp1;
10764+
SELECT * FROM #temp1;
1076710765
"""
1076810766

1076910767
cursor.execute(multi_statement_sql)
1077010768
results = cursor.fetchall()
1077110769

1077210770
assert len(results) > 0, "Multi-statement query should return results"
10773-
assert results[0][2] == 'SUCCESS', "Should return success status"
10771+
assert results[0][1] == 'test', "Should return string- test"
1077410772

1077510773
except Exception as e:
1077610774
pytest.fail(f"Multi-statement query test failed: {e}")
1077710775
finally:
1077810776
try:
10779-
cursor.execute("DROP TABLE #TestData")
10780-
cursor.execute("DROP TABLE #TempResult")
10777+
cursor.execute("DROP TABLE #temp1")
10778+
db_connection.commit()
10779+
except:
10780+
pass
10781+
10782+
def test_multiple_result_sets_with_nextset(cursor, db_connection):
10783+
"""Test multiple result sets with multiple select statements on temp tables with nextset()"""
10784+
try:
10785+
# Create temp tables and execute multiple SELECT statements
10786+
multi_select_sql = """
10787+
CREATE TABLE #TempData1 (id INT, name NVARCHAR(50));
10788+
INSERT INTO #TempData1 VALUES (1, 'First'), (2, 'Second');
10789+
10790+
CREATE TABLE #TempData2 (id INT, value INT);
10791+
INSERT INTO #TempData2 VALUES (1, 100), (2, 200);
10792+
10793+
SELECT id, name FROM #TempData1 ORDER BY id;
10794+
SELECT id, value FROM #TempData2 ORDER BY id;
10795+
SELECT t1.name, t2.value FROM #TempData1 t1 JOIN #TempData2 t2 ON t1.id = t2.id ORDER BY t1.id;
10796+
"""
10797+
10798+
cursor.execute(multi_select_sql)
10799+
10800+
# First result set
10801+
results1 = cursor.fetchall()
10802+
assert len(results1) == 2, "First result set should have 2 rows"
10803+
assert results1[0][1] == 'First', "First row should contain 'First'"
10804+
10805+
# Move to second result set
10806+
assert cursor.nextset() is True, "Should have second result set"
10807+
results2 = cursor.fetchall()
10808+
assert len(results2) == 2, "Second result set should have 2 rows"
10809+
assert results2[0][1] == 100, "First row should contain value 100"
10810+
10811+
# Move to third result set
10812+
assert cursor.nextset() is True, "Should have third result set"
10813+
results3 = cursor.fetchall()
10814+
assert len(results3) == 2, "Third result set should have 2 rows"
10815+
assert results3[0][0] == 'First', "First row should contain 'First'"
10816+
assert results3[0][1] == 100, "First row should contain value 100"
10817+
10818+
# Check if there are more result sets (there shouldn't be any more SELECT results)
10819+
next_result = cursor.nextset()
10820+
if next_result is not None:
10821+
# If there are more, they should be empty (from CREATE/INSERT statements)
10822+
remaining_results = cursor.fetchall()
10823+
assert len(remaining_results) == 0, "Any remaining result sets should be empty"
10824+
10825+
except Exception as e:
10826+
pytest.fail(f"Multiple result sets with nextset test failed: {e}")
10827+
finally:
10828+
try:
10829+
cursor.execute("DROP TABLE #TempData1")
10830+
cursor.execute("DROP TABLE #TempData2")
10831+
db_connection.commit()
10832+
except:
10833+
pass
10834+
10835+
def test_semicolons_in_string_literals(cursor, db_connection):
10836+
"""Test semicolons in string literals to ensure no false positives in buffering logic"""
10837+
try:
10838+
# SQL with semicolons inside string literals - should not be treated as statement separators
10839+
sql_with_semicolons = """
10840+
CREATE TABLE #StringTest (id INT, data NVARCHAR(200));
10841+
INSERT INTO #StringTest VALUES
10842+
(1, 'Value with; semicolon inside'),
10843+
(2, 'Another; value; with; multiple; semicolons'),
10844+
(3, 'Normal value');
10845+
SELECT id, data, 'Status: OK; Processing: Complete' as status_message
10846+
FROM #StringTest
10847+
WHERE data LIKE '%semicolon%' OR data = 'Normal value'
10848+
ORDER BY id;
10849+
"""
10850+
10851+
cursor.execute(sql_with_semicolons)
10852+
results = cursor.fetchall()
10853+
10854+
assert len(results) == 3, "Should return 3 rows"
10855+
assert 'semicolon inside' in results[0][1], "Should preserve semicolon in string literal"
10856+
assert 'multiple; semicolons' in results[1][1], "Should preserve multiple semicolons in string literal"
10857+
assert 'Status: OK; Processing: Complete' in results[0][2], "Should preserve semicolons in status message"
10858+
10859+
except Exception as e:
10860+
pytest.fail(f"Semicolons in string literals test failed: {e}")
10861+
finally:
10862+
try:
10863+
cursor.execute("DROP TABLE #StringTest")
10864+
db_connection.commit()
10865+
except:
10866+
pass
10867+
10868+
def test_multi_statement_batch_final_non_select(cursor, db_connection):
10869+
"""Test multi-statement batch where the final statement is not a SELECT"""
10870+
try:
10871+
# Multi-statement batch ending with non-SELECT statement
10872+
multi_statement_non_select = """
10873+
CREATE TABLE #BatchTest (id INT, name NVARCHAR(50), created_at DATETIME);
10874+
INSERT INTO #BatchTest VALUES (1, 'Test1', GETDATE()), (2, 'Test2', GETDATE());
10875+
SELECT COUNT(*) as record_count FROM #BatchTest;
10876+
UPDATE #BatchTest SET name = name + '_updated' WHERE id IN (1, 2);
10877+
"""
10878+
10879+
cursor.execute(multi_statement_non_select)
10880+
10881+
# Should be able to fetch results from the SELECT statement
10882+
results = cursor.fetchall()
10883+
assert len(results) == 1, "Should return 1 row from COUNT query"
10884+
assert results[0][0] == 2, "Should count 2 records"
10885+
10886+
# Verify the UPDATE was executed by checking the updated records
10887+
cursor.execute("SELECT name FROM #BatchTest ORDER BY id")
10888+
updated_results = cursor.fetchall()
10889+
assert len(updated_results) == 2, "Should have 2 updated records"
10890+
assert updated_results[0][0] == 'Test1_updated', "First record should be updated"
10891+
assert updated_results[1][0] == 'Test2_updated', "Second record should be updated"
10892+
10893+
except Exception as e:
10894+
pytest.fail(f"Multi-statement batch with final non-SELECT test failed: {e}")
10895+
finally:
10896+
try:
10897+
cursor.execute("DROP TABLE #BatchTest")
1078110898
db_connection.commit()
1078210899
except:
1078310900
pass

0 commit comments

Comments
 (0)