Handle SET SQL_MODE and NAMES in same query #1279

pull/1287/head
René Cannaò 8 years ago
parent c6d01ccf7f
commit f78139e55e

@ -3693,8 +3693,70 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
return true;
}
} else {
proxy_error("Unable to parse query. If correct, report it as a bug: %s\n", nq.c_str());
return false;
// try case listed in #1279
// this is not a complete solution. A right solution involves true parsing
re2::RE2::Options *opt2=new re2::RE2::Options(RE2::Quiet);
opt2->set_case_sensitive(false);
char *pattern=(char *)"^(?: *)SET *(?:|SESSION +|@@|@@session.)SQL_MODE *(?:|:)= *(?:'||\")((\\w|,)*)(?:'||\")(?: *, *NAMES *)(?:'||\")((\\w|\\d)*)(?:'||\")(?:| +COLLATE +(?:'||\")((\\w|\\d)*)(?:'||\")) *(?:(|;|-- .*|#.*))$";
re2::RE2 *re=new RE2(pattern, *opt2);
string s1;
string s2;
string s3;
rc=RE2::FullMatch(nq, *re, &s1, (void *)NULL, &s2, (void *)NULL, &s3);
//proxy_info("s1 = %s\n",s1.c_str());
//proxy_info("s2 = %s\n",s2.c_str());
//proxy_info("s3 = %s\n",s3.c_str());
delete re;
delete opt2;
if (rc) {
const CHARSET_INFO * c;
if (s3.length()) {
c = proxysql_find_charset_collate_names(s2.c_str(), s3.c_str());
} else {
c = proxysql_find_charset_name(s2.c_str());
}
if (!c) {
char *m = NULL;
char *errmsg = NULL;
if (s3.length()) {
m=(char *)"Unknown character set '%s' or collation '%s'";
errmsg=(char *)malloc(s2.length() + s3.length() + strlen(m));
sprintf(errmsg,m,s2.c_str(), s3.c_str());
} else {
m=(char *)"Unknown character set: '%s'";
errmsg=(char *)malloc(s2.length()+strlen(m));
sprintf(errmsg,m,s2.c_str());
}
client_myds->DSS=STATE_QUERY_SENT_NET;
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1115,(char *)"42000",errmsg);
free(errmsg);
return true;
} else {
uint32_t sql_mode_int=SpookyHash::Hash32(s1.c_str(),s1.length(),10);
if (client_myds->myconn->options.sql_mode_int != sql_mode_int) {
client_myds->myconn->options.sql_mode_int = sql_mode_int;
if (client_myds->myconn->options.sql_mode) {
free(client_myds->myconn->options.sql_mode);
}
client_myds->myconn->options.sql_mode=strdup(s1.c_str());
}
client_myds->myconn->set_charset(c->nr);
if (command_type == _MYSQL_COM_QUERY) {
client_myds->DSS=STATE_QUERY_SENT_NET;
uint16_t setStatus = (nTrx ? SERVER_STATUS_IN_TRANS : 0 );
if (autocommit) setStatus= SERVER_STATUS_AUTOCOMMIT;
client_myds->myprot.generate_pkt_OK(true,NULL,NULL,1,0,0,setStatus,0,NULL);
client_myds->DSS=STATE_SLEEP;
status=WAITING_CLIENT_DATA;
l_free(pkt->size,pkt->ptr);
RequestEnd(NULL);
return true;
}
}
} else {
proxy_error("Unable to parse query. If correct, report it as a bug: %s\n", nq.c_str());
return false;
}
}
}
if (match_regexes && match_regexes[2]->match(dig)) {

Loading…
Cancel
Save