--- sql/mysql/parser3mysql.C 2017/08/01 16:50:13 1.52 +++ sql/mysql/parser3mysql.C 2019/09/03 20:19:34 1.56 @@ -15,7 +15,7 @@ #include "pa_sql_driver.h" -volatile const char * IDENT_PARSER3MYSQL_C="$Id: parser3mysql.C,v 1.52 2017/08/01 16:50:13 moko Exp $" IDENT_PA_SQL_DRIVER_H; +volatile const char * IDENT_PARSER3MYSQL_C="$Id: parser3mysql.C,v 1.56 2019/09/03 20:19:34 moko Exp $" IDENT_PA_SQL_DRIVER_H; #define NO_CLIENT_LONG_LONG #include "mysql.h" @@ -99,11 +99,11 @@ inline static bool is_column_transcode_r } } -inline static const char* strdup(SQL_Driver_services& services, char* str, size_t length) { +inline static char* strdup(SQL_Driver_services& services, char* str, size_t length) { char *strm=(char*)services.malloc_atomic(length+1); memcpy(strm, str, length); strm[length]=0; - return (const char*)strm; + return strm; } struct Connection { @@ -170,12 +170,16 @@ public: connection.client_charset=0; connection.autocommit=true; - char *port_cstr=lsplit(host, ':'); - int port=port_cstr?strtol(port_cstr, &error_pos, 0):0; - - while(options){ - if(char *key=lsplit(&options, '&')){ - if(*key){ + while(1){ + char *next_host=lsplit(host, ','); + char *host_options=next_host && options ? strdup(services, options, strlen(options)) : options; + + char *port_cstr=lsplit(host, ':'); + int port=port_cstr?strtol(port_cstr, &error_pos, 0):0; + + while(host_options){ + char *key=lsplit(&host_options, '&'); + if(key && *key){ if(char *value=lsplit(key, '=')){ if(strcmp(key, "ClientCharset")==0){ // transcoding with parser toupper_str(value, value, strlen(value)); @@ -204,16 +208,26 @@ public: } else if(strcasecmp(key, "multi_statements")==0){ if(atoi(value)!=0) client_flag=CLIENT_MULTI_STATEMENTS; + } else if(strcasecmp(key, "config_file")==0){ + if(mysql_options(connection.handle, MYSQL_READ_DEFAULT_FILE, value)!=0) + services._throw(mysql_error(connection.handle)); + } else if(strcasecmp(key, "config_group")==0){ + if(mysql_options(connection.handle, MYSQL_READ_DEFAULT_GROUP, value)!=0) + services._throw(mysql_error(connection.handle)); } else services._throw("unknown connect option" /*key*/); - } else + } else services._throw("connect option without =value" /*key*/); } } - } - if(!mysql_real_connect(connection.handle, host, user, pwd, db, port, unix_socket, CLIENT_MULTI_RESULTS)){ - services._throw(mysql_error(connection.handle)); + if(mysql_real_connect(connection.handle, host, user, pwd, db, port, unix_socket, client_flag)) + break; + + if(!next_host) + services._throw(mysql_error(connection.handle)); + + host=next_host; } if(charset){ @@ -329,10 +343,7 @@ public: if(transcode_needed) { statement_size=strlen(astatement); // transcode query from $request:charset to ?ClientCharset - services.transcode(astatement, statement_size, - astatement, statement_size, - services.request_charset(), - connection.client_charset); + services.transcode(astatement, statement_size, astatement, statement_size, services.request_charset(), connection.client_charset); } const char *statement; @@ -410,23 +421,17 @@ public: bool* transcode_column=0; if(transcode_needed) { - transcode_column = new bool[column_count]; + bool transcode_column[column_count]; DO_FETCH_FIELDS( transcode_column[i] = is_column_transcode_required(field->type); // transcode column's name from ?ClientCharset to $request:charset - services.transcode(str, length, - str, length, - connection.client_charset, - services.request_charset()); + services.transcode(str, length, str, length, connection.client_charset, services.request_charset()); ) CHECK(handlers.before_rows(sql_error)); DO_FETCH_ROWS( + // transcode cell's value from ?ClientCharset to $request:charset if(transcode_column[i]) - // transcode cell's value from ?ClientCharset to $request:charset - services.transcode(str, length, - str, length, - connection.client_charset, - services.request_charset()); + services.transcode(str, length, str, length, connection.client_charset, services.request_charset()); ) } else { // without transcoding @@ -435,8 +440,6 @@ public: DO_FETCH_ROWS() } cleanup: - if(transcode_column) - delete transcode_column; mysql_free_result(res); if(failed) services._throw(sql_error); @@ -452,10 +455,7 @@ private: void _throw(Connection& connection, const char* aerr_msg) { size_t length=strlen(aerr_msg); if(length && _transcode_required(connection)) { - connection.services->transcode(aerr_msg, length, - aerr_msg, length, - connection.client_charset, - connection.services->request_charset()); + connection.services->transcode(aerr_msg, length, aerr_msg, length, connection.client_charset, connection.services->request_charset()); } connection.services->_throw(aerr_msg); }