include/mysql/components/services/pfs_plugin_table_service.h (249 lines of code) (raw):
/* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
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 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 */
#ifndef PFS_PLUGIN_TABLE_SERVICE_H
#define PFS_PLUGIN_TABLE_SERVICE_H
#include <mysql/components/service.h>
#include <mysql/components/service_implementation.h>
/**
@page EXAMPLE_PLUGIN_COMPONENT Example plugin/component to use this service.
Any plugin/component, which exposes tables in performance schema, has to
- provide implementation of interface PFS_engine_table_proxy.
As there is no storage engine here to handle table data, plugin/component has to:
- maintain storage for table being exposed.
- take care of handling any duplicate check (Primary/Unique Key, etc.)
Following table explains datatypes exposed to plugin/component which should be
used for respective columns type in table.
COLUMN TYPE | TO BE USED | NULL VALUE INDICATION
----------- | ------------ | :---------------------:
INTEGER | PSI_int | is_null=true
TINYINT | PSI_tinyint | -do-
SMALLINT | PSI_smallint | -do-
BIGINT | PSI_bigint | -do-
MEDIUMINT | PSI_mediumint| -do-
DECIMAL | PSI_decimal | -do-
FLOAT | PSI_float | -do-
DOUBLE | PSI_double | -do-
ENUM | PSI_enum | -do-
YEAR | PSI_year | -do-
DATE | char array | length=0
TIME | char array | -do-
DATETIME | char array | -do-
TIMESTAMP | char array | -do-
CHAR | char array | -do-
VARCHAR | char array | -do-
BLOB | char array | -do-
@section STEPS Steps to write a plugin/component exposing tables in Performance Schema
- TBD
Following are the example implementations of a plugin and a component which
uses this pfs_plugin_table service.
@subpage EXAMPLE_PLUGIN
@subpage EXAMPLE_COMPONENT
*/
/* Define ERRORS */
#define PFS_HA_ERR_WRONG_COMMAND 131
#define PFS_HA_ERR_RECORD_DELETED 134
#define PFS_HA_ERR_END_OF_FILE 137
#define PFS_HA_ERR_NO_REFERENCED_ROW 151
#define PFS_HA_ERR_FOUND_DUPP_KEY 121
#define PFS_HA_ERR_RECORD_FILE_FULL 135
/* Helper macro */
struct PFS_string
{
char *str;
unsigned int length;
};
typedef struct PFS_string PFS_string;
/**
This is an opaque structure to denote filed in plugin/component code.
*/
typedef struct PSI_field PSI_field;
/**
This is an opaque structure to denote table handle in plugin/component code.
*/
typedef struct PSI_table_handle PSI_table_handle;
/**
This is an opaque structure to denote cursor position in plugin/component code.
*/
typedef struct PSI_pos PSI_pos;
/**
This is an opaque structure to denote Key Reader in plugin/component code.
*/
typedef struct PSI_key_reader PSI_key_reader;
/**
This is an opaque structure to denote Index Handle in plugin/component code.
*/
typedef struct PSI_index_handle PSI_index_handle;
struct PSI_long
{
long val; /* Column value */
bool is_null; /* If Column value is NULL */
};
typedef struct PSI_long PSI_long;
struct PSI_ulong
{
unsigned long val; /* Column value */
bool is_null; /* If Column value is NULL */
};
typedef struct PSI_ulong PSI_ulong;
struct PSI_longlong
{
long long val; /* Column value */
bool is_null /* If Column value is NULL */;
};
typedef struct PSI_longlong PSI_longlong;
struct PSI_ulonglong
{
unsigned long long val; /* Column value */
bool is_null /* If Column value is NULL */;
};
typedef struct PSI_ulonglong PSI_ulonglong;
struct PSI_double
{
double val; /* Column value */
bool is_null /* If Column value is NULL */;
};
typedef struct PSI_double PSI_double;
#define PSI_tinyint PSI_long
#define PSI_utinyint PSI_ulong
#define PSI_smallint PSI_long
#define PSI_usmallint PSI_ulong
#define PSI_mediumint PSI_long
#define PSI_umediumint PSI_ulong
#define PSI_int PSI_long
#define PSI_uint PSI_ulong
#define PSI_bigint PSI_longlong
#define PSI_ubigint PSI_ulonglong
#define PSI_year PSI_ulong
#define PSI_enum PSI_ulonglong
#define PSI_decimal PSI_double
#define PSI_float PSI_double
/**
A structure to denote a key of type long in an index.
*/
struct PSI_plugin_key_integer
{
/* name of the key column */
const char *m_name;
/* find flags */
int m_find_flags;
/* is column NULL */
bool m_is_null;
/* value of the key column */
long m_value;
};
typedef struct PSI_plugin_key_integer PSI_plugin_key_integer;
/**
A structure to denote a key of type string in an index.
*/
struct PSI_plugin_key_string
{
/* name of the key column */
const char *m_name;
/* find flags */
int m_find_flags;
/* is column null */
bool m_is_null;
/* buffer to store key column value */
char *m_value_buffer;
// FIXME: size_t
/* length of the key value in buffer */
unsigned int m_value_buffer_length;
/* Maximum size of buffer */
unsigned int m_value_buffer_capacity;
};
typedef struct PSI_plugin_key_string PSI_plugin_key_string;
/**
Api to read the next record.
@param handle Table handle.
@return Operation status
@retval 0 Success
@retval !=0 Error
*/
typedef int (*rnd_next_t)(PSI_table_handle* handle);
/**
API to initialize for random scan or read.
@param handle Table handle.
@param scan True, if its a random scan.
False, if its a random read.
@return Operation status
@retval 0 Success
@retval !=0 Error
*/
typedef int (*rnd_init_t)(PSI_table_handle* handle, bool scan);
/**
API to read row from a position which is set in table handle.
@param handle Table handle.
@return Operation status
@retval 0 Success
@retval !=0 Error
*/
typedef int (*rnd_pos_t)(PSI_table_handle* handle);
/**
API to initialize index(es).
@param handle Table handle.
@param idx Index of the index to be initialized (in case of multiple
indexes on table)
@param sorted
@param index Initialized index handle.
@return Operation status
@retval 0 Success
@retval !=0 Error
*/
typedef int (*index_init_t)(PSI_table_handle* table, unsigned int idx,
bool sorted, PSI_index_handle ** index);
/**
API to read keys in index.
@param index Index handle.
@param reader Key reader.
@param idx Index of the index to be read.
@param find_flag find flag.
@return Operation status
@retval 0 Success
@retval !=0 Error
*/
typedef int (*index_read_t)(PSI_index_handle *index, PSI_key_reader* reader,
unsigned int idx, int find_flag);
/**
API to read next record with matching index.
@param handle Table handle.
@return Operation status
@retval 0 Success
@retval !=0 Error
*/
typedef int (*index_next_t)(PSI_table_handle *table);
/**
API to reset cursor position
@param handle Table handle.
*/
typedef void (*reset_position_t)(PSI_table_handle* handle);
/**
API to read a column value from table.
@param handle Table handle.
@param field Field for which value is to be read.
@param index Index of field in table column.
@return Operation status
@retval 0 Success
@retval !=0 Error
*/
typedef int (*read_column_value_t)(PSI_table_handle* handle,
PSI_field *field,
unsigned int index);
/**
API to write a column value in table.
@param handle Table handle.
@param field Field for which value is to be written.
@param index Index of field in table column.
@return Operation status
@retval 0 Success
@retval !=0 Error
*/
typedef int (*write_column_value_t)(PSI_table_handle* handle,
PSI_field* fields,
unsigned int index);
/**
API to write a record in table.
@param handle Table handle having new record to be written.
*/
typedef int (*write_row_values_t)(PSI_table_handle* handle);
/**
API to update a column value in table.
@param handle Table handle.
@param field Field for which value is to be updated.
@param index Index of field in table column.
@return Operation status
@retval 0 Success
@retval !=0 Error
*/
typedef int (*update_column_value_t)(PSI_table_handle* handle,
PSI_field* fields,
unsigned int index);
/**
API to write a record in table.
@param handle Table handle having updated record to be updated.
*/
typedef int (*update_row_values_t)(PSI_table_handle* handle);
/**
API to delete record from table.
@param handle Table handle having record to be deleted.
*/
typedef int (*delete_row_values_t)(PSI_table_handle* handle);
/**
API to Open a table handle in plugin/component code and reset position
pointer when a new table handle in opened in Performance Schema.
@param pos pos pointer to be updated.
@return initialized table handle.
*/
typedef PSI_table_handle* (*open_table_t)(PSI_pos** pos);
/**
API to Close a table handle in plugin/component code and reset position
pointer when a table handle in closed in Performance Schema.
@param handle table handle
*/
typedef void (*close_table_t)(PSI_table_handle* handle);
/**
A structure to keep callback functions to be implemented by
plugin/component.
*/
struct PFS_engine_table_proxy
{
rnd_next_t rnd_next;
rnd_init_t rnd_init;
rnd_pos_t rnd_pos;
index_init_t index_init;
index_read_t index_read;
index_next_t index_next;
read_column_value_t read_column_value;
reset_position_t reset_position;
write_column_value_t write_column_value;
write_row_values_t write_row_values;
update_column_value_t update_column_value;
update_row_values_t update_row_values;
delete_row_values_t delete_row_values;
open_table_t open_table;
close_table_t close_table;
};
typedef struct PFS_engine_table_proxy PFS_engine_table_proxy;
/**
Types of access allowed to tables.
*/
enum Access_control
{
/* Only Read is allowed */
READONLY =0,
/* Read/Truncate allowed but no Update/Insert/Delete. */
TRUNCATABLE,
/* Read/Truncate/Update allowed but no Insert/Delete. */
UPDATABLE,
/* Read/Truncate/Insert/UPDATE/Delete allowed. */
EDITABLE
};
/**
API to delete/truncate all the rows in a table
*/
typedef int (*delete_all_rows_t)(void);
/**
API to give number of rows in a table
@return number of rows.
*/
typedef unsigned long long (*get_row_count_t)(void);
/**
A share to be initialized by plugin/component code and to be provided
to add_table() service method of pfs_plugin_table service.
*/
struct PFS_engine_table_share_proxy
{
public:
/* Callback functions list of APIs */
PFS_engine_table_proxy m_proxy_engine_table;
/* Name of the table to be added */
const char* m_table_name;
/* Length of the table name */
unsigned int m_table_name_length;
/* Table Columns definition */
const char* m_table_definition;
unsigned int m_ref_length;
/* Access allowed on the table */
enum Access_control m_acl;
delete_all_rows_t delete_all_rows;
get_row_count_t get_row_count;
};
typedef struct PFS_engine_table_share_proxy PFS_engine_table_share_proxy;
/**
Definition of pfs_plugin_table service and its methods.
*/
BEGIN_SERVICE_DEFINITION(pfs_plugin_table)
/* Methods to add tables in Performance Schema */
DECLARE_METHOD(int, add_tables,
(PFS_engine_table_share_proxy** st_share, unsigned int share_count));
/* Methods to delete tables in Performance Schema */
DECLARE_METHOD(int, delete_tables,
(PFS_engine_table_share_proxy** st_share, unsigned int share_count));
/* TINYINT */
DECLARE_METHOD(void, set_field_tinyint,
(PSI_field *f, PSI_tinyint value));
DECLARE_METHOD(void, set_field_utinyint,
(PSI_field *f, PSI_utinyint value));
DECLARE_METHOD(void, get_field_tinyint,
(PSI_field *f, PSI_tinyint *value));
/* SMALLINT */
DECLARE_METHOD(void, set_field_smallint,
(PSI_field *f, PSI_smallint value));
DECLARE_METHOD(void, set_field_usmallint,
(PSI_field *f, PSI_usmallint value));
DECLARE_METHOD(void, get_field_smallint,
(PSI_field *f, PSI_smallint *value));
/* MIDIUMINT */
DECLARE_METHOD(void, set_field_mediumint,
(PSI_field *f, PSI_mediumint value));
DECLARE_METHOD(void, set_field_umediumint,
(PSI_field *f, PSI_umediumint value));
DECLARE_METHOD(void, get_field_mediumint,
(PSI_field *f, PSI_mediumint *value));
/* INTEGER(INT) */
DECLARE_METHOD(void, set_field_integer,
(PSI_field *f, PSI_int value));
DECLARE_METHOD(void, set_field_uinteger,
(PSI_field *f, PSI_uint value));
DECLARE_METHOD(void, get_field_integer,
(PSI_field *f, PSI_int *value));
DECLARE_METHOD(void, read_key_integer,
(PSI_key_reader* reader, PSI_plugin_key_integer *key, int find_flag));
DECLARE_METHOD(bool, match_key_integer,
(bool record_null, long record_value, PSI_plugin_key_integer *key));
/* BIGINT */
DECLARE_METHOD(void, set_field_bigint,
(PSI_field *f, PSI_bigint value));
DECLARE_METHOD(void, set_field_ubigint,
(PSI_field *f, PSI_ubigint value));
DECLARE_METHOD(void , get_field_bigint,
(PSI_field *f, PSI_bigint *value));
/* DECIMAL */
DECLARE_METHOD(void, set_field_decimal,
(PSI_field *f, PSI_double value));
DECLARE_METHOD(void, get_field_decimal,
(PSI_field *f, PSI_double *value));
/* FLOAT */
DECLARE_METHOD(void, set_field_float,
(PSI_field *f, PSI_double value));
DECLARE_METHOD(void, get_field_float,
(PSI_field *f, PSI_double *value));
/* DOUBLE */
DECLARE_METHOD(void, set_field_double,
(PSI_field *f, PSI_double value));
DECLARE_METHOD(void, get_field_double,
(PSI_field *f, PSI_double *value));
/* CHAR */
DECLARE_METHOD(void, set_field_char_utf8,
(PSI_field *f, const char *value, unsigned int length));
DECLARE_METHOD(void, get_field_char_utf8,
(PSI_field *f, char *str, unsigned int *length));
DECLARE_METHOD(void, read_key_string,
(PSI_key_reader* reader, PSI_plugin_key_string *key, int find_flag));
DECLARE_METHOD(bool, match_key_string,
(bool record_null, const char* record_string_value,
unsigned int record_string_length, PSI_plugin_key_string *key));
/* VARCHAR */
DECLARE_METHOD(void, set_field_varchar_utf8,
(PSI_field *f, const char *str));
DECLARE_METHOD(void, set_field_varchar_utf8_len,
(PSI_field *f, const char *str, unsigned int len));
DECLARE_METHOD(void, get_field_varchar_utf8,
(PSI_field *f, char *str, unsigned int *length));
DECLARE_METHOD(void, set_field_varchar_utf8mb4,
(PSI_field *f, const char *str));
DECLARE_METHOD(void, set_field_varchar_utf8mb4_len,
(PSI_field *f, const char *str, unsigned int len));
/* BLOB/TEXT */
DECLARE_METHOD(void, set_field_blob,
(PSI_field *f, const char *val, unsigned int len));
DECLARE_METHOD(void, get_field_blob,
(PSI_field *f, char *val, unsigned int* len));
/* ENUM */
DECLARE_METHOD(void, set_field_enum,
(PSI_field *f, PSI_enum value));
DECLARE_METHOD(void, get_field_enum,
(PSI_field *f, PSI_enum *value));
/* DATE */
DECLARE_METHOD(void, set_field_date,
(PSI_field *f, const char* str, unsigned int length));
DECLARE_METHOD(void, get_field_date,
(PSI_field *f, char* val, unsigned int* len));
/* TIME */
DECLARE_METHOD(void, set_field_time,
(PSI_field *f, const char* str, unsigned int length));
DECLARE_METHOD(void, get_field_time,
(PSI_field *f, char* val, unsigned int* len));
/* DATETIME */
DECLARE_METHOD(void, set_field_datetime,
(PSI_field *f, const char* str, unsigned int length));
DECLARE_METHOD(void, get_field_datetime,
(PSI_field *f, char* val, unsigned int* len));
/* TIMESTAMP */
DECLARE_METHOD(void, set_field_timestamp,
(PSI_field *f, const char* str, unsigned int length));
DECLARE_METHOD(void, get_field_timestamp,
(PSI_field *f, char* val, unsigned int* len));
/* YEAR */
DECLARE_METHOD(void, set_field_year,
(PSI_field *f, PSI_year value));
DECLARE_METHOD(void, get_field_year,
(PSI_field *f, PSI_year *value));
/* NULL */
DECLARE_METHOD(void, set_field_null,
(PSI_field *f));
END_SERVICE_DEFINITION(pfs_plugin_table)
#endif