@ -984,6 +984,190 @@ void ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign
}
SQLite3_result * ProxySQL_Admin : : generate_show_fields_from ( const char * tablename , char * * err ) {
char * tn = NULL ; // tablename
// note that tablename is passed with a trailing '
tn = ( char * ) malloc ( strlen ( tablename ) ) ;
unsigned int i = 0 , j = 0 ;
while ( i < strlen ( tablename ) ) {
if ( tablename [ i ] ! = ' \\ ' & & tablename [ i ] ! = ' ` ' & & tablename [ i ] ! = ' \' ' ) {
tn [ j ] = tablename [ i ] ;
j + + ;
}
i + + ;
}
tn [ j ] = 0 ;
/*
if ( ! strcmp ( tablename , " global_variables` " ) | | ! strcmp ( tablename , " global \\ _variables` " ) ) tn = ( char * ) " global_variables " ;
else if ( ! strcmp ( tablename , " debug_levels` " ) | | ! strcmp ( tablename , " debug_levels` " ) ) tn = ( char * ) " debug_levels " ;
else if ( ! strcmp ( tablename , " mysql_collations` " ) | | ! strcmp ( tablename , " mysql \\ _collations` " ) ) tn = ( char * ) " mysql_collations " ;
else if ( ! strcmp ( tablename , " mysql_query_rules` " ) | | ! strcmp ( tablename , " mysql \\ _query \\ _rules` " ) ) tn = ( char * ) " mysql_query_rules " ;
else if ( ! strcmp ( tablename , " mysql_servers` " ) | | ! strcmp ( tablename , " mysql \\ _servers` " ) ) tn = ( char * ) " mysql_servers " ;
else if ( ! strcmp ( tablename , " mysql_users` " ) | | ! strcmp ( tablename , " mysql \\ _users` " ) ) tn = ( char * ) " mysql_users " ;
*/
/*
if ( tn = = NULL ) {
* err = strdup ( ( char * ) " Table does not exist " ) ;
free ( tn ) ;
return NULL ;
}
*/
SQLite3_result * resultset = NULL ;
char * q1 = ( char * ) " PRAGMA table_info(%s) " ;
char * q2 = ( char * ) malloc ( strlen ( q1 ) + strlen ( tn ) ) ;
sprintf ( q2 , q1 , tn ) ;
int affected_rows ;
int cols ;
char * error = NULL ;
admindb - > execute_statement ( q2 , & error , & cols , & affected_rows , & resultset ) ;
if ( error ) {
proxy_error ( " Error on %s : %s \n " , q2 , error ) ;
free ( q2 ) ;
* err = strdup ( error ) ;
free ( error ) ;
if ( resultset ) delete resultset ;
free ( tn ) ;
return NULL ;
}
if ( resultset = = NULL ) {
free ( tn ) ;
return NULL ;
}
if ( resultset - > rows_count = = 0 ) {
free ( tn ) ;
delete resultset ;
* err = strdup ( ( char * ) " Table does not exist " ) ;
return NULL ;
}
SQLite3_result * result = new SQLite3_result ( 6 ) ;
result - > add_column_definition ( SQLITE_TEXT , " Field " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Type " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Null " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Key " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Default " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Extra " ) ;
char * pta [ 6 ] ;
pta [ 1 ] = ( char * ) " varchar(255) " ;
pta [ 2 ] = ( char * ) " NO " ;
pta [ 3 ] = ( char * ) " " ;
pta [ 4 ] = ( char * ) " " ;
pta [ 5 ] = ( char * ) " " ;
free ( q2 ) ;
for ( std : : vector < SQLite3_row * > : : iterator it = resultset - > rows . begin ( ) ; it ! = resultset - > rows . end ( ) ; + + it ) {
SQLite3_row * r = * it ;
pta [ 0 ] = r - > fields [ 0 ] ;
result - > add_row ( pta ) ;
}
delete resultset ;
free ( tn ) ;
return result ;
}
SQLite3_result * ProxySQL_Admin : : generate_show_table_status ( const char * tablename , char * * err ) {
char * pta [ 18 ] ;
pta [ 0 ] = NULL ;
char * tn = NULL ; // tablename
// note that tablename is passed with a trailing '
tn = ( char * ) malloc ( strlen ( tablename ) ) ;
unsigned int i = 0 , j = 0 ;
while ( i < strlen ( tablename ) ) {
if ( tablename [ i ] ! = ' \\ ' & & tablename [ i ] ! = ' ` ' & & tablename [ i ] ! = ' \' ' ) {
tn [ j ] = tablename [ i ] ;
j + + ;
}
i + + ;
}
tn [ j ] = 0 ;
/*
if ( ! strcmp ( tablename , " global_variables' " ) | | ! strcmp ( tablename , " global \\ _variables' " ) ) pta [ 0 ] = ( char * ) " global_variables " ;
else if ( ! strcmp ( tablename , " debug_levels' " ) | | ! strcmp ( tablename , " debug \\ _levels' " ) ) pta [ 0 ] = ( char * ) " debug_levels " ;
else if ( ! strcmp ( tablename , " mysql_collations' " ) | | ! strcmp ( tablename , " mysql \\ _collations' " ) ) pta [ 0 ] = ( char * ) " mysql_collations " ;
else if ( ! strcmp ( tablename , " mysql_query_rules' " ) | | ! strcmp ( tablename , " mysql \\ _query \\ _rules' " ) ) pta [ 0 ] = ( char * ) " mysql_query_rules " ;
else if ( ! strcmp ( tablename , " mysql_servers' " ) | | ! strcmp ( tablename , " mysql \\ _servers' " ) ) pta [ 0 ] = ( char * ) " mysql_servers " ;
else if ( ! strcmp ( tablename , " mysql_users' " ) | | ! strcmp ( tablename , " mysql \\ _users' " ) ) pta [ 0 ] = ( char * ) " mysql_users " ;
*/
/*
if ( tn = = NULL ) {
* err = strdup ( ( char * ) " Table does not exist " ) ;
free ( tn ) ;
return NULL ;
}
*/
SQLite3_result * resultset = NULL ;
char * q1 = ( char * ) " PRAGMA table_info(%s) " ;
char * q2 = ( char * ) malloc ( strlen ( q1 ) + strlen ( tn ) ) ;
sprintf ( q2 , q1 , tn ) ;
int affected_rows ;
int cols ;
char * error = NULL ;
admindb - > execute_statement ( q2 , & error , & cols , & affected_rows , & resultset ) ;
if ( error ) {
proxy_error ( " Error on %s : %s \n " , q2 , error ) ;
free ( q2 ) ;
* err = strdup ( error ) ;
free ( error ) ;
if ( resultset ) delete resultset ;
free ( tn ) ;
return NULL ;
}
if ( resultset = = NULL ) {
free ( tn ) ;
return NULL ;
}
if ( resultset - > rows_count = = 0 ) {
free ( tn ) ;
delete resultset ;
* err = strdup ( ( char * ) " Table does not exist " ) ;
return NULL ;
}
SQLite3_result * result = new SQLite3_result ( 18 ) ;
result - > add_column_definition ( SQLITE_TEXT , " Name " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Engine " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Version " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Row_format " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Rows " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Avg_row_length " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Data_length " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Max_data_length " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Index_length " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Data_free " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Auto_increment " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Create_time " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Update_time " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Check_time " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Collation " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Checksum " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Create_options " ) ;
result - > add_column_definition ( SQLITE_TEXT , " Comment " ) ;
pta [ 0 ] = tn ;
pta [ 1 ] = ( char * ) " SQLite " ;
pta [ 2 ] = ( char * ) " 10 " ;
pta [ 3 ] = ( char * ) " Dynamic " ;
pta [ 4 ] = ( char * ) " 10 " ;
pta [ 5 ] = ( char * ) " 0 " ;
pta [ 6 ] = ( char * ) " 0 " ;
pta [ 7 ] = ( char * ) " 0 " ;
pta [ 8 ] = ( char * ) " 0 " ;
pta [ 9 ] = ( char * ) " 0 " ;
pta [ 10 ] = ( char * ) " NULL " ;
pta [ 11 ] = ( char * ) " 0000-00-00 00:00:00 " ;
pta [ 12 ] = ( char * ) " 0000-00-00 00:00:00 " ;
pta [ 13 ] = ( char * ) " 0000-00-00 00:00:00 " ;
pta [ 14 ] = ( char * ) " utf8_bin " ;
pta [ 15 ] = ( char * ) " NULL " ;
pta [ 16 ] = ( char * ) " " ;
pta [ 17 ] = ( char * ) " " ;
result - > add_row ( pta ) ;
free ( tn ) ;
return result ;
}
void admin_session_handler ( MySQL_Session * sess , ProxySQL_Admin * pa , PtrSize_t * pkt ) {
char * error = NULL ;
@ -1032,6 +1216,80 @@ void admin_session_handler(MySQL_Session *sess, ProxySQL_Admin *pa, PtrSize_t *p
goto __run_query ;
}
// queries generated by mysqldump
ProxySQL_Admin * SPA = ( ProxySQL_Admin * ) pa ;
if (
! strncmp ( " /*!40014 SET " , query_no_space , 13 ) | |
! strncmp ( " /*!40101 SET " , query_no_space , 13 ) | |
! strncmp ( " /*!40103 SET " , query_no_space , 13 ) | |
! strncmp ( " /*!40111 SET " , query_no_space , 13 ) | |
! strncmp ( " /*!40000 ALTER TABLE " , query_no_space , strlen ( " /*!40000 ALTER TABLE " ) )
| |
! strncmp ( " /*!40100 SET @@SQL_MODE='' */ " , query_no_space , strlen ( " /*!40100 SET @@SQL_MODE='' */ " ) )
| |
! strncmp ( " /*!40103 SET TIME_ZONE= " , query_no_space , strlen ( " /*!40103 SET TIME_ZONE= " ) )
| |
! strncmp ( " LOCK TABLES " , query_no_space , strlen ( " LOCK TABLES " ) )
| |
! strncmp ( " UNLOCK TABLES " , query_no_space , strlen ( " UNLOCK TABLES " ) )
| |
! strncmp ( " SET SQL_QUOTE_SHOW_CREATE=1 " , query_no_space , strlen ( " SET SQL_QUOTE_SHOW_CREATE=1 " ) )
| |
! strncmp ( " SET SESSION character_set_results " , query_no_space , strlen ( " SET SESSION character_set_results " ) )
| |
! strncasecmp ( " USE " , query_no_space , strlen ( " USE " ) ) // this applies to all clients, not only mysqldump
) {
SPA - > send_MySQL_OK ( & sess - > client_myds - > myprot , NULL ) ;
run_query = false ;
goto __run_query ;
}
if ( ! strncmp ( " SHOW VARIABLES LIKE 'gtid \\ _mode' " , query_no_space , strlen ( " SHOW VARIABLES LIKE 'gtid \\ _mode' " ) ) ) {
l_free ( query_length , query ) ;
query = l_strdup ( " SELECT variable_name Variable_name, Variable_value Value FROM global_variables WHERE Variable_name='gtid_mode' " ) ;
query_length = strlen ( query ) + 1 ;
goto __run_query ;
}
if ( ! strncmp ( " select @@collation_database " , query_no_space , strlen ( " select @@collation_database " ) ) ) {
l_free ( query_length , query ) ;
query = l_strdup ( " SELECT Collation '@@collation_database' FROM mysql_collations WHERE Collation='utf8_general_ci' LIMIT 1 " ) ;
query_length = strlen ( query ) + 1 ;
goto __run_query ;
}
if ( ! strncmp ( " SHOW VARIABLES LIKE 'ndbinfo \\ _version' " , query_no_space , strlen ( " SHOW VARIABLES LIKE 'ndbinfo \\ _version' " ) ) ) {
l_free ( query_length , query ) ;
query = l_strdup ( " SELECT variable_name Variable_name, Variable_value Value FROM global_variables WHERE Variable_name='ndbinfo_version' " ) ;
query_length = strlen ( query ) + 1 ;
goto __run_query ;
}
if ( ! strncmp ( " show table status like ' " , query_no_space , strlen ( " show table status like ' " ) ) ) {
char * strA = query_no_space + 24 ;
int strAl = strlen ( strA ) ;
if ( strAl < 2 ) { // error
goto __run_query ;
}
char * err = NULL ;
SQLite3_result * resultset = SPA - > generate_show_table_status ( strA , & err ) ;
sess - > SQLite3_to_MySQL ( resultset , err , 0 , & sess - > client_myds - > myprot ) ;
if ( resultset ) delete resultset ;
if ( err ) free ( err ) ;
run_query = false ;
goto __run_query ;
}
if ( ! strncmp ( " show fields from ` " , query_no_space , strlen ( " show fields from ` " ) ) ) {
char * strA = query_no_space + 18 ;
int strAl = strlen ( strA ) ;
if ( strAl < 2 ) { // error
goto __run_query ;
}
char * err = NULL ;
SQLite3_result * resultset = SPA - > generate_show_fields_from ( strA , & err ) ;
sess - > SQLite3_to_MySQL ( resultset , err , 0 , & sess - > client_myds - > myprot ) ;
if ( resultset ) delete resultset ;
if ( err ) free ( err ) ;
run_query = false ;
goto __run_query ;
}
}
// FIXME: this should be removed, it is just a POC for issue #253 . What is important is the call to GloMTH->signal_all_threads();
@ -1123,6 +1381,33 @@ void admin_session_handler(MySQL_Session *sess, ProxySQL_Admin *pa, PtrSize_t *p
goto __run_query ;
}
if ( ( query_no_space_length > 17 ) & & ( ! strncasecmp ( " SHOW TABLES LIKE " , query_no_space , 17 ) ) ) {
strA = query_no_space + 17 ;
strAl = strlen ( strA ) ;
strB = ( char * ) " SELECT name AS tables FROM sqlite_master WHERE type='table' AND name LIKE '%s' " ;
strBl = strlen ( strB ) ;
char * tn = NULL ; // tablename
tn = ( char * ) malloc ( strlen ( strA ) ) ;
unsigned int i = 0 , j = 0 ;
while ( i < strlen ( strA ) ) {
if ( strA [ i ] ! = ' \\ ' & & strA [ i ] ! = ' ` ' & & strA [ i ] ! = ' \' ' ) {
tn [ j ] = strA [ i ] ;
j + + ;
}
i + + ;
}
tn [ j ] = 0 ;
int l = strBl + strlen ( tn ) - 2 ;
char * b = ( char * ) l_alloc ( l + 1 ) ;
snprintf ( b , l + 1 , strB , tn ) ;
b [ l ] = 0 ;
free ( tn ) ;
l_free ( query_length , query ) ;
query = b ;
query_length = l + 1 ;
goto __run_query ;
}
if ( query_no_space_length = = strlen ( " SHOW MYSQL USERS " ) & & ! strncasecmp ( " SHOW MYSQL USERS " , query_no_space , query_no_space_length ) ) {
l_free ( query_length , query ) ;
query = l_strdup ( " SELECT * FROM mysql_users ORDER BY username, active DESC, username ASC " ) ;
@ -1187,6 +1472,13 @@ void admin_session_handler(MySQL_Session *sess, ProxySQL_Admin *pa, PtrSize_t *p
tbh = dbh ;
dbh = strdup ( " main " ) ;
}
if ( strlen ( tbh ) > = 3 & & tbh [ 0 ] = = ' ` ' & & tbh [ strlen ( tbh ) - 1 ] = = ' ` ' ) { // tablename is quoted
char * tbh_tmp = ( char * ) malloc ( strlen ( tbh ) - 1 ) ;
strncpy ( tbh_tmp , tbh + 1 , strlen ( tbh ) - 2 ) ;
tbh_tmp [ strlen ( tbh ) - 2 ] = 0 ;
free ( tbh ) ;
tbh = tbh_tmp ;
}
int l = strBl + strlen ( tbh ) * 3 + strlen ( dbh ) - 8 ;
char * buff = ( char * ) l_alloc ( l + 1 ) ;
snprintf ( buff , l + 1 , strB , tbh , tbh , dbh , tbh ) ;