37 #include "sql_servers.h"
41 #include "hash_filo.h"
46 #include "transaction.h"
54 static HASH servers_cache;
58 static bool get_server_from_table_to_cache(
TABLE *
table);
61 static bool insert_server(THD *thd,
FOREIGN_SERVER *server_options);
63 static bool insert_server_record_into_cache(
FOREIGN_SERVER *server);
65 prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options);
69 size_t server_name_length,
71 static bool delete_server_record_in_cache(LEX_SERVER_OPTIONS *server_options,
75 static void prepare_server_struct_for_update(LEX_SERVER_OPTIONS *server_options,
81 static bool update_server_record_in_cache(
FOREIGN_SERVER *existing,
88 static uchar *servers_cache_get_key(
FOREIGN_SERVER *server,
size_t *length,
89 my_bool not_used __attribute__((unused)))
91 DBUG_ENTER(
"servers_cache_get_key");
92 DBUG_PRINT(
"info", (
"server_name_length %d server_name %s",
93 server->server_name_length,
94 server->server_name));
96 *length= (uint) server->server_name_length;
97 DBUG_RETURN((uchar*) server->server_name);
100 #ifdef HAVE_PSI_INTERFACE
101 static PSI_rwlock_key key_rwlock_THR_LOCK_servers;
103 static PSI_rwlock_info all_servers_cache_rwlocks[]=
105 { &key_rwlock_THR_LOCK_servers,
"THR_LOCK_servers", PSI_FLAG_GLOBAL}
108 static void init_servers_cache_psi_keys(
void)
110 const char* category=
"sql";
113 count= array_elements(all_servers_cache_rwlocks);
137 bool servers_init(
bool dont_read_servers_table)
140 bool return_val= FALSE;
141 DBUG_ENTER(
"servers_init");
143 #ifdef HAVE_PSI_INTERFACE
144 init_servers_cache_psi_keys();
152 if (my_hash_init(&servers_cache, system_charset_info, 32, 0, 0,
153 (my_hash_get_key) servers_cache_get_key, 0, 0))
160 init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
162 if (dont_read_servers_table)
170 thd->thread_stack= (
char*) &thd;
171 thd->store_globals();
177 return_val= servers_reload(thd);
180 my_pthread_setspecific_ptr(THR_THD, 0);
183 DBUG_RETURN(return_val);
202 static bool servers_load(THD *thd,
TABLE_LIST *tables)
206 bool return_val= TRUE;
207 DBUG_ENTER(
"servers_load");
209 my_hash_reset(&servers_cache);
210 free_root(&mem, MYF(0));
211 init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
213 if (init_read_record(&read_record_info, thd, table=tables[0].table,
217 while (!(read_record_info.read_record(&read_record_info)))
220 if ((get_server_from_table_to_cache(table)))
227 end_read_record(&read_record_info);
228 DBUG_RETURN(return_val);
251 bool servers_reload(THD *thd)
254 bool return_val= TRUE;
255 DBUG_ENTER(
"servers_reload");
257 DBUG_PRINT(
"info", (
"locking servers_cache"));
260 tables[0].
init_one_table(
"mysql", 5,
"servers", 7,
"servers", TL_READ);
268 if (thd->get_stmt_da()->is_error())
269 sql_print_error(
"Can't open and lock privilege tables: %s",
270 thd->get_stmt_da()->message());
275 if ((return_val= servers_load(thd, tables)))
279 DBUG_PRINT(
"error",(
"Reverting to old privileges"));
285 DBUG_PRINT(
"info", (
"unlocking servers_cache"));
287 DBUG_RETURN(return_val);
318 get_server_from_table_to_cache(
TABLE *table)
322 char *
const blank= (
char*)
"";
325 DBUG_ENTER(
"get_server_from_table_to_cache");
326 table->use_all_columns();
329 ptr= get_field(&mem, table->field[0]);
330 server->server_name= ptr ? ptr : blank;
331 server->server_name_length= (uint) strlen(server->server_name);
332 ptr= get_field(&mem, table->field[1]);
333 server->host= ptr ? ptr : blank;
334 ptr= get_field(&mem, table->field[2]);
335 server->db= ptr ? ptr : blank;
336 ptr= get_field(&mem, table->field[3]);
337 server->username= ptr ? ptr : blank;
338 ptr= get_field(&mem, table->field[4]);
339 server->password= ptr ? ptr : blank;
340 ptr= get_field(&mem, table->field[5]);
341 server->sport= ptr ? ptr : blank;
343 server->port= server->sport ? atoi(server->sport) : 0;
345 ptr= get_field(&mem, table->field[6]);
346 server->socket= ptr && strlen(ptr) ? ptr : blank;
347 ptr= get_field(&mem, table->field[7]);
348 server->scheme= ptr ? ptr : blank;
349 ptr= get_field(&mem, table->field[8]);
350 server->owner= ptr ? ptr : blank;
351 DBUG_PRINT(
"info", (
"server->server_name %s", server->server_name));
352 DBUG_PRINT(
"info", (
"server->host %s", server->host));
353 DBUG_PRINT(
"info", (
"server->db %s", server->db));
354 DBUG_PRINT(
"info", (
"server->username %s", server->username));
355 DBUG_PRINT(
"info", (
"server->password %s", server->password));
356 DBUG_PRINT(
"info", (
"server->socket %s", server->socket));
357 if (my_hash_insert(&servers_cache, (uchar*) server))
359 DBUG_PRINT(
"info", (
"had a problem inserting server %s at %lx",
360 server->server_name, (
long unsigned int) server));
384 DBUG_ENTER(
"insert_server");
387 tables.
init_one_table(
"mysql", 5,
"servers", 7,
"servers", TL_WRITE);
390 TABLE *table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT);
395 bool error= (insert_server_record(table, server) ||
396 insert_server_record_into_cache(server));
416 static bool insert_server_record_into_cache(
FOREIGN_SERVER *server)
418 DBUG_ENTER(
"insert_server_record_into_cache");
423 DBUG_PRINT(
"info", (
"inserting server %s at %lx, length %d",
424 server->server_name, (
long unsigned int) server,
425 server->server_name_length));
426 if (my_hash_insert(&servers_cache, (uchar*) server))
428 DBUG_PRINT(
"info", (
"had a problem inserting server %s at %lx",
429 server->server_name, (
long unsigned int) server));
430 my_error(ER_OUT_OF_RESOURCES, MYF(0));
459 table->use_all_columns();
469 table->field[1]->store(server->host,
470 (uint) strlen(server->host), system_charset_info);
472 table->field[2]->store(server->db,
473 (uint) strlen(server->db), system_charset_info);
474 if (server->username)
475 table->field[3]->store(server->username,
476 (uint) strlen(server->username), system_charset_info);
477 if (server->password)
478 table->field[4]->store(server->password,
479 (uint) strlen(server->password), system_charset_info);
480 if (server->port > -1)
481 table->field[5]->store(server->port);
484 table->field[6]->store(server->socket,
485 (uint) strlen(server->socket), system_charset_info);
487 table->field[7]->store(server->scheme,
488 (uint) strlen(server->scheme), system_charset_info);
490 table->field[8]->store(server->owner,
491 (uint) strlen(server->owner), system_charset_info);
515 DBUG_ENTER(
"insert_server_record");
516 tmp_disable_binlog(table->in_use);
517 table->use_all_columns();
522 table->field[0]->store(server->server_name,
523 server->server_name_length,
524 system_charset_info);
528 (uchar *)table->field[0]->ptr,
534 if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
538 store_server_fields(table, server);
540 DBUG_PRINT(
"info",(
"record for server '%s' not found!",
541 server->server_name));
543 if ((error=table->file->ha_write_row(table->record[0])))
548 my_error(ER_FOREIGN_SERVER_EXISTS, MYF(0), server->server_name);
552 reenable_binlog(table->in_use);
553 DBUG_RETURN(error != 0);
576 bool drop_server(THD *thd, LEX_SERVER_OPTIONS *server_options,
bool if_exists)
578 DBUG_ENTER(
"drop_server");
579 DBUG_PRINT(
"info", (
"server name server->server_name %s",
580 server_options->server_name));
583 tables.
init_one_table(
"mysql", 5,
"servers", 7,
"servers", TL_WRITE);
587 TABLE *table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT);
595 server_options->server_name_length };
597 bool error= (delete_server_record_in_cache(server_options, if_exists) ||
598 delete_server_record(table, name.str, name.length, if_exists));
605 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
606 ER_UNKNOWN_ERROR,
"Server connection in use");
610 DBUG_RETURN(error || thd->killed);
628 static bool delete_server_record_in_cache(LEX_SERVER_OPTIONS *server_options,
631 DBUG_ENTER(
"delete_server_record_in_cache");
632 DBUG_PRINT(
"info",(
"trying to obtain server name %s length %d",
633 server_options->server_name,
634 server_options->server_name_length));
638 (uchar*) server_options->server_name,
639 server_options->server_name_length);
642 DBUG_PRINT(
"info", (
"server_name %s length %d not found!",
643 server_options->server_name,
644 server_options->server_name_length));
646 my_error(ER_FOREIGN_SERVER_DOESNT_EXIST, MYF(0),
647 server_options->server_name);
654 DBUG_PRINT(
"info",(
"deleting server %s length %d",
656 server->server_name_length));
658 my_hash_delete(&servers_cache, (uchar*) server);
687 DBUG_ENTER(
"update_server");
690 tables.
init_one_table(
"mysql", 5,
"servers", 7,
"servers", TL_WRITE);
692 TABLE *table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT);
696 bool error= (update_server_record(table, altered) ||
697 update_server_record_in_cache(existing, altered));
700 servers_load(thd, &tables);
729 DBUG_ENTER(
"update_server_record_in_cache");
735 merge_server_struct(existing, altered);
738 my_hash_delete(&servers_cache, (uchar*)existing);
741 if (my_hash_insert(&servers_cache, (uchar*)altered))
743 DBUG_PRINT(
"info", (
"had a problem inserting server %s at %lx",
744 altered->server_name, (
long unsigned int) altered));
745 my_error(ER_OUT_OF_RESOURCES, MYF(0));
774 DBUG_ENTER(
"merge_server_struct");
776 to->host= strdup_root(&mem, from->host);
778 to->db= strdup_root(&mem, from->db);
780 to->username= strdup_root(&mem, from->username);
782 to->password= strdup_root(&mem, from->password);
784 to->port= from->port;
785 if (!to->socket && from->socket)
786 to->socket= strdup_root(&mem, from->socket);
787 if (!to->scheme && from->scheme)
788 to->scheme= strdup_root(&mem, from->scheme);
790 to->owner= strdup_root(&mem, from->owner);
817 DBUG_ENTER(
"update_server_record");
818 tmp_disable_binlog(table->in_use);
819 table->use_all_columns();
821 table->field[0]->store(server->server_name,
822 server->server_name_length,
823 system_charset_info);
826 (uchar *)table->field[0]->ptr,
831 if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
833 DBUG_PRINT(
"info",(
"server not found!"));
834 my_error(ER_FOREIGN_SERVER_DOESNT_EXIST, MYF(0), server->server_name);
839 store_record(table,
record[1]);
840 store_server_fields(table, server);
841 if ((error=table->file->ha_update_row(table->record[1],
842 table->record[0])) &&
843 error != HA_ERR_RECORD_IS_THE_SAME)
846 DBUG_PRINT(
"info",(
"problems with ha_update_row %d", error));
852 reenable_binlog(table->in_use);
853 DBUG_RETURN(error != 0);
867 static bool delete_server_record(
TABLE *table,
char *server_name,
868 size_t server_name_length,
bool if_exists)
871 DBUG_ENTER(
"delete_server_record");
872 tmp_disable_binlog(table->in_use);
873 table->use_all_columns();
876 table->field[0]->store(server_name, server_name_length, system_charset_info);
879 (uchar *)table->field[0]->ptr,
884 if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
886 DBUG_PRINT(
"info",(
"server not found!"));
888 my_error(ER_FOREIGN_SERVER_DOESNT_EXIST, MYF(0), server_name);
892 if ((error= table->file->ha_delete_row(table->record[0])))
896 reenable_binlog(table->in_use);
897 DBUG_RETURN(error != 0);
909 bool create_server(THD *thd, LEX_SERVER_OPTIONS *server_options)
914 DBUG_ENTER(
"create_server");
915 DBUG_PRINT(
"info", (
"server_options->server_name %s",
916 server_options->server_name));
921 if (my_hash_search(&servers_cache, (uchar*) server_options->server_name,
922 server_options->server_name_length))
924 my_error(ER_FOREIGN_SERVER_EXISTS, MYF(0), server_options->server_name);
928 server= prepare_server_struct_for_insert(server_options);
931 my_error(ER_OUT_OF_RESOURCES, MYF(0));
935 error= insert_server(thd, server);
939 DBUG_RETURN(error || thd->killed);
951 bool alter_server(THD *thd, LEX_SERVER_OPTIONS *server_options)
955 LEX_STRING name= { server_options->server_name,
956 server_options->server_name_length };
958 DBUG_ENTER(
"alter_server");
959 DBUG_PRINT(
"info", (
"server_options->server_name %s",
960 server_options->server_name));
969 my_error(ER_FOREIGN_SERVER_DOESNT_EXIST, MYF(0), name.str);
975 prepare_server_struct_for_update(server_options, existing, altered);
977 error= update_server(thd, existing, altered);
981 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
982 ER_UNKNOWN_ERROR,
"Server connection in use");
987 DBUG_RETURN(error || thd->killed);
1007 prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options)
1009 char *unset_ptr= (
char*)
"";
1011 DBUG_ENTER(
"prepare_server_struct");
1017 if (!(server->server_name= strdup_root(&mem, server_options->server_name)))
1019 server->server_name_length= server_options->server_name_length;
1021 if (!(server->host= server_options->host ?
1022 strdup_root(&mem, server_options->host) : unset_ptr))
1025 if (!(server->db= server_options->db ?
1026 strdup_root(&mem, server_options->db) : unset_ptr))
1029 if (!(server->username= server_options->username ?
1030 strdup_root(&mem, server_options->username) : unset_ptr))
1033 if (!(server->password= server_options->password ?
1034 strdup_root(&mem, server_options->password) : unset_ptr))
1038 server->port= server_options->port > -1 ?
1039 server_options->port : 0;
1041 if (!(server->socket= server_options->socket ?
1042 strdup_root(&mem, server_options->socket) : unset_ptr))
1045 if (!(server->scheme= server_options->scheme ?
1046 strdup_root(&mem, server_options->scheme) : unset_ptr))
1049 if (!(server->owner= server_options->owner ?
1050 strdup_root(&mem, server_options->owner) : unset_ptr))
1053 DBUG_RETURN(server);
1070 prepare_server_struct_for_update(LEX_SERVER_OPTIONS *server_options,
1074 DBUG_ENTER(
"prepare_server_struct_for_update");
1076 altered->server_name= strdup_root(&mem, server_options->server_name);
1077 altered->server_name_length= server_options->server_name_length;
1078 DBUG_PRINT(
"info", (
"existing name %s altered name %s",
1079 existing->server_name, altered->server_name));
1086 (server_options->host && (strcmp(server_options->host, existing->host))) ?
1087 strdup_root(&mem, server_options->host) : 0;
1090 (server_options->db && (strcmp(server_options->db, existing->db))) ?
1091 strdup_root(&mem, server_options->db) : 0;
1094 (server_options->username &&
1095 (strcmp(server_options->username, existing->username))) ?
1096 strdup_root(&mem, server_options->username) : 0;
1099 (server_options->password &&
1100 (strcmp(server_options->password, existing->password))) ?
1101 strdup_root(&mem, server_options->password) : 0;
1106 altered->port= (server_options->port > -1 &&
1107 server_options->port != existing->port) ?
1108 server_options->port : -1;
1111 (server_options->socket &&
1112 (strcmp(server_options->socket, existing->socket))) ?
1113 strdup_root(&mem, server_options->socket) : 0;
1116 (server_options->scheme &&
1117 (strcmp(server_options->scheme, existing->scheme))) ?
1118 strdup_root(&mem, server_options->scheme) : 0;
1121 (server_options->owner &&
1122 (strcmp(server_options->owner, existing->owner))) ?
1123 strdup_root(&mem, server_options->owner) : 0;
1141 void servers_free(
bool end)
1143 DBUG_ENTER(
"servers_free");
1144 if (!my_hash_inited(&servers_cache))
1148 free_root(&mem, MYF(MY_MARK_BLOCKS_FREE));
1149 my_hash_reset(&servers_cache);
1153 free_root(&mem,MYF(0));
1154 my_hash_free(&servers_cache);
1181 DBUG_ENTER(
"sql_server.cc:clone_server");
1186 buffer->server_name= strmake_root(mem, server->server_name,
1187 server->server_name_length);
1188 buffer->port= server->port;
1189 buffer->server_name_length= server->server_name_length;
1192 buffer->db= server->db ? strdup_root(mem, server->db) : NULL;
1193 buffer->scheme= server->scheme ? strdup_root(mem, server->scheme) : NULL;
1194 buffer->username= server->username? strdup_root(mem, server->username): NULL;
1195 buffer->password= server->password? strdup_root(mem, server->password): NULL;
1196 buffer->socket= server->socket ? strdup_root(mem, server->socket) : NULL;
1197 buffer->owner= server->owner ? strdup_root(mem, server->owner) : NULL;
1198 buffer->host= server->host ? strdup_root(mem, server->host) : NULL;
1200 DBUG_RETURN(buffer);
1220 size_t server_name_length;
1222 DBUG_ENTER(
"get_server_by_name");
1223 DBUG_PRINT(
"info", (
"server_name %s", server_name));
1225 server_name_length= strlen(server_name);
1227 if (! server_name || !strlen(server_name))
1229 DBUG_PRINT(
"info", (
"server_name not defined!"));
1233 DBUG_PRINT(
"info", (
"locking servers_cache"));
1236 (uchar*) server_name,
1237 server_name_length)))
1239 DBUG_PRINT(
"info", (
"server_name %s length %u not found!",
1240 server_name, (
unsigned) server_name_length));
1245 server= clone_server(mem, server, buff);
1247 DBUG_PRINT(
"info", (
"unlocking servers_cache"));
1249 DBUG_RETURN(server);