Support for collations

Issues #780 #554 #1219
pull/1243/head
René Cannaò 9 years ago
parent ba423d27b4
commit 83b2a2a463

2
deps/Makefile vendored

@ -65,7 +65,7 @@ mariadb-client-library/mariadb_client/include/my_config.h:
cd mariadb-client-library/mariadb_client && cmake .
cd mariadb-client-library/mariadb_client && patch libmariadb/libmariadb.c < ../libmariadb.c.patch
cd mariadb-client-library/mariadb_client && patch libmariadb/net.c < ../net.c.patch
# cd mariadb-client-library/mariadb_client && patch libmariadb/mysql_async.c < ../mysql_async.c.patch
cd mariadb-client-library/mariadb_client && patch libmariadb/mysql_async.c < ../mysql_async.c.patch
cd mariadb-client-library/mariadb_client && patch libmariadb/password.c < ../password.c.patch
# cd mariadb-client-library/mariadb_client && patch libmariadb/ma_secure.c < ../ma_secure.c.patch
cd mariadb-client-library/mariadb_client && patch include/mysql.h < ../mysql.h.patch

@ -69,11 +69,10 @@
mysql->user= s_user;
mysql->passwd= s_passwd;
mysql->db= s_db;
@@ -2395,6 +2404,36 @@
/* Clear pointers for better safety */
@@ -2396,6 +2405,36 @@
bzero((char*) &mysql->options,sizeof(mysql->options));
mysql->net.vio= 0;
+ if (mysql->free_me)
if (mysql->free_me)
+ my_free((gptr) mysql);
+ }
+ DBUG_VOID_RETURN;
@ -103,6 +102,42 @@
+ /* Clear pointers for better safety */
+ bzero((char*) &mysql->options,sizeof(mysql->options));
+ mysql->net.vio= 0;
if (mysql->free_me)
+ if (mysql->free_me)
my_free(mysql);
}
DBUG_VOID_RETURN;
@@ -3510,19 +3549,27 @@
DBUG_VOID_RETURN;
}
-int STDCALL mysql_set_character_set(MYSQL *mysql, const char *csname)
+int STDCALL mysql_set_character_set(MYSQL *mysql, const char *csname, uint charsetnr)
{
const CHARSET_INFO *cs;
DBUG_ENTER("mysql_set_character_set");
- if (!csname)
+ if (!csname && !charsetnr)
goto error;
- if ((cs= mysql_find_charset_name(csname)))
- {
- char buff[64];
-
- my_snprintf(buff, 63, "SET NAMES %s", cs->csname);
+ if (csname) {
+ cs = mysql_find_charset_name(csname);
+ } else {
+ cs = mysql_find_charset_nr(charsetnr);
+ }
+ if (cs)
+ {
+ char buff[128];
+ if (csname) { // default behavior
+ my_snprintf(buff, 63, "SET NAMES %s", cs->csname);
+ } else {
+ my_snprintf(buff, 63, "SET NAMES %s COLLATE %s", cs->csname, cs->name);
+ }
if (!mysql_real_query(mysql, buff, (uint)strlen(buff)))
{
mysql->charset= cs;

@ -1,3 +1,12 @@
@@ -404,7 +404,7 @@
unsigned long STDCALL mysql_thread_id(MYSQL *mysql);
const char * STDCALL mysql_character_set_name(MYSQL *mysql);
void STDCALL mysql_get_character_set_info(MYSQL *mysql, MY_CHARSET_INFO *cs);
-int STDCALL mysql_set_character_set(MYSQL *mysql, const char *csname);
+int STDCALL mysql_set_character_set(MYSQL *mysql, const char *csname, uint charsetnr);
MYSQL * STDCALL mysql_init(MYSQL *mysql);
int STDCALL mysql_ssl_set(MYSQL *mysql, const char *key,
@@ -424,6 +424,7 @@
const char *unix_socket,
unsigned long clientflag);
@ -6,3 +15,12 @@
int STDCALL mysql_select_db(MYSQL *mysql, const char *db);
int STDCALL mysql_query(MYSQL *mysql, const char *q);
int STDCALL mysql_send_query(MYSQL *mysql, const char *q,
@@ -515,7 +516,7 @@
int STDCALL mysql_stmt_close_start(my_bool *ret, MYSQL_STMT *stmt);
int STDCALL mysql_stmt_close_cont(my_bool *ret, MYSQL_STMT * stmt, int status);
int STDCALL mysql_set_character_set_start(int *ret, MYSQL *mysql,
- const char *csname);
+ const char *csname, uint charsetnr);
int STDCALL mysql_set_character_set_cont(int *ret, MYSQL *mysql,
int status);
int STDCALL mysql_change_user_start(my_bool *ret, MYSQL *mysql,

@ -1,9 +1,31 @@
@@ -805,7 +805,7 @@
int res;
/* It is legitimate to have NULL sock argument, which will do nothing. */
- if (sock)
+ if (sock && sock->net.vio)
{
res= mysql_close_slow_part_start(sock);
/* If we need to block, return now and do the rest in mysql_close_cont(). */
@@ -570,19 +570,20 @@
struct mysql_set_character_set_params {
MYSQL *mysql;
const char *csname;
+ uint charsetnr;
};
static void
mysql_set_character_set_start_internal(void *d)
{
MK_ASYNC_INTERNAL_BODY(
mysql_set_character_set,
- (parms->mysql, parms->csname),
+ (parms->mysql, parms->csname, parms->charsetnr),
parms->mysql,
int,
r_int)
}
int STDCALL
-mysql_set_character_set_start(int *ret, MYSQL *mysql, const char *csname)
+mysql_set_character_set_start(int *ret, MYSQL *mysql, const char *csname, uint charsetnr)
{
MK_ASYNC_START_BODY(
mysql_set_character_set,
@@ -591,6 +592,7 @@
WIN_SET_NONBLOCKING(mysql)
parms.mysql= mysql;
parms.csname= csname;
+ parms.charsetnr= charsetnr;
},
1,
r_int,

@ -16,6 +16,7 @@
#define EXPMARIA
extern const CHARSET_INFO * proxysql_find_charset_name(const char * const name);
extern CHARSET_INFO * proxysql_find_charset_collate_names(const char *csname, const char *collatename);
extern MySQL_Authentication *GloMyAuth;
extern ProxySQL_Admin *GloAdmin;
@ -676,16 +677,36 @@ bool MySQL_Session::handler_special_queries(PtrSize_t *pkt) {
pkt->ptr=pkt_2.ptr;
}
}
if ( (pkt->size < 35) && (pkt->size > 15) && (strncasecmp((char *)"SET NAMES ",(char *)pkt->ptr+5,10)==0) ) {
if ( (pkt->size < 100) && (pkt->size > 15) && (strncasecmp((char *)"SET NAMES ",(char *)pkt->ptr+5,10)==0) ) {
char *unstripped=strndup((char *)pkt->ptr+15,pkt->size-15);
char *name=trim_spaces_and_quotes_in_place(unstripped);
const CHARSET_INFO * c = proxysql_find_charset_name(name);
char *csname=trim_spaces_and_quotes_in_place(unstripped);
bool collation_specified = false;
unsigned int charsetnr = 0;
const CHARSET_INFO * c;
char * collation_name = NULL;
if (strcasestr(csname," COLLATE ")) {
collation_specified = true;
collation_name = strcasestr(csname," COLLATE ") + strlen(" COLLATE ");
char *_s=index(csname,' ');
*_s = '\0';
c = proxysql_find_charset_collate_names(csname,collation_name);
} else {
c = proxysql_find_charset_name(csname);
}
client_myds->DSS=STATE_QUERY_SENT_NET;
if (!c) {
char *m=(char *)"Unknown character set: '%s'";
char *errmsg=(char *)malloc(strlen(name)+strlen(m));
sprintf(errmsg,m,name);
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1115,(char *)"#42000",errmsg);
char *m = NULL;
char *errmsg = NULL;
if (collation_specified) {
m=(char *)"Unknown character set '%s' or collation '%s'";
errmsg=(char *)malloc(strlen(csname)+strlen(collation_name)+strlen(m));
sprintf(errmsg,m,csname,collation_name);
} else {
m=(char *)"Unknown character set: '%s'";
errmsg=(char *)malloc(strlen(csname)+strlen(m));
sprintf(errmsg,m,csname);
}
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1115,(char *)"42000",errmsg);
free(errmsg);
} else {
client_myds->myconn->set_charset(c->nr);

@ -45,6 +45,17 @@ CHARSET_INFO * proxysql_find_charset_name(const char *name) {
return NULL;
}
CHARSET_INFO * proxysql_find_charset_collate_names(const char *csname, const char *collatename) {
CHARSET_INFO *c = (CHARSET_INFO *)compiled_charsets;
do {
if (!strcasecmp(c->csname, csname) && !strcasecmp(c->name, collatename)) {
return c;
}
++c;
} while (c[0].nr != 0);
return NULL;
}
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

@ -471,7 +471,7 @@ void MySQL_Connection::set_names_start() {
proxy_error("Not existing charset number %u\n", options.charset);
assert(0);
}
async_exit_status = mysql_set_character_set_start(&interr,mysql, c->csname);
async_exit_status = mysql_set_character_set_start(&interr,mysql, NULL, options.charset);
}
void MySQL_Connection::set_names_cont(short event) {

Loading…
Cancel
Save