./my_component/0000775000175000017500000000000014555666157012724 5ustar kamilkamil./my_component/README.md0000664000175000017500000000112714555666157014204 0ustar kamilkamilThis example is loosely based on the component_httpd_table example demonstrated there: https://archive.fosdem.org/2022/schedule/event/mysql_component/ by Joro Kodinov. Please note that this is just a dirty implementation to demonstrate the problem with information_schema tables. To compile and run: 1. put the component directory into mysql-server/components directory 2. compile the server and the component 3. start mysqld with the right --plugin-dir containing the component binary 4. INSTALL COMPONENT "file://component_my_component"; The component is dumping its output into the error log. ./my_component/my_component.cc0000664000175000017500000001177014555666564015752 0ustar kamilkamil#include #include #include #include #include #include #include #include #include REQUIRES_SERVICE_PLACEHOLDER_AS(mysql_charset, charset_srv); REQUIRES_SERVICE_PLACEHOLDER_AS(mysql_string_factory, string_factory_srv); REQUIRES_SERVICE_PLACEHOLDER_AS(mysql_string_charset_converter, string_converter_srv); REQUIRES_SERVICE_PLACEHOLDER_AS(table_access_factory_v1, ta_factory_srv); REQUIRES_SERVICE_PLACEHOLDER_AS(table_access_v1, ta_srv); REQUIRES_SERVICE_PLACEHOLDER_AS(table_access_index_v1, ta_index_srv); REQUIRES_SERVICE_PLACEHOLDER_AS(table_access_scan_v1, ta_scan_srv); REQUIRES_SERVICE_PLACEHOLDER_AS(field_access_nullability_v1, fa_null_srv); REQUIRES_SERVICE_PLACEHOLDER_AS(field_integer_access_v1, fa_integer_srv); REQUIRES_SERVICE_PLACEHOLDER_AS(field_varchar_access_v1, fa_varchar_srv); #define C_STR(x) x, sizeof(x) - 1 static size_t fill_table_data(char *buf, size_t buf_size) { size_t retval = 0; TA_table tb = nullptr; Table_access ta = nullptr; TA_key pk = nullptr; size_t ticket = 0; std::ostringstream ss; my_h_string plugin_name_value; my_h_string plugin_status_value; /* init table access */ ta = ta_factory_srv->create(nullptr, 1); if (!ta) { fprintf(stderr, "ta_factory_srv->create() error\n"); goto cleanup; } /* add one table */ ticket = ta_srv->add(ta, C_STR("information_schema"), C_STR("PLUGINS"), TA_READ); // ticket = ta_srv->add(ta, C_STR("performance_schema"), C_STR("threads"), TA_READ); /* begin transaction */ if (ta_srv->begin(ta)) { fprintf(stderr, "ta_srv->begin() error\n"); goto cleanup; } /* set index access by primary key */ tb = ta_srv->get(ta, ticket); if (!tb) { fprintf(stderr, "ta_srv->get() error\n"); goto cleanup; } if (ta_scan_srv->init(ta, tb)) { fprintf(stderr, "ta_scan_srv->init() error\n"); goto cleanup; } string_factory_srv->create(&plugin_name_value); string_factory_srv->create(&plugin_status_value); ss << "information_schema.plugins table: \n"; while (ta_scan_srv->next(ta, tb) == 0) { // PLUGIN_NAME column in information_schema.PLUGINS is as index 0 fa_varchar_srv->get(ta, tb, 0, plugin_name_value); // PLUGIN_STATUS column in information_schema.PLUGINS is as index 2 fa_varchar_srv->get(ta, tb, 2, plugin_status_value); // Use name_value and address_value char tmp_buf[1024]; string_converter_srv->convert_to_buffer(plugin_name_value, tmp_buf, 1024, charset_srv->get_utf8mb4()); ss << "Name: " << tmp_buf; string_converter_srv->convert_to_buffer(plugin_status_value, tmp_buf, 1024, charset_srv->get_utf8mb4()); ss << " Status: " << tmp_buf << "\n"; } ta_scan_srv->end(ta, tb); memcpy(buf, ss.str().c_str(), std::min(buf_size, ss.str().length())); buf[buf_size-1] = 0; ta_srv->commit(ta); retval = strlen(buf); cleanup: if (pk) ta_index_srv->end(ta, tb, pk); if (ta) ta_factory_srv->destroy(ta); if (string_factory_srv) string_factory_srv->destroy(plugin_name_value); if (string_factory_srv) string_factory_srv->destroy(plugin_status_value); return retval; } static std::thread worker_thd; static bool stop_worker_thd = false; static void dump_table() { while(true){ if(stop_worker_thd) { break; } char buf[4096]; fill_table_data(buf, 4096); fprintf(stderr, "%s", buf); std::this_thread::sleep_for(std::chrono::seconds(5)); } } static mysql_service_status_t my_component_init() { std::thread thd(dump_table); std::swap(worker_thd, thd); return 0; } static mysql_service_status_t my_component_deinit() { stop_worker_thd = true; worker_thd.join(); return 0; } BEGIN_COMPONENT_PROVIDES(my_component) END_COMPONENT_PROVIDES(); BEGIN_COMPONENT_REQUIRES(my_component) REQUIRES_SERVICE_AS(mysql_charset, charset_srv), REQUIRES_SERVICE_AS(mysql_string_factory, string_factory_srv), REQUIRES_SERVICE_AS(mysql_string_charset_converter, string_converter_srv), REQUIRES_SERVICE_AS(table_access_factory_v1, ta_factory_srv), REQUIRES_SERVICE_AS(table_access_v1, ta_srv), REQUIRES_SERVICE_AS(table_access_index_v1, ta_index_srv), REQUIRES_SERVICE_AS(table_access_scan_v1, ta_scan_srv), REQUIRES_SERVICE_AS(field_access_nullability_v1, fa_null_srv), REQUIRES_SERVICE_AS(field_integer_access_v1, fa_integer_srv), REQUIRES_SERVICE_AS(field_varchar_access_v1, fa_varchar_srv), END_COMPONENT_REQUIRES(); BEGIN_COMPONENT_METADATA(my_component) METADATA("mysql.author", "Oracle Corporation"), METADATA("mysql.license", "GPL"), METADATA("mysql.version", "1"), END_COMPONENT_METADATA(); DECLARE_COMPONENT(my_component, "mysql:my_component") my_component_init, my_component_deinit END_DECLARE_COMPONENT(); DECLARE_LIBRARY_COMPONENTS &COMPONENT_REF(my_component) END_DECLARE_LIBRARY_COMPONENTS./my_component/CMakeLists.txt0000664000175000017500000000234114555663553015461 0ustar kamilkamil# Copyright (c) 2017, 2021, Oracle and/or its affiliates. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2.0, # as published by the Free Software Foundation. # # This program is also distributed with certain software (including # but not limited to OpenSSL) that is licensed under separate terms, # as designated in a particular file or component or in included license # documentation. The authors of MySQL hereby grant you an additional # permission to link the program and your derivative works with the # separately licensed software that they have included with MySQL. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License, version 2.0, for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA DISABLE_MISSING_PROFILE_WARNING() MYSQL_ADD_COMPONENT(my_component my_component.cc MODULE_ONLY TEST_ONLY )