@@ -3578,3 +3578,75 @@ def test_set(self):
3578
3578
exp .append ((row .id , row .name , row .dept ))
3579
3579
self .assertEqual (exp , data [1 :])
3580
3580
cur .close ()
3581
+
3582
+
3583
+ class BugOra20653441 (tests .MySQLConnectorTests ):
3584
+
3585
+ """BUG#20653441: PYTHON CONNECTOR HANGS IF A QUERY IS KILLED (ERROR 1317)"""
3586
+
3587
+ def setUp (self ):
3588
+ self .table_name = 'Bug20653441'
3589
+
3590
+ def _setup (self ):
3591
+ self .cnx .cmd_query ("DROP TABLE IF EXISTS {0}" .format (self .table_name ))
3592
+ table = (
3593
+ "CREATE TABLE {table} ("
3594
+ " id INT UNSIGNED NOT NULL AUTO_INCREMENT,"
3595
+ " c1 VARCHAR(255) DEFAULT '{default}',"
3596
+ " PRIMARY KEY (id)"
3597
+ ")"
3598
+ ).format (table = self .table_name , default = 'a' * 255 )
3599
+ self .cnx .cmd_query (table )
3600
+
3601
+ stmt = "INSERT INTO {table} (id) VALUES {values}" .format (
3602
+ table = self .table_name ,
3603
+ values = ',' .join (['(NULL)' ] * 1024 )
3604
+ )
3605
+ self .cnx .cmd_query (stmt )
3606
+
3607
+ def tearDown (self ):
3608
+ try :
3609
+ cnx = connection .MySQLConnection (** tests .get_mysql_config ())
3610
+ cnx .cmd_query (
3611
+ "DROP TABLE IF EXISTS {0}" .format (self .table_name ))
3612
+ cnx .close ()
3613
+ except :
3614
+ pass
3615
+
3616
+ @foreach_cnx ()
3617
+ def test_kill_query (self ):
3618
+ self ._setup ()
3619
+
3620
+ def kill (connection_id ):
3621
+ """Kill query using separate connection"""
3622
+ killer = connection .MySQLConnection (** tests .get_mysql_config ())
3623
+ time .sleep (1 )
3624
+ killer .cmd_query ("KILL QUERY {0}" .format (connection_id ))
3625
+ killer .close ()
3626
+
3627
+ def sleepy_select (cnx ):
3628
+ """Execute a SELECT statement which takes a while to complete"""
3629
+ cur = cnx .cursor ()
3630
+ # Ugly query ahead!
3631
+ stmt = "SELECT x1.*, x2.* from {table} as x1, {table} as x2" .format (
3632
+ table = self .table_name )
3633
+ cur .execute (stmt )
3634
+ # Save the error so we can check in the calling thread
3635
+ cnx .test_error = None
3636
+
3637
+ try :
3638
+ cur .fetchall ()
3639
+ except errors .Error as err :
3640
+ cnx .test_error = err
3641
+
3642
+ worker = Thread (target = sleepy_select , args = [self .cnx ])
3643
+ killer = Thread (target = kill , args = [self .cnx .connection_id ])
3644
+ worker .start ()
3645
+ killer .start ()
3646
+ worker .join ()
3647
+ killer .join ()
3648
+
3649
+ self .assertTrue (isinstance (self .cnx .test_error , errors .DatabaseError ))
3650
+ self .assertEqual (str (self .cnx .test_error ),
3651
+ "1317 (70100): Query execution was interrupted" )
3652
+ self .cnx .close ()
0 commit comments