diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2014-03-20 12:05:47 +0100 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2014-03-20 12:05:47 +0100 |
commit | 7b400a088d049661b9a4dded385ac78923bb0017 (patch) | |
tree | bb3ee7bac4454f66ec6f38cf6683f24bc6c065d4 /storage/connect/ha_connect.h | |
parent | d67ad26b33ea16a3b59215ef967bdd9b89345e04 (diff) | |
parent | e5729127b8a50a0e553fd8b87b2683e4a684dfcc (diff) | |
download | mariadb-git-7b400a088d049661b9a4dded385ac78923bb0017.tar.gz |
- MRR + Block Indexing
modified:
storage/connect/array.h
storage/connect/catalog.h
storage/connect/colblk.cpp
storage/connect/colblk.h
storage/connect/connect.cc
storage/connect/connect.h
storage/connect/domdoc.h
storage/connect/filamap.cpp
storage/connect/filamap.h
storage/connect/filamdbf.h
storage/connect/filamfix.cpp
storage/connect/filamfix.h
storage/connect/filamtxt.cpp
storage/connect/filamtxt.h
storage/connect/filamvct.cpp
storage/connect/filamvct.h
storage/connect/filamzip.cpp
storage/connect/filamzip.h
storage/connect/filter.cpp
storage/connect/filter.h
storage/connect/global.h
storage/connect/ha_connect.cc
storage/connect/ha_connect.h
storage/connect/myconn.h
storage/connect/plgcnx.h
storage/connect/plgdbsem.h
storage/connect/plgdbutl.cpp
storage/connect/plugutil.c
storage/connect/preparse.h
storage/connect/reldef.cpp
storage/connect/reldef.h
storage/connect/tabcol.h
storage/connect/tabdos.cpp
storage/connect/tabdos.h
storage/connect/tabfix.cpp
storage/connect/tabfmt.cpp
storage/connect/tabfmt.h
storage/connect/table.cpp
storage/connect/tabmysql.cpp
storage/connect/tabmysql.h
storage/connect/taboccur.h
storage/connect/tabodbc.h
storage/connect/tabsys.h
storage/connect/tabtbl.h
storage/connect/tabutil.h
storage/connect/tabvct.cpp
storage/connect/tabvct.h
storage/connect/tabwmi.h
storage/connect/tabxml.h
storage/connect/user_connect.cc
storage/connect/user_connect.h
storage/connect/valblk.cpp
storage/connect/valblk.h
storage/connect/value.cpp
storage/connect/value.h
storage/connect/xindex.cpp
storage/connect/xindex.h
storage/connect/xobject.cpp
storage/connect/xobject.h
storage/connect/xtable.h
Diffstat (limited to 'storage/connect/ha_connect.h')
-rw-r--r-- | storage/connect/ha_connect.h | 1053 |
1 files changed, 524 insertions, 529 deletions
diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h index a2d3c5d6801..1924d8de185 100644 --- a/storage/connect/ha_connect.h +++ b/storage/connect/ha_connect.h @@ -1,529 +1,524 @@ -/* Copyright (C) Olivier Bertrand 2004 - 2013 - - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/** @file ha_connect.h - - @brief - The ha_connect engine is a prototype storage engine to access external data. - - @see - /sql/handler.h and /storage/connect/ha_connect.cc -*/ - -#ifdef USE_PRAGMA_INTERFACE -#pragma interface /* gcc class implementation */ -#endif - -/****************************************************************************/ -/* Structures used to pass info between CONNECT and ha_connect. */ -/****************************************************************************/ -typedef struct _create_xinfo { - char *Type; /* Retrieved from table comment */ - char *Filename; /* Set if not standard */ - char *IndexFN; /* Set if not standard */ - ulonglong Maxrows; /* Estimated max nb of rows */ - ulong Lrecl; /* Set if not default */ - ulong Elements; /* Number of lines in blocks */ - bool Fixed; /* False for DOS type */ - void *Pcf; /* To list of columns */ - void *Pxdf; /* To list of indexes */ -} CRXINFO, *PCXF; - -typedef struct _xinfo { - ulonglong data_file_length; /* Length of data file */ - ha_rows records; /* Records in table */ - ulong mean_rec_length; /* Physical record length */ - char *data_file_name; /* Physical file name */ -} XINFO, *PXF; - -class XCHK : public BLOCK { -public: - XCHK(void) {oldsep= newsep= false; - oldopn= newopn= NULL; - oldpix= newpix= NULL;} - - inline char *SetName(PGLOBAL g, char *name) { - char *nm= NULL; - if (name) {nm= (char*)PlugSubAlloc(g, NULL, strlen(name) + 1); - strcpy(nm, name);} - return nm;} - - bool oldsep; // Sepindex before create/alter - bool newsep; // Sepindex after create/alter - char *oldopn; // Optname before create/alter - char *newopn; // Optname after create/alter - PIXDEF oldpix; // The indexes before create/alter - PIXDEF newpix; // The indexes after create/alter -}; // end of class XCHK - -typedef class XCHK *PCHK; -typedef class user_connect *PCONNECT; -typedef struct ha_table_option_struct TOS, *PTOS; -typedef struct ha_field_option_struct FOS, *PFOS; - -extern handlerton *connect_hton; - -/** - structure for CREATE TABLE options (table options) - - These can be specified in the CREATE TABLE: - CREATE TABLE ( ... ) {...here...} -*/ -struct ha_table_option_struct { - const char *type; - const char *filename; - const char *optname; - const char *tabname; - const char *tablist; - const char *dbname; - const char *separator; -//const char *connect; - const char *qchar; - const char *module; - const char *subtype; - const char *catfunc; - const char *srcdef; - const char *colist; - const char *oplist; - const char *data_charset; - ulonglong lrecl; - ulonglong elements; -//ulonglong estimate; - ulonglong multiple; - ulonglong header; - ulonglong quoted; - ulonglong ending; - ulonglong compressed; - bool mapped; - bool huge; - bool split; - bool readonly; - bool sepindex; - }; - -/** - structure for CREATE TABLE options (field options) - - These can be specified in the CREATE TABLE per field: - CREATE TABLE ( field ... {...here...}, ... ) -*/ -struct ha_field_option_struct -{ - ulonglong offset; - ulonglong freq; // Not used by this version - ulonglong opt; // Not used by this version - ulonglong fldlen; - const char *dateformat; - const char *fieldformat; - char *special; -}; - -/** @brief - CONNECT_SHARE is a structure that will be shared among all open handlers. - This example implements the minimum of what you will probably need. -*/ -class CONNECT_SHARE : public Handler_share { -public: - mysql_mutex_t mutex; - THR_LOCK lock; - CONNECT_SHARE() - { - thr_lock_init(&lock); - } - ~CONNECT_SHARE() - { - thr_lock_delete(&lock); - mysql_mutex_destroy(&mutex); - } -}; - -typedef class ha_connect *PHC; - -/** @brief - Class definition for the storage engine -*/ -class ha_connect: public handler -{ - THR_LOCK_DATA lock; ///< MySQL lock - CONNECT_SHARE *share; ///< Shared lock info - CONNECT_SHARE *get_share(); - -public: - ha_connect(handlerton *hton, TABLE_SHARE *table_arg); - ~ha_connect(); - - // CONNECT Implementation - static bool connect_init(void); - static bool connect_end(void); - TABTYPE GetRealType(PTOS pos); - char *GetStringOption(char *opname, char *sdef= NULL); - PTOS GetTableOptionStruct(TABLE *table_arg); - bool GetBooleanOption(char *opname, bool bdef); - bool SetBooleanOption(char *opname, bool b); - int GetIntegerOption(char *opname); - bool CheckString(const char *str1, const char *str2); - bool SameString(TABLE *tab, char *opn); - bool SetIntegerOption(char *opname, int n); - bool SameInt(TABLE *tab, char *opn); - bool SameBool(TABLE *tab, char *opn); - bool FileExists(const char *fn); - bool NoFieldOptionChange(TABLE *tab); - PFOS GetFieldOptionStruct(Field *fp); - void *GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf); - PIXDEF GetIndexInfo(TABLE_SHARE *s= NULL); - const char *GetDBName(const char *name); - const char *GetTableName(void); -//int GetColNameLen(Field *fp); -//char *GetColName(Field *fp); -//void AddColName(char *cp, Field *fp); - TABLE *GetTable(void) {return table;} - bool IsSameIndex(PIXDEF xp1, PIXDEF xp2); - - PTDB GetTDB(PGLOBAL g); - int OpenTable(PGLOBAL g, bool del= false); - bool IsOpened(void); - int CloseTable(PGLOBAL g); - int MakeRecord(char *buf); - int ScanRecord(PGLOBAL g, uchar *buf); - int CheckRecord(PGLOBAL g, const uchar *oldbuf, uchar *newbuf); - int ReadIndexed(uchar *buf, OPVAL op, const uchar* key= NULL, - uint key_len= 0); - - /** @brief - The name that will be used for display purposes. - */ - const char *table_type() const {return "CONNECT";} - - /** @brief - The name of the index type that will be used for display. - Don't implement this method unless you really have indexes. - */ - const char *index_type(uint inx) { return "XPLUG"; } - - /** @brief - The file extensions. - */ - const char **bas_ext() const; - - /** - Check if a storage engine supports a particular alter table in-place - @note Called without holding thr_lock.c lock. - */ - virtual enum_alter_inplace_result - check_if_supported_inplace_alter(TABLE *altered_table, - Alter_inplace_info *ha_alter_info); - - /** @brief - This is a list of flags that indicate what functionality the storage engine - implements. The current table flags are documented in handler.h - */ - ulonglong table_flags() const; - - /** @brief - This is a bitmap of flags that indicates how the storage engine - implements indexes. The current index flags are documented in - handler.h. If you do not implement indexes, just return zero here. - - @details - part is the key part to check. First key part is 0. - If all_parts is set, MySQL wants to know the flags for the combined - index, up to and including 'part'. - */ - ulong index_flags(uint inx, uint part, bool all_parts) const - { - return HA_READ_NEXT | HA_READ_RANGE | HA_READ_ORDER -#if defined(MRRBKA_SUPPORT) - | HA_KEYREAD_ONLY -#endif // MRRBKA_SUPPORT - ; - } // end of index_flags - - /** @brief - unireg.cc will call max_supported_record_length(), max_supported_keys(), - max_supported_key_parts(), uint max_supported_key_length() - to make sure that the storage engine can handle the data it is about to - send. Return *real* limits of your storage engine here; MySQL will do - min(your_limits, MySQL_limits) automatically. - */ - uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; } - - /** @brief - unireg.cc will call this to make sure that the storage engine can handle - the data it is about to send. Return *real* limits of your storage engine - here; MySQL will do min(your_limits, MySQL_limits) automatically. - - @details - There is no need to implement ..._key_... methods if your engine doesn't - support indexes. - */ - uint max_supported_keys() const { return 10; } - - /** @brief - unireg.cc will call this to make sure that the storage engine can handle - the data it is about to send. Return *real* limits of your storage engine - here; MySQL will do min(your_limits, MySQL_limits) automatically. - - @details - There is no need to implement ..._key_... methods if your engine doesn't - support indexes. - */ - uint max_supported_key_parts() const { return 10; } - - /** @brief - unireg.cc will call this to make sure that the storage engine can handle - the data it is about to send. Return *real* limits of your storage engine - here; MySQL will do min(your_limits, MySQL_limits) automatically. - - @details - There is no need to implement ..._key_... methods if your engine doesn't - support indexes. - */ - uint max_supported_key_length() const { return 255; } - - /** @brief - Called in test_quick_select to determine if indexes should be used. - */ - virtual double scan_time() { return (double) (stats.records+stats.deleted) / 20.0+10; } - - /** @brief - This method will never be called if you do not implement indexes. - */ - virtual double read_time(uint, uint, ha_rows rows) - { return (double) rows / 20.0+1; } - - /* - Everything below are methods that we implement in ha_connect.cc. - - Most of these methods are not obligatory, skip them and - MySQL will treat them as not implemented - */ - virtual bool get_error_message(int error, String *buf); - - /** - Push condition down to the table handler. - - @param cond Condition to be pushed. The condition tree must not be - modified by the by the caller. - - @return - The 'remainder' condition that caller must use to filter out records. - NULL means the handler will not return rows that do not match the - passed condition. - - @note - The pushed conditions form a stack (from which one can remove the - last pushed condition using cond_pop). - The table handler filters out rows using (pushed_cond1 AND pushed_cond2 - AND ... AND pushed_condN) - or less restrictive condition, depending on handler's capabilities. - - handler->ha_reset() call empties the condition stack. - Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the - condition stack. - */ -virtual const COND *cond_push(const COND *cond); -PCFIL CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond); -const char *GetValStr(OPVAL vop, bool neg); -#if defined(BLK_INDX) -PFIL CondFilter(PGLOBAL g, Item *cond); -#endif // BLK_INDX - - /** - Number of rows in table. It will only be called if - (table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0 - */ - virtual ha_rows records(); - - /** - Type of table for caching query - CONNECT should not use caching because its tables are external - data prone to me modified out of MariaDB - */ - virtual uint8 table_cache_type(void) - { -#if defined(MEMORY_TRACE) - // Temporary until bug MDEV-4771 is fixed - return HA_CACHE_TBL_NONTRANSACT; -#else - return HA_CACHE_TBL_NOCACHE; -#endif - } - - /** @brief - We implement this in ha_connect.cc; it's a required method. - */ - int open(const char *name, int mode, uint test_if_locked); // required - - /** @brief - We implement this in ha_connect.cc; it's a required method. - */ - int close(void); // required - - /** @brief - We implement this in ha_connect.cc. It's not an obligatory method; - skip it and and MySQL will treat it as not implemented. - */ - int write_row(uchar *buf); - - /** @brief - We implement this in ha_connect.cc. It's not an obligatory method; - skip it and and MySQL will treat it as not implemented. - */ - int update_row(const uchar *old_data, uchar *new_data); - - /** @brief - We implement this in ha_connect.cc. It's not an obligatory method; - skip it and and MySQL will treat it as not implemented. - */ - int delete_row(const uchar *buf); - - // Added to the connect handler - int index_init(uint idx, bool sorted); - int index_end(); - int index_read(uchar * buf, const uchar * key, uint key_len, - enum ha_rkey_function find_flag); - int index_next_same(uchar *buf, const uchar *key, uint keylen); - - /** @brief - We implement this in ha_connect.cc. It's not an obligatory method; - skip it and and MySQL will treat it as not implemented. - */ -//int index_read_map(uchar *buf, const uchar *key, -// key_part_map keypart_map, enum ha_rkey_function find_flag); - - /** @brief - We implement this in ha_connect.cc. It's not an obligatory method; - skip it and and MySQL will treat it as not implemented. - */ - int index_next(uchar *buf); - - /** @brief - We implement this in ha_connect.cc. It's not an obligatory method; - skip it and and MySQL will treat it as not implemented. - */ -//int index_prev(uchar *buf); - - /** @brief - We implement this in ha_connect.cc. It's not an obligatory method; - skip it and and MySQL will treat it as not implemented. - */ - int index_first(uchar *buf); - - /** @brief - We implement this in ha_connect.cc. It's not an obligatory method; - skip it and and MySQL will treat it as not implemented. - */ -//int index_last(uchar *buf); - - /** @brief - Unlike index_init(), rnd_init() can be called two consecutive times - without rnd_end() in between (it only makes sense if scan=1). In this - case, the second call should prepare for the new table scan (e.g if - rnd_init() allocates the cursor, the second call should position the - cursor to the start of the table; no need to deallocate and allocate - it again. This is a required method. - */ - int rnd_init(bool scan); //required - int rnd_end(); - int rnd_next(uchar *buf); ///< required - int rnd_pos(uchar *buf, uchar *pos); ///< required - void position(const uchar *record); ///< required - int info(uint); ///< required - int extra(enum ha_extra_function operation); - int start_stmt(THD *thd, thr_lock_type lock_type); - int external_lock(THD *thd, int lock_type); ///< required - int delete_all_rows(void); - ha_rows records_in_range(uint inx, key_range *min_key, - key_range *max_key); - /** - These methods can be overridden, but their default implementation - provide useful functionality. - */ - int rename_table(const char *from, const char *to); - /** - Delete a table in the engine. Called for base as well as temporary - tables. - */ - int delete_table(const char *name); - /** - Called by delete_table and rename_table - */ - int delete_or_rename_table(const char *from, const char *to); - int create(const char *name, TABLE *form, - HA_CREATE_INFO *create_info); ///< required - bool check_if_incompatible_data(HA_CREATE_INFO *info, - uint table_changes); - - THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, - enum thr_lock_type lock_type); ///< required - int optimize(THD* thd, HA_CHECK_OPT* check_opt); - -protected: - bool check_privileges(THD *thd, PTOS options, char *dbn); - MODE CheckMode(PGLOBAL g, THD *thd, MODE newmode, bool *chk, bool *cras); - char *GetDBfromName(const char *name); - - // Members - static ulong num; // Tracable handler number - PCONNECT xp; // To user_connect associated class - ulong hnum; // The number of this handler - query_id_t valid_query_id; // The one when tdbp was allocated - query_id_t creat_query_id; // The one when handler was allocated - PTDB tdbp; // To table class object - PVAL sdvalin; // Used to convert date values - PVAL sdvalout; // Used to convert date values - bool istable; // True for table handler -//char tname[64]; // The table name - MODE xmod; // Table mode - XINFO xinfo; // The table info structure - bool valid_info; // True if xinfo is valid - bool stop; // Used when creating index - bool alter; // True when converting to other engine - bool mrr; // True when getting index positions - int indexing; // Type of indexing for CONNECT - int locked; // Table lock - THR_LOCK_DATA lock_data; - -public: - TABLE_SHARE *tshp; // Used by called tables - char *data_file_name; - char *index_file_name; - uint int_table_flags; // Inherited from MyISAM - bool enable_activate_all_index; // Inherited from MyISAM - -#if defined(MRRBKA_SUPPORT) - /** - * Multi Range Read interface - */ - int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, - uint n_ranges, uint mode, HANDLER_BUFFER *buf); - int multi_range_read_next(range_id_t *range_info); - ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, - void *seq_init_param, - uint n_ranges, uint *bufsz, - uint *flags, Cost_estimate *cost); - ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys, - uint key_parts, uint *bufsz, - uint *flags, Cost_estimate *cost); - int multi_range_read_explain_info(uint mrr_mode, char *str, size_t size); - - int reset(void) {ds_mrr.dsmrr_close(); return 0;} - - /* Index condition pushdown implementation */ -// Item *idx_cond_push(uint keyno, Item* idx_cond); -private: - DsMrr_impl ds_mrr; -#endif // MRRBKA_SUPPORT -}; // end of ha_connect class definition +/* Copyright (C) Olivier Bertrand 2004 - 2014
+
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/** @file ha_connect.h
+
+ @brief
+ The ha_connect engine is a prototype storage engine to access external data.
+
+ @see
+ /sql/handler.h and /storage/connect/ha_connect.cc
+*/
+
+#ifdef USE_PRAGMA_INTERFACE
+#pragma interface /* gcc class implementation */
+#endif
+
+/****************************************************************************/
+/* Structures used to pass info between CONNECT and ha_connect. */
+/****************************************************************************/
+typedef struct _create_xinfo {
+ char *Type; /* Retrieved from table comment */
+ char *Filename; /* Set if not standard */
+ char *IndexFN; /* Set if not standard */
+ ulonglong Maxrows; /* Estimated max nb of rows */
+ ulong Lrecl; /* Set if not default */
+ ulong Elements; /* Number of lines in blocks */
+ bool Fixed; /* False for DOS type */
+ void *Pcf; /* To list of columns */
+ void *Pxdf; /* To list of indexes */
+} CRXINFO, *PCXF;
+
+typedef struct _xinfo {
+ ulonglong data_file_length; /* Length of data file */
+ ha_rows records; /* Records in table */
+ ulong mean_rec_length; /* Physical record length */
+ char *data_file_name; /* Physical file name */
+} XINFO, *PXF;
+
+class XCHK : public BLOCK {
+public:
+ XCHK(void) {oldsep= newsep= false;
+ oldopn= newopn= NULL;
+ oldpix= newpix= NULL;}
+
+ inline char *SetName(PGLOBAL g, char *name) {
+ char *nm= NULL;
+ if (name) {nm= (char*)PlugSubAlloc(g, NULL, strlen(name) + 1);
+ strcpy(nm, name);}
+ return nm;}
+
+ bool oldsep; // Sepindex before create/alter
+ bool newsep; // Sepindex after create/alter
+ char *oldopn; // Optname before create/alter
+ char *newopn; // Optname after create/alter
+ PIXDEF oldpix; // The indexes before create/alter
+ PIXDEF newpix; // The indexes after create/alter
+}; // end of class XCHK
+
+typedef class XCHK *PCHK;
+typedef class user_connect *PCONNECT;
+typedef struct ha_table_option_struct TOS, *PTOS;
+typedef struct ha_field_option_struct FOS, *PFOS;
+
+extern handlerton *connect_hton;
+
+/**
+ structure for CREATE TABLE options (table options)
+
+ These can be specified in the CREATE TABLE:
+ CREATE TABLE ( ... ) {...here...}
+*/
+struct ha_table_option_struct {
+ const char *type;
+ const char *filename;
+ const char *optname;
+ const char *tabname;
+ const char *tablist;
+ const char *dbname;
+ const char *separator;
+//const char *connect;
+ const char *qchar;
+ const char *module;
+ const char *subtype;
+ const char *catfunc;
+ const char *srcdef;
+ const char *colist;
+ const char *oplist;
+ const char *data_charset;
+ ulonglong lrecl;
+ ulonglong elements;
+//ulonglong estimate;
+ ulonglong multiple;
+ ulonglong header;
+ ulonglong quoted;
+ ulonglong ending;
+ ulonglong compressed;
+ bool mapped;
+ bool huge;
+ bool split;
+ bool readonly;
+ bool sepindex;
+ };
+
+/**
+ structure for CREATE TABLE options (field options)
+
+ These can be specified in the CREATE TABLE per field:
+ CREATE TABLE ( field ... {...here...}, ... )
+*/
+struct ha_field_option_struct
+{
+ ulonglong offset;
+ ulonglong freq;
+ ulonglong opt;
+ ulonglong fldlen;
+ const char *dateformat;
+ const char *fieldformat;
+ char *special;
+};
+
+/** @brief
+ CONNECT_SHARE is a structure that will be shared among all open handlers.
+ This example implements the minimum of what you will probably need.
+*/
+class CONNECT_SHARE : public Handler_share {
+public:
+ mysql_mutex_t mutex;
+ THR_LOCK lock;
+ CONNECT_SHARE()
+ {
+ thr_lock_init(&lock);
+ }
+ ~CONNECT_SHARE()
+ {
+ thr_lock_delete(&lock);
+ mysql_mutex_destroy(&mutex);
+ }
+};
+
+typedef class ha_connect *PHC;
+
+/** @brief
+ Class definition for the storage engine
+*/
+class ha_connect: public handler
+{
+ THR_LOCK_DATA lock; ///< MySQL lock
+ CONNECT_SHARE *share; ///< Shared lock info
+ CONNECT_SHARE *get_share();
+
+public:
+ ha_connect(handlerton *hton, TABLE_SHARE *table_arg);
+ ~ha_connect();
+
+ // CONNECT Implementation
+ static bool connect_init(void);
+ static bool connect_end(void);
+ TABTYPE GetRealType(PTOS pos);
+ char *GetStringOption(char *opname, char *sdef= NULL);
+ PTOS GetTableOptionStruct(TABLE *table_arg);
+ bool GetBooleanOption(char *opname, bool bdef);
+ bool SetBooleanOption(char *opname, bool b);
+ int GetIntegerOption(char *opname);
+ bool CheckString(const char *str1, const char *str2);
+ bool SameString(TABLE *tab, char *opn);
+ bool SetIntegerOption(char *opname, int n);
+ bool SameInt(TABLE *tab, char *opn);
+ bool SameBool(TABLE *tab, char *opn);
+ bool FileExists(const char *fn);
+ bool NoFieldOptionChange(TABLE *tab);
+ PFOS GetFieldOptionStruct(Field *fp);
+ void *GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf);
+ PIXDEF GetIndexInfo(TABLE_SHARE *s= NULL);
+ const char *GetDBName(const char *name);
+ const char *GetTableName(void);
+//int GetColNameLen(Field *fp);
+//char *GetColName(Field *fp);
+//void AddColName(char *cp, Field *fp);
+ TABLE *GetTable(void) {return table;}
+ bool IsSameIndex(PIXDEF xp1, PIXDEF xp2);
+
+ PTDB GetTDB(PGLOBAL g);
+ int OpenTable(PGLOBAL g, bool del= false);
+ bool IsOpened(void);
+ int CloseTable(PGLOBAL g);
+ int MakeRecord(char *buf);
+ int ScanRecord(PGLOBAL g, uchar *buf);
+ int CheckRecord(PGLOBAL g, const uchar *oldbuf, uchar *newbuf);
+ int ReadIndexed(uchar *buf, OPVAL op, const uchar* key= NULL,
+ uint key_len= 0);
+
+ /** @brief
+ The name that will be used for display purposes.
+ */
+ const char *table_type() const {return "CONNECT";}
+
+ /** @brief
+ The name of the index type that will be used for display.
+ Don't implement this method unless you really have indexes.
+ */
+ const char *index_type(uint inx) { return "XPLUG"; }
+
+ /** @brief
+ The file extensions.
+ */
+ const char **bas_ext() const;
+
+ /**
+ Check if a storage engine supports a particular alter table in-place
+ @note Called without holding thr_lock.c lock.
+ */
+ virtual enum_alter_inplace_result
+ check_if_supported_inplace_alter(TABLE *altered_table,
+ Alter_inplace_info *ha_alter_info);
+
+ /** @brief
+ This is a list of flags that indicate what functionality the storage engine
+ implements. The current table flags are documented in handler.h
+ */
+ ulonglong table_flags() const;
+
+ /** @brief
+ This is a bitmap of flags that indicates how the storage engine
+ implements indexes. The current index flags are documented in
+ handler.h. If you do not implement indexes, just return zero here.
+
+ @details
+ part is the key part to check. First key part is 0.
+ If all_parts is set, MySQL wants to know the flags for the combined
+ index, up to and including 'part'.
+ */
+ ulong index_flags(uint inx, uint part, bool all_parts) const
+ {
+ return HA_READ_NEXT | HA_READ_RANGE | HA_READ_ORDER | HA_KEYREAD_ONLY;
+ } // end of index_flags
+
+ /** @brief
+ unireg.cc will call max_supported_record_length(), max_supported_keys(),
+ max_supported_key_parts(), uint max_supported_key_length()
+ to make sure that the storage engine can handle the data it is about to
+ send. Return *real* limits of your storage engine here; MySQL will do
+ min(your_limits, MySQL_limits) automatically.
+ */
+ uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+ here; MySQL will do min(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+ support indexes.
+ */
+ uint max_supported_keys() const { return 10; }
+
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+ here; MySQL will do min(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+ support indexes.
+ */
+ uint max_supported_key_parts() const { return 10; }
+
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+ here; MySQL will do min(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+ support indexes.
+ */
+ uint max_supported_key_length() const { return 255; }
+
+ /** @brief
+ Called in test_quick_select to determine if indexes should be used.
+ */
+ virtual double scan_time() { return (double) (stats.records+stats.deleted) / 20.0+10; }
+
+ /** @brief
+ This method will never be called if you do not implement indexes.
+ */
+ virtual double read_time(uint, uint, ha_rows rows)
+ { return (double) rows / 20.0+1; }
+
+ /*
+ Everything below are methods that we implement in ha_connect.cc.
+
+ Most of these methods are not obligatory, skip them and
+ MySQL will treat them as not implemented
+ */
+ virtual bool get_error_message(int error, String *buf);
+
+ /**
+ Push condition down to the table handler.
+
+ @param cond Condition to be pushed. The condition tree must not be
+ modified by the by the caller.
+
+ @return
+ The 'remainder' condition that caller must use to filter out records.
+ NULL means the handler will not return rows that do not match the
+ passed condition.
+
+ @note
+ The pushed conditions form a stack (from which one can remove the
+ last pushed condition using cond_pop).
+ The table handler filters out rows using (pushed_cond1 AND pushed_cond2
+ AND ... AND pushed_condN)
+ or less restrictive condition, depending on handler's capabilities.
+
+ handler->ha_reset() call empties the condition stack.
+ Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the
+ condition stack.
+ */
+virtual const COND *cond_push(const COND *cond);
+PCFIL CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond);
+const char *GetValStr(OPVAL vop, bool neg);
+PFIL CondFilter(PGLOBAL g, Item *cond);
+
+ /**
+ Number of rows in table. It will only be called if
+ (table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0
+ */
+ virtual ha_rows records();
+
+ /**
+ Type of table for caching query
+ CONNECT should not use caching because its tables are external
+ data prone to me modified out of MariaDB
+ */
+ virtual uint8 table_cache_type(void)
+ {
+#if defined(MEMORY_TRACE)
+ // Temporary until bug MDEV-4771 is fixed
+ return HA_CACHE_TBL_NONTRANSACT;
+#else
+ return HA_CACHE_TBL_NOCACHE;
+#endif
+ }
+
+ /** @brief
+ We implement this in ha_connect.cc; it's a required method.
+ */
+ int open(const char *name, int mode, uint test_if_locked); // required
+
+ /** @brief
+ We implement this in ha_connect.cc; it's a required method.
+ */
+ int close(void); // required
+
+ /** @brief
+ We implement this in ha_connect.cc. It's not an obligatory method;
+ skip it and and MySQL will treat it as not implemented.
+ */
+ int write_row(uchar *buf);
+
+ /** @brief
+ We implement this in ha_connect.cc. It's not an obligatory method;
+ skip it and and MySQL will treat it as not implemented.
+ */
+ int update_row(const uchar *old_data, uchar *new_data);
+
+ /** @brief
+ We implement this in ha_connect.cc. It's not an obligatory method;
+ skip it and and MySQL will treat it as not implemented.
+ */
+ int delete_row(const uchar *buf);
+
+ // Added to the connect handler
+ int index_init(uint idx, bool sorted);
+ int index_end();
+ int index_read(uchar * buf, const uchar * key, uint key_len,
+ enum ha_rkey_function find_flag);
+ int index_next_same(uchar *buf, const uchar *key, uint keylen);
+
+ /** @brief
+ We implement this in ha_connect.cc. It's not an obligatory method;
+ skip it and and MySQL will treat it as not implemented.
+ */
+//int index_read_map(uchar *buf, const uchar *key,
+// key_part_map keypart_map, enum ha_rkey_function find_flag);
+
+ /** @brief
+ We implement this in ha_connect.cc. It's not an obligatory method;
+ skip it and and MySQL will treat it as not implemented.
+ */
+ int index_next(uchar *buf);
+
+ /** @brief
+ We implement this in ha_connect.cc. It's not an obligatory method;
+ skip it and and MySQL will treat it as not implemented.
+ */
+//int index_prev(uchar *buf);
+
+ /** @brief
+ We implement this in ha_connect.cc. It's not an obligatory method;
+ skip it and and MySQL will treat it as not implemented.
+ */
+ int index_first(uchar *buf);
+
+ /** @brief
+ We implement this in ha_connect.cc. It's not an obligatory method;
+ skip it and and MySQL will treat it as not implemented.
+ */
+//int index_last(uchar *buf);
+
+ /* Index condition pushdown implementation */
+//Item *idx_cond_push(uint keyno, Item* idx_cond);
+
+ /** @brief
+ Unlike index_init(), rnd_init() can be called two consecutive times
+ without rnd_end() in between (it only makes sense if scan=1). In this
+ case, the second call should prepare for the new table scan (e.g if
+ rnd_init() allocates the cursor, the second call should position the
+ cursor to the start of the table; no need to deallocate and allocate
+ it again. This is a required method.
+ */
+ int rnd_init(bool scan); //required
+ int rnd_end();
+ int rnd_next(uchar *buf); ///< required
+ int rnd_pos(uchar *buf, uchar *pos); ///< required
+ void position(const uchar *record); ///< required
+ int info(uint); ///< required
+ int extra(enum ha_extra_function operation);
+ int start_stmt(THD *thd, thr_lock_type lock_type);
+ int external_lock(THD *thd, int lock_type); ///< required
+ int delete_all_rows(void);
+ ha_rows records_in_range(uint inx, key_range *min_key,
+ key_range *max_key);
+ /**
+ These methods can be overridden, but their default implementation
+ provide useful functionality.
+ */
+ int rename_table(const char *from, const char *to);
+ /**
+ Delete a table in the engine. Called for base as well as temporary
+ tables.
+ */
+ int delete_table(const char *name);
+ /**
+ Called by delete_table and rename_table
+ */
+ int delete_or_rename_table(const char *from, const char *to);
+ int create(const char *name, TABLE *form,
+ HA_CREATE_INFO *create_info); ///< required
+ bool check_if_incompatible_data(HA_CREATE_INFO *info,
+ uint table_changes);
+
+ THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
+ enum thr_lock_type lock_type); ///< required
+ int optimize(THD* thd, HA_CHECK_OPT* check_opt);
+
+ /**
+ * Multi Range Read interface
+ */
+ int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
+ uint n_ranges, uint mode, HANDLER_BUFFER *buf);
+ int multi_range_read_next(range_id_t *range_info);
+ ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
+ void *seq_init_param,
+ uint n_ranges, uint *bufsz,
+ uint *flags, Cost_estimate *cost);
+ ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+ uint key_parts, uint *bufsz,
+ uint *flags, Cost_estimate *cost);
+ int multi_range_read_explain_info(uint mrr_mode, char *str, size_t size);
+
+ int reset(void) {ds_mrr.dsmrr_close(); return 0;}
+
+ /* Index condition pushdown implementation */
+// Item *idx_cond_push(uint keyno, Item* idx_cond);
+private:
+ DsMrr_impl ds_mrr;
+
+protected:
+ bool check_privileges(THD *thd, PTOS options, char *dbn);
+ MODE CheckMode(PGLOBAL g, THD *thd, MODE newmode, bool *chk, bool *cras);
+ char *GetDBfromName(const char *name);
+
+ // Members
+ static ulong num; // Tracable handler number
+ PCONNECT xp; // To user_connect associated class
+ ulong hnum; // The number of this handler
+ query_id_t valid_query_id; // The one when tdbp was allocated
+ query_id_t creat_query_id; // The one when handler was allocated
+ PTDB tdbp; // To table class object
+ PVAL sdvalin; // Used to convert date values
+ PVAL sdvalout; // Used to convert date values
+ bool istable; // True for table handler
+//char tname[64]; // The table name
+ MODE xmod; // Table mode
+ XINFO xinfo; // The table info structure
+ bool valid_info; // True if xinfo is valid
+ bool stop; // Used when creating index
+ bool alter; // True when converting to other engine
+ bool mrr; // True when getting index positions
+ int indexing; // Type of indexing for CONNECT
+ int locked; // Table lock
+ THR_LOCK_DATA lock_data;
+
+public:
+ TABLE_SHARE *tshp; // Used by called tables
+ char *data_file_name;
+ char *index_file_name;
+ uint int_table_flags; // Inherited from MyISAM
+ bool enable_activate_all_index; // Inherited from MyISAM
+}; // end of ha_connect class definition
|