@@ -153,6 +153,28 @@ char * Query_Info::get_digest_text() {
153
153
return GloQPro->get_digest_text (&QueryParserArgs);
154
154
}
155
155
156
+ bool Query_Info::is_select_NOT_for_update () {
157
+ // to avoid an expensive strlen() on the digest_text, we consider only the real query
158
+ if (QueryPointer==NULL ) {
159
+ return false ;
160
+ }
161
+ if (QueryLength<7 ) {
162
+ return false ;
163
+ }
164
+ if (strncasecmp ((char *)QueryPointer,(char *)" SELECT " ,7 )) {
165
+ return false ;
166
+ }
167
+ // if we arrive till here, it is a SELECT
168
+ if (QueryLength>=17 ) {
169
+ char *p=(char *)QueryPointer;
170
+ p+=QueryLength-11 ;
171
+ if (strncasecmp (p," FOR UPDATE" ,11 )==0 ) {
172
+ return false ;
173
+ }
174
+ }
175
+ return true ;
176
+ }
177
+
156
178
void * MySQL_Session::operator new (size_t size) {
157
179
return l_alloc (size);
158
180
}
@@ -388,6 +410,7 @@ bool MySQL_Session::handler_SetAutocommit(PtrSize_t *pkt) {
388
410
389
411
if (fd==0 ) {
390
412
autocommit=false ; // we set it, no matter if already set or not
413
+ /*
391
414
if (nTrx) {
392
415
// there is an active transaction, we need to forward it
393
416
// because this can potentially close the transaction
@@ -398,6 +421,11 @@ bool MySQL_Session::handler_SetAutocommit(PtrSize_t *pkt) {
398
421
// just return OK
399
422
goto __ret_autocommit_OK;
400
423
}
424
+ */
425
+ // it turned out I was wrong
426
+ // set autocommit=0 has no effect if there is an acrive transaction
427
+ // therefore, we never forward set autocommit = 0
428
+ goto __ret_autocommit_OK;
401
429
}
402
430
__ret_autocommit_OK:
403
431
client_myds->DSS =STATE_QUERY_SENT_NET;
@@ -416,6 +444,14 @@ bool MySQL_Session::handler_SetAutocommit(PtrSize_t *pkt) {
416
444
}
417
445
418
446
bool MySQL_Session::handler_special_queries (PtrSize_t *pkt) {
447
+
448
+ if (handler_SetAutocommit (pkt) == true ) {
449
+ return true ;
450
+ }
451
+ if (handler_CommitRollback (pkt) == true ) {
452
+ return true ;
453
+ }
454
+
419
455
if (pkt->size ==SELECT_LAST_INSERT_ID_LEN+5 && strncasecmp ((char *)SELECT_LAST_INSERT_ID,(char *)pkt->ptr +5 ,pkt->size -5 )==0 ) {
420
456
char buf[16 ];
421
457
sprintf (buf," %u" ,last_insert_id);
@@ -830,8 +866,19 @@ int MySQL_Session::handler() {
830
866
NEXT_IMMEDIATE (CHANGING_CHARSET);
831
867
}
832
868
if (autocommit != mybe->server_myds ->myconn ->IsAutoCommit ()) {
833
- previous_status.push (PROCESSING_QUERY);
834
- NEXT_IMMEDIATE (CHANGING_AUTOCOMMIT);
869
+ // see case #485
870
+ if (mysql_thread___enforce_autocommit_on_reads == false ) {
871
+ // enforce_autocommit_on_reads is disabled
872
+ // we need to check if it is a SELECT not FOR UPDATE
873
+ if (CurrentQuery.is_select_NOT_for_update ()==false ) {
874
+ previous_status.push (PROCESSING_QUERY);
875
+ NEXT_IMMEDIATE (CHANGING_AUTOCOMMIT);
876
+ }
877
+ } else {
878
+ // in every other cases, enforce autocommit
879
+ previous_status.push (PROCESSING_QUERY);
880
+ NEXT_IMMEDIATE (CHANGING_AUTOCOMMIT);
881
+ }
835
882
}
836
883
}
837
884
status=PROCESSING_QUERY;
0 commit comments