diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2014-10-21 17:29:51 +0200 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2014-10-21 17:29:51 +0200 |
commit | 56e27713213e5b0f7be6b3ac01f06ee26584f38a (patch) | |
tree | 38df18a52a5bdff0df36a5bc0786745091bfe179 /storage | |
parent | c65a9fb4c6a0c7aade6fa4c52641cfec3a88b377 (diff) | |
download | mariadb-git-56e27713213e5b0f7be6b3ac01f06ee26584f38a.tar.gz |
1) Handling string memory allocation with a new STRING class. This is only
the beginning. Defining the STRING class and begining to use it (MYSQL)
2) Change the xtrace, use_tempfile and exact_info connect variables from
GLOBAL to SESSION. Remaining GLOBAL variables have been made readonly.
3) Take care of LEX_STRING variables. The .str should not be regarded as
allways being 0 terminated. This is handled by the Strz functions that
make sure to return 0 terminated strings.
Bug fix:
- When inserting in MYSQL table with special column(s) a query such as:
insert into t2 values(0,4,'new04'),(0,5,'new05');
failed saying: column id (the special column) not found in t2.
It is now accepted but must be counted in values (these 0 are ignored)
- ROWID was returning row numbers based 0. Now it is from base 1.
modified:
storage/connect/array.cpp
storage/connect/blkfil.cpp
storage/connect/colblk.cpp
storage/connect/connect.cc
storage/connect/filamap.cpp
storage/connect/filamdbf.cpp
storage/connect/filamfix.cpp
storage/connect/filamtxt.cpp
storage/connect/filamvct.cpp
storage/connect/filamzip.cpp
storage/connect/filamzip.h
storage/connect/filter.cpp
storage/connect/global.h
storage/connect/ha_connect.cc
storage/connect/ha_connect.h
storage/connect/libdoc.cpp
storage/connect/mycat.cc
storage/connect/myconn.cpp
storage/connect/odbconn.cpp
storage/connect/plgdbutl.cpp
storage/connect/plugutil.c
storage/connect/reldef.cpp
storage/connect/tabcol.cpp
storage/connect/tabdos.cpp
storage/connect/tabfix.cpp
storage/connect/tabfmt.cpp
storage/connect/table.cpp
storage/connect/tabmul.cpp
storage/connect/tabmysql.cpp
storage/connect/tabmysql.h
storage/connect/taboccur.cpp
storage/connect/tabodbc.cpp
storage/connect/tabpivot.cpp
storage/connect/tabsys.cpp
storage/connect/tabtbl.cpp
storage/connect/tabutil.cpp
storage/connect/tabvct.cpp
storage/connect/tabwmi.cpp
storage/connect/tabwmi.h
storage/connect/tabxcl.cpp
storage/connect/tabxml.cpp
storage/connect/user_connect.cc
storage/connect/valblk.cpp
storage/connect/value.cpp
storage/connect/value.h
storage/connect/xindex.cpp
storage/connect/xobject.cpp
storage/connect/xobject.h
storage/connect/xtable.h
Diffstat (limited to 'storage')
49 files changed, 1352 insertions, 1233 deletions
diff --git a/storage/connect/array.cpp b/storage/connect/array.cpp index 466d71d3b06..a2f537436c9 100644 --- a/storage/connect/array.cpp +++ b/storage/connect/array.cpp @@ -52,11 +52,6 @@ #endif /***********************************************************************/ -/* Static variables. */ -/***********************************************************************/ -extern "C" int trace; - -/***********************************************************************/ /* DB static external variables. */ /***********************************************************************/ extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */ diff --git a/storage/connect/blkfil.cpp b/storage/connect/blkfil.cpp index c1099261cef..802231b24ec 100644 --- a/storage/connect/blkfil.cpp +++ b/storage/connect/blkfil.cpp @@ -39,11 +39,6 @@ #include "array.h" // ARRAY classes dcls #include "blkfil.h" // Block Filter classes dcls -/***********************************************************************/ -/* Static variables. */ -/***********************************************************************/ -extern "C" int trace; - /* ------------------------ Class BLOCKFILTER ------------------------ */ /***********************************************************************/ diff --git a/storage/connect/colblk.cpp b/storage/connect/colblk.cpp index 81ab1ad7245..78aba7bc494 100644 --- a/storage/connect/colblk.cpp +++ b/storage/connect/colblk.cpp @@ -23,8 +23,6 @@ #include "xindex.h"
#include "xtable.h"
-extern "C" int trace;
-
/***********************************************************************/
/* COLBLK protected constructor. */
/***********************************************************************/
diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc index 381e437f9ec..500873ce850 100644 --- a/storage/connect/connect.cc +++ b/storage/connect/connect.cc @@ -49,11 +49,6 @@ #define my_stricmp(a, b) my_strcasecmp(default_charset_info, (a), (b)) /***********************************************************************/ -/* DB static variables. */ -/***********************************************************************/ -extern "C" int trace; - -/***********************************************************************/ /* Routines called internally by semantic routines. */ /***********************************************************************/ void CntEndDB(PGLOBAL); @@ -289,7 +284,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2, // } else colp= tdbp->ColDB(g, p, 0); - if (!colp) { + if (!colp && !(mode == MODE_INSERT && tdbp->IsSpecial(p))) { sprintf(g->Message, "Column %s not found in %s", p, tdbp->GetName()); goto err; } // endif colp diff --git a/storage/connect/filamap.cpp b/storage/connect/filamap.cpp index 5efe9c95d81..8abe6cedd07 100644 --- a/storage/connect/filamap.cpp +++ b/storage/connect/filamap.cpp @@ -46,8 +46,6 @@ #include "filamap.h" #include "tabdos.h" -extern "C" int trace; - /* --------------------------- Class MAPFAM -------------------------- */ /***********************************************************************/ diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp index a214ab8acf2..38b02a02ffc 100644 --- a/storage/connect/filamdbf.cpp +++ b/storage/connect/filamdbf.cpp @@ -63,8 +63,6 @@ #define DBFTYPE 3 /* value of bits 0 and 1 if .dbf */ #define EOH 0x0D /* end-of-header marker in .dbf file */ -extern "C" int trace; // The general trace value - /****************************************************************************/ /* First 32 bytes of a .dbf file. */ /* Note: some reserved fields are used here to store info (Fields) */ diff --git a/storage/connect/filamfix.cpp b/storage/connect/filamfix.cpp index 1fa72d52746..0df5e8087ac 100644 --- a/storage/connect/filamfix.cpp +++ b/storage/connect/filamfix.cpp @@ -52,7 +52,6 @@ #define INVALID_SET_FILE_POINTER 0xFFFFFFFF #endif -extern "C" int trace; extern int num_read, num_there, num_eq[2]; // Statistics /* --------------------------- Class FIXFAM -------------------------- */ diff --git a/storage/connect/filamtxt.cpp b/storage/connect/filamtxt.cpp index 851faaaaf1a..ffe4c92d251 100644 --- a/storage/connect/filamtxt.cpp +++ b/storage/connect/filamtxt.cpp @@ -56,7 +56,6 @@ #endif extern int num_read, num_there, num_eq[2]; // Statistics -extern "C" int trace; /***********************************************************************/ /* Routine called externally by TXTFAM SortedRows functions. */ diff --git a/storage/connect/filamvct.cpp b/storage/connect/filamvct.cpp index b93adbd13dd..84ebad5f3d0 100755 --- a/storage/connect/filamvct.cpp +++ b/storage/connect/filamvct.cpp @@ -64,7 +64,6 @@ extern int num_read, num_there; // Statistics static int num_write; -extern "C" int trace; #if defined(UNIX) // Add dummy strerror (NGC) diff --git a/storage/connect/filamzip.cpp b/storage/connect/filamzip.cpp index 8473011ab8b..1288689325c 100644 --- a/storage/connect/filamzip.cpp +++ b/storage/connect/filamzip.cpp @@ -62,7 +62,6 @@ /* DB static variables. */ /***********************************************************************/ extern int num_read, num_there, num_eq[]; // Statistics -extern "C" int trace; /* ------------------------------------------------------------------- */ diff --git a/storage/connect/filamzip.h b/storage/connect/filamzip.h index 6d27cb67e81..edb8b5db323 100644 --- a/storage/connect/filamzip.h +++ b/storage/connect/filamzip.h @@ -1,170 +1,170 @@ -/************** FilAmZip H Declares Source Code File (.H) **************/
-/* Name: FILAMZIP.H Version 1.2 */
-/* */
-/* (C) Copyright to the author Olivier BERTRAND 2005-2014 */
-/* */
-/* This file contains the GZIP access method classes declares. */
-/***********************************************************************/
-#ifndef __FILAMZIP_H
-#define __FILAMZIP_H
-
-#include "zlib.h"
-
-typedef class ZIPFAM *PZIPFAM;
-typedef class ZBKFAM *PZBKFAM;
-typedef class ZIXFAM *PZIXFAM;
-typedef class ZLBFAM *PZLBFAM;
-
-/***********************************************************************/
-/* This is the access method class declaration for not optimized */
-/* variable record length files compressed using the gzip library */
-/* functions. File is accessed record by record (row). */
-/***********************************************************************/
-class DllExport ZIPFAM : public TXTFAM {
-// friend class DOSCOL;
- public:
- // Constructor
- ZIPFAM(PDOSDEF tdp) : TXTFAM(tdp) {Zfile = NULL; Zpos = 0;}
- ZIPFAM(PZIPFAM txfp);
-
- // Implementation
- virtual AMT GetAmType(void) {return TYPE_AM_ZIP;}
- virtual int GetPos(void);
- virtual int GetNextPos(void);
- virtual PTXF Duplicate(PGLOBAL g)
- {return (PTXF)new(g) ZIPFAM(this);}
-
- // Methods
- virtual void Reset(void);
- virtual int GetFileLength(PGLOBAL g);
- virtual int Cardinality(PGLOBAL g) {return (g) ? -1 : 0;}
- virtual int MaxBlkSize(PGLOBAL g, int s) {return s;}
- virtual bool AllocateBuffer(PGLOBAL g);
- virtual int GetRowID(void);
- virtual bool RecordPos(PGLOBAL g);
- virtual bool SetPos(PGLOBAL g, int recpos);
- virtual int SkipRecord(PGLOBAL g, bool header);
- virtual bool OpenTableFile(PGLOBAL g);
- virtual int ReadBuffer(PGLOBAL g);
- virtual int WriteBuffer(PGLOBAL g);
- virtual int DeleteRecords(PGLOBAL g, int irc);
- virtual void CloseTableFile(PGLOBAL g, bool abort);
- virtual void Rewind(void);
-
- protected:
- int Zerror(PGLOBAL g); // GZ error function
-
- // Members
- gzFile Zfile; // Points to GZ file structure
- z_off_t Zpos; // Uncompressed file position
- }; // end of class ZIPFAM
-
-/***********************************************************************/
-/* This is the access method class declaration for optimized variable */
-/* record length files compressed using the gzip library functions. */
-/* The File is accessed by block (requires an opt file). */
-/***********************************************************************/
-class DllExport ZBKFAM : public ZIPFAM {
- public:
- // Constructor
- ZBKFAM(PDOSDEF tdp);
- ZBKFAM(PZBKFAM txfp);
-
- // Implementation
- virtual int GetPos(void);
- virtual int GetNextPos(void) {return 0;}
- virtual PTXF Duplicate(PGLOBAL g)
- {return (PTXF)new(g) ZBKFAM(this);}
-
- // Methods
- virtual int Cardinality(PGLOBAL g);
- virtual int MaxBlkSize(PGLOBAL g, int s);
- virtual bool AllocateBuffer(PGLOBAL g);
- virtual int GetRowID(void);
- virtual bool RecordPos(PGLOBAL g);
- virtual int SkipRecord(PGLOBAL g, bool header);
- virtual int ReadBuffer(PGLOBAL g);
- virtual int WriteBuffer(PGLOBAL g);
- virtual int DeleteRecords(PGLOBAL g, int irc);
- virtual void CloseTableFile(PGLOBAL g, bool abort);
- virtual void Rewind(void);
-
- protected:
- // Members
- char *CurLine; // Position of current line in buffer
- char *NxtLine; // Position of Next line in buffer
- bool Closing; // True when closing on Insert
- }; // end of class ZBKFAM
-
-/***********************************************************************/
-/* This is the access method class declaration for fixed record */
-/* length files compressed using the gzip library functions. */
-/* The file is always accessed by block. */
-/***********************************************************************/
-class DllExport ZIXFAM : public ZBKFAM {
- public:
- // Constructor
- ZIXFAM(PDOSDEF tdp);
- ZIXFAM(PZIXFAM txfp) : ZBKFAM(txfp) {}
-
- // Implementation
- virtual int GetNextPos(void) {return 0;}
- virtual PTXF Duplicate(PGLOBAL g)
- {return (PTXF)new(g) ZIXFAM(this);}
-
- // Methods
- virtual int Cardinality(PGLOBAL g);
- virtual bool AllocateBuffer(PGLOBAL g);
- virtual int ReadBuffer(PGLOBAL g);
- virtual int WriteBuffer(PGLOBAL g);
-
- protected:
- // No additional Members
- }; // end of class ZIXFAM
-
-/***********************************************************************/
-/* This is the DOS/UNIX Access Method class declaration for PlugDB */
-/* fixed/variable files compressed using the zlib library functions. */
-/* Physically these are written and read using the same technique */
-/* than blocked variable files, only the contain of each block is */
-/* compressed using the deflate zlib function. The purpose of this */
-/* specific format is to have a fast mechanism for direct access of */
-/* records so blocked optimization is fast and direct access (joins) */
-/* is allowed. Note that the block length is written ahead of each */
-/* block to enable reading when optimization file is not available. */
-/***********************************************************************/
-class DllExport ZLBFAM : public BLKFAM {
- public:
- // Constructor
- ZLBFAM(PDOSDEF tdp);
- ZLBFAM(PZLBFAM txfp);
-
- // Implementation
- virtual AMT GetAmType(void) {return TYPE_AM_ZLIB;}
- virtual int GetPos(void);
- virtual int GetNextPos(void);
- virtual PTXF Duplicate(PGLOBAL g)
- {return (PTXF)new(g) ZLBFAM(this);}
- inline void SetOptimized(bool b) {Optimized = b;}
-
- // Methods
- virtual int GetFileLength(PGLOBAL g);
+/************** FilAmZip H Declares Source Code File (.H) **************/ +/* Name: FILAMZIP.H Version 1.2 */ +/* */ +/* (C) Copyright to the author Olivier BERTRAND 2005-2014 */ +/* */ +/* This file contains the GZIP access method classes declares. */ +/***********************************************************************/ +#ifndef __FILAMZIP_H +#define __FILAMZIP_H + +#include "zlib.h" + +typedef class ZIPFAM *PZIPFAM; +typedef class ZBKFAM *PZBKFAM; +typedef class ZIXFAM *PZIXFAM; +typedef class ZLBFAM *PZLBFAM; + +/***********************************************************************/ +/* This is the access method class declaration for not optimized */ +/* variable record length files compressed using the gzip library */ +/* functions. File is accessed record by record (row). */ +/***********************************************************************/ +class DllExport ZIPFAM : public TXTFAM { +// friend class DOSCOL; + public: + // Constructor + ZIPFAM(PDOSDEF tdp) : TXTFAM(tdp) {Zfile = NULL; Zpos = 0;} + ZIPFAM(PZIPFAM txfp); + + // Implementation + virtual AMT GetAmType(void) {return TYPE_AM_ZIP;} + virtual int GetPos(void); + virtual int GetNextPos(void); + virtual PTXF Duplicate(PGLOBAL g) + {return (PTXF)new(g) ZIPFAM(this);} + + // Methods + virtual void Reset(void); + virtual int GetFileLength(PGLOBAL g); + virtual int Cardinality(PGLOBAL g) {return (g) ? -1 : 0;} + virtual int MaxBlkSize(PGLOBAL g, int s) {return s;} + virtual bool AllocateBuffer(PGLOBAL g); + virtual int GetRowID(void); + virtual bool RecordPos(PGLOBAL g); virtual bool SetPos(PGLOBAL g, int recpos); - virtual bool AllocateBuffer(PGLOBAL g);
- virtual int ReadBuffer(PGLOBAL g);
- virtual int WriteBuffer(PGLOBAL g);
- virtual void CloseTableFile(PGLOBAL g, bool abort);
- virtual void Rewind(void);
-
- protected:
- bool WriteCompressedBuffer(PGLOBAL g);
- int ReadCompressedBuffer(PGLOBAL g, void *rdbuf);
-
- // Members
- z_streamp Zstream; // Compression/decompression stream
- Byte *Zbuffer; // Compressed block buffer
- int *Zlenp; // Pointer to block length
- bool Optimized; // true when opt file is available
- }; // end of class ZLBFAM
-
-#endif // __FILAMZIP_H
+ virtual int SkipRecord(PGLOBAL g, bool header); + virtual bool OpenTableFile(PGLOBAL g); + virtual int ReadBuffer(PGLOBAL g); + virtual int WriteBuffer(PGLOBAL g); + virtual int DeleteRecords(PGLOBAL g, int irc); + virtual void CloseTableFile(PGLOBAL g, bool abort); + virtual void Rewind(void); + + protected: + int Zerror(PGLOBAL g); // GZ error function + + // Members + gzFile Zfile; // Points to GZ file structure + z_off_t Zpos; // Uncompressed file position + }; // end of class ZIPFAM + +/***********************************************************************/ +/* This is the access method class declaration for optimized variable */ +/* record length files compressed using the gzip library functions. */ +/* The File is accessed by block (requires an opt file). */ +/***********************************************************************/ +class DllExport ZBKFAM : public ZIPFAM { + public: + // Constructor + ZBKFAM(PDOSDEF tdp); + ZBKFAM(PZBKFAM txfp); + + // Implementation + virtual int GetPos(void); + virtual int GetNextPos(void) {return 0;} + virtual PTXF Duplicate(PGLOBAL g) + {return (PTXF)new(g) ZBKFAM(this);} + + // Methods + virtual int Cardinality(PGLOBAL g); + virtual int MaxBlkSize(PGLOBAL g, int s); + virtual bool AllocateBuffer(PGLOBAL g); + virtual int GetRowID(void); + virtual bool RecordPos(PGLOBAL g); + virtual int SkipRecord(PGLOBAL g, bool header); + virtual int ReadBuffer(PGLOBAL g); + virtual int WriteBuffer(PGLOBAL g); + virtual int DeleteRecords(PGLOBAL g, int irc); + virtual void CloseTableFile(PGLOBAL g, bool abort); + virtual void Rewind(void); + + protected: + // Members + char *CurLine; // Position of current line in buffer + char *NxtLine; // Position of Next line in buffer + bool Closing; // True when closing on Insert + }; // end of class ZBKFAM + +/***********************************************************************/ +/* This is the access method class declaration for fixed record */ +/* length files compressed using the gzip library functions. */ +/* The file is always accessed by block. */ +/***********************************************************************/ +class DllExport ZIXFAM : public ZBKFAM { + public: + // Constructor + ZIXFAM(PDOSDEF tdp); + ZIXFAM(PZIXFAM txfp) : ZBKFAM(txfp) {} + + // Implementation + virtual int GetNextPos(void) {return 0;} + virtual PTXF Duplicate(PGLOBAL g) + {return (PTXF)new(g) ZIXFAM(this);} + + // Methods + virtual int Cardinality(PGLOBAL g); + virtual bool AllocateBuffer(PGLOBAL g); + virtual int ReadBuffer(PGLOBAL g); + virtual int WriteBuffer(PGLOBAL g); + + protected: + // No additional Members + }; // end of class ZIXFAM + +/***********************************************************************/ +/* This is the DOS/UNIX Access Method class declaration for PlugDB */ +/* fixed/variable files compressed using the zlib library functions. */ +/* Physically these are written and read using the same technique */ +/* than blocked variable files, only the contain of each block is */ +/* compressed using the deflate zlib function. The purpose of this */ +/* specific format is to have a fast mechanism for direct access of */ +/* records so blocked optimization is fast and direct access (joins) */ +/* is allowed. Note that the block length is written ahead of each */ +/* block to enable reading when optimization file is not available. */ +/***********************************************************************/ +class DllExport ZLBFAM : public BLKFAM { + public: + // Constructor + ZLBFAM(PDOSDEF tdp); + ZLBFAM(PZLBFAM txfp); + + // Implementation + virtual AMT GetAmType(void) {return TYPE_AM_ZLIB;} + virtual int GetPos(void); + virtual int GetNextPos(void); + virtual PTXF Duplicate(PGLOBAL g) + {return (PTXF)new(g) ZLBFAM(this);} + inline void SetOptimized(bool b) {Optimized = b;} + + // Methods + virtual int GetFileLength(PGLOBAL g); + virtual bool SetPos(PGLOBAL g, int recpos); + virtual bool AllocateBuffer(PGLOBAL g); + virtual int ReadBuffer(PGLOBAL g); + virtual int WriteBuffer(PGLOBAL g); + virtual void CloseTableFile(PGLOBAL g, bool abort); + virtual void Rewind(void); + + protected: + bool WriteCompressedBuffer(PGLOBAL g); + int ReadCompressedBuffer(PGLOBAL g, void *rdbuf); + + // Members + z_streamp Zstream; // Compression/decompression stream + Byte *Zbuffer; // Compressed block buffer + int *Zlenp; // Pointer to block length + bool Optimized; // true when opt file is available + }; // end of class ZLBFAM + +#endif // __FILAMZIP_H diff --git a/storage/connect/filter.cpp b/storage/connect/filter.cpp index ce4f69c5ecc..6bdd175a662 100644 --- a/storage/connect/filter.cpp +++ b/storage/connect/filter.cpp @@ -40,11 +40,6 @@ #include "xindex.h" /***********************************************************************/ -/* Static variables. */ -/***********************************************************************/ -extern "C" int trace; - -/***********************************************************************/ /* Utility routines. */ /***********************************************************************/ void PlugConvertConstant(PGLOBAL, void* &, short&); diff --git a/storage/connect/global.h b/storage/connect/global.h index ae4440b12bc..5348768d66d 100644 --- a/storage/connect/global.h +++ b/storage/connect/global.h @@ -47,6 +47,11 @@ #endif // !WIN32 /***********************************************************************/ +/* Define access to the thread based trace value. */ +/***********************************************************************/ +#define trace GetTraceValue() + +/***********************************************************************/ /* Miscellaneous Constants */ /***********************************************************************/ #define NO_IVAL -95684275 /* Used by GetIntegerOption */ @@ -255,6 +260,7 @@ DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t); DllExport char *PlugDup(PGLOBAL g, const char *str); DllExport void *MakePtr(void *, OFFSET); DllExport void htrc(char const *fmt, ...); +DllExport int GetTraceValue(void); #if defined(__cplusplus) } // extern "C" diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 697b29ff72c..819767aeefb 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -182,31 +182,26 @@ extern "C" { #if defined(XMSG) char msglang[]; // Default message language #endif - int trace= 0; // The general trace value +// int trace= 0; // The general trace value int xconv= 0; // The type conversion option int zconv= SZCONV; // The text conversion size - USETEMP Use_Temp= TMP_AUTO; // The temporary file use } // extern "C" #if defined(XMAP) bool xmap= false; #endif // XMAP - bool xinfo= false; uint worksize= SZWORK; ulong ha_connect::num= 0; //int DTVAL::Shift= 0; /* CONNECT system variables */ -static int xtrace= 0; static int conv_size= SZCONV; static uint work_size= SZWORK; static ulong type_conv= 0; -static ulong use_tempfile= 1; #if defined(XMAP) static my_bool indx_map= 0; #endif // XMAP -static my_bool exact_info= 0; /***********************************************************************/ /* Utility functions. */ @@ -228,16 +223,69 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, TABLE_SHARE *table_s, HA_CREATE_INFO *info); +/****************************************************************************/ +/* Return str as a zero terminated string. */ +/****************************************************************************/ +static char *strz(PGLOBAL g, LEX_STRING &ls) +{ + char *str= (char*)PlugSubAlloc(g, NULL, ls.length + 1); + + memcpy(str, ls.str, ls.length); + str[ls.length]= 0; + return str; +} // end of strz + /***********************************************************************/ -/* Global variables update functions. */ +/* CONNECT session variables definitions. */ /***********************************************************************/ -static void update_connect_xtrace(MYSQL_THD thd, - struct st_mysql_sys_var *var, - void *var_ptr, const void *save) +// Tracing: 0 no, 1 yes, >1 more tracing +static MYSQL_THDVAR_INT(xtrace, + PLUGIN_VAR_RQCMDARG, "Console trace value.", + NULL, NULL, 0, 0, INT_MAX, 1); + +// Getting exact info values +static MYSQL_THDVAR_BOOL(exact_info, PLUGIN_VAR_RQCMDARG, + "Getting exact info values", + NULL, NULL, 0); + +/** + Temporary file usage: + no: Not using temporary file + auto: Using temporary file when needed + yes: Allways using temporary file + force: Force using temporary file (no MAP) + test: Reserved +*/ +const char *usetemp_names[]= +{ + "NO", "AUTO", "YES", "FORCE", "TEST", NullS +}; + +TYPELIB usetemp_typelib= { - trace= *(int *)var_ptr= *(int *)save; -} // end of update_connect_xtrace + array_elements(usetemp_names) - 1, "usetemp_typelib", + usetemp_names, NULL +}; + +static MYSQL_THDVAR_ENUM( + use_tempfile, // name + PLUGIN_VAR_RQCMDARG, // opt + "Temporary file use.", // comment + NULL, // check + NULL, // update function + 1, // def (AUTO) + &usetemp_typelib); // typelib + +/***********************************************************************/ +/* Function to export session variable values to other source files. */ +/***********************************************************************/ +extern "C" int GetTraceValue(void) {return THDVAR(current_thd, xtrace);} +bool ExactInfo(void) {return THDVAR(current_thd, exact_info);} +USETEMP UseTemp(void) {return (USETEMP)THDVAR(current_thd, use_tempfile);} +/***********************************************************************/ +/* Global variables update functions. */ +/***********************************************************************/ static void update_connect_zconv(MYSQL_THD thd, struct st_mysql_sys_var *var, void *var_ptr, const void *save) @@ -259,13 +307,6 @@ static void update_connect_worksize(MYSQL_THD thd, worksize= (uint)(*(ulong *)var_ptr= *(ulong *)save); } // end of update_connect_worksize -static void update_connect_usetemp(MYSQL_THD thd, - struct st_mysql_sys_var *var, - void *var_ptr, const void *save) -{ - Use_Temp= (USETEMP)(*(ulong *)var_ptr= *(ulong *)save); -} // end of update_connect_usetemp - #if defined(XMAP) static void update_connect_xmap(MYSQL_THD thd, struct st_mysql_sys_var *var, @@ -275,13 +316,6 @@ static void update_connect_xmap(MYSQL_THD thd, } // end of update_connect_xmap #endif // XMAP -static void update_connect_xinfo(MYSQL_THD thd, - struct st_mysql_sys_var *var, - void *var_ptr, const void *save) -{ - xinfo= (bool)(*(my_bool *)var_ptr= *(my_bool *)save); -} // end of update_connect_xinfo - /***********************************************************************/ /* The CONNECT handlerton object. */ /***********************************************************************/ @@ -471,9 +505,6 @@ static int connect_init_func(void *p) sql_print_information("CONNECT: %s", compver); - // xtrace is now a system variable - trace= xtrace; - #ifdef LIBXML2_SUPPORT XmlInitParserLib(); #endif // LIBXML2_SUPPORT @@ -491,7 +522,7 @@ static int connect_init_func(void *p) connect_hton->tablefile_extensions= ha_connect_exts; connect_hton->discover_table_structure= connect_assisted_discovery; - if (xtrace) + if (trace) sql_print_information("connect_init: hton=%p", p); DTVAL::SetTimeShift(); // Initialize time zone shift once for all @@ -564,9 +595,10 @@ static handler* connect_create_handler(handlerton *hton, { handler *h= new (mem_root) ha_connect(hton, table); - if (xtrace) - htrc("New CONNECT %p, table: %s\n", - h, table ? table->table_name.str : "<null>"); + if (trace) + htrc("New CONNECT %p, table: %.*s\n", h, + table ? table->table_name.length : 6, + table ? table->table_name.str : "<null>"); return h; } // end of connect_create_handler @@ -619,8 +651,9 @@ ha_connect::ha_connect(handlerton *hton, TABLE_SHARE *table_arg) /****************************************************************************/ ha_connect::~ha_connect(void) { - if (xtrace) - htrc("Delete CONNECT %p, table: %s, xp=%p count=%d\n", this, + if (trace) + htrc("Delete CONNECT %p, table: %.*s, xp=%p count=%d\n", this, + table ? table->s->table_name.length : 6, table ? table->s->table_name.str : "<null>", xp, xp ? xp->count : 0); @@ -876,6 +909,15 @@ char *ha_connect::GetRealString(const char *s) return sv; } // end of GetRealString +inline char *ha_connect::Strz(LEX_STRING &ls) +{ + if (unlikely(ls.str && ls.str[ls.length])) + return strz(xp->g, ls); + else + return ls.str; + +} // end of Strz + /****************************************************************************/ /* Return the value of a string option or NULL if not specified. */ /****************************************************************************/ @@ -885,10 +927,11 @@ char *ha_connect::GetStringOption(char *opname, char *sdef) PTOS options= GetTableOptionStruct(); if (!stricmp(opname, "Connect")) { - LEX_STRING cnc= (tshp) ? tshp->connect_string : table->s->connect_string; + LEX_STRING cnc= (tshp) ? tshp->connect_string + : table->s->connect_string; if (cnc.length) - opval= GetRealString(cnc.str); + opval= GetRealString(Strz(cnc)); } else if (!stricmp(opname, "Query_String")) opval= thd_query_string(table->in_use)->str; @@ -1229,9 +1272,11 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf) // Get the comment if any if (fp->comment.str && fp->comment.length) { - pcf->Remark= (char*)PlugSubAlloc(g, NULL, fp->comment.length + 1); - memcpy(pcf->Remark, fp->comment.str, fp->comment.length); - pcf->Remark[fp->comment.length]= 0; + if ((pcf->Remark= (char*)PlgDBSubAlloc(g, NULL, fp->comment.length + 1))) { + memcpy(pcf->Remark, fp->comment.str, fp->comment.length); + pcf->Remark[fp->comment.length]= 0; + } // endif Remark + } else pcf->Remark= NULL; @@ -1260,8 +1305,8 @@ bool ha_connect::GetIndexOption(KEY *kp, char *opname) else if (!stricmp(opname, "Mapped")) opval= options->mapped; - } else if (kp->comment.str != NULL) { - char *pv, *oplist= kp->comment.str; + } else if (kp->comment.str && kp->comment.length) { + char *pv, *oplist= Strz(kp->comment); if ((pv= GetListOption(xp->g, opname, oplist))) opval= (!*pv || *pv == 'y' || *pv == 'Y' || atoi(pv) != 0); @@ -1298,7 +1343,7 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s) s= table->s; for (int n= 0; (unsigned)n < s->keynames.count; n++) { - if (xtrace) + if (trace) htrc("Getting created index %d info\n", n + 1); // Find the index to describe @@ -1371,12 +1416,12 @@ bool ha_connect::IsPartitioned(void) const char *ha_connect::GetDBName(const char* name) { - return (name) ? name : table->s->db.str; + return (name) ? name : Strz(table->s->db); } // end of GetDBName const char *ha_connect::GetTableName(void) { - return (tshp) ? tshp->table_name.str : table_share->table_name.str; + return Strz(tshp ? tshp->table_name : table_share->table_name); } // end of GetTableName char *ha_connect::GetPartName(void) @@ -1669,7 +1714,7 @@ int ha_connect::MakeRecord(char *buf) PCOL colp= NULL; DBUG_ENTER("ha_connect::MakeRecord"); - if (xtrace > 1) + if (trace > 1) htrc("Maps: read=%08X write=%08X vcol=%08X defr=%08X defw=%08X\n", *table->read_set->bitmap, *table->write_set->bitmap, *table->vcol_set->bitmap, @@ -2099,14 +2144,14 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond) if (!cond) return NULL; - if (xtrace) + if (trace) htrc("Cond type=%d\n", cond->type()); if (cond->type() == COND::COND_ITEM) { PFIL fp; Item_cond *cond_item= (Item_cond *)cond; - if (xtrace) + if (trace) htrc("Cond: Ftype=%d name=%s\n", cond_item->functype(), cond_item->func_name()); @@ -2140,7 +2185,7 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond) Item_func *condf= (Item_func *)cond; Item* *args= condf->arguments(); - if (xtrace) + if (trace) htrc("Func type=%d argnum=%d\n", condf->functype(), condf->argument_count()); @@ -2169,11 +2214,11 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond) return NULL; for (i= 0; i < condf->argument_count(); i++) { - if (xtrace) + if (trace) htrc("Argtype(%d)=%d\n", i, args[i]->type()); if (i >= 2 && !ismul) { - if (xtrace) + if (trace) htrc("Unexpected arg for vop=%d\n", vop); continue; @@ -2190,10 +2235,10 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond) !(colp[i]= tdbp->ColDB(g, (PSZ)pField->field->field_name, 0))) return NULL; // Column does not belong to this table - if (xtrace) { + if (trace) { htrc("Field index=%d\n", pField->field->field_index); htrc("Field name=%s\n", pField->field->field_name); - } // endif xtrace + } // endif trace } else { char buff[256]; @@ -2210,8 +2255,8 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond) switch (args[i]->real_type()) { case COND::STRING_ITEM: - pp->Type= TYPE_STRING; pp->Value= PlugSubAllocStr(g, NULL, res->ptr(), res->length()); + pp->Type= (pp->Value) ? TYPE_STRING : TYPE_ERROR; break; case COND::INT_ITEM: pp->Type= TYPE_INT; @@ -2239,7 +2284,7 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond) return NULL; } // endswitch type - if (xtrace) + if (trace) htrc("Value=%.*s\n", res->length(), res->ptr()); // Append the value to the argument list @@ -2257,7 +2302,7 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond) filp= MakeFilter(g, colp, pop, pfirst, neg); } else { - if (xtrace) + if (trace) htrc("Unsupported condition\n"); return NULL; @@ -2279,7 +2324,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond) if (!cond) return NULL; - if (xtrace) + if (trace) htrc("Cond type=%d\n", cond->type()); if (cond->type() == COND::COND_ITEM) { @@ -2289,7 +2334,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond) if (x) return NULL; - if (xtrace) + if (trace) htrc("Cond: Ftype=%d name=%s\n", cond_item->functype(), cond_item->func_name()); @@ -2336,7 +2381,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond) Item_func *condf= (Item_func *)cond; Item* *args= condf->arguments(); - if (xtrace) + if (trace) htrc("Func type=%d argnum=%d\n", condf->functype(), condf->argument_count()); @@ -2367,11 +2412,11 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond) return NULL; for (i= 0; i < condf->argument_count(); i++) { - if (xtrace) + if (trace) htrc("Argtype(%d)=%d\n", i, args[i]->type()); if (i >= 2 && !ismul) { - if (xtrace) + if (trace) htrc("Unexpected arg for vop=%d\n", vop); continue; @@ -2403,10 +2448,10 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond) else fnm= pField->field->field_name; - if (xtrace) { + if (trace) { htrc("Field index=%d\n", pField->field->field_index); htrc("Field name=%s\n", pField->field->field_name); - } // endif xtrace + } // endif trace // IN and BETWEEN clauses should be col VOP list if (i && ismul) @@ -2442,7 +2487,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond) if ((res= pval->val_str(&tmp)) == NULL) return NULL; // To be clarified - if (xtrace) + if (trace) htrc("Value=%.*s\n", res->length(), res->ptr()); // IN and BETWEEN clauses should be col VOP list @@ -2487,7 +2532,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond) filp->Op= vop; } else { - if (xtrace) + if (trace) htrc("Unsupported condition\n"); return NULL; @@ -2521,6 +2566,7 @@ const COND *ha_connect::cond_push(const COND *cond) DBUG_ENTER("ha_connect::cond_push"); if (tdbp) { + int rc; PGLOBAL& g= xp->g; AMT tty= tdbp->GetAmType(); bool x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC); @@ -2528,6 +2574,16 @@ const COND *ha_connect::cond_push(const COND *cond) tty == TYPE_AM_TBL || tty == TYPE_AM_MYSQL || tty == TYPE_AM_PLG || x); + // Save stack and allocation environment and prepare error return + if (g->jump_level == MAX_JUMP) { + strcpy(g->Message, MSG(TOO_MANY_JUMPS)); + DBUG_RETURN(cond); + } // endif jump_level + + // This should never happen but is done to avoid crashing + if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) + goto fin; + if (b) { PCFIL filp= (PCFIL)PlugSubAlloc(g, NULL, sizeof(CONDFIL)); @@ -2537,7 +2593,7 @@ const COND *ha_connect::cond_push(const COND *cond) filp->Cmds= NULL; if (CheckCond(g, filp, tty, (Item *)cond)) { - if (xtrace) + if (trace) htrc("cond_push: %s\n", filp->Body); if (!x) @@ -2552,6 +2608,8 @@ const COND *ha_connect::cond_push(const COND *cond) } else tdbp->SetFilter(CondFilter(g, (Item *)cond)); + fin: + g->jump_level--; } // endif tdbp // Let MySQL do the filtering @@ -2650,7 +2708,7 @@ int ha_connect::open(const char *name, int mode, uint test_if_locked) int rc= 0; DBUG_ENTER("ha_connect::open"); - if (xtrace) + if (trace) htrc("open: name=%s mode=%d test=%u\n", name, mode, test_if_locked); if (!(share= get_share())) @@ -2862,7 +2920,7 @@ int ha_connect::update_row(const uchar *old_data, uchar *new_data) PGLOBAL& g= xp->g; DBUG_ENTER("ha_connect::update_row"); - if (xtrace > 1) + if (trace > 1) htrc("update_row: old=%s new=%s\n", old_data, new_data); // Check values for possible change in indexed column @@ -2923,7 +2981,7 @@ int ha_connect::index_init(uint idx, bool sorted) PGLOBAL& g= xp->g; DBUG_ENTER("index_init"); - if (xtrace) + if (trace) htrc("index_init: this=%p idx=%u sorted=%d\n", this, idx, sorted); if (GetIndexType(GetRealType()) == 2) { @@ -2976,7 +3034,7 @@ int ha_connect::index_init(uint idx, bool sorted) rc= 0; } // endif indexing - if (xtrace) + if (trace) htrc("index_init: rc=%d indexing=%d active_index=%d\n", rc, indexing, active_index); @@ -3023,7 +3081,7 @@ int ha_connect::ReadIndexed(uchar *buf, OPVAL op, const uchar *key, uint key_len break; } // endswitch RC - if (xtrace > 1) + if (trace > 1) htrc("ReadIndexed: op=%d rc=%d\n", op, rc); table->status= (rc == RC_OK) ? 0 : STATUS_NOT_FOUND; @@ -3066,7 +3124,7 @@ int ha_connect::index_read(uchar * buf, const uchar * key, uint key_len, default: DBUG_RETURN(-1); break; } // endswitch find_flag - if (xtrace > 1) + if (trace > 1) htrc("%p index_read: op=%d\n", this, op); if (indexing > 0) { @@ -3224,7 +3282,7 @@ int ha_connect::rnd_init(bool scan) alter= 1; } // endif xmod - if (xtrace) + if (trace) htrc("rnd_init: this=%p scan=%d xmod=%d alter=%d\n", this, scan, xmod, alter); @@ -3330,7 +3388,7 @@ int ha_connect::rnd_next(uchar *buf) break; } // endswitch RC - if (xtrace > 1 && (rc || !(xp->nrd++ % 16384))) { + if (trace > 1 && (rc || !(xp->nrd++ % 16384))) { ulonglong tb2= my_interval_timer(); double elapsed= (double) (tb2 - xp->tb1) / 1000000000ULL; DBUG_PRINT("rnd_next", ("rc=%d nrd=%u fnd=%u nfd=%u sec=%.3lf\n", @@ -3462,7 +3520,7 @@ int ha_connect::info(uint flag) DBUG_ENTER("ha_connect::info"); - if (xtrace) + if (trace) htrc("%p In info: flag=%u valid_info=%d\n", this, flag, valid_info); // tdbp must be available to get updated info @@ -3477,10 +3535,8 @@ int ha_connect::info(uint flag) } // endif xmod // This is necessary for getting file length -// if (cat && table) -// cat->SetDataPath(g, table->s->db.str); if (table) - SetDataPath(g, table->s->db.str); + SetDataPath(g, Strz(table->s->db)); else DBUG_RETURN(HA_ERR_INTERNAL_ERROR); // Should never happen @@ -3703,11 +3759,11 @@ bool ha_connect::IsSameIndex(PIXDEF xp1, PIXDEF xp2) MODE ha_connect::CheckMode(PGLOBAL g, THD *thd, MODE newmode, bool *chk, bool *cras) { - if ((trace= xtrace)) { + if (trace) { LEX_STRING *query_string= thd_query_string(thd); htrc("%p check_mode: cmdtype=%d\n", this, thd_sql_command(thd)); htrc("Cmd=%.*s\n", (int) query_string->length, query_string->str); - } // endif xtrace + } // endif trace // Next code is temporarily replaced until sql_command is set stop= false; @@ -3816,7 +3872,7 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd, } // endif's newmode - if (xtrace) + if (trace) htrc("New mode=%d\n", newmode); return newmode; @@ -3891,7 +3947,7 @@ int ha_connect::external_lock(THD *thd, int lock_type) DBUG_ASSERT(thd == current_thd); - if (xtrace) + if (trace) htrc("external_lock: this=%p thd=%p xp=%p g=%p lock_type=%d\n", this, thd, xp, g, lock_type); @@ -4032,7 +4088,7 @@ int ha_connect::external_lock(THD *thd, int lock_type) DBUG_ASSERT(table && table->s); - if (check_privileges(thd, options, table->s->db.str)) { + if (check_privileges(thd, options, Strz(table->s->db))) { strcpy(g->Message, "This operation requires the FILE privilege"); htrc("%s\n", g->Message); DBUG_RETURN(HA_ERR_INTERNAL_ERROR); @@ -4066,7 +4122,7 @@ int ha_connect::external_lock(THD *thd, int lock_type) if (cras) g->Createas= 1; // To tell created table to ignore FLAG - if (xtrace) { + if (trace) { #if 0 htrc("xcheck=%d cras=%d\n", xcheck, cras); @@ -4075,7 +4131,7 @@ int ha_connect::external_lock(THD *thd, int lock_type) ((PCHK)g->Xchk)->oldsep, ((PCHK)g->Xchk)->oldpix); #endif // 0 htrc("Calling CntCheckDB db=%s cras=%d\n", GetDBName(NULL), cras); - } // endif xtrace + } // endif trace // Set or reset the good database environment if (CntCheckDB(g, this, GetDBName(NULL))) { @@ -4099,7 +4155,7 @@ int ha_connect::external_lock(THD *thd, int lock_type) // Delay open until used fields are known } // endif tdbp - if (xtrace) + if (trace) htrc("external_lock: rc=%d\n", rc); DBUG_RETURN(rc); @@ -4235,7 +4291,7 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to) THD *thd= current_thd; int sqlcom= thd_sql_command(thd); - if (xtrace) { + if (trace) { if (to) htrc("rename_table: this=%p thd=%p sqlcom=%d from=%s to=%s\n", this, thd, sqlcom, name, to); @@ -4243,7 +4299,7 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to) htrc("delete_table: this=%p thd=%p sqlcom=%d name=%s\n", this, thd, sqlcom, name); - } // endif xtrace + } // endif trace if (to && (filename_to_dbname_and_tablename(to, db, sizeof(db), tabname, sizeof(tabname)) @@ -4343,7 +4399,7 @@ ha_rows ha_connect::records_in_range(uint inx, key_range *min_key, if (index_init(inx, false)) DBUG_RETURN(HA_POS_ERROR); - if (xtrace) + if (trace) htrc("records_in_range: inx=%d indexing=%d\n", inx, indexing); if (indexing > 0) { @@ -4397,83 +4453,6 @@ static char *encode(PGLOBAL g, const char *cnm) @return Return 0 if ok */ -#if defined(NEW_WAY) -static bool add_fields(PGLOBAL g, - THD *thd, - Alter_info *alter_info, - char *name, - int typ, int len, int dec, - uint type_modifier, - char *rem, -// CHARSET_INFO *cs, -// void *vcolinfo, -// engine_option_value *create_options, - int flg, - bool dbf, - char v) -{ - register Create_field *new_field; - char *length, *decimals= NULL; - enum_field_types type; -//Virtual_column_info *vcol_info= (Virtual_column_info *)vcolinfo; - engine_option_value *crop; - LEX_STRING *comment; - LEX_STRING *field_name; - - DBUG_ENTER("ha_connect::add_fields"); - - if (len) { - if (!v && typ == TYPE_STRING && len > 255) - v= 'V'; // Change CHAR to VARCHAR - - length= (char*)PlugSubAlloc(g, NULL, 8); - sprintf(length, "%d", len); - - if (typ == TYPE_DOUBLE) { - decimals= (char*)PlugSubAlloc(g, NULL, 8); - sprintf(decimals, "%d", min(dec, (min(len, 31) - 1))); - } // endif dec - - } else - length= NULL; - - if (!rem) - rem= ""; - - type= PLGtoMYSQL(typ, dbf, v); - comment= thd->make_lex_string(rem, strlen(rem)); - field_name= thd->make_lex_string(name, strlen(name)); - - switch (v) { - case 'Z': type_modifier|= ZEROFILL_FLAG; - case 'U': type_modifier|= UNSIGNED_FLAG; break; - } // endswitch v - - if (flg) { - engine_option_value *start= NULL, *end= NULL; - LEX_STRING *flag= thd->make_lex_string("flag", 4); - - crop= new(thd->mem_root) engine_option_value(*flag, (ulonglong)flg, - &start, &end, thd->mem_root); - } else - crop= NULL; - - if (check_string_char_length(field_name, "", NAME_CHAR_LEN, - system_charset_info, 1)) { - my_error(ER_TOO_LONG_IDENT, MYF(0), field_name->str); /* purecov: inspected */ - DBUG_RETURN(1); /* purecov: inspected */ - } // endif field_name - - if (!(new_field= new Create_field()) || - new_field->init(thd, field_name->str, type, length, decimals, - type_modifier, NULL, NULL, comment, NULL, - NULL, NULL, 0, NULL, crop, true)) - DBUG_RETURN(1); - - alter_info->create_list.push_back(new_field); - DBUG_RETURN(0); -} // end of add_fields -#else // !NEW_WAY static bool add_field(String *sql, const char *field_name, int typ, int len, int dec, uint tm, const char *rem, char *dft, char *xtra, int flag, bool dbf, char v) @@ -4543,7 +4522,6 @@ static bool add_field(String *sql, const char *field_name, int typ, error|= sql->append(','); return error; } // end of add_field -#endif // !NEW_WAY /** Initialise the table share with the new columns. @@ -4551,114 +4529,9 @@ static bool add_field(String *sql, const char *field_name, int typ, @return Return 0 if ok */ -#if defined(NEW_WAY) -//static bool sql_unusable_for_discovery(THD *thd, const char *sql); - -static int init_table_share(THD *thd, - TABLE_SHARE *table_s, - HA_CREATE_INFO *create_info, - Alter_info *alter_info) -{ - KEY *not_used_1; - uint not_used_2; - int rc= 0; - handler *file; - LEX_CUSTRING frm= {0,0}; - - DBUG_ENTER("init_table_share"); - -#if 0 - ulonglong saved_mode= thd->variables.sql_mode; - CHARSET_INFO *old_cs= thd->variables.character_set_client; - Parser_state parser_state; - char *sql_copy; - LEX *old_lex; - Query_arena *arena, backup; - LEX tmp_lex; - - /* - Ouch. Parser may *change* the string it's working on. - Currently (2013-02-26) it is used to permanently disable - conditional comments. - Anyway, let's copy the caller's string... - */ - if (!(sql_copy= thd->strmake(sql, sql_length))) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - - if (parser_state.init(thd, sql_copy, sql_length)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - - thd->variables.sql_mode= MODE_NO_ENGINE_SUBSTITUTION | MODE_NO_DIR_IN_CREATE; - thd->variables.character_set_client= system_charset_info; - old_lex= thd->lex; - thd->lex= &tmp_lex; - - arena= thd->stmt_arena; - - if (arena->is_conventional()) - arena= 0; - else - thd->set_n_backup_active_arena(arena, &backup); - - lex_start(thd); - - if ((error= parse_sql(thd, & parser_state, NULL))) - goto ret; - - if (table_s->sql_unusable_for_discovery(thd, NULL)) { - my_error(ER_SQL_DISCOVER_ERROR, MYF(0), plugin_name(db_plugin)->str, - db.str, table_name.str, sql_copy); - goto ret; - } // endif unusable - - thd->lex->create_info.db_type= plugin_data(db_plugin, handlerton *); - - if (tabledef_version.str) - thd->lex->create_info.tabledef_version= tabledef_version; -#endif // 0 - - tmp_disable_binlog(thd); - - file= mysql_create_frm_image(thd, table_s->db.str, table_s->table_name.str, - create_info, alter_info, C_ORDINARY_CREATE, - ¬_used_1, ¬_used_2, &frm); - if (file) - delete file; - else - rc= OPEN_FRM_CORRUPTED; - - if (!rc && frm.str) { - table_s->option_list= 0; // cleanup existing options ... - table_s->option_struct= 0; // ... if it's an assisted discovery - rc= table_s->init_from_binary_frm_image(thd, true, frm.str, frm.length); - } // endif frm - -//ret: - my_free(const_cast<uchar*>(frm.str)); - reenable_binlog(thd); -#if 0 - lex_end(thd->lex); - thd->lex= old_lex; - if (arena) - thd->restore_active_arena(arena, &backup); - thd->variables.sql_mode= saved_mode; - thd->variables.character_set_client= old_cs; -#endif // 0 - - if (thd->is_error() || rc) { - thd->clear_error(); - my_error(ER_NO_SUCH_TABLE, MYF(0), table_s->db.str, - table_s->table_name.str); - DBUG_RETURN(HA_ERR_NOT_A_TABLE); - } else - DBUG_RETURN(0); - -} // end of init_table_share -#else // !NEW_WAY static int init_table_share(THD* thd, TABLE_SHARE *table_s, HA_CREATE_INFO *create_info, -// char *dsn, String *sql) { bool oom= false; @@ -4717,12 +4590,10 @@ static int init_table_share(THD* thd, } // endfor opt if (create_info->connect_string.length) { -//if (dsn) { oom|= sql->append(' '); oom|= sql->append("CONNECTION='"); oom|= sql->append_for_single_quote(create_info->connect_string.str, create_info->connect_string.length); -// oom|= sql->append_for_single_quote(dsn, strlen(dsn)); oom|= sql->append('\''); if (oom) @@ -4740,29 +4611,21 @@ static int init_table_share(THD* thd, } // endif charset - if (xtrace) + if (trace) htrc("s_init: %.*s\n", sql->length(), sql->ptr()); return table_s->init_from_sql_statement_string(thd, true, sql->ptr(), sql->length()); } // end of init_table_share -#endif // !NEW_WAY -// Add an option to the create_info option list -static void add_option(THD* thd, HA_CREATE_INFO *create_info, - const char *opname, const char *opval) -{ -#if defined(NEW_WAY) - LEX_STRING *opn= thd->make_lex_string(opname, strlen(opname)); - LEX_STRING *val= thd->make_lex_string(opval, strlen(opval)); - engine_option_value *pov, **start= &create_info->option_list, *end= NULL; - - for (pov= *start; pov; pov= pov->next) - end= pov; +static inline char *Strz(PGLOBAL g, LEX_STRING &ls) +{ + if (unlikely(ls.str && ls.str[ls.length])) + return strz(g, ls); + else + return ls.str; - pov= new(thd->mem_root) engine_option_value(*opn, *val, false, start, &end); -#endif // NEW_WAY -} // end of add_option +} // end of Strz // Used to check whether a MYSQL table is created on itself bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host, @@ -4772,9 +4635,9 @@ bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host, return false; else if (host && stricmp(host, "localhost") && strcmp(host, "127.0.0.1")) return false; - else if (db && stricmp(db, s->db.str)) + else if (db && stricmp(db, Strz(g, s->db))) return false; - else if (tab && stricmp(tab, s->table_name.str)) + else if (tab && stricmp(tab, Strz(g, s->table_name))) return false; else if (port && port != (signed)GetDefaultPort()) return false; @@ -4879,7 +4742,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, } // endif option_list if (!(shm= (char*)db)) - db= table_s->db.str; // Default value + db= Strz(g, table_s->db); // Default value // Check table type if (ttp == TAB_UNDEF) { @@ -4887,13 +4750,24 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ttp= GetTypeID(topt->type); sprintf(g->Message, "No table_type. Was set to %s", topt->type); push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); - add_option(thd, create_info, "table_type", topt->type); } else if (ttp == TAB_NIY) { sprintf(g->Message, "Unsupported table type %s", topt->type); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); return HA_ERR_INTERNAL_ERROR; } // endif ttp + // Save stack and allocation environment and prepare error return + if (g->jump_level == MAX_JUMP) { + strcpy(g->Message, MSG(TOO_MANY_JUMPS)); + return HA_ERR_INTERNAL_ERROR; + } // endif jump_level + + if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) { + my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); + goto err; + } // endif rc + + if (!tab) { if (ttp == TAB_TBL) { // Make tab the first table of the list @@ -4902,7 +4776,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, if (!tbl) { strcpy(g->Message, "Missing table list"); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); - return HA_ERR_INTERNAL_ERROR; + goto err; } // endif tbl tab= (char*)PlugSubAlloc(g, NULL, strlen(tbl) + 1); @@ -4918,7 +4792,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, } // endif p } else if (ttp != TAB_ODBC || !(fnc & (FNC_TABLE | FNC_COL))) - tab= table_s->table_name.str; // Default value + tab= Strz(g, table_s->table_name); // Default value #if defined(NEW_WAY) // add_option(thd, create_info, "tabname", tab); @@ -4928,7 +4802,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, switch (ttp) { #if defined(ODBC_SUPPORT) case TAB_ODBC: - dsn= create_info->connect_string.str; + dsn= Strz(g, create_info->connect_string); if (fnc & (FNC_DSN | FNC_DRIVER)) { ok= true; @@ -5014,7 +4888,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, case TAB_XCL: case TAB_OCCUR: if (!src && !stricmp(tab, create_info->alias) && - (!db || !stricmp(db, table_s->db.str))) + (!db || !stricmp(db, Strz(g, table_s->db)))) sprintf(g->Message, "A %s table cannot refer to itself", topt->type); else ok= true; @@ -5049,11 +4923,11 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, int i, len, prec, dec, typ, flg; // if (cat) -// cat->SetDataPath(g, table_s->db.str); +// cat->SetDataPath(g, Strz(g, table_s->db)); // else // return HA_ERR_INTERNAL_ERROR; // Should never happen - dpath= SetPath(g, table_s->db.str); + dpath= SetPath(g, Strz(g, table_s->db)); if (src && ttp != TAB_PIVOT && ttp != TAB_ODBC) { qrp= SrcColumns(g, host, db, user, pwd, src, port); @@ -5061,7 +4935,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, if (qrp && ttp == TAB_OCCUR) if (OcrSrcCols(g, qrp, col, ocl, rnk)) { my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); - return HA_ERR_INTERNAL_ERROR; + goto err; } // endif OcrSrcCols } else switch (ttp) { @@ -5123,7 +4997,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, if (qrp && ttp == TAB_OCCUR && fnc != FNC_COL) if (OcrColumns(g, qrp, col, ocl, rnk)) { my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); - return HA_ERR_INTERNAL_ERROR; + goto err; } // endif OcrColumns break; @@ -5140,7 +5014,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, if (!qrp) { my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); - return HA_ERR_INTERNAL_ERROR; + goto err; } // endif !qrp if (fnc != FNC_NO || src || ttp == TAB_PIVOT) { @@ -5176,7 +5050,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, strcpy(g->Message, "Fail to retrieve columns"); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); - return HA_ERR_INTERNAL_ERROR; + goto err; } // endif !nblin for (i= 0; !rc && i < qrp->Nblin; i++) { @@ -5247,7 +5121,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, if (!(plgtyp= TranslateSQLType(typ, dec, prec, v))) { sprintf(g->Message, "Unsupported SQL type %d", typ); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); - return HA_ERR_INTERNAL_ERROR; + goto err; } else typ= plgtyp; @@ -5291,10 +5165,14 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, // rc= init_table_share(thd, table_s, create_info, dsn, &sql); #endif // !NEW_WAY + g->jump_level--; return rc; } // endif ok my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); + + err: + g->jump_level--; return HA_ERR_INTERNAL_ERROR; } // end of connect_assisted_discovery @@ -5367,7 +5245,7 @@ int ha_connect::create(const char *name, TABLE *table_arg, table= table_arg; // Used by called functions - if (xtrace) + if (trace) htrc("create: this=%p thd=%p xp=%p g=%p sqlcom=%d name=%s\n", this, thd, xp, g, sqlcom, GetTableName()); @@ -5433,7 +5311,8 @@ int ha_connect::create(const char *name, TABLE *table_arg, push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); } else if (options->tabname) { if (!stricmp(options->tabname, create_info->alias) && - (!options->dbname || !stricmp(options->dbname, table_arg->s->db.str))) { + (!options->dbname || + !stricmp(options->dbname, Strz(table_arg->s->db)))) { sprintf(g->Message, "A %s table cannot refer to itself", options->type); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); @@ -5648,7 +5527,7 @@ int ha_connect::create(const char *name, TABLE *table_arg, // the database directory named table_name.table_type. // (temporarily not done for XML because a void file causes // the XML parsers to report an error on the first Insert) - char buf[256], fn[_MAX_PATH], dbpath[128], lwt[12]; + char buf[_MAX_PATH], fn[_MAX_PATH], dbpath[_MAX_PATH], lwt[12]; int h; // Check for incompatible options @@ -5695,7 +5574,7 @@ int ha_connect::create(const char *name, TABLE *table_arg, if (sqlcom == SQLCOM_CREATE_TABLE) push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); - strcat(strcat(strcpy(dbpath, "./"), table->s->db.str), "/"); + strcat(strcat(strcpy(dbpath, "./"), Strz(table->s->db)), "/"); #if defined(WITH_PARTITION_STORAGE_ENGINE) } // endif part_info #endif // WITH_PARTITION_STORAGE_ENGINE @@ -5718,7 +5597,7 @@ int ha_connect::create(const char *name, TABLE *table_arg, } // endif sqlcom - if (xtrace) + if (trace) htrc("xchk=%p createas=%d\n", g->Xchk, g->Createas); // To check whether indexes have to be made or remade @@ -5769,10 +5648,10 @@ int ha_connect::create(const char *name, TABLE *table_arg, PDBUSER dup= PlgGetUser(g); PCATLG cat= (dup) ? dup->Catalog : NULL; - SetDataPath(g, table_arg->s->db.str); + SetDataPath(g, Strz(table_arg->s->db)); if (cat) { -// cat->SetDataPath(g, table_arg->s->db.str); +// cat->SetDataPath(g, Strz(table_arg->s->db)); #if defined(WITH_PARTITION_STORAGE_ENGINE) if (part_info) @@ -5822,7 +5701,7 @@ bool ha_connect::FileExists(const char *fn, bool bf) return true; if (table) { - char *s, tfn[_MAX_PATH], filename[_MAX_PATH], path[128]; + char *s, tfn[_MAX_PATH], filename[_MAX_PATH], path[_MAX_PATH]; bool b= false; int n; struct stat info; @@ -5846,7 +5725,7 @@ bool ha_connect::FileExists(const char *fn, bool bf) } else strcpy(tfn, fn); - strcat(strcat(strcat(strcpy(path, "."), s), table->s->db.str), s); + strcat(strcat(strcat(strcpy(path, "."), s), Strz(table->s->db)), s); PlugSetPath(filename, tfn, path); n= stat(filename, &info); @@ -6060,7 +5939,7 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table, xcp->newsep= xcp->SetName(g, GetStringOption("optname")); tshp= NULL; - if (xtrace && g->Xchk) + if (trace && g->Xchk) htrc( "oldsep=%d newsep=%d oldopn=%s newopn=%s oldpix=%p newpix=%p\n", xcp->oldsep, xcp->newsep, @@ -6265,15 +6144,18 @@ struct st_mysql_storage_engine connect_storage_engine= /***********************************************************************/ /* CONNECT global variables definitions. */ /***********************************************************************/ -// Tracing: 0 no, 1 yes, >1 more tracing -static MYSQL_SYSVAR_INT(xtrace, xtrace, - PLUGIN_VAR_RQCMDARG, "Console trace value.", - NULL, update_connect_xtrace, 0, 0, INT_MAX, 1); - // Size used when converting TEXT columns to VARCHAR +#if defined(_DEBUG) +static MYSQL_SYSVAR_INT(conv_size, conv_size, + PLUGIN_VAR_RQCMDARG, // opt + "Size used when converting TEXT columns.", + NULL, update_connect_zconv, SZCONV, 0, 65500, 1); +#else static MYSQL_SYSVAR_INT(conv_size, conv_size, - PLUGIN_VAR_RQCMDARG, "Size used when converting TEXT columns.", + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, // opt + "Size used when converting TEXT columns.", NULL, update_connect_zconv, SZCONV, 0, 65500, 1); +#endif /** Type conversion: @@ -6292,6 +6174,7 @@ TYPELIB xconv_typelib= xconv_names, NULL }; +#if defined(_DEBUG) static MYSQL_SYSVAR_ENUM( type_conv, // name type_conv, // varname @@ -6301,35 +6184,17 @@ static MYSQL_SYSVAR_ENUM( update_connect_xconv, // update function 0, // def (no) &xconv_typelib); // typelib - -/** - Temporary file usage: - no: Not using temporary file - auto: Using temporary file when needed - yes: Allways using temporary file - force: Force using temporary file (no MAP) - test: Reserved -*/ -const char *usetemp_names[]= -{ - "NO", "AUTO", "YES", "FORCE", "TEST", NullS -}; - -TYPELIB usetemp_typelib= -{ - array_elements(usetemp_names) - 1, "usetemp_typelib", - usetemp_names, NULL -}; - +#else static MYSQL_SYSVAR_ENUM( - use_tempfile, // name - use_tempfile, // varname - PLUGIN_VAR_RQCMDARG, // opt - "Temporary file use.", // comment + type_conv, // name + type_conv, // varname + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, + "Unsupported types conversion.", // comment NULL, // check - update_connect_usetemp, // update function - 1, // def (AUTO) - &usetemp_typelib); // typelib + update_connect_xconv, // update function + 0, // def (no) + &xconv_typelib); // typelib +#endif #if defined(XMAP) // Using file mapping for indexes if true @@ -6340,14 +6205,10 @@ static MYSQL_SYSVAR_BOOL(indx_map, indx_map, PLUGIN_VAR_RQCMDARG, // Size used for g->Sarea_Size static MYSQL_SYSVAR_UINT(work_size, work_size, - PLUGIN_VAR_RQCMDARG, "Size of the CONNECT work area.", + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, + "Size of the CONNECT work area.", NULL, update_connect_worksize, SZWORK, SZWMIN, UINT_MAX, 1); -// Getting exact info values -static MYSQL_SYSVAR_BOOL(exact_info, exact_info, PLUGIN_VAR_RQCMDARG, - "Getting exact info values", - NULL, update_connect_xinfo, 0); - static struct st_mysql_sys_var* connect_system_variables[]= { MYSQL_SYSVAR(xtrace), MYSQL_SYSVAR(conv_size), diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h index 47665a87a65..2b96e931bb3 100644 --- a/storage/connect/ha_connect.h +++ b/storage/connect/ha_connect.h @@ -26,6 +26,8 @@ #pragma interface /* gcc class implementation */ #endif +static char *strz(PGLOBAL g, LEX_STRING &ls); + /****************************************************************************/ /* Structures used to pass info between CONNECT and ha_connect. */ /****************************************************************************/ @@ -177,13 +179,16 @@ class ha_connect: public handler protected: char *PlugSubAllocStr(PGLOBAL g, void *memp, const char *str, size_t length) { - char *ptr; - if (!(ptr= (char*) PlugSubAlloc(g, memp, length + 1))) - return NULL; - memcpy(ptr, str, length); - ptr[length]= '\0'; + char *ptr= (char*)PlgDBSubAlloc(g, memp, length + 1); + + if (ptr) { + memcpy(ptr, str, length); + ptr[length]= '\0'; + } // endif ptr + return ptr; - } + } // end of PlugSubAllocStr + public: ha_connect(handlerton *hton, TABLE_SHARE *table_arg); ~ha_connect(); @@ -235,6 +240,8 @@ public: uint key_len= 0); bool MakeKeyWhere(PGLOBAL g, char *qry, OPVAL op, char *q, const void *key, int klen); + inline char *Strz(LEX_STRING &ls); + /** @brief The name that will be used for display purposes. diff --git a/storage/connect/libdoc.cpp b/storage/connect/libdoc.cpp index d019d1b61d9..e576c1cf5fa 100644 --- a/storage/connect/libdoc.cpp +++ b/storage/connect/libdoc.cpp @@ -180,7 +180,6 @@ class XML2ATTR : public XMLATTRIBUTE { extern "C" { extern char version[]; -extern int trace; } // "C" #if defined(MEMORY_TRACE) diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc index 5c11580c891..09a5b7a4dbc 100644 --- a/storage/connect/mycat.cc +++ b/storage/connect/mycat.cc @@ -98,8 +98,6 @@ extern "C" HINSTANCE s_hModule; // Saved module handle #endif // !WIN32 -extern "C" int trace; - PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info); /***********************************************************************/ diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp index 0c4b50f1d0b..53100b60a4d 100644 --- a/storage/connect/myconn.cpp +++ b/storage/connect/myconn.cpp @@ -46,11 +46,11 @@ #include "plgcnx.h" // For DB types #include "resource.h" //#include "value.h" -#include "valblk.h" +//#include "valblk.h" +#include "xobject.h" #define DLL_EXPORT // Items are exported from this DLL #include "myconn.h" -extern "C" int trace; extern "C" int zconv; extern MYSQL_PLUGIN_IMPORT uint mysqld_port; extern MYSQL_PLUGIN_IMPORT char *mysqld_unix_port; @@ -135,7 +135,7 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db, FLD_REM, FLD_NO, FLD_DEFAULT, FLD_EXTRA, FLD_CHARSET}; unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0}; - char *fld, *colname, *chset, *fmt, v, cmd[128], uns[16], zero[16]; + char *fld, *colname, *chset, *fmt, v, buf[128], uns[16], zero[16]; int i, n, nf, ncol = sizeof(buftyp) / sizeof(int); int len, type, prec, rc, k = 0; PQRYRES qrp; @@ -155,16 +155,26 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db, /********************************************************************/ /* Do an evaluation of the result size. */ /********************************************************************/ - sprintf(cmd, "SHOW FULL COLUMNS FROM %s", table); - strcat(strcat(cmd, " FROM "), (db) ? db : PlgGetUser(g)->DBName); + STRING cmd(g, 64, "SHOW FULL COLUMNS FROM "); + bool b = cmd.Append((PSZ)table); - if (colpat) - strcat(strcat(cmd, " LIKE "), colpat); + b |= cmd.Append(" FROM "); + b |= cmd.Append((PSZ)(db ? db : PlgGetUser(g)->DBName)); + + if (colpat) { + b |= cmd.Append(" LIKE "); + b |= cmd.Append((PSZ)colpat); + } // endif colpat + + if (b) { + strcpy(g->Message, "Out of memory"); + return NULL; + } // endif b if (trace) htrc("MyColumns: cmd='%s'\n", cmd); - if ((n = myc.GetResultSize(g, cmd)) < 0) { + if ((n = myc.GetResultSize(g, cmd.GetStr())) < 0) { myc.Close(); return NULL; } // endif n @@ -225,15 +235,15 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db, *uns = 0; *zero = 0; - switch ((nf = sscanf(fld, "%[^(](%d,%d", cmd, &len, &prec))) { + switch ((nf = sscanf(fld, "%[^(](%d,%d", buf, &len, &prec))) { case 3: - nf = sscanf(fld, "%[^(](%d,%d) %s %s", cmd, &len, &prec, uns, zero); + nf = sscanf(fld, "%[^(](%d,%d) %s %s", buf, &len, &prec, uns, zero); break; case 2: - nf = sscanf(fld, "%[^(](%d) %s %s", cmd, &len, uns, zero) + 1; + nf = sscanf(fld, "%[^(](%d) %s %s", buf, &len, uns, zero) + 1; break; case 1: - nf = sscanf(fld, "%s %s %s", cmd, uns, zero) + 2; + nf = sscanf(fld, "%s %s %s", buf, uns, zero) + 2; break; default: sprintf(g->Message, MSG(BAD_FIELD_TYPE), fld); @@ -241,16 +251,16 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db, return NULL; } // endswitch nf - if ((type = MYSQLtoPLG(cmd, &v)) == TYPE_ERROR) { + if ((type = MYSQLtoPLG(buf, &v)) == TYPE_ERROR) { if (v == 'K') { // Skip this column sprintf(g->Message, "Column %s skipped (unsupported type %s)", - colname, cmd); + colname, buf); PushWarning(g, thd); continue; } // endif v - sprintf(g->Message, "Column %s unsupported type %s", colname, cmd); + sprintf(g->Message, "Column %s unsupported type %s", colname, buf); myc.Close(); return NULL; } else if (type == TYPE_STRING) { @@ -276,11 +286,11 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db, } // endswitch nf crp = crp->Next; // Type_Name - crp->Kdata->SetValue(cmd, i); + crp->Kdata->SetValue(buf, i); if (type == TYPE_DATE) { // When creating tables we do need info about date columns - fmt = MyDateFmt(cmd); + fmt = MyDateFmt(buf); len = strlen(fmt); } else fmt = NULL; diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp index 679e8dc703c..4f4bde36b94 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -64,8 +64,6 @@ extern "C" HINSTANCE s_hModule; // Saved module handle #define DEBUG_ONLY(f) ((void)0) #endif // !_DEBUG -extern "C" int trace; - /***********************************************************************/ /* GetSQLType: returns the SQL_TYPE corresponding to a PLG type. */ /***********************************************************************/ diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp index 755aeb21105..47062726305 100644 --- a/storage/connect/plgdbutl.cpp +++ b/storage/connect/plgdbutl.cpp @@ -90,7 +90,6 @@ extern "C" { #if defined(XMSG) char msglang[16] = "ENGLISH"; // Default language #endif -extern int trace; extern char version[]; } // extern "C" diff --git a/storage/connect/plugutil.c b/storage/connect/plugutil.c index c3b77544983..1bed67d402f 100644 --- a/storage/connect/plugutil.c +++ b/storage/connect/plugutil.c @@ -81,8 +81,6 @@ extern HINSTANCE s_hModule; /* Saved module handle */ #endif // WIN32 -extern int trace; - #if defined(XMSG) extern char msglang[]; #endif // XMSG diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp index 8d5f96dce95..e469ae40f1f 100644 --- a/storage/connect/reldef.cpp +++ b/storage/connect/reldef.cpp @@ -49,13 +49,15 @@ #include "tabmul.h" #include "ha_connect.h" -extern "C" int trace; -extern "C" USETEMP Use_Temp; - #if !defined(WIN32) extern handlerton *connect_hton; #endif // !WIN32 +/***********************************************************************/ +/* External function. */ +/***********************************************************************/ +USETEMP UseTemp(void); + /* --------------------------- Class RELDEF -------------------------- */ /***********************************************************************/ @@ -591,7 +593,7 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode) PTXF txfp = NULL; PDOSDEF defp = (PDOSDEF)Pxdef; bool map = defp->Mapped && mode != MODE_INSERT && - !(Use_Temp == TMP_FORCE && + !(UseTemp() == TMP_FORCE && (mode == MODE_UPDATE || mode == MODE_DELETE)); int cmpr = defp->Compressed; diff --git a/storage/connect/tabcol.cpp b/storage/connect/tabcol.cpp index 96ec4f45861..8f350c6f074 100644 --- a/storage/connect/tabcol.cpp +++ b/storage/connect/tabcol.cpp @@ -22,8 +22,6 @@ #include "xtable.h" #include "tabcol.h" -extern "C" int trace; - /***********************************************************************/ /* XTAB public constructor. */ /***********************************************************************/ diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp index 7bba914a1ca..d9bb17043d9 100644 --- a/storage/connect/tabdos.cpp +++ b/storage/connect/tabdos.cpp @@ -65,16 +65,18 @@ /***********************************************************************/ int num_read, num_there, num_eq[2]; // Statistics -extern "C" int trace; -extern "C" USETEMP Use_Temp; -extern bool xinfo; - /***********************************************************************/ /* Size of optimize file header. */ /***********************************************************************/ #define NZ 4 /***********************************************************************/ +/* External function. */ +/***********************************************************************/ +bool ExactInfo(void); +USETEMP UseTemp(void); + +/***********************************************************************/ /* Min and Max blocks contains zero ended fields (blank = false). */ /* No conversion of block values (check = true). */ /***********************************************************************/ @@ -316,7 +318,7 @@ bool DOSDEF::InvalidateIndex(PGLOBAL g) PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode) { // Mapping not used for insert - USETEMP tmp = Use_Temp; + USETEMP tmp = UseTemp(); bool map = Mapped && mode != MODE_INSERT && !(tmp != TMP_NO && Recfm == RECFM_VAR && mode == MODE_UPDATE) && @@ -1905,7 +1907,7 @@ int TDBDOS::Cardinality(PGLOBAL g) } // endif Mode - if (Mode == MODE_ANY && xinfo) { + if (Mode == MODE_ANY && ExactInfo()) { // Using index impossible or failed, do it the hard way Mode = MODE_READ; To_Line = (char*)PlugSubAlloc(g, NULL, Lrecl + 1); @@ -2018,8 +2020,10 @@ int TDBDOS::EstimatedLength(PGLOBAL g) /***********************************************************************/ bool TDBDOS::IsUsingTemp(PGLOBAL g) { - return (Use_Temp == TMP_YES || Use_Temp == TMP_FORCE || - (Use_Temp == TMP_AUTO && Mode == MODE_UPDATE)); + USETEMP utp = UseTemp(); + + return (utp == TMP_YES || utp == TMP_FORCE || + (utp == TMP_AUTO && Mode == MODE_UPDATE)); } // end of IsUsingTemp /***********************************************************************/ @@ -2059,7 +2063,7 @@ bool TDBDOS::OpenDB(PGLOBAL g) Txfp = new(g) DOSFAM((PDOSDEF)To_Def); Txfp->SetTdbp(this); } else if (Txfp->Blocked && (Mode == MODE_DELETE || - (Mode == MODE_UPDATE && Use_Temp != TMP_NO))) { + (Mode == MODE_UPDATE && UseTemp() != TMP_NO))) { /*******************************************************************/ /* Delete is not currently handled in block mode neither Update */ /* when using a temporary file. */ diff --git a/storage/connect/tabfix.cpp b/storage/connect/tabfix.cpp index 91f06536272..77e47e6f8dd 100644 --- a/storage/connect/tabfix.cpp +++ b/storage/connect/tabfix.cpp @@ -51,13 +51,15 @@ /***********************************************************************/ /* DB static variables. */ /***********************************************************************/ -extern "C" int trace; -extern "C" USETEMP Use_Temp; - extern int num_read, num_there, num_eq[2]; // Statistics static const longlong M2G = 0x80000000; static const longlong M4G = (longlong)2 * M2G; +/***********************************************************************/ +/* External function. */ +/***********************************************************************/ +USETEMP UseTemp(void); + /* ------------------------------------------------------------------- */ /***********************************************************************/ @@ -273,9 +275,9 @@ bool TDBFIX::IsUsingTemp(PGLOBAL g) { // Not ready yet to handle using a temporary file with mapping // or while deleting from DBF files. - return ((Use_Temp == TMP_YES && Txfp->GetAmType() != TYPE_AM_MAP && + return ((UseTemp() == TMP_YES && Txfp->GetAmType() != TYPE_AM_MAP && !(Mode == MODE_DELETE && Txfp->GetAmType() == TYPE_AM_DBF)) || - Use_Temp == TMP_FORCE || Use_Temp == TMP_TEST); + UseTemp() == TMP_FORCE || UseTemp() == TMP_TEST); } // end of IsUsingTemp /***********************************************************************/ @@ -307,7 +309,7 @@ bool TDBFIX::OpenDB(PGLOBAL g) } // endif use if (Mode == MODE_DELETE && Txfp->GetAmType() == TYPE_AM_MAP && - (!Next || Use_Temp == TMP_FORCE)) { + (!Next || UseTemp() == TMP_FORCE)) { // Delete all lines or using temp. Not handled in MAP mode Txfp = new(g) FIXFAM((PDOSDEF)To_Def); Txfp->SetTdbp(this); diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp index 2efdd0d661b..d5f8dc50a89 100644 --- a/storage/connect/tabfmt.cpp +++ b/storage/connect/tabfmt.cpp @@ -66,8 +66,10 @@ #define MAXCOL 200 /* Default max column nb in result */ #define TYPE_UNKNOWN 10 /* Must be greater than other types */ -extern "C" int trace; -extern "C" USETEMP Use_Temp; +/***********************************************************************/ +/* External function. */ +/***********************************************************************/ +USETEMP UseTemp(void); /***********************************************************************/ /* CSVColumns: constructs the result blocks containing the description */ @@ -446,7 +448,7 @@ PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode) PTDBASE tdbp; if (Catfunc != FNC_COL) { - USETEMP tmp = Use_Temp; + USETEMP tmp = UseTemp(); bool map = Mapped && mode != MODE_INSERT && !(tmp != TMP_NO && mode == MODE_UPDATE) && !(tmp == TMP_FORCE && diff --git a/storage/connect/table.cpp b/storage/connect/table.cpp index 5db50d44787..b093e2102c2 100644 --- a/storage/connect/table.cpp +++ b/storage/connect/table.cpp @@ -28,8 +28,6 @@ int TDB::Tnum = 0; -extern "C" int trace; // The general trace value - /***********************************************************************/ /* Utility routines. */ /***********************************************************************/ @@ -193,6 +191,18 @@ PSZ TDBASE::GetPath(void) } // end of GetPath /***********************************************************************/ +/* Return true if name is a special column of this table. */ +/***********************************************************************/ +bool TDBASE::IsSpecial(PSZ name) + { + for (PCOLDEF cdp = To_Def->GetCols(); cdp; cdp = cdp->GetNext()) + if (!stricmp(cdp->GetName(), name) && (cdp->Flags & U_SPECIAL)) + return true; // Special column to ignore while inserting + + return false; // Not found or not special or not inserting + } // end of IsSpecial + +/***********************************************************************/ /* Initialize TDBASE based column description block construction. */ /* name is used to call columns by name. */ /* num is used by TBL to construct columns by index number. */ diff --git a/storage/connect/tabmul.cpp b/storage/connect/tabmul.cpp index 4b40e6c5509..86d4deb60f3 100755 --- a/storage/connect/tabmul.cpp +++ b/storage/connect/tabmul.cpp @@ -68,8 +68,6 @@ #include "tabdos.h" // TDBDOS and DOSCOL class dcls #include "tabmul.h" // TDBMUL and MULCOL classes dcls -extern "C" int trace; - /* ------------------------- Class TDBMUL ---------------------------- */ /***********************************************************************/ diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp index 08938cb9626..80d384d611e 100644 --- a/storage/connect/tabmysql.cpp +++ b/storage/connect/tabmysql.cpp @@ -67,13 +67,15 @@ void PrintResult(PGLOBAL, PSEM, PQRYRES); #endif // _CONSOLE -extern "C" int trace; -extern bool xinfo; - // Used to check whether a MYSQL table is created on itself bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host, const char *db, char *tab, const char *src, int port); +/***********************************************************************/ +/* External function. */ +/***********************************************************************/ +bool ExactInfo(void); + /* -------------- Implementation of the MYSQLDEF class --------------- */ /***********************************************************************/ @@ -430,7 +432,6 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp) Bind = NULL; Query = NULL; - Qbuf = NULL; Fetched = false; m_Rc = RC_FX; AftRows = 0; @@ -454,7 +455,6 @@ TDBMYSQL::TDBMYSQL(PGLOBAL g, PTDBMY tdbp) : TDBASE(tdbp) Delayed = tdbp->Delayed; Bind = NULL; Query = tdbp->Query; - Qbuf = NULL; Fetched = tdbp->Fetched; m_Rc = tdbp->m_Rc; AftRows = tdbp->AftRows; @@ -495,9 +495,10 @@ PCOL TDBMYSQL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) /***********************************************************************/ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx) { - char *tk = "`"; +//char *tk = "`"; + char tk = '`'; int len = 0, rank = 0; - bool b = false; + bool b = false, oom = false; PCOL colp; //PDBUSER dup = PlgGetUser(g); @@ -505,27 +506,24 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx) return false; // already done if (Srcdef) { - Query = Srcdef; + Query = new(g)STRING(g, 0, Srcdef); return false; } // endif Srcdef - //Find the address of the suballocated query - Query = (char*)PlugSubAlloc(g, NULL, 0); - strcpy(Query, "SELECT "); + // Allocate the string used to contain Query + Query = new(g) STRING(g, 1023, "SELECT "); if (Columns) { for (colp = Columns; colp; colp = colp->GetNext()) if (!colp->IsSpecial()) { -// if (colp->IsSpecial()) { -// strcpy(g->Message, MSG(NO_SPEC_COL)); -// return true; -// } else { if (b) - strcat(Query, ", "); + oom |= Query->Append(", "); else b = true; - strcat(strcat(strcat(Query, tk), colp->GetName()), tk); + oom |= Query->Append(tk); + oom |= Query->Append(colp->GetName()); + oom |= Query->Append(tk); ((PMYCOL)colp)->Rank = rank++; } // endif colp @@ -534,27 +532,38 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx) // Query count(*) from... for which we will count the rows from // Query '*' from... // (the use of a char constant minimize the result storage) - strcat(Query, (Isview) ? "*" : "'*'"); + if (Isview) + oom |= Query->Append('*'); + else + oom |= Query->Append("'*'"); + } // endif ncol - strcat(strcat(strcat(strcat(Query, " FROM "), tk), Tabname), tk); - len = strlen(Query); + oom |= Query->Append(" FROM "); + oom |= Query->Append(tk); + oom |= Query->Append(Tabname); + oom |= Query->Append(tk); + len = Query->GetLength(); if (To_CondFil) { if (!mx) { - strcat(strcat(Query, " WHERE "), To_CondFil->Body); - len = strlen(Query) + 1; + oom |= Query->Append(" WHERE "); + oom |= Query->Append(To_CondFil->Body); + len = Query->GetLength() + 1; } else len += (strlen(To_CondFil->Body) + 256); } else len += (mx ? 256 : 1); + if (oom || Query->Resize(len)) { + strcpy(g->Message, "MakeSelect: Out of memory"); + return true; + } // endif oom + if (trace) - htrc("Query=%s\n", Query); + htrc("Query=%s\n", Query->GetStr()); - // Now we know how much to suballocate - PlugSubAlloc(g, NULL, len); return false; } // end of MakeSelect @@ -563,81 +572,82 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx) /***********************************************************************/ bool TDBMYSQL::MakeInsert(PGLOBAL g) { - char *colist, *valist = NULL; char *tk = "`"; - int len = 0, qlen = 0; - bool b = false; + uint len = 0; + bool b = false, oom; PCOL colp; if (Query) return false; // already done - for (colp = Columns; colp; colp = colp->GetNext()) - if (!colp->IsSpecial()) { -// if (colp->IsSpecial()) { -// strcpy(g->Message, MSG(NO_SPEC_COL)); -// return true; -// } else { - len += (strlen(colp->GetName()) + 4); - ((PMYCOL)colp)->Rank = Nparm++; - } // endif colp - - colist = (char*)PlugSubAlloc(g, NULL, len); - *colist = '\0'; - if (Prep) { -#if defined(MYSQL_PREPARED_STATEMENTS) - valist = (char*)PlugSubAlloc(g, NULL, 2 * Nparm); - *valist = '\0'; -#else // !MYSQL_PREPARED_STATEMENTS +#if !defined(MYSQL_PREPARED_STATEMENTS) strcpy(g->Message, "Prepared statements not used (not supported)"); PushWarning(g, this); Prep = false; #endif // !MYSQL_PREPARED_STATEMENTS } // endif Prep - for (colp = Columns; colp; colp = colp->GetNext()) { - if (b) { - strcat(colist, ", "); - if (Prep) strcat(valist, ","); - } else - b = true; - - strcat(strcat(strcat(colist, tk), colp->GetName()), tk); - - // Parameter marker - if (!Prep) { - if (colp->GetResultType() == TYPE_DATE) - qlen += 20; - else - qlen += colp->GetLength(); + for (colp = Columns; colp; colp = colp->GetNext()) + if (colp->IsSpecial()) { + strcpy(g->Message, MSG(NO_SPEC_COL)); + return true; + } else { + len += (strlen(colp->GetName()) + 4); - } else // Prep - strcat(valist, "?"); + // Parameter marker + if (!Prep) { + if (colp->GetResultType() == TYPE_DATE) + len += 20; + else + len += colp->GetLength(); + + } else + len += 2; - } // endfor colp + ((PMYCOL)colp)->Rank = Nparm++; + } // endif colp // Below 40 is enough to contain the fixed part of the query - len = (strlen(Tabname) + strlen(colist) - + ((Prep) ? strlen(valist) : 0) + 40); - Query = (char*)PlugSubAlloc(g, NULL, len); + len += (strlen(Tabname) + 40); + Query = new(g) STRING(g, len); if (Delayed) - strcpy(Query, "INSERT DELAYED INTO "); + oom = Query->Set("INSERT DELAYED INTO "); else - strcpy(Query, "INSERT INTO "); + oom = Query->Set("INSERT INTO "); - strcat(strcat(strcat(Query, tk), Tabname), tk); - strcat(strcat(strcat(Query, " ("), colist), ") VALUES ("); + oom |= Query->Append(tk); + oom |= Query->Append(Tabname); + oom |= Query->Append("` ("); - if (Prep) - strcat(strcat(Query, valist), ")"); - else { - qlen += (strlen(Query) + Nparm); - Qbuf = (char *)PlugSubAlloc(g, NULL, qlen); - } // endelse Prep + for (colp = Columns; colp; colp = colp->GetNext()) { + if (b) + oom |= Query->Append(", "); + else + b = true; + + oom |= Query->Append(tk); + oom |= Query->Append(colp->GetName()); + oom |= Query->Append(tk); + } // endfor colp - return false; + oom |= Query->Append(") VALUES ("); + +#if defined(MYSQL_PREPARED_STATEMENTS) + if (Prep) { + for (int i = 0; i < Nparm; i++) + oom |= Query->Append("?,"); + + Query->RepLast(')'); + Query->Trim(); + } // endif Prep +#endif // MYSQL_PREPARED_STATEMENTS + + if (oom) + strcpy(g->Message, "MakeInsert: Out of memory"); + + return oom; } // end of MakeInsert /***********************************************************************/ @@ -646,7 +656,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g) /***********************************************************************/ int TDBMYSQL::MakeCommand(PGLOBAL g) { - Query = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64); + Query = new(g) STRING(g, strlen(Qrystr) + 64); if (Quoted > 0 || stricmp(Name, Tabname)) { char *p, *qrystr, name[68]; @@ -665,16 +675,23 @@ int TDBMYSQL::MakeCommand(PGLOBAL g) strlwr(strcpy(name, Name)); // Not a keyword if ((p = strstr(qrystr, name))) { - memcpy(Query, Qrystr, p - qrystr); - Query[p - qrystr] = 0; + bool oom = Query->Set(Qrystr, p - qrystr); - if (qtd && *(p-1) == ' ') - strcat(strcat(strcat(Query, "`"), Tabname), "`"); - else - strcat(Query, Tabname); + if (qtd && *(p-1) == ' ') { + oom |= Query->Append('`'); + oom |= Query->Append(Tabname); + oom |= Query->Append('`'); + } else + oom |= Query->Append(Tabname); + + oom |= Query->Append(Qrystr + (p - qrystr) + strlen(name)); + + if (oom) { + strcpy(g->Message, "MakeCommand: Out of memory"); + return RC_FX; + } else + strlwr(strcpy(qrystr, Query->GetStr())); - strcat(Query, Qrystr + (p - qrystr) + strlen(name)); - strlwr(strcpy(qrystr, Query)); } else { sprintf(g->Message, "Cannot use this %s command", (Mode == MODE_UPDATE) ? "UPDATE" : "DELETE"); @@ -682,7 +699,7 @@ int TDBMYSQL::MakeCommand(PGLOBAL g) } // endif p } else - strcpy(Query, Qrystr); + (void)Query->Set(Qrystr); return RC_OK; } // end of MakeCommand @@ -755,7 +772,7 @@ int TDBMYSQL::Cardinality(PGLOBAL g) if (!g) return (Mode == MODE_ANY && !Srcdef) ? 1 : 0; - if (Cardinal < 0 && Mode == MODE_ANY && !Srcdef && xinfo) { + if (Cardinal < 0 && Mode == MODE_ANY && !Srcdef && ExactInfo()) { // Info command, we must return the exact table row number char query[96]; MYSQLC myc; @@ -802,7 +819,7 @@ int TDBMYSQL::GetMaxSize(PGLOBAL g) /***********************************************************************/ int TDBMYSQL::RowNumber(PGLOBAL g, bool b) { - return N; + return N + 1; } // end of RowNumber /***********************************************************************/ @@ -871,7 +888,8 @@ bool TDBMYSQL::OpenDB(PGLOBAL g) /*********************************************************************/ if (Mode == MODE_READ || Mode == MODE_READX) { MakeSelect(g, Mode == MODE_READX); - m_Rc = (Mode == MODE_READ) ? Myc.ExecSQL(g, Query) : RC_OK; + m_Rc = (Mode == MODE_READ) + ? Myc.ExecSQL(g, Query->GetStr()) : RC_OK; #if 0 if (!Myc.m_Res || !Myc.m_Fields) { @@ -894,7 +912,8 @@ bool TDBMYSQL::OpenDB(PGLOBAL g) if (!MakeInsert(g)) { #if defined(MYSQL_PREPARED_STATEMENTS) - int n = (Prep) ? Myc.PrepareSQL(g, Query) : Nparm; + int n = (Prep) + ? Myc.PrepareSQL(g, Query->GetCharValue()) : Nparm; if (Nparm != n) { if (n >= 0) // Other errors return negative values @@ -1007,7 +1026,7 @@ int TDBMYSQL::SendCommand(PGLOBAL g) { int w; - if (Myc.ExecSQLcmd(g, Query, &w) == RC_NF) { + if (Myc.ExecSQLcmd(g, Query->GetStr(), &w) == RC_NF) { AftRows = Myc.m_Afrw; sprintf(g->Message, "%s: %d affected rows", Tabname, AftRows); PushWarning(g, this, 0); // 0 means a Note @@ -1037,28 +1056,45 @@ int TDBMYSQL::SendCommand(PGLOBAL g) /***********************************************************************/ bool TDBMYSQL::ReadKey(PGLOBAL g, OPVAL op, const void *key, int len) { - int oldlen = strlen(Query); + bool oom; + int oldlen = Query->GetLength(); if (!key || op == OP_NEXT || Mode == MODE_UPDATE || Mode == MODE_DELETE) return false; else if (op == OP_FIRST) { - if (To_CondFil) - strcat(strcat(Query, " WHERE "), To_CondFil->Body); + if (To_CondFil) { + oom = Query->Append(" WHERE "); + + if ((oom |= Query->Append(To_CondFil->Body))) { + strcpy(g->Message, "Readkey: Out of memory"); + return true; + } // endif oom + + } // endif To_Condfil } else { if (Myc.m_Res) Myc.FreeResult(); - To_Def->GetHandler()->MakeKeyWhere(g, Query, op, "`", key, len); + To_Def->GetHandler()->MakeKeyWhere(g, Query->GetStr(), + op, "`", key, len); - if (To_CondFil) - strcat(strcat(strcat(Query, " AND ("), To_CondFil->Body), ")"); + if (To_CondFil) { + oom = Query->Append(" AND ("); + oom |= Query->Append(To_CondFil->Body); + + if ((oom |= Query->Append(')'))) { + strcpy(g->Message, "Readkey: Out of memory"); + return true; + } // endif oom + + } // endif To_Condfil } // endif's op - m_Rc = Myc.ExecSQL(g, Query); - Query[oldlen] = 0; + m_Rc = Myc.ExecSQL(g, Query->GetStr()); + Query->Truncate(oldlen); return (m_Rc == RC_FX) ? true : false; } // end of ReadKey @@ -1102,31 +1138,38 @@ int TDBMYSQL::WriteDB(PGLOBAL g) // Statement was not prepared, we must construct and execute // an insert query for each line to insert int rc; + uint len = Query->GetLength(); char buf[64]; - - strcpy(Qbuf, Query); + bool b, oom = false; // Make the Insert command value list for (PCOL colp = Columns; colp; colp = colp->GetNext()) { if (!colp->GetValue()->IsNull()) { - if (colp->GetResultType() == TYPE_STRING || - colp->GetResultType() == TYPE_DATE) - strcat(Qbuf, "'"); - - strcat(Qbuf, colp->GetValue()->GetCharString(buf)); - - if (colp->GetResultType() == TYPE_STRING || - colp->GetResultType() == TYPE_DATE) - strcat(Qbuf, "'"); - + if ((b = colp->GetResultType() == TYPE_STRING || + colp->GetResultType() == TYPE_DATE)) + oom |= Query->Append('\''); + + oom |= Query->Append(colp->GetValue()->GetCharString(buf)); + + if (b) + oom |= Query->Append('\''); + } else - strcat(Qbuf, "NULL"); - - strcat(Qbuf, (colp->GetNext()) ? "," : ")"); + oom |= Query->Append("NULL"); + + oom |= Query->Append(','); } // endfor colp - Myc.m_Rows = -1; // To execute the query - rc = Myc.ExecSQL(g, Qbuf); + if (unlikely(oom)) { + strcpy(g->Message, "WriteDB: Out of memory"); + rc = RC_FX; + } else { + Query->RepLast(')'); + Myc.m_Rows = -1; // To execute the query + rc = Myc.ExecSQL(g, Query->GetStr()); + Query->Truncate(len); // Restore query + } // endif oom + return (rc == RC_NF) ? RC_OK : rc; // RC_NF is Ok } // end of WriteDB @@ -1531,7 +1574,7 @@ bool TDBMYEXC::OpenDB(PGLOBAL g) if (!(Cmdlist = MakeCMD(g))) { Myc.Close(); return true; - } // endif Query + } // endif Cmdlist return false; } // end of OpenDB @@ -1559,9 +1602,12 @@ int TDBMYEXC::ReadDB(PGLOBAL g) int rc; do { - Query = Cmdlist->Cmd; + if (Query) + Query->Set(Cmdlist->Cmd); + else + Query = new(g) STRING(g, 0, Cmdlist->Cmd); - switch (rc = Myc.ExecSQLcmd(g, Query, &Warnings)) { + switch (rc = Myc.ExecSQLcmd(g, Query->GetStr(), &Warnings)) { case RC_NF: AftRows = Myc.m_Afrw; strcpy(g->Message, "Affected rows"); @@ -1650,11 +1696,11 @@ void MYXCOL::ReadColumn(PGLOBAL g) } else switch (Flag) { - case 0: Value->SetValue_psz(tdbp->Query); break; - case 1: Value->SetValue(tdbp->AftRows); break; - case 2: Value->SetValue_psz(g->Message); break; - case 3: Value->SetValue(tdbp->Warnings); break; - default: Value->SetValue_psz("Invalid Flag"); break; + case 0: Value->SetValue_psz(tdbp->Query->GetStr()); break; + case 1: Value->SetValue(tdbp->AftRows); break; + case 2: Value->SetValue_psz(g->Message); break; + case 3: Value->SetValue(tdbp->Warnings); break; + default: Value->SetValue_psz("Invalid Flag"); break; } // endswitch Flag } // end of ReadColumn diff --git a/storage/connect/tabmysql.h b/storage/connect/tabmysql.h index 68cf453a9e6..99930d43a57 100644 --- a/storage/connect/tabmysql.h +++ b/storage/connect/tabmysql.h @@ -119,6 +119,7 @@ class TDBMYSQL : public TDBASE { // Members MYSQLC Myc; // MySQL connection class MYSQL_BIND *Bind; // To the MySQL bind structure array + PSTRG Query; // Constructed SQL query char *Host; // Host machine to use char *User; // User logon info char *Pwd; // Password logon info @@ -126,8 +127,6 @@ class TDBMYSQL : public TDBASE { char *Tabname; // External table name char *Srcdef; // The source table SQL definition char *Server; // The server ID - char *Query; // Points to SQL query - char *Qbuf; // Used for not prepared insert char *Qrystr; // The original query bool Fetched; // True when fetch was done bool Isview; // True if this table is a MySQL view diff --git a/storage/connect/taboccur.cpp b/storage/connect/taboccur.cpp index 917685faae3..86f0bd20d47 100644 --- a/storage/connect/taboccur.cpp +++ b/storage/connect/taboccur.cpp @@ -51,8 +51,6 @@ #include "ha_connect.h" #include "mycat.h" -extern "C" int trace; - /***********************************************************************/ /* Prepare and count columns in the column list. */ /***********************************************************************/ diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp index c9f5fbe31c7..6f006fb5967 100644 --- a/storage/connect/tabodbc.cpp +++ b/storage/connect/tabodbc.cpp @@ -75,15 +75,17 @@ #include "sql_string.h" -extern "C" int trace; -extern bool xinfo; - /***********************************************************************/ /* DB static variables. */ /***********************************************************************/ // int num_read, num_there, num_eq[2], num_nf; // Statistics extern int num_read, num_there, num_eq[2]; // Statistics +/***********************************************************************/ +/* External function. */ +/***********************************************************************/ +bool ExactInfo(void); + /* -------------------------- Class ODBCDEF -------------------------- */ /***********************************************************************/ @@ -672,7 +674,7 @@ int TDBODBC::Cardinality(PGLOBAL g) if (!g) return (Mode == MODE_ANY && !Srcdef) ? 1 : 0; - if (Cardinal < 0 && Mode == MODE_ANY && !Srcdef && xinfo) { + if (Cardinal < 0 && Mode == MODE_ANY && !Srcdef && ExactInfo()) { // Info command, we must return the exact table row number char qry[96], tbn[64]; ODBConn *ocp = new(g) ODBConn(g, this); diff --git a/storage/connect/tabpivot.cpp b/storage/connect/tabpivot.cpp index 7e54b62caaa..94e9d7187f0 100644 --- a/storage/connect/tabpivot.cpp +++ b/storage/connect/tabpivot.cpp @@ -51,8 +51,6 @@ #include "ha_connect.h" #include "mycat.h" // For GetHandler -extern "C" int trace; - /***********************************************************************/ /* Make the Pivot table column list. */ /***********************************************************************/ diff --git a/storage/connect/tabsys.cpp b/storage/connect/tabsys.cpp index ae92c0771b6..3ed182c5e33 100644 --- a/storage/connect/tabsys.cpp +++ b/storage/connect/tabsys.cpp @@ -53,8 +53,6 @@ GetPrivateProfileString(NULL,NULL,"",S,L,I) #endif // !WIN32 -extern "C" int trace; - /* -------------- Implementation of the INI classes ------------------ */ /***********************************************************************/ diff --git a/storage/connect/tabtbl.cpp b/storage/connect/tabtbl.cpp index f5a516ad1d0..22ec3849b6f 100644 --- a/storage/connect/tabtbl.cpp +++ b/storage/connect/tabtbl.cpp @@ -86,8 +86,6 @@ #define SYSEXIT void * #endif // !WIN32 -extern "C" int trace; - /* ---------------------------- Class TBLDEF ---------------------------- */ /**************************************************************************/ diff --git a/storage/connect/tabutil.cpp b/storage/connect/tabutil.cpp index f4a8f2ee470..d469594916f 100644 --- a/storage/connect/tabutil.cpp +++ b/storage/connect/tabutil.cpp @@ -54,7 +54,6 @@ #include "tabutil.h" #include "ha_connect.h" -extern "C" int trace; extern "C" int zconv; /************************************************************************/ diff --git a/storage/connect/tabvct.cpp b/storage/connect/tabvct.cpp index 6d7059e2306..3ed40540395 100644 --- a/storage/connect/tabvct.cpp +++ b/storage/connect/tabvct.cpp @@ -76,8 +76,10 @@ char *strerror(int num); #endif // UNIX -extern "C" int trace; -extern "C" USETEMP Use_Temp; +/***********************************************************************/ +/* External function. */ +/***********************************************************************/ +USETEMP UseTemp(void); /***********************************************************************/ /* Char VCT column blocks are right filled with blanks (blank = true) */ @@ -209,7 +211,7 @@ PTDB VCTDEF::GetTable(PGLOBAL g, MODE mode) // Mapping not used for insert (except for true VEC not split tables) // or when UseTemp is forced bool map = Mapped && (Estimate || mode != MODE_INSERT) && - !(Use_Temp == TMP_FORCE && + !(UseTemp() == TMP_FORCE && (mode == MODE_UPDATE || mode == MODE_DELETE)); PTXF txfp; PTDB tdbp; @@ -291,7 +293,7 @@ PCOL TDBVCT::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) bool TDBVCT::IsUsingTemp(PGLOBAL g) { // For developpers - return (Use_Temp == TMP_TEST); + return (UseTemp() == TMP_TEST); } // end of IsUsingTemp /***********************************************************************/ diff --git a/storage/connect/tabwmi.cpp b/storage/connect/tabwmi.cpp index f93776c31da..7c69426a066 100644 --- a/storage/connect/tabwmi.cpp +++ b/storage/connect/tabwmi.cpp @@ -21,8 +21,6 @@ #include "plgcnx.h" // For DB types #include "resource.h" -extern "C" int trace; - /* ------------------- Functions WMI Column info --------------------- */ /***********************************************************************/ diff --git a/storage/connect/tabwmi.h b/storage/connect/tabwmi.h index 6f25c0de258..6abb85453a1 100644 --- a/storage/connect/tabwmi.h +++ b/storage/connect/tabwmi.h @@ -1,151 +1,151 @@ -// TABWMI.H Olivier Bertrand 2012
-// WMI: Virtual table to Get WMI information
-#define _WIN32_DCOM
-#include <wbemidl.h>
-# pragma comment(lib, "wbemuuid.lib")
-#include <iostream>
-using namespace std;
-#include <comdef.h>
-
-/***********************************************************************/
-/* Definitions. */
-/***********************************************************************/
-typedef class WMIDEF *PWMIDEF;
-typedef class TDBWMI *PTDBWMI;
-typedef class WMICOL *PWMICOL;
-typedef class TDBWCL *PTDBWCL;
-typedef class WCLCOL *PWCLCOL;
-
-/***********************************************************************/
-/* Structure used by WMI column info functions. */
-/***********************************************************************/
-typedef struct _WMIutil {
- IWbemServices *Svc;
- IWbemClassObject *Cobj;
-} WMIUTIL, *PWMIUT;
-
-/***********************************************************************/
-/* Functions used externally. */
-/***********************************************************************/
-PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *cls, bool info);
-
-/* -------------------------- WMI classes ---------------------------- */
-
-/***********************************************************************/
-/* WMI: Virtual table to get the WMI information. */
-/***********************************************************************/
-class WMIDEF : public TABDEF { /* Logical table description */
- friend class TDBWMI;
- friend class TDBWCL;
- friend class TDBWCX;
- public:
- // Constructor
- WMIDEF(void) {Pseudo = 3; Nspace = NULL; Wclass = NULL; Ems = 0;}
-
- // Implementation
- virtual const char *GetType(void) {return "WMI";}
-
- // Methods
- virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
- virtual PTDB GetTable(PGLOBAL g, MODE m);
-
- protected:
- // Members
- char *Nspace;
- char *Wclass;
- int Ems;
- }; // end of WMIDEF
-
-/***********************************************************************/
-/* This is the class declaration for the WMI table. */
-/***********************************************************************/
-class TDBWMI : public TDBASE {
- friend class WMICOL;
- public:
- // Constructor
- TDBWMI(PWMIDEF tdp);
-
- // Implementation
- virtual AMT GetAmType(void) {return TYPE_AM_WMI;}
-
- // Methods
- virtual int GetRecpos(void);
- virtual int GetProgCur(void) {return N;}
- virtual int RowNumber(PGLOBAL g, bool b = false) {return N + 1;}
-
- // Database routines
- virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
+// TABWMI.H Olivier Bertrand 2012 +// WMI: Virtual table to Get WMI information +#define _WIN32_DCOM +#include <wbemidl.h> +# pragma comment(lib, "wbemuuid.lib") +#include <iostream> +using namespace std; +#include <comdef.h> + +/***********************************************************************/ +/* Definitions. */ +/***********************************************************************/ +typedef class WMIDEF *PWMIDEF; +typedef class TDBWMI *PTDBWMI; +typedef class WMICOL *PWMICOL; +typedef class TDBWCL *PTDBWCL; +typedef class WCLCOL *PWCLCOL; + +/***********************************************************************/ +/* Structure used by WMI column info functions. */ +/***********************************************************************/ +typedef struct _WMIutil { + IWbemServices *Svc; + IWbemClassObject *Cobj; +} WMIUTIL, *PWMIUT; + +/***********************************************************************/ +/* Functions used externally. */ +/***********************************************************************/ +PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *cls, bool info); + +/* -------------------------- WMI classes ---------------------------- */ + +/***********************************************************************/ +/* WMI: Virtual table to get the WMI information. */ +/***********************************************************************/ +class WMIDEF : public TABDEF { /* Logical table description */ + friend class TDBWMI; + friend class TDBWCL; + friend class TDBWCX; + public: + // Constructor + WMIDEF(void) {Pseudo = 3; Nspace = NULL; Wclass = NULL; Ems = 0;} + + // Implementation + virtual const char *GetType(void) {return "WMI";} + + // Methods + virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); + virtual PTDB GetTable(PGLOBAL g, MODE m); + + protected: + // Members + char *Nspace; + char *Wclass; + int Ems; + }; // end of WMIDEF + +/***********************************************************************/ +/* This is the class declaration for the WMI table. */ +/***********************************************************************/ +class TDBWMI : public TDBASE { + friend class WMICOL; + public: + // Constructor + TDBWMI(PWMIDEF tdp); + + // Implementation + virtual AMT GetAmType(void) {return TYPE_AM_WMI;} + + // Methods + virtual int GetRecpos(void); + virtual int GetProgCur(void) {return N;} + virtual int RowNumber(PGLOBAL g, bool b = false) {return N + 1;} + + // Database routines + virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); virtual int Cardinality(PGLOBAL g) {return GetMaxSize(g);} - virtual int GetMaxSize(PGLOBAL g);
- virtual bool OpenDB(PGLOBAL g);
- virtual int ReadDB(PGLOBAL g);
- virtual int WriteDB(PGLOBAL g);
- virtual int DeleteDB(PGLOBAL g, int irc);
- virtual void CloseDB(PGLOBAL g);
-
- protected:
- // Specific routines
- bool Initialize(PGLOBAL g);
- char *MakeWQL(PGLOBAL g);
- void DoubleSlash(PGLOBAL g);
- bool GetWMIInfo(PGLOBAL g);
-
- // Members
- IWbemServices *Svc; // IWbemServices pointer
- IEnumWbemClassObject *Enumerator;
- IWbemClassObject *ClsObj;
- char *Nspace; // Namespace
- char *Wclass; // Class name
- char *ObjPath; // Used for direct access
- char *Kvp; // Itou
- int Ems; // Estimated max size
- PCOL Kcol; // Key column
- HRESULT Res;
- PVBLK Vbp;
- bool Init;
- bool Done;
- ULONG Rc;
- int N; // Row number
- }; // end of class TDBWMI
-
-/***********************************************************************/
-/* Class WMICOL: WMI Address column. */
-/***********************************************************************/
-class WMICOL : public COLBLK {
- friend class TDBWMI;
- public:
- // Constructors
- WMICOL(PCOLDEF cdp, PTDB tdbp, int n);
-
- // Implementation
- virtual int GetAmType(void) {return TYPE_AM_WMI;}
-
- // Methods
- virtual void ReadColumn(PGLOBAL g);
-
- protected:
- WMICOL(void) {} // Default constructor not to be used
-
- // Members
- PTDBWMI Tdbp; // Points to WMI table block
- VARIANT Prop; // Property value
- CIMTYPE Ctype; // CIM Type
- HRESULT Res;
- }; // end of class WMICOL
-
-/***********************************************************************/
-/* This is the class declaration for the WMI catalog table. */
-/***********************************************************************/
-class TDBWCL : public TDBCAT {
- public:
- // Constructor
- TDBWCL(PWMIDEF tdp);
-
- protected:
- // Specific routines
- virtual PQRYRES GetResult(PGLOBAL g);
-
- // Members
- char *Nsp; // Name space
- char *Cls; // Class
- }; // end of class TDBWCL
+ virtual int GetMaxSize(PGLOBAL g); + virtual bool OpenDB(PGLOBAL g); + virtual int ReadDB(PGLOBAL g); + virtual int WriteDB(PGLOBAL g); + virtual int DeleteDB(PGLOBAL g, int irc); + virtual void CloseDB(PGLOBAL g); + + protected: + // Specific routines + bool Initialize(PGLOBAL g); + char *MakeWQL(PGLOBAL g); + void DoubleSlash(PGLOBAL g); + bool GetWMIInfo(PGLOBAL g); + + // Members + IWbemServices *Svc; // IWbemServices pointer + IEnumWbemClassObject *Enumerator; + IWbemClassObject *ClsObj; + char *Nspace; // Namespace + char *Wclass; // Class name + char *ObjPath; // Used for direct access + char *Kvp; // Itou + int Ems; // Estimated max size + PCOL Kcol; // Key column + HRESULT Res; + PVBLK Vbp; + bool Init; + bool Done; + ULONG Rc; + int N; // Row number + }; // end of class TDBWMI + +/***********************************************************************/ +/* Class WMICOL: WMI Address column. */ +/***********************************************************************/ +class WMICOL : public COLBLK { + friend class TDBWMI; + public: + // Constructors + WMICOL(PCOLDEF cdp, PTDB tdbp, int n); + + // Implementation + virtual int GetAmType(void) {return TYPE_AM_WMI;} + + // Methods + virtual void ReadColumn(PGLOBAL g); + + protected: + WMICOL(void) {} // Default constructor not to be used + + // Members + PTDBWMI Tdbp; // Points to WMI table block + VARIANT Prop; // Property value + CIMTYPE Ctype; // CIM Type + HRESULT Res; + }; // end of class WMICOL + +/***********************************************************************/ +/* This is the class declaration for the WMI catalog table. */ +/***********************************************************************/ +class TDBWCL : public TDBCAT { + public: + // Constructor + TDBWCL(PWMIDEF tdp); + + protected: + // Specific routines + virtual PQRYRES GetResult(PGLOBAL g); + + // Members + char *Nsp; // Name space + char *Cls; // Class + }; // end of class TDBWCL diff --git a/storage/connect/tabxcl.cpp b/storage/connect/tabxcl.cpp index 66e2577056a..6cf17c38820 100644 --- a/storage/connect/tabxcl.cpp +++ b/storage/connect/tabxcl.cpp @@ -57,8 +57,6 @@ #include "ha_connect.h" #include "mycat.h" -extern "C" int trace; - /* -------------- Implementation of the XCOL classes ---------------- */ /***********************************************************************/ diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp index 76e4b111bda..8c73907c7ee 100644 --- a/storage/connect/tabxml.cpp +++ b/storage/connect/tabxml.cpp @@ -49,10 +49,7 @@ #include "tabxml.h" #include "tabmul.h" -extern "C" { -extern char version[]; -extern int trace; -} // "C" +extern "C" char version[]; #if defined(WIN32) && defined(DOMDOC_SUPPORT) #define XMLSUP "MS-DOM" diff --git a/storage/connect/user_connect.cc b/storage/connect/user_connect.cc index b5f835c9cc9..557b94d8347 100644 --- a/storage/connect/user_connect.cc +++ b/storage/connect/user_connect.cc @@ -47,7 +47,6 @@ #include "user_connect.h" #include "mycat.h" -extern "C" int trace; extern uint worksize; /****************************************************************************/ diff --git a/storage/connect/valblk.cpp b/storage/connect/valblk.cpp index 3827deec43d..df7011583cd 100644 --- a/storage/connect/valblk.cpp +++ b/storage/connect/valblk.cpp @@ -43,7 +43,6 @@ #define CheckBlanks assert(!Blanks); #define CheckParms(V, N) ChkIndx(N); ChkTyp(V); -extern "C" int trace; extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */ /***********************************************************************/ diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp index 41e425d54e2..81d00862703 100644 --- a/storage/connect/value.cpp +++ b/storage/connect/value.cpp @@ -48,7 +48,6 @@ #include "global.h" #include "plgdbsem.h" #include "preparse.h" // For DATPAR -//#include "value.h" #include "valblk.h" #define NO_FUNC // Already defined in ODBConn #include "plgcnx.h" // For DB types @@ -69,12 +68,6 @@ #define FOURYEARS 126230400 // Four years in seconds (1 leap) /***********************************************************************/ -/* Static variables. */ -/***********************************************************************/ - -extern "C" int trace; - -/***********************************************************************/ /* Initialize the DTVAL static member. */ /***********************************************************************/ int DTVAL::Shift = 0; @@ -1019,8 +1012,11 @@ TYPVAL<PSZ>::TYPVAL(PGLOBAL g, PSZ s, int n, int c) if (!s) { if (g) { - Strp = (char *)PlugSubAlloc(g, NULL, Len + 1); - Strp[Len] = '\0'; + if ((Strp = (char *)PlgDBSubAlloc(g, NULL, Len + 1))) + Strp[Len] = '\0'; + else + Len = 0; + } else assert(false); diff --git a/storage/connect/value.h b/storage/connect/value.h index 295fa11107a..3ce7027aeeb 100644 --- a/storage/connect/value.h +++ b/storage/connect/value.h @@ -256,6 +256,7 @@ class DllExport TYPVAL<PSZ>: public VALUE { virtual bool FormatValue(PVAL vp, char *fmt); virtual bool SetConstFormat(PGLOBAL, FORMAT&); + protected: // Members PSZ Strp; bool Ci; // true if case insensitive @@ -283,6 +284,7 @@ class DllExport DECVAL: public TYPVAL<PSZ> { virtual bool IsEqual(PVAL vp, bool chktype); virtual int CompareValue(PVAL vp); + protected: // Members }; // end of class DECVAL @@ -337,6 +339,7 @@ class DllExport BINVAL: public VALUE { virtual bool FormatValue(PVAL vp, char *fmt); virtual bool SetConstFormat(PGLOBAL, FORMAT&); + protected: // Members void *Binp; char *Chrp; diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp index 7cc52580760..f87ba8e035a 100755 --- a/storage/connect/xindex.cpp +++ b/storage/connect/xindex.cpp @@ -58,10 +58,9 @@ #endif /***********************************************************************/ -/* DB static external variables. */ +/* DB external variables. */ /***********************************************************************/ extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */ -extern "C" int trace; #if defined(XMAP) extern bool xmap; #endif // XMAP diff --git a/storage/connect/xobject.cpp b/storage/connect/xobject.cpp index cdc2ef9bf62..202ee4adb12 100644 --- a/storage/connect/xobject.cpp +++ b/storage/connect/xobject.cpp @@ -1,186 +1,371 @@ -/************ Xobject C++ Functions Source Code File (.CPP) ************/
-/* Name: XOBJECT.CPP Version 2.3 */
-/* */
-/* (C) Copyright to the author Olivier BERTRAND 1998-2014 */
-/* */
-/* This file contains base XOBJECT class functions. */
-/* Also here is the implementation of the CONSTANT class. */
-/***********************************************************************/
-
-/***********************************************************************/
-/* Include mariaDB header file. */
-/***********************************************************************/
-#include "my_global.h"
-
-/***********************************************************************/
-/* Include required application header files */
-/* global.h is header containing all global Plug declarations. */
-/* plgdbsem.h is header containing the DB applic. declarations. */
-/***********************************************************************/
-#include "global.h"
-#include "plgdbsem.h"
-#include "xobject.h"
-
-/***********************************************************************/
-/* Macro definitions. */
-/***********************************************************************/
-#if defined(_DEBUG) || defined(DEBTRACE)
-#define ASSERT(B) assert(B);
-#else
-#define ASSERT(B)
-#endif
-
-/***********************************************************************/
-/* The one and only needed void object. */
-/***********************************************************************/
-XVOID Xvoid;
-PXOB const pXVOID = &Xvoid; // Pointer used by other classes
-
-/* ------------------------- Class XOBJECT --------------------------- */
-
-/***********************************************************************/
-/* GetCharValue: returns the Result value as a char string. */
-/* Using GetCharValue provides no conversion from numeric types. */
-/***********************************************************************/
-PSZ XOBJECT::GetCharValue(void)
- {
- ASSERT(Value)
- return Value->GetCharValue();
- } // end of GetCharValue()
-
-/***********************************************************************/
-/* GetShortValue: returns the Result value as a short integer. */
-/***********************************************************************/
-short XOBJECT::GetShortValue(void)
- {
- ASSERT(Value)
- return Value->GetShortValue();
- } // end of GetShortValue
-
-/***********************************************************************/
-/* GetIntValue: returns the Result value as a int integer. */
-/***********************************************************************/
-int XOBJECT::GetIntValue(void)
- {
- ASSERT(Value)
- return Value->GetIntValue();
- } // end of GetIntValue
-
-/***********************************************************************/
-/* GetFloatValue: returns the Result value as a double float. */
-/***********************************************************************/
-double XOBJECT::GetFloatValue(void)
- {
- ASSERT(Value)
- return Value->GetFloatValue();
- } // end of GetFloatValue
-
-/* ------------------------- Class CONSTANT -------------------------- */
-
-/***********************************************************************/
-/* CONSTANT public constructor. */
-/***********************************************************************/
-CONSTANT::CONSTANT(PGLOBAL g, void *value, short type)
- {
- if (!(Value = AllocateValue(g, value, (int)type)))
- longjmp(g->jumper[g->jump_level], TYPE_CONST);
-
- Constant = true;
- } // end of CONSTANT constructor
-
-/***********************************************************************/
-/* CONSTANT public constructor. */
-/***********************************************************************/
-CONSTANT::CONSTANT(PGLOBAL g, int n)
- {
- if (!(Value = AllocateValue(g, &n, TYPE_INT)))
- longjmp(g->jumper[g->jump_level], TYPE_CONST);
-
- Constant = true;
- } // end of CONSTANT constructor
-
-/***********************************************************************/
-/* GetLengthEx: returns an evaluation of the constant string length. */
-/* Note: When converting from token to string, length has to be */
-/* specified but we need the domain length, not the value length. */
-/***********************************************************************/
-int CONSTANT::GetLengthEx(void)
- {
- return Value->GetValLen();
- } // end of GetLengthEx
-
-/***********************************************************************/
-/* Convert a constant to the given type. */
-/***********************************************************************/
-void CONSTANT::Convert(PGLOBAL g, int newtype)
- {
- if (Value->GetType() != newtype)
- if (!(Value = AllocateValue(g, Value, newtype)))
- longjmp(g->jumper[g->jump_level], TYPE_CONST);
-
- } // end of Convert
-
-/***********************************************************************/
-/* Compare: returns true if this object is equivalent to xp. */
-/***********************************************************************/
-bool CONSTANT::Compare(PXOB xp)
- {
- if (this == xp)
- return true;
- else if (xp->GetType() != TYPE_CONST)
- return false;
- else
- return Value->IsEqual(xp->GetValue(), true);
-
- } // end of Compare
-
-#if 0
-/***********************************************************************/
-/* Rephrase: temporary implementation used by PlugRephraseSQL. */
-/***********************************************************************/
-bool CONSTANT::Rephrase(PGLOBAL g, PSZ work)
- {
- switch (Value->GetType()) {
- case TYPE_STRING:
- sprintf(work + strlen(work), "'%s'", Value->GetCharValue());
- break;
- case TYPE_SHORT:
- sprintf(work + strlen(work), "%hd", Value->GetShortValue());
- break;
- case TYPE_INT:
- case TYPE_DATE:
- sprintf(work + strlen(work), "%d", Value->GetIntValue());
- break;
- case TYPE_DOUBLE:
- sprintf(work + strlen(work), "%lf", Value->GetFloatValue());
- break;
- case TYPE_BIGINT:
- sprintf(work + strlen(work), "%lld", Value->GetBigintValue());
- break;
- case TYPE_TINY:
- sprintf(work + strlen(work), "%d", Value->GetTinyValue());
- break;
- default:
- sprintf(g->Message, MSG(BAD_CONST_TYPE), Value->GetType());
- return false;
- } // endswitch
-
- return false;
- } // end of Rephrase
-#endif // 0
-
-/***********************************************************************/
-/* Make file output of a constant object. */
-/***********************************************************************/
-void CONSTANT::Print(PGLOBAL g, FILE *f, uint n)
- {
- Value->Print(g, f, n);
- } /* end of Print */
-
-/***********************************************************************/
-/* Make string output of a constant object. */
-/***********************************************************************/
-void CONSTANT::Print(PGLOBAL g, char *ps, uint z)
- {
- Value->Print(g, ps, z);
- } /* end of Print */
+/************ Xobject C++ Functions Source Code File (.CPP) ************/ +/* Name: XOBJECT.CPP Version 2.4 */ +/* */ +/* (C) Copyright to the author Olivier BERTRAND 1998-2014 */ +/* */ +/* This file contains base XOBJECT class functions. */ +/* Also here is the implementation of the CONSTANT class. */ +/***********************************************************************/ + +/***********************************************************************/ +/* Include mariaDB header file. */ +/***********************************************************************/ +#include "my_global.h" + +/***********************************************************************/ +/* Include required application header files */ +/* global.h is header containing all global Plug declarations. */ +/* plgdbsem.h is header containing the DB applic. declarations. */ +/***********************************************************************/ +#include "global.h" +#include "plgdbsem.h" +#include "xobject.h" + +/***********************************************************************/ +/* Macro definitions. */ +/***********************************************************************/ +#if defined(_DEBUG) || defined(DEBTRACE) +#define ASSERT(B) assert(B); +#else +#define ASSERT(B) +#endif + +/***********************************************************************/ +/* The one and only needed void object. */ +/***********************************************************************/ +XVOID Xvoid; +PXOB const pXVOID = &Xvoid; // Pointer used by other classes + +/* ------------------------- Class XOBJECT --------------------------- */ + +/***********************************************************************/ +/* GetCharValue: returns the Result value as a char string. */ +/* Using GetCharValue provides no conversion from numeric types. */ +/***********************************************************************/ +PSZ XOBJECT::GetCharValue(void) + { + ASSERT(Value) + return Value->GetCharValue(); + } // end of GetCharValue() + +/***********************************************************************/ +/* GetShortValue: returns the Result value as a short integer. */ +/***********************************************************************/ +short XOBJECT::GetShortValue(void) + { + ASSERT(Value) + return Value->GetShortValue(); + } // end of GetShortValue + +/***********************************************************************/ +/* GetIntValue: returns the Result value as a int integer. */ +/***********************************************************************/ +int XOBJECT::GetIntValue(void) + { + ASSERT(Value) + return Value->GetIntValue(); + } // end of GetIntValue + +/***********************************************************************/ +/* GetFloatValue: returns the Result value as a double float. */ +/***********************************************************************/ +double XOBJECT::GetFloatValue(void) + { + ASSERT(Value) + return Value->GetFloatValue(); + } // end of GetFloatValue + +/* ------------------------- Class CONSTANT -------------------------- */ + +/***********************************************************************/ +/* CONSTANT public constructor. */ +/***********************************************************************/ +CONSTANT::CONSTANT(PGLOBAL g, void *value, short type) + { + if (!(Value = AllocateValue(g, value, (int)type))) + longjmp(g->jumper[g->jump_level], TYPE_CONST); + + Constant = true; + } // end of CONSTANT constructor + +/***********************************************************************/ +/* CONSTANT public constructor. */ +/***********************************************************************/ +CONSTANT::CONSTANT(PGLOBAL g, int n) + { + if (!(Value = AllocateValue(g, &n, TYPE_INT))) + longjmp(g->jumper[g->jump_level], TYPE_CONST); + + Constant = true; + } // end of CONSTANT constructor + +/***********************************************************************/ +/* GetLengthEx: returns an evaluation of the constant string length. */ +/* Note: When converting from token to string, length has to be */ +/* specified but we need the domain length, not the value length. */ +/***********************************************************************/ +int CONSTANT::GetLengthEx(void) + { + return Value->GetValLen(); + } // end of GetLengthEx + +/***********************************************************************/ +/* Convert a constant to the given type. */ +/***********************************************************************/ +void CONSTANT::Convert(PGLOBAL g, int newtype) + { + if (Value->GetType() != newtype) + if (!(Value = AllocateValue(g, Value, newtype))) + longjmp(g->jumper[g->jump_level], TYPE_CONST); + + } // end of Convert + +/***********************************************************************/ +/* Compare: returns true if this object is equivalent to xp. */ +/***********************************************************************/ +bool CONSTANT::Compare(PXOB xp) + { + if (this == xp) + return true; + else if (xp->GetType() != TYPE_CONST) + return false; + else + return Value->IsEqual(xp->GetValue(), true); + + } // end of Compare + +#if 0 +/***********************************************************************/ +/* Rephrase: temporary implementation used by PlugRephraseSQL. */ +/***********************************************************************/ +bool CONSTANT::Rephrase(PGLOBAL g, PSZ work) + { + switch (Value->GetType()) { + case TYPE_STRING: + sprintf(work + strlen(work), "'%s'", Value->GetCharValue()); + break; + case TYPE_SHORT: + sprintf(work + strlen(work), "%hd", Value->GetShortValue()); + break; + case TYPE_INT: + case TYPE_DATE: + sprintf(work + strlen(work), "%d", Value->GetIntValue()); + break; + case TYPE_DOUBLE: + sprintf(work + strlen(work), "%lf", Value->GetFloatValue()); + break; + case TYPE_BIGINT: + sprintf(work + strlen(work), "%lld", Value->GetBigintValue()); + break; + case TYPE_TINY: + sprintf(work + strlen(work), "%d", Value->GetTinyValue()); + break; + default: + sprintf(g->Message, MSG(BAD_CONST_TYPE), Value->GetType()); + return false; + } // endswitch + + return false; + } // end of Rephrase +#endif // 0 + +/***********************************************************************/ +/* Make file output of a constant object. */ +/***********************************************************************/ +void CONSTANT::Print(PGLOBAL g, FILE *f, uint n) + { + Value->Print(g, f, n); + } /* end of Print */ + +/***********************************************************************/ +/* Make string output of a constant object. */ +/***********************************************************************/ +void CONSTANT::Print(PGLOBAL g, char *ps, uint z) + { + Value->Print(g, ps, z); + } /* end of Print */ + +/* -------------------------- Class STRING --------------------------- */ + +/***********************************************************************/ +/* STRING public constructor for new char values. Alloc Size must be */ +/* calculated because PlugSubAlloc rounds up size to multiple of 8. */ +/***********************************************************************/ +STRING::STRING(PGLOBAL g, uint n, char *str) +{ + G = g; + Length = (str) ? strlen(str) : 0; + + if ((Strp = (PSZ)PlgDBSubAlloc(g, NULL, MY_MAX(n, Length) + 1))) { + if (str) + strcpy(Strp, str); + else + *Strp = 0; + + Next = GetNext(); + Size = Next - Strp; + } else { + // This should normally never happen + Next = NULL; + Size = 0; + } // endif Strp + +} // end of STRING constructor + +/***********************************************************************/ +/* Reallocate the string memory and return the (new) position. */ +/* If Next is equal to GetNext() this means that no new suballocation */ +/* has been done. Then we can just increase the size of the current */ +/* allocation and the Strp will remain pointing to the same memory. */ +/***********************************************************************/ +char *STRING::Realloc(uint len) +{ + char *p; + bool b = (Next == GetNext()); + + p = (char*)PlgDBSubAlloc(G, NULL, b ? len - Size : len); + + if (!p) { + // No more room in Sarea; this is very unlikely + strcpy(G->Message, "No more room in work area"); + return NULL; + } // endif p + + if (b) + p = Strp; + + Next = GetNext(); + Size = Next - p; + return p; +} // end of Realloc + +/***********************************************************************/ +/* Set a STRING new PSZ value. */ +/***********************************************************************/ +bool STRING::Set(PSZ s) +{ + if (!s) + return false; + + uint len = strlen(s) + 1; + + if (len > Size) { + char *p = Realloc(len); + + if (!p) + return true; + else + Strp = p; + + } // endif n + + strcpy(Strp, s); + Length = len - 1; + return false; +} // end of Set + +/***********************************************************************/ +/* Set a STRING new PSZ value. */ +/***********************************************************************/ +bool STRING::Set(char *s, uint n) +{ + if (!s) + return false; + + uint len = MY_MIN(strlen(s), n) + 1; + + if (len > Size) { + char *p = Realloc(len); + + if (!p) + return true; + else + Strp = p; + + } // endif n + + strncpy(Strp, s, n); + Length = len - 1; + return false; +} // end of Set + +/***********************************************************************/ +/* Append a PSZ to a STRING. */ +/***********************************************************************/ +bool STRING::Append(PSZ s) +{ + if (!s) + return false; + + uint len = Length + strlen(s) + 1; + + if (len > Size) { + char *p = Realloc(len); + + if (!p) + return true; + else if (p != Strp) { + strcpy(p, Strp); + Strp = p; + } // endif p + + } // endif n + + strcpy(Strp + Length, s); + Length = len - 1; + return false; +} // end of Append + +/***********************************************************************/ +/* Append a STRING to a STRING. */ +/***********************************************************************/ +bool STRING::Append(STRING &str) +{ + return Append(str.GetStr()); +} // end of Append + +/***********************************************************************/ +/* Append a char to a STRING. */ +/***********************************************************************/ +bool STRING::Append(char c) +{ + if (Length + 2 > Size) { + char *p = Realloc(Length + 2); + + if (!p) + return true; + else if (p != Strp) { + strcpy(p, Strp); + Strp = p; + } // endif p + + } // endif n + + Strp[Length++] = c; + Strp[Length] = 0; + return false; +} // end of Append + +/***********************************************************************/ +/* Resize to given length but only when last suballocated. */ +/* New size should be greater than string length. */ +/***********************************************************************/ +bool STRING::Resize(uint newsize) +{ + if (Next == GetNext() && newsize > Length) { + uint nsz = (((signed)newsize + 7) / 8) * 8; + int diff = (signed)Size - (signed)nsz; + PPOOLHEADER pp = (PPOOLHEADER)G->Sarea; + + if ((signed)pp->FreeBlk + diff < 0) + return true; // Out of memory + + pp->To_Free -= diff; + pp->FreeBlk += diff; + Size = nsz; + return false; + } else + return newsize > Size; + +} // end of Resize + diff --git a/storage/connect/xobject.h b/storage/connect/xobject.h index 1621b4e82ff..4624e962c38 100644 --- a/storage/connect/xobject.h +++ b/storage/connect/xobject.h @@ -1,119 +1,160 @@ -/*************** Xobject H Declares Source Code File (.H) **************/
-/* Name: XOBJECT.H Version 2.4 */
-/* */
-/* (C) Copyright to the author Olivier BERTRAND 1998-2014 */
-/* */
-/* This file contains the XOBJECT and derived classes declares. */
-/***********************************************************************/
-
-#ifndef __XOBJECT__H
-#define __XOBJECT__H
-
-/***********************************************************************/
-/* Include required application header files */
-/* block.h is header containing Block global declarations. */
-/***********************************************************************/
-#include "block.h"
-#include "valblk.h" // includes value.h
-
-/***********************************************************************/
-/* Types used in some class definitions. */
-/***********************************************************************/
-//typedef struct _tabdesc *PTABD; // For friend setting
-
-/***********************************************************************/
-/* The pointer to the one and only needed void object. */
-/***********************************************************************/
-extern PXOB const pXVOID;
-
-/***********************************************************************/
-/* Class XOBJECT is the base class for all classes that can be used */
-/* in evaluation operations: FILTER, EXPRESSION, SCALF, FNC, COLBLK, */
-/* SELECT, FILTER as well as all the constant object types. */
-/***********************************************************************/
-class DllExport XOBJECT : public BLOCK {
- public:
- XOBJECT(void) {Value = NULL; Constant = false;}
-
- // Implementation
- PVAL GetValue(void) {return Value;}
- bool IsConstant(void) {return Constant;}
- virtual int GetType(void) {return TYPE_XOBJECT;}
- virtual int GetResultType(void) {return TYPE_VOID;}
- virtual int GetKey(void) {return 0;}
-#if defined(_DEBUG)
- virtual void SetKey(int k) {assert(false);}
-#else // !_DEBUG
- virtual void SetKey(int k) {} // Only defined for COLBLK
-#endif // !_DEBUG
- virtual int GetLength(void) = 0;
- virtual int GetLengthEx(void) = 0;
- virtual PSZ GetCharValue(void);
- virtual short GetShortValue(void);
- virtual int GetIntValue(void);
- virtual double GetFloatValue(void);
- virtual int GetScale(void) = 0;
-
- // Methods
- virtual void Reset(void) {}
- virtual bool Compare(PXOB) = 0;
- virtual bool Init(PGLOBAL) {return false;}
- virtual bool Eval(PGLOBAL) {return false;}
- virtual bool SetFormat(PGLOBAL, FORMAT&) = 0;
-
- protected:
- PVAL Value; // The current value of the object.
- bool Constant; // true for an object having a constant value.
- }; // end of class XOBJECT
-
-/***********************************************************************/
-/* Class XVOID: represent a void (null) object. */
-/* Used to represent a void parameter for count(*) or for a filter. */
-/***********************************************************************/
-class DllExport XVOID : public XOBJECT {
- public:
- XVOID(void) {Constant = true;}
-
- // Implementation
- virtual int GetType(void) {return TYPE_VOID;}
- virtual int GetLength(void) {return 0;}
- virtual int GetLengthEx(void) {return 0;}
- virtual PSZ GetCharValue(void) {return NULL;}
- virtual int GetIntValue(void) {return 0;}
- virtual double GetFloatValue(void) {return 0.0;}
- virtual int GetScale() {return 0;}
-
- // Methods
- virtual bool Compare(PXOB xp) {return xp->GetType() == TYPE_VOID;}
- virtual bool SetFormat(PGLOBAL, FORMAT&) {return true;}
- }; // end of class XVOID
-
-
-/***********************************************************************/
-/* Class CONSTANT: represents a constant XOBJECT of any value type. */
-/* Note that the CONSTANT class is a friend of the VALUE class; */
-/***********************************************************************/
-class DllExport CONSTANT : public XOBJECT {
- public:
- CONSTANT(PGLOBAL g, void *value, short type);
- CONSTANT(PGLOBAL g, int n);
- CONSTANT(PVAL valp) {Value = valp; Constant = true;}
-
- // Implementation
- virtual int GetType(void) {return TYPE_CONST;}
- virtual int GetResultType(void) {return Value->Type;}
- virtual int GetLength(void) {return Value->GetValLen();}
- virtual int GetScale() {return Value->GetValPrec();}
- virtual int GetLengthEx(void);
-
- // Methods
- virtual bool Compare(PXOB xp);
- virtual bool SetFormat(PGLOBAL g, FORMAT& fmt)
- {return Value->SetConstFormat(g, fmt);}
- void Convert(PGLOBAL g, int newtype);
- void SetValue(PVAL vp) {Value = vp;}
- virtual void Print(PGLOBAL g, FILE *, uint);
- virtual void Print(PGLOBAL g, char *, uint);
- }; // end of class CONSTANT
-
-#endif
+/*************** Xobject H Declares Source Code File (.H) **************/ +/* Name: XOBJECT.H Version 2.4 */ +/* */ +/* (C) Copyright to the author Olivier BERTRAND 1998-2014 */ +/* */ +/* This file contains the XOBJECT and derived classes declares. */ +/***********************************************************************/ + +#ifndef __XOBJECT__H +#define __XOBJECT__H + +/***********************************************************************/ +/* Include required application header files */ +/* block.h is header containing Block global declarations. */ +/***********************************************************************/ +#include "block.h" +#include "valblk.h" // includes value.h + +/***********************************************************************/ +/* Types used in some class definitions. */ +/***********************************************************************/ +typedef class STRING *PSTRG; + +/***********************************************************************/ +/* The pointer to the one and only needed void object. */ +/***********************************************************************/ +extern PXOB const pXVOID; + +/***********************************************************************/ +/* Class XOBJECT is the base class for all classes that can be used */ +/* in evaluation operations: FILTER, EXPRESSION, SCALF, FNC, COLBLK, */ +/* SELECT, FILTER as well as all the constant object types. */ +/***********************************************************************/ +class DllExport XOBJECT : public BLOCK { + public: + XOBJECT(void) {Value = NULL; Constant = false;} + + // Implementation + PVAL GetValue(void) {return Value;} + bool IsConstant(void) {return Constant;} + virtual int GetType(void) {return TYPE_XOBJECT;} + virtual int GetResultType(void) {return TYPE_VOID;} + virtual int GetKey(void) {return 0;} +#if defined(_DEBUG) + virtual void SetKey(int k) {assert(false);} +#else // !_DEBUG + virtual void SetKey(int k) {} // Only defined for COLBLK +#endif // !_DEBUG + virtual int GetLength(void) = 0; + virtual int GetLengthEx(void) = 0; + virtual PSZ GetCharValue(void); + virtual short GetShortValue(void); + virtual int GetIntValue(void); + virtual double GetFloatValue(void); + virtual int GetScale(void) = 0; + + // Methods + virtual void Reset(void) {} + virtual bool Compare(PXOB) = 0; + virtual bool Init(PGLOBAL) {return false;} + virtual bool Eval(PGLOBAL) {return false;} + virtual bool SetFormat(PGLOBAL, FORMAT&) = 0; + + protected: + PVAL Value; // The current value of the object. + bool Constant; // true for an object having a constant value. + }; // end of class XOBJECT + +/***********************************************************************/ +/* Class XVOID: represent a void (null) object. */ +/* Used to represent a void parameter for count(*) or for a filter. */ +/***********************************************************************/ +class DllExport XVOID : public XOBJECT { + public: + XVOID(void) {Constant = true;} + + // Implementation + virtual int GetType(void) {return TYPE_VOID;} + virtual int GetLength(void) {return 0;} + virtual int GetLengthEx(void) {return 0;} + virtual PSZ GetCharValue(void) {return NULL;} + virtual int GetIntValue(void) {return 0;} + virtual double GetFloatValue(void) {return 0.0;} + virtual int GetScale() {return 0;} + + // Methods + virtual bool Compare(PXOB xp) {return xp->GetType() == TYPE_VOID;} + virtual bool SetFormat(PGLOBAL, FORMAT&) {return true;} + }; // end of class XVOID + + +/***********************************************************************/ +/* Class CONSTANT: represents a constant XOBJECT of any value type. */ +/* Note that the CONSTANT class is a friend of the VALUE class; */ +/***********************************************************************/ +class DllExport CONSTANT : public XOBJECT { + public: + CONSTANT(PGLOBAL g, void *value, short type); + CONSTANT(PGLOBAL g, int n); + CONSTANT(PVAL valp) {Value = valp; Constant = true;} + + // Implementation + virtual int GetType(void) {return TYPE_CONST;} + virtual int GetResultType(void) {return Value->Type;} + virtual int GetLength(void) {return Value->GetValLen();} + virtual int GetScale() {return Value->GetValPrec();} + virtual int GetLengthEx(void); + + // Methods + virtual bool Compare(PXOB xp); + virtual bool SetFormat(PGLOBAL g, FORMAT& fmt) + {return Value->SetConstFormat(g, fmt);} + void Convert(PGLOBAL g, int newtype); + void SetValue(PVAL vp) {Value = vp;} + virtual void Print(PGLOBAL g, FILE *, uint); + virtual void Print(PGLOBAL g, char *, uint); + }; // end of class CONSTANT + +/***********************************************************************/ +/* Class STRING handles variable length char strings. */ +/* It is mainly used to avoid buffer overrun. */ +/***********************************************************************/ +class DllExport STRING : public BLOCK { + public: + // Constructor + STRING(PGLOBAL g, uint n, PSZ str = NULL); + + // Implementation + inline int GetLength(void) {return (int)Length;} + inline PSZ GetStr(void) {return Strp;} + inline uint32 GetSize(void) {return Size;} + + // Methods + inline void Reset(void) {*Strp = 0;} + bool Set(PSZ s); + bool Set(char *s, uint n); + bool Append(PSZ s); + bool Append(STRING &str); + bool Append(char c); + bool Resize(uint n); + inline void Trim(void) {(void)Resize(Length + 1);} + inline void Chop(void) {if (Length) Strp[--Length] = 0;} + inline void RepLast(char c) {if (Length) Strp[Length-1] = c;} + inline void Truncate(uint n) {if (n >= 0 && n < Length) + {Strp[n] = 0; Length = n;}} + + protected: + char *Realloc(uint len); + inline char *GetNext(void) + {return ((char*)G->Sarea)+((PPOOLHEADER)G->Sarea)->To_Free;} + + // Members + PGLOBAL G; // To avoid parameter + PSZ Strp; // The char string + uint Length; // String length + uint Size; // Allocated size + char *Next; // Next alloc position + }; // end of class STRING + +#endif diff --git a/storage/connect/xtable.h b/storage/connect/xtable.h index 628ab96135d..49fbbb0de26 100644 --- a/storage/connect/xtable.h +++ b/storage/connect/xtable.h @@ -83,6 +83,7 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block. // Methods virtual bool IsSame(PTDB tp) {return tp == this;} + virtual bool IsSpecial(PSZ name) = 0; virtual bool GetBlockValues(PGLOBAL g) {return false;} virtual int Cardinality(PGLOBAL g) {return 0;} virtual int GetMaxSize(PGLOBAL) = 0; @@ -158,6 +159,7 @@ class DllExport TDBASE : public TDB { // Methods virtual bool IsUsingTemp(PGLOBAL g) {return false;} virtual bool IsIndexed(void) {return false;} + virtual bool IsSpecial(PSZ name); virtual PCATLG GetCat(void); virtual PSZ GetPath(void); virtual void PrintAM(FILE *f, char *m); |