@@ -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