summaryrefslogtreecommitdiff
path: root/storage/connect/ha_connect.h
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2014-03-20 12:05:47 +0100
committerOlivier Bertrand <bertrandop@gmail.com>2014-03-20 12:05:47 +0100
commit7b400a088d049661b9a4dded385ac78923bb0017 (patch)
treebb3ee7bac4454f66ec6f38cf6683f24bc6c065d4 /storage/connect/ha_connect.h
parentd67ad26b33ea16a3b59215ef967bdd9b89345e04 (diff)
parente5729127b8a50a0e553fd8b87b2683e4a684dfcc (diff)
downloadmariadb-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.h1053
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