Commit 81252031 authored by Olivier Bertrand's avatar Olivier Bertrand

- Commit merged files

modified:
  storage/connect/CMakeLists.txt
  storage/connect/connect.h
  storage/connect/global.h
  storage/connect/ha_connect.cc
  storage/connect/ha_connect.h
  storage/connect/myconn.cpp
  storage/connect/myconn.h
  storage/connect/mysql-test/connect/r/pivot.result
  storage/connect/mysql-test/connect/suite.pm
  storage/connect/mysql-test/connect/t/pivot.test
  storage/connect/myutil.cpp
  storage/connect/osutil.c
  storage/connect/plgdbsem.h
  storage/connect/plugutil.c
  storage/connect/tabmysql.cpp
  storage/connect/tabpivot.cpp
  storage/connect/tabutil.cpp
  storage/connect/user_connect.cc
  storage/connect/valblk.cpp
  storage/connect/valblk.h
  storage/connect/value.cpp
  storage/connect/value.h
  storage/connect/xindex.cpp
  storage/connect/xindex.h
parents cc7a08c9 b43e82dc
...@@ -123,7 +123,7 @@ IF(WIN32) ...@@ -123,7 +123,7 @@ IF(WIN32)
# /MP option of the Microsoft compiler does not work well with COM #import # /MP option of the Microsoft compiler does not work well with COM #import
string(REPLACE "/MP" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") string(REPLACE "/MP" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
string(REPLACE "/MP" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") string(REPLACE "/MP" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
OPTION(CONNECT_WITH_MSXML "Compile CONNECT storage engine with MSXML support" ON) OPTION(CONNECT_WITH_MSXML "Compile CONNECT storage engine with MSXML support" ON)
IF(CONNECT_WITH_MSXML) IF(CONNECT_WITH_MSXML)
find_library(MSXML_LIBRARY find_library(MSXML_LIBRARY
...@@ -264,6 +264,17 @@ int main() { ...@@ -264,6 +264,17 @@ int main() {
ENDIF(UNIX) ENDIF(UNIX)
ENDIF(CONNECT_WITH_ODBC) ENDIF(CONNECT_WITH_ODBC)
#
# XMAP
#
OPTION(CONNECT_WITH_XMAP "Compile CONNECT storage engine with index file mapping support" ON)
IF(CONNECT_WITH_XMAP)
add_definitions(-DXMAP)
ENDIF(CONNECT_WITH_XMAP)
# #
# Plugin definition # Plugin definition
# #
...@@ -271,6 +282,7 @@ ENDIF(CONNECT_WITH_ODBC) ...@@ -271,6 +282,7 @@ ENDIF(CONNECT_WITH_ODBC)
MYSQL_ADD_PLUGIN(connect ${CONNECT_SOURCES} MYSQL_ADD_PLUGIN(connect ${CONNECT_SOURCES}
STORAGE_ENGINE STORAGE_ENGINE
COMPONENT connect-engine COMPONENT connect-engine
RECOMPILE_FOR_EMBEDDED
LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY} LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY}
${ODBC_LIBRARY} ${IPHLPAPI_LIBRARY}) ${ODBC_LIBRARY} ${IPHLPAPI_LIBRARY})
...@@ -36,8 +36,7 @@ bool CntRewindTable(PGLOBAL g, PTDB tdbp); ...@@ -36,8 +36,7 @@ bool CntRewindTable(PGLOBAL g, PTDB tdbp);
int CntCloseTable(PGLOBAL g, PTDB tdbp); int CntCloseTable(PGLOBAL g, PTDB tdbp);
int CntIndexInit(PGLOBAL g, PTDB tdbp, int id); int CntIndexInit(PGLOBAL g, PTDB tdbp, int id);
RCODE CntReadNext(PGLOBAL g, PTDB tdbp); RCODE CntReadNext(PGLOBAL g, PTDB tdbp);
RCODE CntIndexRead(PGLOBAL g, PTDB, OPVAL op, const void *k, int n, RCODE CntIndexRead(PGLOBAL g, PTDB, OPVAL op, const void *k, int n, bool mrr);
bool mrr = false);
RCODE CntWriteRow(PGLOBAL g, PTDB tdbp); RCODE CntWriteRow(PGLOBAL g, PTDB tdbp);
RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp); RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp);
RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all); RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all);
......
/***********************************************************************/ /***********************************************************************/
/* GLOBAL.H: Declaration file used by all CONNECT implementations. */ /* GLOBAL.H: Declaration file used by all CONNECT implementations. */
/* (C) Copyright Olivier Bertrand 1993-2012 */ /* (C) Copyright Olivier Bertrand 1993-2014 */
/***********************************************************************/ /***********************************************************************/
/***********************************************************************/ /***********************************************************************/
/* Included C-definition files common to all Plug routines */ /* Included C-definition files common to all Plug routines */
/***********************************************************************/ /***********************************************************************/
#include <string.h> /* String manipulation declares */ #include <string.h> /* String manipulation declares */
#include <stdlib.h> /* C standard library */ #include <stdlib.h> /* C standard library */
#include <ctype.h> /* C language specific types */ #include <ctype.h> /* C language specific types */
#include <stdio.h> /* FOPEN_MAX declaration */ #include <stdio.h> /* FOPEN_MAX declaration */
#include <time.h> /* time_t type declaration */ #include <time.h> /* time_t type declaration */
#include <setjmp.h> /* Long jump declarations */ #include <setjmp.h> /* Long jump declarations */
#if defined(WIN32) && !defined(NOEX) #if defined(WIN32) && !defined(NOEX)
#define DllExport __declspec( dllexport ) #define DllExport __declspec( dllexport )
#else // !WIN32 #else // !WIN32
#define DllExport #define DllExport
#endif // !WIN32 #endif // !WIN32
#if defined(DOMDOC_SUPPORT) || defined(LIBXML2_SUPPORT) #if defined(DOMDOC_SUPPORT) || defined(LIBXML2_SUPPORT)
#define XML_SUPPORT 1 #define XML_SUPPORT 1
#endif #endif
#if defined(XMSG) #if defined(XMSG)
// Definition used to read messages from message file. // Definition used to read messages from message file.
#include "msgid.h" #include "msgid.h"
#define MSG(I) PlugReadMessage(NULL, MSG_##I, #I) #define MSG(I) PlugReadMessage(NULL, MSG_##I, #I)
#define STEP(I) PlugReadMessage(g, MSG_##I, #I) #define STEP(I) PlugReadMessage(g, MSG_##I, #I)
#elif defined(NEWMSG) #elif defined(NEWMSG)
// Definition used to get messages from resource. // Definition used to get messages from resource.
#include "msgid.h" #include "msgid.h"
#define MSG(I) PlugGetMessage(NULL, MSG_##I) #define MSG(I) PlugGetMessage(NULL, MSG_##I)
#define STEP(I) PlugGetMessage(g, MSG_##I) #define STEP(I) PlugGetMessage(g, MSG_##I)
#else // !XMSG and !NEWMSG #else // !XMSG and !NEWMSG
// Definition used to replace messages ID's by their definition. // Definition used to replace messages ID's by their definition.
#include "messages.h" #include "messages.h"
#define MSG(I) MSG_##I #define MSG(I) MSG_##I
#define STEP(I) MSG_##I #define STEP(I) MSG_##I
#endif // !XMSG and !NEWMSG #endif // !XMSG and !NEWMSG
#if defined(WIN32) #if defined(WIN32)
#define CRLF 2 #define CRLF 2
#else // !WIN32 #else // !WIN32
#define CRLF 1 #define CRLF 1
#endif // !WIN32 #endif // !WIN32
/***********************************************************************/ /***********************************************************************/
/* Miscellaneous Constants */ /* Miscellaneous Constants */
/***********************************************************************/ /***********************************************************************/
#define NO_IVAL -95684275 /* Used by GetIntegerOption */ #define NO_IVAL -95684275 /* Used by GetIntegerOption */
#define VMLANG 370 /* Size of olf VM lang blocks */ #define VMLANG 370 /* Size of olf VM lang blocks */
#define MAX_JUMP 24 /* Maximum jump level number */ #define MAX_JUMP 24 /* Maximum jump level number */
#define MAX_STR 1024 /* Maximum string length */ #define MAX_STR 1024 /* Maximum string length */
#define STR_SIZE 501 /* Length of char strings. */ #define STR_SIZE 501 /* Length of char strings. */
#define STD_INPUT 0 /* Standard language input */ #define STD_INPUT 0 /* Standard language input */
#define STD_OUTPUT 1 /* Standard language output */ #define STD_OUTPUT 1 /* Standard language output */
#define ERROR_OUTPUT 2 /* Error message output */ #define ERROR_OUTPUT 2 /* Error message output */
#define DEBUG_OUTPUT 3 /* Debug info output */ #define DEBUG_OUTPUT 3 /* Debug info output */
#define PROMPT_OUTPUT 4 /* Prompt message output */ #define PROMPT_OUTPUT 4 /* Prompt message output */
#define COPY_OUTPUT 5 /* Copy of language input */ #define COPY_OUTPUT 5 /* Copy of language input */
#define STD_MSG 6 /* System message file */ #define STD_MSG 6 /* System message file */
#define DEBUG_MSG 7 /* Debug message file */ #define DEBUG_MSG 7 /* Debug message file */
#define DUMMY 0 /* Dummy file index in Ldm block */ #define DUMMY 0 /* Dummy file index in Ldm block */
#define STDIN 1 /* stdin file index in Ldm block */ #define STDIN 1 /* stdin file index in Ldm block */
#define STDOUT 2 /* stdout file index in Ldm block */ #define STDOUT 2 /* stdout file index in Ldm block */
#define STDERR 3 /* stderr file index in Ldm block */ #define STDERR 3 /* stderr file index in Ldm block */
#define STDEBUG 4 /* debug file index in Ldm block */ #define STDEBUG 4 /* debug file index in Ldm block */
#define STDPRN 5 /* stdprn file index in Ldm block */ #define STDPRN 5 /* stdprn file index in Ldm block */
#define STDFREE 6 /* Free file index in Ldm block */ #define STDFREE 6 /* Free file index in Ldm block */
#define TYPE_SEM -2 /* Returned semantic function */ #define TYPE_SEM -2 /* Returned semantic function */
#define TYPE_DFONC -2 /* Indirect sem ref in FPARM */ #define TYPE_DFONC -2 /* Indirect sem ref in FPARM */
#define TYPE_VOID -1 #define TYPE_VOID -1
#define TYPE_SBPAR -1 /* Phrase reference in FPARM */ #define TYPE_SBPAR -1 /* Phrase reference in FPARM */
#define TYPE_SEMX 0 /* Initial semantic function type? */ #define TYPE_SEMX 0 /* Initial semantic function type? */
#define TYPE_ERROR 0 #define TYPE_ERROR 0
#define TYPE_STRING 1 #define TYPE_STRING 1
#define TYPE_DOUBLE 2 #define TYPE_DOUBLE 2
#define TYPE_SHORT 3 #define TYPE_SHORT 3
#define TYPE_TINY 4 #define TYPE_TINY 4
#define TYPE_BIGINT 5 #define TYPE_BIGINT 5
#define TYPE_LIST 6 #define TYPE_LIST 6
#define TYPE_INT 7 #define TYPE_INT 7
#define TYPE_DECIM 9 #define TYPE_DECIM 9
#define TYPE_BIN 10
#if defined(OS32)
#define SYS_STAMP "OS32" #if defined(OS32)
#elif defined(UNIX) || defined(LINUX) || defined(UNIV_LINUX) #define SYS_STAMP "OS32"
#define SYS_STAMP "UNIX" #elif defined(UNIX) || defined(LINUX) || defined(UNIV_LINUX)
#elif defined(OS16) #define SYS_STAMP "UNIX"
#define SYS_STAMP "OS16" #elif defined(OS16)
#elif defined(DOSR) #define SYS_STAMP "OS16"
#define SYS_STAMP "DOSR" #elif defined(DOSR)
#elif defined(WIN) #define SYS_STAMP "DOSR"
#define SYS_STAMP "WIN1" #elif defined(WIN)
#elif defined(WIN32) #define SYS_STAMP "WIN1"
#define SYS_STAMP "WIN2" #elif defined(WIN32)
#else #define SYS_STAMP "WIN2"
#define SYS_STAMP "XXXX" #else
#endif #define SYS_STAMP "XXXX"
#endif
#if defined(__cplusplus)
extern "C" { #if defined(__cplusplus)
#endif extern "C" {
#endif
/***********************************************************************/
/* Static variables */ /***********************************************************************/
/***********************************************************************/ /* Static variables */
#if defined(STORAGE) /***********************************************************************/
char sys_stamp[4] = SYS_STAMP; #if defined(STORAGE)
#else char sys_stamp[4] = SYS_STAMP;
extern char sys_stamp[]; #else
#endif extern char sys_stamp[];
#endif
/***********************************************************************/
/* File-Selection Indicators */ /***********************************************************************/
/***********************************************************************/ /* File-Selection Indicators */
#define PAT_LOG "log" /***********************************************************************/
#define PAT_LOG "log"
#if defined(UNIX) || defined(LINUX) || defined(UNIV_LINUX)
/*********************************************************************/ #if defined(UNIX) || defined(LINUX) || defined(UNIV_LINUX)
/* printf does not accept null pointer for %s target. */ /*********************************************************************/
/*********************************************************************/ /* printf does not accept null pointer for %s target. */
#define SVP(S) ((S) ? S : "<null>") /*********************************************************************/
#else #define SVP(S) ((S) ? S : "<null>")
/*********************************************************************/ #else
/* printf accepts null pointer for %s target. */ /*********************************************************************/
/*********************************************************************/ /* printf accepts null pointer for %s target. */
#define SVP(S) S /*********************************************************************/
#endif #define SVP(S) S
#endif
#if defined(STORAGE)
FILE *debug; #if defined(STORAGE)
#else FILE *debug;
extern FILE *debug; #else
#endif extern FILE *debug;
#endif
/***********************************************************************/
/* General purpose type definitions. */ /***********************************************************************/
/***********************************************************************/ /* General purpose type definitions. */
#include "os.h" /***********************************************************************/
#include "os.h"
typedef uint OFFSET;
typedef char NAME[9]; typedef uint OFFSET;
typedef char NAME[9];
typedef struct {
ushort Length; typedef struct {
char String[2]; ushort Length;
} VARSTR; char String[2];
} VARSTR;
#if !defined(PGLOBAL_DEFINED)
typedef struct _global *PGLOBAL; #if !defined(PGLOBAL_DEFINED)
#define PGLOBAL_DEFINED typedef struct _global *PGLOBAL;
#endif #define PGLOBAL_DEFINED
typedef struct _globplg *PGS; #endif
typedef struct _activity *PACTIVITY; typedef struct _globplg *PGS;
typedef struct _parm *PPARM; typedef struct _activity *PACTIVITY;
typedef struct _parm *PPARM;
/***********************************************************************/
/* Segment Sub-Allocation block structure declares. */ /***********************************************************************/
/* Next block is an implementation dependent segment suballoc save */ /* Segment Sub-Allocation block structure declares. */
/* structure used to keep the suballocation system offsets and to */ /* Next block is an implementation dependent segment suballoc save */
/* restore them if needed. This scheme implies that no SubFree be used */ /* structure used to keep the suballocation system offsets and to */
/***********************************************************************/ /* restore them if needed. This scheme implies that no SubFree be used */
typedef struct { /* Plug Area SubAlloc header */ /***********************************************************************/
OFFSET To_Free; /* Offset of next free block */ typedef struct { /* Plug Area SubAlloc header */
uint FreeBlk; /* Size of remaining free memory */ OFFSET To_Free; /* Offset of next free block */
} POOLHEADER, *PPOOLHEADER; uint FreeBlk; /* Size of remaining free memory */
} POOLHEADER, *PPOOLHEADER;
/***********************************************************************/
/* Language block. Containing all global information for the language */ /***********************************************************************/
/* this block is saved and retrieved with the language. Information */ /* Language block. Containing all global information for the language */
/* in this block can be set and modified under Grammar editing. */ /* this block is saved and retrieved with the language. Information */
/***********************************************************************/ /* in this block can be set and modified under Grammar editing. */
#if defined(BIT64) /***********************************************************************/
typedef int TIME_T; /* Lang block size must not change */ #if defined(BIT64)
#else // BIT32 typedef int TIME_T; /* Lang block size must not change */
typedef time_t TIME_T; /* time_t */ #else // BIT32
#endif // BIT32 typedef time_t TIME_T; /* time_t */
#endif // BIT32
typedef struct {
uint Memsize; typedef struct {
uint Size; uint Memsize;
} AREADEF; uint Size;
} AREADEF;
typedef struct Lang_block {
NAME LangName; /* Language name */ typedef struct Lang_block {
NAME Application; /* Application name */ NAME LangName; /* Language name */
} LANG, *PLANG; NAME Application; /* Application name */
} LANG, *PLANG;
/***********************************************************************/
/* Application block. It contains all global information for the */ /***********************************************************************/
/* current parse and execution using the corresponding language. */ /* Application block. It contains all global information for the */
/* This block is dynamically allocated and set at language init. */ /* current parse and execution using the corresponding language. */
/***********************************************************************/ /* This block is dynamically allocated and set at language init. */
typedef struct _activity { /* Describes activity and language */ /***********************************************************************/
void *Aptr; /* Points to user work area(s) */ typedef struct _activity { /* Describes activity and language */
NAME Ap_Name; /* Current application name */ void *Aptr; /* Points to user work area(s) */
} ACTIVITY; NAME Ap_Name; /* Current application name */
} ACTIVITY;
/*---------------- UNIT ?????????? VERSION ? ----------------------*/
typedef struct _parm { /*---------------- UNIT ?????????? VERSION ? ----------------------*/
void *Value; typedef struct _parm {
short Type, Domain; void *Value;
PPARM Next; short Type, Domain;
} PARM; PPARM Next;
} PARM;
/***********************************************************************/
/* Global Structure Block. This block contains, or points to, all */ /***********************************************************************/
/* information used by CONNECT tables. Passed as an argument */ /* Global Structure Block. This block contains, or points to, all */
/* to any routine allows it to have access to the entire information */ /* information used by CONNECT tables. Passed as an argument */
/* currently available for the whole set of loaded languages. */ /* to any routine allows it to have access to the entire information */
/***********************************************************************/ /* currently available for the whole set of loaded languages. */
typedef struct _global { /* Global structure */ /***********************************************************************/
void *Sarea; /* Points to work area */ typedef struct _global { /* Global structure */
uint Sarea_Size; /* Work area size */ void *Sarea; /* Points to work area */
PACTIVITY Activityp, ActivityStart; uint Sarea_Size; /* Work area size */
char Message[MAX_STR]; PACTIVITY Activityp, ActivityStart;
int Createas; /* To pass info to created table */ char Message[MAX_STR];
void *Xchk; /* indexes in create/alter */ int Createas; /* To pass info to created table */
short Alchecked; /* Checked for ALTER */ void *Xchk; /* indexes in create/alter */
short Mrr; /* True when doing mrr */ short Alchecked; /* Checked for ALTER */
short Trace; short Mrr; /* True when doing mrr */
int jump_level; short Trace;
jmp_buf jumper[MAX_JUMP + 2]; int jump_level;
} GLOBAL; jmp_buf jumper[MAX_JUMP + 2];
} GLOBAL;
/***********************************************************************/
/* Exported routine declarations. */ /***********************************************************************/
/***********************************************************************/ /* Exported routine declarations. */
#if defined(XMSG) /***********************************************************************/
DllExport char *PlugReadMessage(PGLOBAL, int, char *); #if defined(XMSG)
#elif defined(NEWMSG) DllExport char *PlugReadMessage(PGLOBAL, int, char *);
DllExport char *PlugGetMessage(PGLOBAL, int); #elif defined(NEWMSG)
#endif // XMSG || NEWMSG DllExport char *PlugGetMessage(PGLOBAL, int);
#if defined(WIN32) #endif // XMSG || NEWMSG
DllExport short GetLineLength(PGLOBAL); // Console line length #if defined(WIN32)
#endif // WIN32 DllExport short GetLineLength(PGLOBAL); // Console line length
DllExport PGLOBAL PlugInit(LPCSTR, uint); // Plug global initialization #endif // WIN32
DllExport int PlugExit(PGLOBAL); // Plug global termination DllExport PGLOBAL PlugInit(LPCSTR, uint); // Plug global initialization
DllExport LPSTR PlugRemoveType(LPSTR, LPCSTR); DllExport int PlugExit(PGLOBAL); // Plug global termination
DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR prefix, LPCSTR name, LPCSTR dir); DllExport LPSTR PlugRemoveType(LPSTR, LPCSTR);
DllExport BOOL PlugIsAbsolutePath(LPCSTR path); DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR prefix, LPCSTR name, LPCSTR dir);
DllExport void *PlugAllocMem(PGLOBAL, uint); DllExport BOOL PlugIsAbsolutePath(LPCSTR path);
DllExport BOOL PlugSubSet(PGLOBAL, void *, uint); DllExport void *PlugAllocMem(PGLOBAL, uint);
DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t); DllExport BOOL PlugSubSet(PGLOBAL, void *, uint);
DllExport char *PlugDup(PGLOBAL g, const char *str); DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t);
DllExport void *MakePtr(void *, OFFSET); DllExport char *PlugDup(PGLOBAL g, const char *str);
DllExport void htrc(char const *fmt, ...); DllExport void *MakePtr(void *, OFFSET);
DllExport void htrc(char const *fmt, ...);
#if defined(__cplusplus)
} // extern "C" #if defined(__cplusplus)
#endif } // extern "C"
#endif
/*-------------------------- End of Global.H --------------------------*/
/*-------------------------- End of Global.H --------------------------*/
This source diff could not be displayed because it is too large. You can view the blob instead.
/* Copyright (C) Olivier Bertrand 2004 - 2014 /* Copyright (C) Olivier Bertrand 2004 - 2014
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License. the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/** @file ha_connect.h /** @file ha_connect.h
@brief @brief
The ha_connect engine is a prototype storage engine to access external data. The ha_connect engine is a prototype storage engine to access external data.
@see @see
/sql/handler.h and /storage/connect/ha_connect.cc /sql/handler.h and /storage/connect/ha_connect.cc
*/ */
#ifdef USE_PRAGMA_INTERFACE #ifdef USE_PRAGMA_INTERFACE
#pragma interface /* gcc class implementation */ #pragma interface /* gcc class implementation */
#endif #endif
/****************************************************************************/ /****************************************************************************/
/* Structures used to pass info between CONNECT and ha_connect. */ /* Structures used to pass info between CONNECT and ha_connect. */
/****************************************************************************/ /****************************************************************************/
typedef struct _create_xinfo { typedef struct _create_xinfo {
char *Type; /* Retrieved from table comment */ char *Type; /* Retrieved from table comment */
char *Filename; /* Set if not standard */ char *Filename; /* Set if not standard */
char *IndexFN; /* Set if not standard */ char *IndexFN; /* Set if not standard */
ulonglong Maxrows; /* Estimated max nb of rows */ ulonglong Maxrows; /* Estimated max nb of rows */
ulong Lrecl; /* Set if not default */ ulong Lrecl; /* Set if not default */
ulong Elements; /* Number of lines in blocks */ ulong Elements; /* Number of lines in blocks */
bool Fixed; /* False for DOS type */ bool Fixed; /* False for DOS type */
void *Pcf; /* To list of columns */ void *Pcf; /* To list of columns */
void *Pxdf; /* To list of indexes */ void *Pxdf; /* To list of indexes */
} CRXINFO, *PCXF; } CRXINFO, *PCXF;
typedef struct _xinfo { typedef struct _xinfo {
ulonglong data_file_length; /* Length of data file */ ulonglong data_file_length; /* Length of data file */
ha_rows records; /* Records in table */ ha_rows records; /* Records in table */
ulong mean_rec_length; /* Physical record length */ ulong mean_rec_length; /* Physical record length */
char *data_file_name; /* Physical file name */ char *data_file_name; /* Physical file name */
} XINFO, *PXF; } XINFO, *PXF;
class XCHK : public BLOCK { class XCHK : public BLOCK {
public: public:
XCHK(void) {oldsep= newsep= false; XCHK(void) {oldsep= newsep= false;
oldopn= newopn= NULL; oldopn= newopn= NULL;
oldpix= newpix= NULL;} oldpix= newpix= NULL;}
inline char *SetName(PGLOBAL g, char *name) { inline char *SetName(PGLOBAL g, char *name) {
char *nm= NULL; char *nm= NULL;
if (name) {nm= (char*)PlugSubAlloc(g, NULL, strlen(name) + 1); if (name) {nm= (char*)PlugSubAlloc(g, NULL, strlen(name) + 1);
strcpy(nm, name);} strcpy(nm, name);}
return nm;} return nm;}
bool oldsep; // Sepindex before create/alter bool oldsep; // Sepindex before create/alter
bool newsep; // Sepindex after create/alter bool newsep; // Sepindex after create/alter
char *oldopn; // Optname before create/alter char *oldopn; // Optname before create/alter
char *newopn; // Optname after create/alter char *newopn; // Optname after create/alter
PIXDEF oldpix; // The indexes before create/alter PIXDEF oldpix; // The indexes before create/alter
PIXDEF newpix; // The indexes after create/alter PIXDEF newpix; // The indexes after create/alter
}; // end of class XCHK }; // end of class XCHK
typedef class XCHK *PCHK; typedef class XCHK *PCHK;
typedef class user_connect *PCONNECT; typedef class user_connect *PCONNECT;
typedef struct ha_table_option_struct TOS, *PTOS; typedef struct ha_table_option_struct TOS, *PTOS;
typedef struct ha_field_option_struct FOS, *PFOS; typedef struct ha_field_option_struct FOS, *PFOS;
extern handlerton *connect_hton; extern handlerton *connect_hton;
/** /**
structure for CREATE TABLE options (table options) structure for CREATE TABLE options (table options)
These can be specified in the CREATE TABLE: These can be specified in the CREATE TABLE:
CREATE TABLE ( ... ) {...here...} CREATE TABLE ( ... ) {...here...}
*/ */
struct ha_table_option_struct { struct ha_table_option_struct {
const char *type; const char *type;
const char *filename; const char *filename;
const char *optname; const char *optname;
const char *tabname; const char *tabname;
const char *tablist; const char *tablist;
const char *dbname; const char *dbname;
const char *separator; const char *separator;
//const char *connect; //const char *connect;
const char *qchar; const char *qchar;
const char *module; const char *module;
const char *subtype; const char *subtype;
const char *catfunc; const char *catfunc;
const char *srcdef; const char *srcdef;
const char *colist; const char *colist;
const char *oplist; const char *oplist;
const char *data_charset; const char *data_charset;
ulonglong lrecl; ulonglong lrecl;
ulonglong elements; ulonglong elements;
//ulonglong estimate; //ulonglong estimate;
ulonglong multiple; ulonglong multiple;
ulonglong header; ulonglong header;
ulonglong quoted; ulonglong quoted;
ulonglong ending; ulonglong ending;
ulonglong compressed; ulonglong compressed;
bool mapped; bool mapped;
bool huge; bool huge;
bool split; bool split;
bool readonly; bool readonly;
bool sepindex; bool sepindex;
}; };
/** /**
structure for CREATE TABLE options (field options) structure for CREATE TABLE options (field options)
These can be specified in the CREATE TABLE per field: These can be specified in the CREATE TABLE per field:
CREATE TABLE ( field ... {...here...}, ... ) CREATE TABLE ( field ... {...here...}, ... )
*/ */
struct ha_field_option_struct struct ha_field_option_struct
{ {
ulonglong offset; ulonglong offset;
ulonglong freq; ulonglong freq;
ulonglong opt; ulonglong opt;
ulonglong fldlen; ulonglong fldlen;
const char *dateformat; const char *dateformat;
const char *fieldformat; const char *fieldformat;
char *special; char *special;
}; };
/* /*
index options can be declared similarly index options can be declared similarly
using the ha_index_option_struct structure. using the ha_index_option_struct structure.
...@@ -137,401 +137,402 @@ struct ha_field_option_struct ...@@ -137,401 +137,402 @@ struct ha_field_option_struct
Their values can be specified in the CREATE TABLE per index: Their values can be specified in the CREATE TABLE per index:
CREATE TABLE ( field ..., .., INDEX .... *here*, ... ) CREATE TABLE ( field ..., .., INDEX .... *here*, ... )
*/ */
struct ha_index_option_struct struct ha_index_option_struct
{ {
bool kindx; bool kindx;
bool mapped; bool mapped;
}; };
/** @brief /** @brief
CONNECT_SHARE is a structure that will be shared among all open handlers. CONNECT_SHARE is a structure that will be shared among all open handlers.
This example implements the minimum of what you will probably need. This example implements the minimum of what you will probably need.
*/ */
class CONNECT_SHARE : public Handler_share { class CONNECT_SHARE : public Handler_share {
public: public:
mysql_mutex_t mutex; mysql_mutex_t mutex;
THR_LOCK lock; THR_LOCK lock;
CONNECT_SHARE() CONNECT_SHARE()
{ {
thr_lock_init(&lock); thr_lock_init(&lock);
} }
~CONNECT_SHARE() ~CONNECT_SHARE()
{ {
thr_lock_delete(&lock); thr_lock_delete(&lock);
mysql_mutex_destroy(&mutex); mysql_mutex_destroy(&mutex);
} }
}; };
typedef class ha_connect *PHC; typedef class ha_connect *PHC;
/** @brief /** @brief
Class definition for the storage engine Class definition for the storage engine
*/ */
class ha_connect: public handler class ha_connect: public handler
{ {
THR_LOCK_DATA lock; ///< MySQL lock THR_LOCK_DATA lock; ///< MySQL lock
CONNECT_SHARE *share; ///< Shared lock info CONNECT_SHARE *share; ///< Shared lock info
CONNECT_SHARE *get_share(); CONNECT_SHARE *get_share();
public: public:
ha_connect(handlerton *hton, TABLE_SHARE *table_arg); ha_connect(handlerton *hton, TABLE_SHARE *table_arg);
~ha_connect(); ~ha_connect();
// CONNECT Implementation // CONNECT Implementation
static bool connect_init(void); static bool connect_init(void);
static bool connect_end(void); static bool connect_end(void);
TABTYPE GetRealType(PTOS pos); TABTYPE GetRealType(PTOS pos);
char *GetStringOption(char *opname, char *sdef= NULL); char *GetStringOption(char *opname, char *sdef= NULL);
PTOS GetTableOptionStruct(TABLE *table_arg); PTOS GetTableOptionStruct(TABLE *table_arg);
bool GetBooleanOption(char *opname, bool bdef); bool GetBooleanOption(char *opname, bool bdef);
bool SetBooleanOption(char *opname, bool b); bool SetBooleanOption(char *opname, bool b);
int GetIntegerOption(char *opname); int GetIntegerOption(char *opname);
bool CheckString(const char *str1, const char *str2); bool CheckString(const char *str1, const char *str2);
bool SameString(TABLE *tab, char *opn); bool SameString(TABLE *tab, char *opn);
bool SetIntegerOption(char *opname, int n); bool SetIntegerOption(char *opname, int n);
bool SameInt(TABLE *tab, char *opn); bool SameInt(TABLE *tab, char *opn);
bool SameBool(TABLE *tab, char *opn); bool SameBool(TABLE *tab, char *opn);
bool FileExists(const char *fn); bool FileExists(const char *fn);
bool NoFieldOptionChange(TABLE *tab); bool NoFieldOptionChange(TABLE *tab);
PFOS GetFieldOptionStruct(Field *fp); PFOS GetFieldOptionStruct(Field *fp);
void *GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf); void *GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf);
PIXDEF GetIndexInfo(TABLE_SHARE *s= NULL); PIXDEF GetIndexInfo(TABLE_SHARE *s= NULL);
const char *GetDBName(const char *name); const char *GetDBName(const char *name);
const char *GetTableName(void); const char *GetTableName(void);
//int GetColNameLen(Field *fp); //int GetColNameLen(Field *fp);
//char *GetColName(Field *fp); //char *GetColName(Field *fp);
//void AddColName(char *cp, Field *fp); //void AddColName(char *cp, Field *fp);
TABLE *GetTable(void) {return table;} TABLE *GetTable(void) {return table;}
bool IsSameIndex(PIXDEF xp1, PIXDEF xp2); bool IsSameIndex(PIXDEF xp1, PIXDEF xp2);
PTDB GetTDB(PGLOBAL g); PTDB GetTDB(PGLOBAL g);
int OpenTable(PGLOBAL g, bool del= false); int OpenTable(PGLOBAL g, bool del= false);
bool IsOpened(void); bool IsOpened(void);
int CloseTable(PGLOBAL g); int CloseTable(PGLOBAL g);
int MakeRecord(char *buf); int MakeRecord(char *buf);
int ScanRecord(PGLOBAL g, uchar *buf); int ScanRecord(PGLOBAL g, uchar *buf);
int CheckRecord(PGLOBAL g, const uchar *oldbuf, uchar *newbuf); int CheckRecord(PGLOBAL g, const uchar *oldbuf, uchar *newbuf);
int ReadIndexed(uchar *buf, OPVAL op, const uchar* key= NULL, int ReadIndexed(uchar *buf, OPVAL op, const uchar* key= NULL,
uint key_len= 0); uint key_len= 0);
/** @brief /** @brief
The name that will be used for display purposes. The name that will be used for display purposes.
*/ */
const char *table_type() const {return "CONNECT";} const char *table_type() const {return "CONNECT";}
/** @brief /** @brief
The name of the index type that will be used for display. The name of the index type that will be used for display.
Don't implement this method unless you really have indexes. Don't implement this method unless you really have indexes.
*/ */
const char *index_type(uint inx) { return "XINDEX"; } const char *index_type(uint inx) { return "XINDEX"; }
/** @brief /** @brief
The file extensions. The file extensions.
*/ */
const char **bas_ext() const; const char **bas_ext() const;
/** /**
Check if a storage engine supports a particular alter table in-place Check if a storage engine supports a particular alter table in-place
@note Called without holding thr_lock.c lock. @note Called without holding thr_lock.c lock.
*/ */
virtual enum_alter_inplace_result virtual enum_alter_inplace_result
check_if_supported_inplace_alter(TABLE *altered_table, check_if_supported_inplace_alter(TABLE *altered_table,
Alter_inplace_info *ha_alter_info); Alter_inplace_info *ha_alter_info);
/** @brief /** @brief
This is a list of flags that indicate what functionality the storage engine This is a list of flags that indicate what functionality the storage engine
implements. The current table flags are documented in handler.h implements. The current table flags are documented in handler.h
*/ */
ulonglong table_flags() const; ulonglong table_flags() const;
/** @brief /** @brief
This is a bitmap of flags that indicates how the storage engine This is a bitmap of flags that indicates how the storage engine
implements indexes. The current index flags are documented in implements indexes. The current index flags are documented in
handler.h. If you do not implement indexes, just return zero here. handler.h. If you do not implement indexes, just return zero here.
@details @details
part is the key part to check. First key part is 0. part is the key part to check. First key part is 0.
If all_parts is set, MySQL wants to know the flags for the combined If all_parts is set, MySQL wants to know the flags for the combined
index, up to and including 'part'. index, up to and including 'part'.
*/ */
ulong index_flags(uint inx, uint part, bool all_parts) const ulong index_flags(uint inx, uint part, bool all_parts) const
{ {
return HA_READ_NEXT | HA_READ_RANGE | HA_READ_ORDER | HA_KEYREAD_ONLY; return HA_READ_NEXT | HA_READ_RANGE | HA_READ_ORDER
} // end of index_flags | HA_KEYREAD_ONLY | HA_KEY_SCAN_NOT_ROR;
} // end of index_flags
/** @brief
unireg.cc will call max_supported_record_length(), max_supported_keys(), /** @brief
max_supported_key_parts(), uint max_supported_key_length() unireg.cc will call max_supported_record_length(), max_supported_keys(),
to make sure that the storage engine can handle the data it is about to max_supported_key_parts(), uint max_supported_key_length()
send. Return *real* limits of your storage engine here; MySQL will do to make sure that the storage engine can handle the data it is about to
min(your_limits, MySQL_limits) automatically. send. Return *real* limits of your storage engine here; MySQL will do
*/ min(your_limits, MySQL_limits) automatically.
uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; } */
uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
/** @brief
unireg.cc will call this to make sure that the storage engine can handle /** @brief
the data it is about to send. Return *real* limits of your storage engine unireg.cc will call this to make sure that the storage engine can handle
here; MySQL will do min(your_limits, MySQL_limits) automatically. the data it is about to send. Return *real* limits of your storage engine
here; MySQL will do min(your_limits, MySQL_limits) automatically.
@details
There is no need to implement ..._key_... methods if your engine doesn't @details
support indexes. There is no need to implement ..._key_... methods if your engine doesn't
*/ support indexes.
uint max_supported_keys() const { return 10; } */
uint max_supported_keys() const { return 10; }
/** @brief
unireg.cc will call this to make sure that the storage engine can handle /** @brief
the data it is about to send. Return *real* limits of your storage engine unireg.cc will call this to make sure that the storage engine can handle
here; MySQL will do min(your_limits, MySQL_limits) automatically. the data it is about to send. Return *real* limits of your storage engine
here; MySQL will do min(your_limits, MySQL_limits) automatically.
@details
There is no need to implement ..._key_... methods if your engine doesn't @details
support indexes. There is no need to implement ..._key_... methods if your engine doesn't
*/ support indexes.
uint max_supported_key_parts() const { return 10; } */
uint max_supported_key_parts() const { return 10; }
/** @brief
unireg.cc will call this to make sure that the storage engine can handle /** @brief
the data it is about to send. Return *real* limits of your storage engine unireg.cc will call this to make sure that the storage engine can handle
here; MySQL will do min(your_limits, MySQL_limits) automatically. the data it is about to send. Return *real* limits of your storage engine
here; MySQL will do min(your_limits, MySQL_limits) automatically.
@details
There is no need to implement ..._key_... methods if your engine doesn't @details
support indexes. There is no need to implement ..._key_... methods if your engine doesn't
*/ support indexes.
uint max_supported_key_length() const { return 255; } */
uint max_supported_key_length() const { return 255; }
/** @brief
Called in test_quick_select to determine if indexes should be used. /** @brief
*/ Called in test_quick_select to determine if indexes should be used.
virtual double scan_time() { return (double) (stats.records+stats.deleted) / 20.0+10; } */
virtual double scan_time() { return (double) (stats.records+stats.deleted) / 20.0+10; }
/** @brief
This method will never be called if you do not implement indexes. /** @brief
*/ This method will never be called if you do not implement indexes.
virtual double read_time(uint, uint, ha_rows rows) */
{ return (double) rows / 20.0+1; } virtual double read_time(uint, uint, ha_rows rows)
{ return (double) rows / 20.0+1; }
/*
Everything below are methods that we implement in ha_connect.cc. /*
Everything below are methods that we implement in ha_connect.cc.
Most of these methods are not obligatory, skip them and
MySQL will treat them as not implemented Most of these methods are not obligatory, skip them and
*/ MySQL will treat them as not implemented
virtual bool get_error_message(int error, String *buf); */
virtual bool get_error_message(int error, String *buf);
/**
Push condition down to the table handler. /**
Push condition down to the table handler.
@param cond Condition to be pushed. The condition tree must not be
modified by the by the caller. @param cond Condition to be pushed. The condition tree must not be
modified by the by the caller.
@return
The 'remainder' condition that caller must use to filter out records. @return
NULL means the handler will not return rows that do not match the The 'remainder' condition that caller must use to filter out records.
passed condition. NULL means the handler will not return rows that do not match the
passed condition.
@note
The pushed conditions form a stack (from which one can remove the @note
last pushed condition using cond_pop). The pushed conditions form a stack (from which one can remove the
The table handler filters out rows using (pushed_cond1 AND pushed_cond2 last pushed condition using cond_pop).
AND ... AND pushed_condN) The table handler filters out rows using (pushed_cond1 AND pushed_cond2
or less restrictive condition, depending on handler's capabilities. AND ... AND pushed_condN)
or less restrictive condition, depending on handler's capabilities.
handler->ha_reset() call empties the condition stack.
Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the handler->ha_reset() call empties the condition stack.
condition stack. Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the
*/ condition stack.
virtual const COND *cond_push(const COND *cond); */
PCFIL CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond); virtual const COND *cond_push(const COND *cond);
const char *GetValStr(OPVAL vop, bool neg); PCFIL CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond);
PFIL CondFilter(PGLOBAL g, Item *cond); const char *GetValStr(OPVAL vop, bool neg);
PFIL CondFilter(PGLOBAL g, Item *cond);
/**
Number of rows in table. It will only be called if /**
(table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0 Number of rows in table. It will only be called if
*/ (table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0
virtual ha_rows records(); */
virtual ha_rows records();
/**
Type of table for caching query /**
CONNECT should not use caching because its tables are external Type of table for caching query
data prone to me modified out of MariaDB CONNECT should not use caching because its tables are external
*/ data prone to me modified out of MariaDB
virtual uint8 table_cache_type(void) */
{ virtual uint8 table_cache_type(void)
#if defined(MEMORY_TRACE) {
// Temporary until bug MDEV-4771 is fixed #if defined(MEMORY_TRACE)
return HA_CACHE_TBL_NONTRANSACT; // Temporary until bug MDEV-4771 is fixed
#else return HA_CACHE_TBL_NONTRANSACT;
return HA_CACHE_TBL_NOCACHE; #else
#endif return HA_CACHE_TBL_NOCACHE;
} #endif
}
/** @brief
We implement this in ha_connect.cc; it's a required method. /** @brief
*/ We implement this in ha_connect.cc; it's a required method.
int open(const char *name, int mode, uint test_if_locked); // required */
int open(const char *name, int mode, uint test_if_locked); // required
/** @brief
We implement this in ha_connect.cc; it's a required method. /** @brief
*/ We implement this in ha_connect.cc; it's a required method.
int close(void); // required */
int close(void); // required
/** @brief
We implement this in ha_connect.cc. It's not an obligatory method; /** @brief
skip it and and MySQL will treat it as not implemented. We implement this in ha_connect.cc. It's not an obligatory method;
*/ skip it and and MySQL will treat it as not implemented.
int write_row(uchar *buf); */
int write_row(uchar *buf);
/** @brief
We implement this in ha_connect.cc. It's not an obligatory method; /** @brief
skip it and and MySQL will treat it as not implemented. We implement this in ha_connect.cc. It's not an obligatory method;
*/ skip it and and MySQL will treat it as not implemented.
int update_row(const uchar *old_data, uchar *new_data); */
int update_row(const uchar *old_data, uchar *new_data);
/** @brief
We implement this in ha_connect.cc. It's not an obligatory method; /** @brief
skip it and and MySQL will treat it as not implemented. We implement this in ha_connect.cc. It's not an obligatory method;
*/ skip it and and MySQL will treat it as not implemented.
int delete_row(const uchar *buf); */
int delete_row(const uchar *buf);
// Added to the connect handler
int index_init(uint idx, bool sorted); // Added to the connect handler
int index_end(); int index_init(uint idx, bool sorted);
int index_read(uchar * buf, const uchar * key, uint key_len, int index_end();
enum ha_rkey_function find_flag); int index_read(uchar * buf, const uchar * key, uint key_len,
int index_next_same(uchar *buf, const uchar *key, uint keylen); enum ha_rkey_function find_flag);
int index_next_same(uchar *buf, const uchar *key, uint keylen);
/** @brief
We implement this in ha_connect.cc. It's not an obligatory method; /** @brief
skip it and and MySQL will treat it as not implemented. We implement this in ha_connect.cc. It's not an obligatory method;
*/ skip it and and MySQL will treat it as not implemented.
//int index_read_map(uchar *buf, const uchar *key, */
// key_part_map keypart_map, enum ha_rkey_function find_flag); //int index_read_map(uchar *buf, const uchar *key,
// key_part_map keypart_map, enum ha_rkey_function find_flag);
/** @brief
We implement this in ha_connect.cc. It's not an obligatory method; /** @brief
skip it and and MySQL will treat it as not implemented. We implement this in ha_connect.cc. It's not an obligatory method;
*/ skip it and and MySQL will treat it as not implemented.
int index_next(uchar *buf); */
int index_next(uchar *buf);
/** @brief
We implement this in ha_connect.cc. It's not an obligatory method; /** @brief
skip it and and MySQL will treat it as not implemented. We implement this in ha_connect.cc. It's not an obligatory method;
*/ skip it and and MySQL will treat it as not implemented.
//int index_prev(uchar *buf); */
//int index_prev(uchar *buf);
/** @brief
We implement this in ha_connect.cc. It's not an obligatory method; /** @brief
skip it and and MySQL will treat it as not implemented. We implement this in ha_connect.cc. It's not an obligatory method;
*/ skip it and and MySQL will treat it as not implemented.
int index_first(uchar *buf); */
int index_first(uchar *buf);
/** @brief
We implement this in ha_connect.cc. It's not an obligatory method; /** @brief
skip it and and MySQL will treat it as not implemented. We implement this in ha_connect.cc. It's not an obligatory method;
*/ skip it and and MySQL will treat it as not implemented.
//int index_last(uchar *buf); */
int index_last(uchar *buf);
/* Index condition pushdown implementation */
//Item *idx_cond_push(uint keyno, Item* idx_cond); /* Index condition pushdown implementation */
//Item *idx_cond_push(uint keyno, Item* idx_cond);
/** @brief
Unlike index_init(), rnd_init() can be called two consecutive times /** @brief
without rnd_end() in between (it only makes sense if scan=1). In this Unlike index_init(), rnd_init() can be called two consecutive times
case, the second call should prepare for the new table scan (e.g if without rnd_end() in between (it only makes sense if scan=1). In this
rnd_init() allocates the cursor, the second call should position the case, the second call should prepare for the new table scan (e.g if
cursor to the start of the table; no need to deallocate and allocate rnd_init() allocates the cursor, the second call should position the
it again. This is a required method. cursor to the start of the table; no need to deallocate and allocate
*/ it again. This is a required method.
int rnd_init(bool scan); //required */
int rnd_end(); int rnd_init(bool scan); //required
int rnd_next(uchar *buf); ///< required int rnd_end();
int rnd_pos(uchar *buf, uchar *pos); ///< required int rnd_next(uchar *buf); ///< required
void position(const uchar *record); ///< required int rnd_pos(uchar *buf, uchar *pos); ///< required
int info(uint); ///< required void position(const uchar *record); ///< required
int extra(enum ha_extra_function operation); int info(uint); ///< required
int start_stmt(THD *thd, thr_lock_type lock_type); int extra(enum ha_extra_function operation);
int external_lock(THD *thd, int lock_type); ///< required int start_stmt(THD *thd, thr_lock_type lock_type);
int delete_all_rows(void); int external_lock(THD *thd, int lock_type); ///< required
ha_rows records_in_range(uint inx, key_range *min_key, int delete_all_rows(void);
key_range *max_key); ha_rows records_in_range(uint inx, key_range *min_key,
/** key_range *max_key);
These methods can be overridden, but their default implementation /**
provide useful functionality. These methods can be overridden, but their default implementation
*/ provide useful functionality.
int rename_table(const char *from, const char *to); */
/** int rename_table(const char *from, const char *to);
Delete a table in the engine. Called for base as well as temporary /**
tables. Delete a table in the engine. Called for base as well as temporary
*/ tables.
int delete_table(const char *name); */
/** int delete_table(const char *name);
Called by delete_table and rename_table /**
*/ Called by delete_table and rename_table
int delete_or_rename_table(const char *from, const char *to); */
int create(const char *name, TABLE *form, int delete_or_rename_table(const char *from, const char *to);
HA_CREATE_INFO *create_info); ///< required int create(const char *name, TABLE *form,
bool check_if_incompatible_data(HA_CREATE_INFO *info, HA_CREATE_INFO *create_info); ///< required
uint table_changes); bool check_if_incompatible_data(HA_CREATE_INFO *info,
uint table_changes);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); ///< required THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
int optimize(THD* thd, HA_CHECK_OPT* check_opt); enum thr_lock_type lock_type); ///< required
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
/**
* Multi Range Read interface /**
*/ * Multi Range Read interface
int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, */
uint n_ranges, uint mode, HANDLER_BUFFER *buf); int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
int multi_range_read_next(range_id_t *range_info); uint n_ranges, uint mode, HANDLER_BUFFER *buf);
ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, int multi_range_read_next(range_id_t *range_info);
void *seq_init_param, ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
uint n_ranges, uint *bufsz, void *seq_init_param,
uint *flags, Cost_estimate *cost); uint n_ranges, uint *bufsz,
ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys, uint *flags, Cost_estimate *cost);
uint key_parts, uint *bufsz, ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
uint *flags, Cost_estimate *cost); uint key_parts, uint *bufsz,
int multi_range_read_explain_info(uint mrr_mode, char *str, size_t size); uint *flags, Cost_estimate *cost);
int multi_range_read_explain_info(uint mrr_mode, char *str, size_t size);
int reset(void) {ds_mrr.dsmrr_close(); return 0;}
int reset(void) {ds_mrr.dsmrr_close(); return 0;}
/* Index condition pushdown implementation */
// Item *idx_cond_push(uint keyno, Item* idx_cond); /* Index condition pushdown implementation */
private: // Item *idx_cond_push(uint keyno, Item* idx_cond);
DsMrr_impl ds_mrr; private:
DsMrr_impl ds_mrr;
protected:
bool check_privileges(THD *thd, PTOS options, char *dbn); protected:
MODE CheckMode(PGLOBAL g, THD *thd, MODE newmode, bool *chk, bool *cras); bool check_privileges(THD *thd, PTOS options, char *dbn);
char *GetDBfromName(const char *name); MODE CheckMode(PGLOBAL g, THD *thd, MODE newmode, bool *chk, bool *cras);
char *GetDBfromName(const char *name);
// Members
static ulong num; // Tracable handler number // Members
PCONNECT xp; // To user_connect associated class static ulong num; // Tracable handler number
ulong hnum; // The number of this handler PCONNECT xp; // To user_connect associated class
query_id_t valid_query_id; // The one when tdbp was allocated ulong hnum; // The number of this handler
query_id_t creat_query_id; // The one when handler was allocated query_id_t valid_query_id; // The one when tdbp was allocated
PTDB tdbp; // To table class object query_id_t creat_query_id; // The one when handler was allocated
PVAL sdvalin; // Used to convert date values PTDB tdbp; // To table class object
PVAL sdvalout; // Used to convert date values PVAL sdvalin; // Used to convert date values
bool istable; // True for table handler PVAL sdvalout; // Used to convert date values
//char tname[64]; // The table name bool istable; // True for table handler
MODE xmod; // Table mode //char tname[64]; // The table name
XINFO xinfo; // The table info structure MODE xmod; // Table mode
bool valid_info; // True if xinfo is valid XINFO xinfo; // The table info structure
bool stop; // Used when creating index bool valid_info; // True if xinfo is valid
bool alter; // True when converting to other engine bool stop; // Used when creating index
bool mrr; // True when getting index positions bool alter; // True when converting to other engine
int indexing; // Type of indexing for CONNECT bool mrr; // True when getting index positions
int locked; // Table lock int indexing; // Type of indexing for CONNECT
THR_LOCK_DATA lock_data; int locked; // Table lock
THR_LOCK_DATA lock_data;
public:
TABLE_SHARE *tshp; // Used by called tables public:
char *data_file_name; TABLE_SHARE *tshp; // Used by called tables
char *index_file_name; char *data_file_name;
uint int_table_flags; // Inherited from MyISAM char *index_file_name;
bool enable_activate_all_index; // Inherited from MyISAM uint int_table_flags; // Inherited from MyISAM
}; // end of ha_connect class definition bool enable_activate_all_index; // Inherited from MyISAM
}; // end of ha_connect class definition
...@@ -47,9 +47,12 @@ ...@@ -47,9 +47,12 @@
#include "myconn.h" #include "myconn.h"
extern "C" int trace; extern "C" int trace;
extern "C" int zconv;
extern MYSQL_PLUGIN_IMPORT uint mysqld_port; extern MYSQL_PLUGIN_IMPORT uint mysqld_port;
extern MYSQL_PLUGIN_IMPORT char *mysqld_unix_port; extern MYSQL_PLUGIN_IMPORT char *mysqld_unix_port;
DllExport void PushWarning(PGLOBAL, THD*, int level = 1);
// Returns the current used port // Returns the current used port
uint GetDefaultPort(void) uint GetDefaultPort(void)
{ {
...@@ -61,7 +64,7 @@ uint GetDefaultPort(void) ...@@ -61,7 +64,7 @@ uint GetDefaultPort(void)
/* of a MySQL table or view. */ /* of a MySQL table or view. */
/* info = TRUE to get catalog column informations. */ /* info = TRUE to get catalog column informations. */
/************************************************************************/ /************************************************************************/
PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
const char *user, const char *pwd, const char *user, const char *pwd,
const char *table, const char *colpat, const char *table, const char *colpat,
int port, bool info) int port, bool info)
...@@ -75,7 +78,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, ...@@ -75,7 +78,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
FLD_REM, FLD_NO, FLD_DEFAULT, FLD_EXTRA, FLD_REM, FLD_NO, FLD_DEFAULT, FLD_EXTRA,
FLD_CHARSET}; FLD_CHARSET};
unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0}; unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0};
char *fld, *fmt, v, cmd[128], uns[16], zero[16]; char *fld, *colname, *chset, *fmt, v, cmd[128], uns[16], zero[16];
int i, n, nf, ncol = sizeof(buftyp) / sizeof(int); int i, n, nf, ncol = sizeof(buftyp) / sizeof(int);
int len, type, prec, rc, k = 0; int len, type, prec, rc, k = 0;
PQRYRES qrp; PQRYRES qrp;
...@@ -144,23 +147,24 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, ...@@ -144,23 +147,24 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
/**********************************************************************/ /**********************************************************************/
/* Now get the results into blocks. */ /* Now get the results into blocks. */
/**********************************************************************/ /**********************************************************************/
for (i = 0; i < n; i++) { for (i = 0; i < n; /*i++*/) {
if ((rc = myc.Fetch(g, -1) == RC_FX)) { if ((rc = myc.Fetch(g, -1)) == RC_FX) {
myc.Close(); myc.Close();
return NULL; return NULL;
} else if (rc == RC_NF) } else if (rc == RC_EF)
break; break;
// Get column name // Get column name
fld = myc.GetCharField(0); colname = myc.GetCharField(0);
crp = qrp->Colresp; // Column_Name crp = qrp->Colresp; // Column_Name
crp->Kdata->SetValue(fld, i); crp->Kdata->SetValue(colname, i);
// Get type, type name, precision, unsigned and zerofill // Get type, type name, precision, unsigned and zerofill
chset = myc.GetCharField(2);
fld = myc.GetCharField(1); fld = myc.GetCharField(1);
prec = 0; prec = 0;
len = 0; len = 0;
v = 0; v = (chset && !strcmp(chset, "binary")) ? 'B' : 0;
*uns = 0; *uns = 0;
*zero = 0; *zero = 0;
...@@ -181,11 +185,28 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, ...@@ -181,11 +185,28 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
} // endswitch nf } // endswitch nf
if ((type = MYSQLtoPLG(cmd, &v)) == TYPE_ERROR) { if ((type = MYSQLtoPLG(cmd, &v)) == TYPE_ERROR) {
sprintf(g->Message, "Unsupported column type %s", cmd); if (v == 'K') {
// Skip this column
sprintf(g->Message, "Column %s skipped (unsupported type %s)",
colname, cmd);
PushWarning(g, thd);
continue;
} // endif v
sprintf(g->Message, "Column %s unsupported type %s", colname, cmd);
myc.Close(); myc.Close();
return NULL; return NULL;
} else if (type == TYPE_STRING) } else if (type == TYPE_STRING) {
len = min(len, 4096); if (v == 'X') {
len = zconv;
sprintf(g->Message, "Column %s converted to varchar(%d)",
colname, len);
PushWarning(g, thd);
v = 'V';
} else
len = min(len, 4096);
} // endif type
qrp->Nblin++; qrp->Nblin++;
crp = crp->Next; // Data_Type crp = crp->Next; // Data_Type
...@@ -241,8 +262,10 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, ...@@ -241,8 +262,10 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
crp->Kdata->SetValue(fld, i); crp->Kdata->SetValue(fld, i);
crp = crp->Next; // New (charset) crp = crp->Next; // New (charset)
fld = myc.GetCharField(2); fld = chset;
crp->Kdata->SetValue(fld, i); crp->Kdata->SetValue(fld, i);
i++; // Can be skipped
} // endfor i } // endfor i
#if 0 #if 0
...@@ -284,7 +307,7 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db, ...@@ -284,7 +307,7 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db,
if (!port) if (!port)
port = mysqld_port; port = mysqld_port;
if (!strnicmp(srcdef, "select ", 7)) { if (!strnicmp(srcdef, "select ", 7)) {
query = (char *)PlugSubAlloc(g, NULL, strlen(srcdef) + 9); query = (char *)PlugSubAlloc(g, NULL, strlen(srcdef) + 9);
strcat(strcpy(query, srcdef), " LIMIT 0"); strcat(strcpy(query, srcdef), " LIMIT 0");
} else } else
...@@ -608,7 +631,7 @@ if (w) ...@@ -608,7 +631,7 @@ if (w)
/***********************************************************************/ /***********************************************************************/
void MYSQLC::DataSeek(my_ulonglong row) void MYSQLC::DataSeek(my_ulonglong row)
{ {
MYSQL_ROWS *tmp=0; MYSQL_ROWS *tmp=0;
//DBUG_PRINT("info",("mysql_data_seek(%ld)",(long) row)); //DBUG_PRINT("info",("mysql_data_seek(%ld)",(long) row));
if (m_Res->data) if (m_Res->data)
...@@ -783,7 +806,7 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb) ...@@ -783,7 +806,7 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb)
else { else {
if (!*row && crp->Nulls) if (!*row && crp->Nulls)
crp->Nulls[n] = '*'; // Null value crp->Nulls[n] = '*'; // Null value
crp->Kdata->Reset(n); crp->Kdata->Reset(n);
} // endelse *row } // endelse *row
} }
...@@ -880,7 +903,7 @@ void MYSQLC::DiscardResults(void) ...@@ -880,7 +903,7 @@ void MYSQLC::DiscardResults(void)
while (!mysql_next_result(m_DB)) { while (!mysql_next_result(m_DB)) {
res = mysql_store_result(m_DB); res = mysql_store_result(m_DB);
mysql_free_result(res); mysql_free_result(res);
} // endwhile next result } // endwhile next result
} // end of DiscardResults } // end of DiscardResults
#endif // 0 #endif // 0
...@@ -34,7 +34,7 @@ typedef class MYSQLC *PMYC; ...@@ -34,7 +34,7 @@ typedef class MYSQLC *PMYC;
/***********************************************************************/ /***********************************************************************/
/* Prototypes of info functions. */ /* Prototypes of info functions. */
/***********************************************************************/ /***********************************************************************/
PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
const char *user, const char *pwd, const char *user, const char *pwd,
const char *table, const char *colpat, const char *table, const char *colpat,
int port, bool info); int port, bool info);
......
...@@ -229,7 +229,7 @@ DROP TABLE pets; ...@@ -229,7 +229,7 @@ DROP TABLE pets;
# #
CREATE TABLE fruit ( CREATE TABLE fruit (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(32) DEFAULT NULL, `name` varchar(32) NOT NULL,
`cnt` int(11) DEFAULT NULL, `cnt` int(11) DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1; ) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
......
...@@ -5,6 +5,11 @@ package My::Suite::Connect; ...@@ -5,6 +5,11 @@ package My::Suite::Connect;
return "No CONNECT engine" unless $ENV{HA_CONNECT_SO} or return "No CONNECT engine" unless $ENV{HA_CONNECT_SO} or
$::mysqld_variables{'connect'} eq "ON"; $::mysqld_variables{'connect'} eq "ON";
# RECOMPILE_FOR_EMBEDDED also means that a plugin
# cannot be dynamically loaded into embedded
return "Not run for embedded server" if $::opt_embedded_server and
$ENV{HA_CONNECT_SO};
sub is_default { 1 } sub is_default { 1 }
bless { }; bless { };
......
-- source include/not_embedded.inc -- source include/not_embedded.inc
let $MYSQLD_DATADIR= `select @@datadir`; let $MYSQLD_DATADIR= `select @@datadir`;
let $PORT= `select @@port`; let $PORT= `select @@port`;
--copy_file $MTR_SUITE_DIR/std_data/expenses.txt $MYSQLD_DATADIR/test/expenses.txt --copy_file $MTR_SUITE_DIR/std_data/expenses.txt $MYSQLD_DATADIR/test/expenses.txt
--echo # --echo #
--echo # Testing the PIVOT table type --echo # Testing the PIVOT table type
--echo # --echo #
CREATE TABLE expenses ( CREATE TABLE expenses (
Who CHAR(10) NOT NULL, Who CHAR(10) NOT NULL,
Week INT(2) NOT NULL, Week INT(2) NOT NULL,
What CHAR(12) NOT NULL, What CHAR(12) NOT NULL,
Amount DOUBLE(8,2)) Amount DOUBLE(8,2))
ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='expenses.txt' ENDING=2; ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='expenses.txt' ENDING=2;
SELECT * FROM expenses; SELECT * FROM expenses;
--echo # --echo #
--echo # Pivoting from What --echo # Pivoting from What
--echo # --echo #
CREATE TABLE pivex ( CREATE TABLE pivex (
Who CHAR(10) NOT NULL, Who CHAR(10) NOT NULL,
Week INT(2) NOT NULL, Week INT(2) NOT NULL,
Beer DOUBLE(8,2) FLAG=1, Beer DOUBLE(8,2) FLAG=1,
Car DOUBLE(8,2) FLAG=1, Car DOUBLE(8,2) FLAG=1,
Food DOUBLE(8,2) FLAG=1) Food DOUBLE(8,2) FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses; ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses;
--replace_result $PORT PORT --replace_result $PORT PORT
--eval ALTER TABLE pivex OPTION_LIST='port=$PORT' --eval ALTER TABLE pivex OPTION_LIST='port=$PORT'
SELECT * FROM pivex; SELECT * FROM pivex;
--echo # --echo #
--echo # Restricting the columns in a Pivot Table --echo # Restricting the columns in a Pivot Table
--echo # --echo #
ALTER TABLE pivex DROP COLUMN week; ALTER TABLE pivex DROP COLUMN week;
SELECT * FROM pivex; SELECT * FROM pivex;
--echo # --echo #
--echo # Using a source definition --echo # Using a source definition
--echo # --echo #
DROP TABLE pivex; DROP TABLE pivex;
CREATE TABLE pivex ( CREATE TABLE pivex (
Who CHAR(10) NOT NULL, Who CHAR(10) NOT NULL,
Week INT(2) NOT NULL, Week INT(2) NOT NULL,
Beer DOUBLE(8,2) FLAG=1, Beer DOUBLE(8,2) FLAG=1,
Car DOUBLE(8,2) FLAG=1, Car DOUBLE(8,2) FLAG=1,
Food DOUBLE(8,2) FLAG=1) Food DOUBLE(8,2) FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT ENGINE=CONNECT TABLE_TYPE=PIVOT
SRCDEF='select who, week, what, sum(amount) as amount from expenses where week in (4,5) group by who, week, what'; SRCDEF='select who, week, what, sum(amount) as amount from expenses where week in (4,5) group by who, week, what';
--replace_result $PORT PORT --replace_result $PORT PORT
--eval ALTER TABLE pivex OPTION_LIST='PivotCol=what,FncCol=amount,port=$PORT' --eval ALTER TABLE pivex OPTION_LIST='PivotCol=what,FncCol=amount,port=$PORT'
SELECT * FROM pivex; SELECT * FROM pivex;
--echo # --echo #
--echo # Pivoting from Week --echo # Pivoting from Week
--echo # --echo #
DROP TABLE pivex; DROP TABLE pivex;
CREATE TABLE pivex ( CREATE TABLE pivex (
Who CHAR(10) NOT NULL, Who CHAR(10) NOT NULL,
What CHAR(12) NOT NULL, What CHAR(12) NOT NULL,
`3` DOUBLE(8,2) FLAG=1, `3` DOUBLE(8,2) FLAG=1,
`4` DOUBLE(8,2) FLAG=1, `4` DOUBLE(8,2) FLAG=1,
`5` DOUBLE(8,2) FLAG=1) `5` DOUBLE(8,2) FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses; ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses;
--replace_result $PORT PORT --replace_result $PORT PORT
--eval ALTER TABLE pivex OPTION_LIST='PivotCol=Week,port=$PORT' --eval ALTER TABLE pivex OPTION_LIST='PivotCol=Week,port=$PORT'
SELECT * FROM pivex; SELECT * FROM pivex;
--echo # --echo #
--echo # Using scalar functions and expresssions --echo # Using scalar functions and expresssions
--echo # --echo #
DROP TABLE pivex; DROP TABLE pivex;
CREATE TABLE pivex ( CREATE TABLE pivex (
Who CHAR(10) NOT NULL, Who CHAR(10) NOT NULL,
What CHAR(12) NOT NULL, What CHAR(12) NOT NULL,
First DOUBLE(8,2) FLAG=1, First DOUBLE(8,2) FLAG=1,
Middle DOUBLE(8,2) FLAG=1, Middle DOUBLE(8,2) FLAG=1,
Last DOUBLE(8,2) FLAG=1) Last DOUBLE(8,2) FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT ENGINE=CONNECT TABLE_TYPE=PIVOT
SRCDEF='select who, what, case when week=3 then ''First'' when week=5 then ''Last'' else ''Middle'' end as wk, sum(amount) * 6.56 as amnt from expenses group by who, what, wk'; SRCDEF='select who, what, case when week=3 then ''First'' when week=5 then ''Last'' else ''Middle'' end as wk, sum(amount) * 6.56 as amnt from expenses group by who, what, wk';
--replace_result $PORT PORT --replace_result $PORT PORT
--eval ALTER TABLE pivex OPTION_LIST='PivotCol=wk,FncCol=amnt,port=$PORT' --eval ALTER TABLE pivex OPTION_LIST='PivotCol=wk,FncCol=amnt,port=$PORT'
SELECT * FROM pivex; SELECT * FROM pivex;
DROP TABLE pivex; DROP TABLE pivex;
DROP TABLE expenses; DROP TABLE expenses;
--echo # --echo #
--echo # Make the PETS table --echo # Make the PETS table
--echo # --echo #
CREATE TABLE pets ( CREATE TABLE pets (
Name VARCHAR(12) NOT NULL, Name VARCHAR(12) NOT NULL,
Race CHAR(6) NOT NULL, Race CHAR(6) NOT NULL,
Number INT NOT NULL) ENGINE=MYISAM; Number INT NOT NULL) ENGINE=MYISAM;
INSERT INTO pets VALUES('John','dog',2); INSERT INTO pets VALUES('John','dog',2);
INSERT INTO pets VALUES('Bill','cat',1); INSERT INTO pets VALUES('Bill','cat',1);
INSERT INTO pets VALUES('Mary','dog',1); INSERT INTO pets VALUES('Mary','dog',1);
INSERT INTO pets VALUES('Mary','cat',1); INSERT INTO pets VALUES('Mary','cat',1);
INSERT INTO pets VALUES('Lisbeth','rabbit',2); INSERT INTO pets VALUES('Lisbeth','rabbit',2);
INSERT INTO pets VALUES('Kevin','cat',2); INSERT INTO pets VALUES('Kevin','cat',2);
INSERT INTO pets VALUES('Kevin','bird',6); INSERT INTO pets VALUES('Kevin','bird',6);
INSERT INTO pets VALUES('Donald','dog',1); INSERT INTO pets VALUES('Donald','dog',1);
INSERT INTO pets VALUES('Donald','fish',3); INSERT INTO pets VALUES('Donald','fish',3);
SELECT * FROM pets; SELECT * FROM pets;
--echo # --echo #
--echo # Pivot the PETS table --echo # Pivot the PETS table
--echo # --echo #
CREATE TABLE pivet ( CREATE TABLE pivet (
name VARCHAR(12) NOT NULL, name VARCHAR(12) NOT NULL,
dog INT NOT NULL DEFAULT 0 FLAG=1, dog INT NOT NULL DEFAULT 0 FLAG=1,
cat INT NOT NULL DEFAULT 0 FLAG=1, cat INT NOT NULL DEFAULT 0 FLAG=1,
rabbit INT NOT NULL DEFAULT 0 FLAG=1, rabbit INT NOT NULL DEFAULT 0 FLAG=1,
bird INT NOT NULL DEFAULT 0 FLAG=1, bird INT NOT NULL DEFAULT 0 FLAG=1,
fish INT NOT NULL DEFAULT 0 FLAG=1) fish INT NOT NULL DEFAULT 0 FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1'; ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
SELECT * FROM pivet; SELECT * FROM pivet;
DROP TABLE pivet; DROP TABLE pivet;
--echo # --echo #
--echo # Testing the "data" column list --echo # Testing the "data" column list
--echo # --echo #
CREATE TABLE pivet ( CREATE TABLE pivet (
name VARCHAR(12) NOT NULL, name VARCHAR(12) NOT NULL,
dog INT NOT NULL DEFAULT 0 FLAG=1, dog INT NOT NULL DEFAULT 0 FLAG=1,
cat INT NOT NULL DEFAULT 0 FLAG=1) cat INT NOT NULL DEFAULT 0 FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1'; ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
--error ER_GET_ERRMSG --error ER_GET_ERRMSG
SELECT * FROM pivet; SELECT * FROM pivet;
ALTER TABLE pivet OPTION_LIST='PivotCol=race,groupby=1,accept=1'; ALTER TABLE pivet OPTION_LIST='PivotCol=race,groupby=1,accept=1';
SELECT * FROM pivet; SELECT * FROM pivet;
DROP TABLE pivet; DROP TABLE pivet;
--echo # --echo #
--echo # Adding a "dump" column --echo # Adding a "dump" column
--echo # --echo #
CREATE TABLE pivet ( CREATE TABLE pivet (
name VARCHAR(12) NOT NULL, name VARCHAR(12) NOT NULL,
dog INT NOT NULL DEFAULT 0 FLAG=1, dog INT NOT NULL DEFAULT 0 FLAG=1,
cat INT NOT NULL DEFAULT 0 FLAG=1, cat INT NOT NULL DEFAULT 0 FLAG=1,
other INT NOT NULL DEFAULT 0 FLAG=2) other INT NOT NULL DEFAULT 0 FLAG=2)
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1'; ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
SELECT * FROM pivet; SELECT * FROM pivet;
DROP TABLE pivet; DROP TABLE pivet;
DROP TABLE pets; DROP TABLE pets;
--echo # --echo #
--echo # MDEV-5734 --echo # MDEV-5734
--echo # --echo #
CREATE TABLE fruit ( CREATE TABLE fruit (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(32) DEFAULT NULL, `name` varchar(32) NOT NULL,
`cnt` int(11) DEFAULT NULL, `cnt` int(11) DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1; ) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
INSERT INTO fruit VALUES (1,'apple',1),(2,'banana',1),(3,'apple',2),(4,'cherry',4),(5,'durazno',2); INSERT INTO fruit VALUES (1,'apple',1),(2,'banana',1),(3,'apple',2),(4,'cherry',4),(5,'durazno',2);
SELECT * FROM fruit; SELECT * FROM fruit;
CREATE TABLE fruit_pivot ENGINE=CONNECT TABLE_TYPE=pivot TABNAME=fruit; CREATE TABLE fruit_pivot ENGINE=CONNECT TABLE_TYPE=pivot TABNAME=fruit;
SELECT * FROM fruit_pivot; SELECT * FROM fruit_pivot;
DROP TABLE fruit_pivot; DROP TABLE fruit_pivot;
DROP TABLE fruit; DROP TABLE fruit;
--remove_file $MYSQLD_DATADIR/test/expenses.txt --remove_file $MYSQLD_DATADIR/test/expenses.txt
/************** MyUtil C++ Program Source Code File (.CPP) **************/ /************** MyUtil C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: MYUTIL */ /* PROGRAM NAME: MYUTIL */
/* ------------- */ /* ------------- */
/* Version 1.1 */ /* Version 1.2 */
/* */ /* */
/* Author Olivier BERTRAND 2013 */ /* Author Olivier BERTRAND 2014 */
/* */ /* */
/* WHAT THIS PROGRAM DOES: */ /* WHAT THIS PROGRAM DOES: */
/* ----------------------- */ /* ----------------------- */
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include "myutil.h" #include "myutil.h"
#define DLL_EXPORT // Items are exported from this DLL #define DLL_EXPORT // Items are exported from this DLL
extern "C" int xconv;
/************************************************************************/ /************************************************************************/
/* Convert from MySQL type name to PlugDB type number */ /* Convert from MySQL type name to PlugDB type number */
/************************************************************************/ /************************************************************************/
...@@ -38,8 +40,7 @@ int MYSQLtoPLG(char *typname, char *var) ...@@ -38,8 +40,7 @@ int MYSQLtoPLG(char *typname, char *var)
type = TYPE_INT; type = TYPE_INT;
else if (!stricmp(typname, "smallint")) else if (!stricmp(typname, "smallint"))
type = TYPE_SHORT; type = TYPE_SHORT;
else if (!stricmp(typname, "char") || !stricmp(typname, "varchar") || else if (!stricmp(typname, "char") || !stricmp(typname, "varchar"))
!stricmp(typname, "text") || !stricmp(typname, "blob"))
type = TYPE_STRING; type = TYPE_STRING;
else if (!stricmp(typname, "double") || !stricmp(typname, "float") || else if (!stricmp(typname, "double") || !stricmp(typname, "float") ||
!stricmp(typname, "real")) !stricmp(typname, "real"))
...@@ -54,7 +55,20 @@ int MYSQLtoPLG(char *typname, char *var) ...@@ -54,7 +55,20 @@ int MYSQLtoPLG(char *typname, char *var)
type = TYPE_BIGINT; type = TYPE_BIGINT;
else if (!stricmp(typname, "tinyint")) else if (!stricmp(typname, "tinyint"))
type = TYPE_TINY; type = TYPE_TINY;
else else if (!stricmp(typname, "text") && var) {
switch (xconv) {
case 1:
type = TYPE_STRING;
*var = 'X';
break;
case 2:
*var = 'K';
default:
type = TYPE_ERROR;
} // endswitch xconv
return type;
} else
type = TYPE_ERROR; type = TYPE_ERROR;
if (var) { if (var) {
...@@ -71,9 +85,11 @@ int MYSQLtoPLG(char *typname, char *var) ...@@ -71,9 +85,11 @@ int MYSQLtoPLG(char *typname, char *var)
else if (!stricmp(typname, "year")) else if (!stricmp(typname, "year"))
*var = 'Y'; *var = 'Y';
} else if (type == TYPE_STRING && stricmp(typname, "char")) } else if (type == TYPE_STRING && !stricmp(typname, "varchar"))
// This is to make the difference between CHAR and VARCHAR // This is to make the difference between CHAR and VARCHAR
*var = 'V'; *var = 'V';
else if (type == TYPE_ERROR && xconv == 2)
*var = 'K';
else else
*var = 0; *var = 0;
...@@ -196,34 +212,50 @@ int MYSQLtoPLG(int mytype, char *var) ...@@ -196,34 +212,50 @@ int MYSQLtoPLG(int mytype, char *var)
#if !defined(ALPHA) #if !defined(ALPHA)
case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VARCHAR:
#endif // !ALPHA) #endif // !ALPHA)
case MYSQL_TYPE_STRING:
type = TYPE_STRING;
break;
case MYSQL_TYPE_BLOB: case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_STRING: if (var) {
type = TYPE_STRING; switch (xconv) {
break; case 1:
if (*var != 'B') {
// This is a TEXT column
type = TYPE_STRING;
*var = 'X';
} else
type = TYPE_ERROR;
break;
case 2:
*var = 'K'; // Skip
default:
type = TYPE_ERROR;
} // endswitch xconv
return type;
} // endif var
default: default:
type = TYPE_ERROR; type = TYPE_ERROR;
} // endswitch mytype } // endswitch mytype
if (var) switch (mytype) { if (var) switch (mytype) {
// This is to make the difference between CHAR and VARCHAR // This is to make the difference between CHAR and VARCHAR
case MYSQL_TYPE_VAR_STRING:
#if !defined(ALPHA) #if !defined(ALPHA)
case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VARCHAR:
#endif // !ALPHA) #endif // !ALPHA)
case MYSQL_TYPE_BLOB: case MYSQL_TYPE_VAR_STRING: *var = 'V'; break;
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB: *var = 'V'; break;
// This is to make the difference between temporal values // This is to make the difference between temporal values
case MYSQL_TYPE_TIMESTAMP: *var = 'S'; break; case MYSQL_TYPE_TIMESTAMP: *var = 'S'; break;
case MYSQL_TYPE_DATE: *var = 'D'; break; case MYSQL_TYPE_DATE: *var = 'D'; break;
case MYSQL_TYPE_DATETIME: *var = 'A'; break; case MYSQL_TYPE_DATETIME: *var = 'A'; break;
case MYSQL_TYPE_YEAR: *var = 'Y'; break; case MYSQL_TYPE_YEAR: *var = 'Y'; break;
case MYSQL_TYPE_TIME: *var = 'T'; break; case MYSQL_TYPE_TIME: *var = 'T'; break;
default: *var = 0; default: *var = 0;
} // endswitch mytype } // endswitch mytype
return type; return type;
......
...@@ -16,6 +16,7 @@ my_bool CloseFileHandle(HANDLE h) ...@@ -16,6 +16,7 @@ my_bool CloseFileHandle(HANDLE h)
#include <sys/stat.h> #include <sys/stat.h>
#include <ctype.h> #include <ctype.h>
#include <fcntl.h> #include <fcntl.h>
#include <pwd.h>
extern FILE *debug; extern FILE *debug;
...@@ -172,16 +173,23 @@ char *_fullpath(char *absPath, const char *relPath, size_t maxLength) ...@@ -172,16 +173,23 @@ char *_fullpath(char *absPath, const char *relPath, size_t maxLength)
// Fixme // Fixme
char *p; char *p;
if( *relPath == '\\' || *relPath == '/' ) { if ( *relPath == '\\' || *relPath == '/' ) {
strncpy(absPath, relPath, maxLength); strncpy(absPath, relPath, maxLength);
} else if(*relPath == '~') { } else if (*relPath == '~') {
// get the path to the home directory // get the path to the home directory
// Fixme struct passwd *pw = getpwuid(getuid());
strncpy(absPath, relPath, maxLength); const char *homedir = pw->pw_dir;
} else {
if (homedir)
strcat(strncpy(absPath, homedir, maxLength), relPath + 1);
else
strncpy(absPath, relPath, maxLength);
} else {
char buff[2*_MAX_PATH]; char buff[2*_MAX_PATH];
assert(getcwd(buff, _MAX_PATH) != NULL); p= getcwd(buff, _MAX_PATH);
assert(p);
strcat(buff,"/"); strcat(buff,"/");
strcat(buff, relPath); strcat(buff, relPath);
strncpy(absPath, buff, maxLength); strncpy(absPath, buff, maxLength);
......
/************** PlgDBSem H Declares Source Code File (.H) **************/ /************** PlgDBSem H Declares Source Code File (.H) **************/
/* Name: PLGDBSEM.H Version 3.6 */ /* Name: PLGDBSEM.H Version 3.6 */
/* */ /* */
/* (C) Copyright to the author Olivier BERTRAND 1998-2014 */ /* (C) Copyright to the author Olivier BERTRAND 1998-2014 */
/* */ /* */
/* This file contains the PlugDB++ application type definitions. */ /* This file contains the PlugDB++ application type definitions. */
/***********************************************************************/ /***********************************************************************/
/***********************************************************************/ /***********************************************************************/
/* Include required application header files */ /* Include required application header files */
/***********************************************************************/ /***********************************************************************/
#include "checklvl.h" #include "checklvl.h"
/***********************************************************************/ /***********************************************************************/
/* DB Constant definitions. */ /* DB Constant definitions. */
/***********************************************************************/ /***********************************************************************/
#if defined(FRENCH) #if defined(FRENCH)
#define DEFAULT_LOCALE "French" #define DEFAULT_LOCALE "French"
#else // !FRENCH #else // !FRENCH
#define DEFAULT_LOCALE "English" #define DEFAULT_LOCALE "English"
#endif // !FRENCH #endif // !FRENCH
#define DOS_MAX_PATH 144 /* Must be the same across systems */ #define DOS_MAX_PATH 144 /* Must be the same across systems */
#define DOS_BUFF_LEN 100 /* Number of lines in binary file buffer */ #define DOS_BUFF_LEN 100 /* Number of lines in binary file buffer */
#undef DOMAIN /* For Unix version */ #undef DOMAIN /* For Unix version */
enum BLKTYP {TYPE_TABLE = 50, /* Table Name/Srcdef/... Block */ enum BLKTYP {TYPE_TABLE = 50, /* Table Name/Srcdef/... Block */
TYPE_COLUMN = 51, /* Column Name/Qualifier Block */ TYPE_COLUMN = 51, /* Column Name/Qualifier Block */
TYPE_TDB = 53, /* Table Description Block */ TYPE_TDB = 53, /* Table Description Block */
TYPE_COLBLK = 54, /* Column Description Block */ TYPE_COLBLK = 54, /* Column Description Block */
TYPE_FILTER = 55, /* Filter Description Block */ TYPE_FILTER = 55, /* Filter Description Block */
TYPE_ARRAY = 63, /* General array type */ TYPE_ARRAY = 63, /* General array type */
TYPE_PSZ = 64, /* Pointer to String ended by 0 */ TYPE_PSZ = 64, /* Pointer to String ended by 0 */
TYPE_SQL = 65, /* Pointer to SQL block */ TYPE_SQL = 65, /* Pointer to SQL block */
TYPE_XOBJECT = 69, /* Extended DB object */ TYPE_XOBJECT = 69, /* Extended DB object */
TYPE_COLCRT = 71, /* Column creation block */ TYPE_COLCRT = 71, /* Column creation block */
TYPE_CONST = 72, /* Constant */ TYPE_CONST = 72, /* Constant */
/*-------------------- type tokenized string --------------------------*/ /*-------------------- type tokenized string --------------------------*/
TYPE_DATE = 8, /* Timestamp */ TYPE_DATE = 8, /* Timestamp */
/*-------------------- additional values used by LNA ------------------*/ /*-------------------- additional values used by LNA ------------------*/
TYPE_COLIST = 14, /* Column list */ TYPE_COLIST = 14, /* Column list */
TYPE_COL = 41, /* Column */ TYPE_COL = 41, /* Column */
/*-------------------- types used by scalar functions -----------------*/ /*-------------------- types used by scalar functions -----------------*/
TYPE_NUM = 12, TYPE_NUM = 12,
TYPE_UNDEF = 13, TYPE_UNDEF = 13,
/*-------------------- file blocks used when closing ------------------*/ /*-------------------- file blocks used when closing ------------------*/
TYPE_FB_FILE = 22, /* File block (stream) */ TYPE_FB_FILE = 22, /* File block (stream) */
TYPE_FB_MAP = 23, /* Mapped file block (storage) */ TYPE_FB_MAP = 23, /* Mapped file block (storage) */
TYPE_FB_HANDLE = 24, /* File block (handle) */ TYPE_FB_HANDLE = 24, /* File block (handle) */
TYPE_FB_XML = 21, /* DOM XML file block */ TYPE_FB_XML = 21, /* DOM XML file block */
TYPE_FB_XML2 = 27}; /* libxml2 XML file block */ TYPE_FB_XML2 = 27}; /* libxml2 XML file block */
enum TABTYPE {TAB_UNDEF = 0, /* Table of undefined type */ enum TABTYPE {TAB_UNDEF = 0, /* Table of undefined type */
TAB_DOS = 1, /* Fixed column offset, variable LRECL */ TAB_DOS = 1, /* Fixed column offset, variable LRECL */
TAB_FIX = 2, /* Fixed column offset, fixed LRECL */ TAB_FIX = 2, /* Fixed column offset, fixed LRECL */
TAB_BIN = 3, /* Like FIX but can have binary fields */ TAB_BIN = 3, /* Like FIX but can have binary fields */
TAB_CSV = 4, /* DOS files with CSV records */ TAB_CSV = 4, /* DOS files with CSV records */
TAB_FMT = 5, /* DOS files with formatted recordss */ TAB_FMT = 5, /* DOS files with formatted recordss */
TAB_DBF = 6, /* DBF Dbase or Foxpro files */ TAB_DBF = 6, /* DBF Dbase or Foxpro files */
TAB_XML = 7, /* XML or HTML files */ TAB_XML = 7, /* XML or HTML files */
TAB_INI = 8, /* INI or CFG files */ TAB_INI = 8, /* INI or CFG files */
TAB_VEC = 9, /* Vector column arrangement */ TAB_VEC = 9, /* Vector column arrangement */
TAB_ODBC = 10, /* Table accessed via (unix)ODBC */ TAB_ODBC = 10, /* Table accessed via (unix)ODBC */
TAB_MYSQL = 11, /* MySQL table accessed via MySQL API */ TAB_MYSQL = 11, /* MySQL table accessed via MySQL API */
TAB_DIR = 12, /* Returns a list of files */ TAB_DIR = 12, /* Returns a list of files */
TAB_MAC = 13, /* MAC address (Windows only) */ TAB_MAC = 13, /* MAC address (Windows only) */
TAB_WMI = 14, /* WMI tables (Windows only) */ TAB_WMI = 14, /* WMI tables (Windows only) */
TAB_TBL = 15, /* Collection of CONNECT tables */ TAB_TBL = 15, /* Collection of CONNECT tables */
TAB_OEM = 16, /* OEM implemented table */ TAB_OEM = 16, /* OEM implemented table */
TAB_XCL = 17, /* XCL table */ TAB_XCL = 17, /* XCL table */
TAB_OCCUR = 18, /* OCCUR table */ TAB_OCCUR = 18, /* OCCUR table */
TAB_PRX = 19, /* Proxy (catalog) table */ TAB_PRX = 19, /* Proxy (catalog) table */
TAB_PLG = 20, /* PLG NIY */ TAB_PLG = 20, /* PLG NIY */
TAB_PIVOT = 21, /* PIVOT NIY */ TAB_PIVOT = 21, /* PIVOT NIY */
TAB_JCT = 22, /* Junction tables NIY */ TAB_JCT = 22, /* Junction tables NIY */
TAB_DMY = 23, /* DMY Dummy tables NIY */ TAB_DMY = 23, /* DMY Dummy tables NIY */
TAB_NIY = 24}; /* Table not implemented yet */ TAB_NIY = 24}; /* Table not implemented yet */
enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_ROWID = 1, /* ROWID type (special column) */ TYPE_AM_ROWID = 1, /* ROWID type (special column) */
TYPE_AM_FILID = 2, /* FILEID type (special column) */ TYPE_AM_FILID = 2, /* FILEID type (special column) */
TYPE_AM_TAB = 3, /* Table (any type) */ TYPE_AM_TAB = 3, /* Table (any type) */
TYPE_AM_VIEW = 4, /* VIEW (any type) */ TYPE_AM_VIEW = 4, /* VIEW (any type) */
TYPE_AM_SRVID = 5, /* SERVID type (special column) */ TYPE_AM_SRVID = 5, /* SERVID type (special column) */
TYPE_AM_TABID = 6, /* TABID type (special column) */ TYPE_AM_TABID = 6, /* TABID type (special column) */
TYPE_AM_CNSID = 7, /* CONSTID type (special column) */ TYPE_AM_CNSID = 7, /* CONSTID type (special column) */
TYPE_AM_COUNT = 10, /* CPT AM type no (count table) */ TYPE_AM_COUNT = 10, /* CPT AM type no (count table) */
TYPE_AM_DCD = 20, /* Decode access method type no */ TYPE_AM_DCD = 20, /* Decode access method type no */
TYPE_AM_CMS = 30, /* CMS access method type no */ TYPE_AM_CMS = 30, /* CMS access method type no */
TYPE_AM_MAP = 32, /* MAP access method type no */ TYPE_AM_MAP = 32, /* MAP access method type no */
TYPE_AM_FMT = 33, /* DOS files with formatted recs */ TYPE_AM_FMT = 33, /* DOS files with formatted recs */
TYPE_AM_CSV = 34, /* DOS files with CSV records */ TYPE_AM_CSV = 34, /* DOS files with CSV records */
TYPE_AM_MCV = 35, /* MAP files with CSV records */ TYPE_AM_MCV = 35, /* MAP files with CSV records */
TYPE_AM_DOS = 36, /* DOS am with Lrecl = V */ TYPE_AM_DOS = 36, /* DOS am with Lrecl = V */
TYPE_AM_FIX = 38, /* DOS am with Lrecl = F */ TYPE_AM_FIX = 38, /* DOS am with Lrecl = F */
TYPE_AM_BIN = 39, /* DOS am with Lrecl = B */ TYPE_AM_BIN = 39, /* DOS am with Lrecl = B */
TYPE_AM_VCT = 40, /* VCT access method type no */ TYPE_AM_VCT = 40, /* VCT access method type no */
TYPE_AM_VMP = 43, /* VMP access method type no */ TYPE_AM_VMP = 43, /* VMP access method type no */
TYPE_AM_QRY = 50, /* QRY access method type no */ TYPE_AM_QRY = 50, /* QRY access method type no */
TYPE_AM_QRS = 51, /* QRYRES access method type no */ TYPE_AM_QRS = 51, /* QRYRES access method type no */
TYPE_AM_SQL = 60, /* SQL VIEW access method type */ TYPE_AM_SQL = 60, /* SQL VIEW access method type */
TYPE_AM_PLG = 70, /* PLG access method type no */ TYPE_AM_PLG = 70, /* PLG access method type no */
TYPE_AM_PLM = 71, /* PDM access method type no */ TYPE_AM_PLM = 71, /* PDM access method type no */
TYPE_AM_DOM = 80, /* DOM access method type no */ TYPE_AM_DOM = 80, /* DOM access method type no */
TYPE_AM_DIR = 90, /* DIR access method type no */ TYPE_AM_DIR = 90, /* DIR access method type no */
TYPE_AM_ODBC = 100, /* ODBC access method type no */ TYPE_AM_ODBC = 100, /* ODBC access method type no */
TYPE_AM_XDBC = 101, /* XDBC access method type no */ TYPE_AM_XDBC = 101, /* XDBC access method type no */
TYPE_AM_OEM = 110, /* OEM access method type no */ TYPE_AM_OEM = 110, /* OEM access method type no */
TYPE_AM_TBL = 115, /* TBL access method type no */ TYPE_AM_TBL = 115, /* TBL access method type no */
TYPE_AM_PIVOT = 120, /* PIVOT access method type no */ TYPE_AM_PIVOT = 120, /* PIVOT access method type no */
TYPE_AM_SRC = 121, /* PIVOT multiple column type no */ TYPE_AM_SRC = 121, /* PIVOT multiple column type no */
TYPE_AM_FNC = 122, /* PIVOT source column type no */ TYPE_AM_FNC = 122, /* PIVOT source column type no */
TYPE_AM_XCOL = 124, /* XCOL access method type no */ TYPE_AM_XCOL = 124, /* XCOL access method type no */
TYPE_AM_XML = 127, /* XML access method type no */ TYPE_AM_XML = 127, /* XML access method type no */
TYPE_AM_OCCUR = 128, /* OCCUR access method type no */ TYPE_AM_OCCUR = 128, /* OCCUR access method type no */
TYPE_AM_PRX = 129, /* PROXY access method type no */ TYPE_AM_PRX = 129, /* PROXY access method type no */
TYPE_AM_XTB = 130, /* SYS table access method type */ TYPE_AM_XTB = 130, /* SYS table access method type */
TYPE_AM_BLK = 131, /* BLK access method type no */ TYPE_AM_BLK = 131, /* BLK access method type no */
TYPE_AM_ZIP = 132, /* ZIP access method type no */ TYPE_AM_ZIP = 132, /* ZIP access method type no */
TYPE_AM_ZLIB = 133, /* ZLIB access method type no */ TYPE_AM_ZLIB = 133, /* ZLIB access method type no */
TYPE_AM_MAC = 137, /* MAC table access method type */ TYPE_AM_MAC = 137, /* MAC table access method type */
TYPE_AM_WMI = 139, /* WMI table access method type */ TYPE_AM_WMI = 139, /* WMI table access method type */
TYPE_AM_XCL = 140, /* SYS column access method type */ TYPE_AM_XCL = 140, /* SYS column access method type */
TYPE_AM_INI = 150, /* INI files access method */ TYPE_AM_INI = 150, /* INI files access method */
TYPE_AM_TFC = 155, /* TFC (Circa) (Fuzzy compare) */ TYPE_AM_TFC = 155, /* TFC (Circa) (Fuzzy compare) */
TYPE_AM_DBF = 160, /* DBF Dbase files am type no */ TYPE_AM_DBF = 160, /* DBF Dbase files am type no */
TYPE_AM_JCT = 170, /* Junction tables am type no */ TYPE_AM_JCT = 170, /* Junction tables am type no */
TYPE_AM_DMY = 172, /* DMY Dummy tables am type no */ TYPE_AM_DMY = 172, /* DMY Dummy tables am type no */
TYPE_AM_SET = 180, /* SET Set tables am type no */ TYPE_AM_SET = 180, /* SET Set tables am type no */
TYPE_AM_MYSQL = 192, /* MYSQL access method type no */ TYPE_AM_MYSQL = 192, /* MYSQL access method type no */
TYPE_AM_MYX = 193, /* MYSQL EXEC access method type */ TYPE_AM_MYX = 193, /* MYSQL EXEC access method type */
TYPE_AM_CAT = 195, /* Catalog access method type no */ TYPE_AM_CAT = 195, /* Catalog access method type no */
TYPE_AM_OUT = 200}; /* Output relations (storage) */ TYPE_AM_OUT = 200}; /* Output relations (storage) */
enum RECFM {RECFM_NAF = -2, /* Not a file */ enum RECFM {RECFM_NAF = -2, /* Not a file */
RECFM_OEM = -1, /* OEM file access method */ RECFM_OEM = -1, /* OEM file access method */
RECFM_VAR = 0, /* Varying length DOS files */ RECFM_VAR = 0, /* Varying length DOS files */
RECFM_FIX = 1, /* Fixed length DOS files */ RECFM_FIX = 1, /* Fixed length DOS files */
RECFM_BIN = 2, /* Binary DOS files (also fixed) */ RECFM_BIN = 2, /* Binary DOS files (also fixed) */
RECFM_VCT = 3, /* VCT formatted files */ RECFM_VCT = 3, /* VCT formatted files */
RECFM_ODBC = 4, /* Table accessed via ODBC */ RECFM_ODBC = 4, /* Table accessed via ODBC */
RECFM_PLG = 5, /* Table accessed via PLGconn */ RECFM_PLG = 5, /* Table accessed via PLGconn */
RECFM_DBF = 6}; /* DBase formatted file */ RECFM_DBF = 6}; /* DBase formatted file */
enum MISC {DB_TABNO = 1, /* DB routines in Utility Table */ enum MISC {DB_TABNO = 1, /* DB routines in Utility Table */
MAX_MULT_KEY = 10, /* Max multiple key number */ MAX_MULT_KEY = 10, /* Max multiple key number */
NAM_LEN = 128, /* Length of col and tab names */ NAM_LEN = 128, /* Length of col and tab names */
ARRAY_SIZE = 50, /* Default array block size */ ARRAY_SIZE = 50, /* Default array block size */
// MAXRES = 500, /* Default maximum result lines */ // MAXRES = 500, /* Default maximum result lines */
// MAXLIN = 10000, /* Default maximum data lines */ // MAXLIN = 10000, /* Default maximum data lines */
MAXBMP = 32}; /* Default XDB2 max bitmap size */ MAXBMP = 32}; /* Default XDB2 max bitmap size */
#if 0 #if 0
enum ALGMOD {AMOD_AUTO = 0, /* PLG chooses best algorithm */ enum ALGMOD {AMOD_AUTO = 0, /* PLG chooses best algorithm */
AMOD_SQL = 1, /* Use SQL algorithm */ AMOD_SQL = 1, /* Use SQL algorithm */
AMOD_QRY = 2}; /* Use QUERY algorithm */ AMOD_QRY = 2}; /* Use QUERY algorithm */
#endif // 0 #endif // 0
enum MODE {MODE_ERROR = -1, /* Invalid mode */ enum MODE {MODE_ERROR = -1, /* Invalid mode */
MODE_ANY = 0, /* Unspecified mode */ MODE_ANY = 0, /* Unspecified mode */
MODE_READ = 10, /* Input/Output mode */ MODE_READ = 10, /* Input/Output mode */
MODE_WRITE = 20, /* Input/Output mode */ MODE_WRITE = 20, /* Input/Output mode */
MODE_UPDATE = 30, /* Input/Output mode */ MODE_UPDATE = 30, /* Input/Output mode */
MODE_INSERT = 40, /* Input/Output mode */ MODE_INSERT = 40, /* Input/Output mode */
MODE_DELETE = 50, /* Input/Output mode */ MODE_DELETE = 50, /* Input/Output mode */
MODE_ALTER = 60}; /* alter mode */ MODE_ALTER = 60}; /* alter mode */
#if !defined(RC_OK_DEFINED) #if !defined(RC_OK_DEFINED)
#define RC_OK_DEFINED #define RC_OK_DEFINED
enum RCODE {RC_OK = 0, /* No error return code */ enum RCODE {RC_OK = 0, /* No error return code */
RC_NF = 1, /* Not found return code */ RC_NF = 1, /* Not found return code */
RC_EF = 2, /* End of file return code */ RC_EF = 2, /* End of file return code */
RC_FX = 3, /* Error return code */ RC_FX = 3, /* Error return code */
RC_INFO = 4}; /* Success with info */ RC_INFO = 4}; /* Success with info */
#endif // !RC_OK_DEFINED #endif // !RC_OK_DEFINED
enum OPVAL {OP_EQ = 1, /* Filtering operator = */ enum OPVAL {OP_EQ = 1, /* Filtering operator = */
OP_NE = 2, /* Filtering operator != */ OP_NE = 2, /* Filtering operator != */
OP_GT = 3, /* Filtering operator > */ OP_GT = 3, /* Filtering operator > */
OP_GE = 4, /* Filtering operator >= */ OP_GE = 4, /* Filtering operator >= */
OP_LT = 5, /* Filtering operator < */ OP_LT = 5, /* Filtering operator < */
OP_LE = 6, /* Filtering operator <= */ OP_LE = 6, /* Filtering operator <= */
OP_IN = 7, /* Filtering operator IN */ OP_IN = 7, /* Filtering operator IN */
OP_NULL = 8, /* Filtering operator IS NULL */ OP_NULL = 8, /* Filtering operator IS NULL */
OP_EXIST = 9, /* Filtering operator EXISTS */ OP_EXIST = 9, /* Filtering operator EXISTS */
OP_LIKE = 10, /* Filtering operator LIKE */ OP_LIKE = 10, /* Filtering operator LIKE */
OP_LOJ = -1, /* Filter op LEFT OUTER JOIN */ OP_LOJ = -1, /* Filter op LEFT OUTER JOIN */
OP_ROJ = -2, /* Filter op RIGHT OUTER JOIN */ OP_ROJ = -2, /* Filter op RIGHT OUTER JOIN */
OP_DTJ = -3, /* Filter op DISTINCT JOIN */ OP_DTJ = -3, /* Filter op DISTINCT JOIN */
OP_XX = 11, /* Filtering operator unknown */ OP_XX = 11, /* Filtering operator unknown */
OP_AND = 12, /* Filtering operator AND */ OP_AND = 12, /* Filtering operator AND */
OP_OR = 13, /* Filtering operator OR */ OP_OR = 13, /* Filtering operator OR */
OP_CNC = 14, /* Expression Concat operator */ OP_CNC = 14, /* Expression Concat operator */
OP_NOT = 15, /* Filtering operator NOT */ OP_NOT = 15, /* Filtering operator NOT */
OP_SEP = 20, /* Filtering separator */ OP_SEP = 20, /* Filtering separator */
OP_ADD = 16, /* Expression Add operator */ OP_ADD = 16, /* Expression Add operator */
OP_SUB = 17, /* Expression Substract operator */ OP_SUB = 17, /* Expression Substract operator */
OP_MULT = 18, /* Expression Multiply operator */ OP_MULT = 18, /* Expression Multiply operator */
OP_DIV = 19, /* Expression Divide operator */ OP_DIV = 19, /* Expression Divide operator */
OP_NOP = 21, /* Scalar function is nopped */ OP_NOP = 21, /* Scalar function is nopped */
OP_NUM = 22, /* Scalar function Op Num */ OP_NUM = 22, /* Scalar function Op Num */
OP_ABS = 23, /* Scalar function Op Abs */ OP_ABS = 23, /* Scalar function Op Abs */
OP_MAX = 24, /* Scalar function Op Max */ OP_MAX = 24, /* Scalar function Op Max */
OP_MIN = 25, /* Scalar function Op Min */ OP_MIN = 25, /* Scalar function Op Min */
OP_CEIL = 26, /* Scalar function Op Ceil */ OP_CEIL = 26, /* Scalar function Op Ceil */
OP_FLOOR = 27, /* Scalar function Op Floor */ OP_FLOOR = 27, /* Scalar function Op Floor */
OP_MOD = 28, /* Scalar function Op Mod */ OP_MOD = 28, /* Scalar function Op Mod */
OP_ROUND = 29, /* Scalar function Op Round */ OP_ROUND = 29, /* Scalar function Op Round */
OP_SIGN = 30, /* Scalar function Op Sign */ OP_SIGN = 30, /* Scalar function Op Sign */
OP_LEN = 31, /* Scalar function Op Len */ OP_LEN = 31, /* Scalar function Op Len */
OP_INSTR = 32, /* Scalar function Op Instr */ OP_INSTR = 32, /* Scalar function Op Instr */
OP_LEFT = 33, /* Scalar function Op Left */ OP_LEFT = 33, /* Scalar function Op Left */
OP_RIGHT = 34, /* Scalar function Op Right */ OP_RIGHT = 34, /* Scalar function Op Right */
OP_ASCII = 35, /* Scalar function Op Ascii */ OP_ASCII = 35, /* Scalar function Op Ascii */
OP_EXP = 36, /* Scalar function Op Exp */ OP_EXP = 36, /* Scalar function Op Exp */
OP_LN = 37, /* Scalar function Op Ln */ OP_LN = 37, /* Scalar function Op Ln */
OP_LOG = 38, /* Scalar function Op Log */ OP_LOG = 38, /* Scalar function Op Log */
OP_POWER = 39, /* Scalar function Op Power */ OP_POWER = 39, /* Scalar function Op Power */
OP_SQRT = 40, /* Scalar function Op Sqrt */ OP_SQRT = 40, /* Scalar function Op Sqrt */
OP_COS = 41, /* Scalar function Op Cos */ OP_COS = 41, /* Scalar function Op Cos */
OP_COSH = 42, /* Scalar function Op Cosh */ OP_COSH = 42, /* Scalar function Op Cosh */
OP_SIN = 43, /* Scalar function Op Sin */ OP_SIN = 43, /* Scalar function Op Sin */
OP_SINH = 44, /* Scalar function Op Sinh */ OP_SINH = 44, /* Scalar function Op Sinh */
OP_TAN = 45, /* Scalar function Op Tan */ OP_TAN = 45, /* Scalar function Op Tan */
OP_TANH = 46, /* Scalar function Op Tanh */ OP_TANH = 46, /* Scalar function Op Tanh */
OP_USER = 47, /* Scalar function Op User */ OP_USER = 47, /* Scalar function Op User */
OP_CHAR = 48, /* Scalar function Op Char */ OP_CHAR = 48, /* Scalar function Op Char */
OP_UPPER = 49, /* Scalar function Op Upper */ OP_UPPER = 49, /* Scalar function Op Upper */
OP_LOWER = 50, /* Scalar function Op Lower */ OP_LOWER = 50, /* Scalar function Op Lower */
OP_RPAD = 51, /* Scalar function Op Rpad */ OP_RPAD = 51, /* Scalar function Op Rpad */
OP_LPAD = 52, /* Scalar function Op Lpad */ OP_LPAD = 52, /* Scalar function Op Lpad */
OP_LTRIM = 53, /* Scalar function Op Ltrim */ OP_LTRIM = 53, /* Scalar function Op Ltrim */
OP_RTRIM = 54, /* Scalar function Op Rtrim */ OP_RTRIM = 54, /* Scalar function Op Rtrim */
OP_REPL = 55, /* Scalar function Op Replace */ OP_REPL = 55, /* Scalar function Op Replace */
OP_SUBST = 56, /* Scalar function Op Substr */ OP_SUBST = 56, /* Scalar function Op Substr */
OP_LJUST = 57, /* Scalar function Op Ljustify */ OP_LJUST = 57, /* Scalar function Op Ljustify */
OP_RJUST = 58, /* Scalar function Op Rjustify */ OP_RJUST = 58, /* Scalar function Op Rjustify */
OP_CJUST = 59, /* Scalar function Op Cjustify */ OP_CJUST = 59, /* Scalar function Op Cjustify */
OP_ENCODE = 60, /* Scalar function Op Encode */ OP_ENCODE = 60, /* Scalar function Op Encode */
OP_DECODE = 61, /* Scalar function Op Decode */ OP_DECODE = 61, /* Scalar function Op Decode */
OP_SEQU = 62, /* Scalar function Op Sequence */ OP_SEQU = 62, /* Scalar function Op Sequence */
OP_IF = 63, /* Scalar function Op If */ OP_IF = 63, /* Scalar function Op If */
OP_STRING = 64, /* Scalar function Op String */ OP_STRING = 64, /* Scalar function Op String */
OP_TOKEN = 65, /* Scalar function Op Token */ OP_TOKEN = 65, /* Scalar function Op Token */
OP_SNDX = 66, /* Scalar function Op Soundex */ OP_SNDX = 66, /* Scalar function Op Soundex */
OP_DATE = 67, /* Scalar function Op Date */ OP_DATE = 67, /* Scalar function Op Date */
OP_MDAY = 68, /* Scalar function Op Month Day */ OP_MDAY = 68, /* Scalar function Op Month Day */
OP_MONTH = 69, /* Scalar function Op Month of */ OP_MONTH = 69, /* Scalar function Op Month of */
OP_YEAR = 70, /* Scalar function Op Year of */ OP_YEAR = 70, /* Scalar function Op Year of */
OP_WDAY = 71, /* Scalar function Op Week Day */ OP_WDAY = 71, /* Scalar function Op Week Day */
OP_YDAY = 72, /* Scalar function Op Year Day */ OP_YDAY = 72, /* Scalar function Op Year Day */
OP_DBTWN = 73, /* Scalar function Op Days betwn */ OP_DBTWN = 73, /* Scalar function Op Days betwn */
OP_MBTWN = 74, /* Scalar function Op Months btw */ OP_MBTWN = 74, /* Scalar function Op Months btw */
OP_YBTWN = 75, /* Scalar function Op Years btwn */ OP_YBTWN = 75, /* Scalar function Op Years btwn */
OP_ADDAY = 76, /* Scalar function Op Add Days */ OP_ADDAY = 76, /* Scalar function Op Add Days */
OP_ADDMTH = 77, /* Scalar function Op Add Months */ OP_ADDMTH = 77, /* Scalar function Op Add Months */
OP_ADDYR = 78, /* Scalar function Op Add Years */ OP_ADDYR = 78, /* Scalar function Op Add Years */
OP_NXTDAY = 79, /* Scalar function Op Next Day */ OP_NXTDAY = 79, /* Scalar function Op Next Day */
OP_SYSDT = 80, /* Scalar function Op SysDate */ OP_SYSDT = 80, /* Scalar function Op SysDate */
OP_DELTA = 81, /* Scalar function Op Delta */ OP_DELTA = 81, /* Scalar function Op Delta */
OP_LAST = 82, /* Scalar function Op Last */ OP_LAST = 82, /* Scalar function Op Last */
OP_IFF = 83, /* Scalar function Op Iff */ OP_IFF = 83, /* Scalar function Op Iff */
OP_MAVG = 84, /* Scalar function Op Moving Avg */ OP_MAVG = 84, /* Scalar function Op Moving Avg */
OP_VWAP = 85, /* Scalar function Op VWAP */ OP_VWAP = 85, /* Scalar function Op VWAP */
OP_TIME = 86, /* Scalar function Op TIME */ OP_TIME = 86, /* Scalar function Op TIME */
OP_SETLEN = 87, /* Scalar function Op Set Length */ OP_SETLEN = 87, /* Scalar function Op Set Length */
OP_TRANSL = 88, /* Scalar function Op Translate */ OP_TRANSL = 88, /* Scalar function Op Translate */
OP_BITAND = 89, /* Expression BitAnd operator */ OP_BITAND = 89, /* Expression BitAnd operator */
OP_BITOR = 90, /* Expression BitOr operator */ OP_BITOR = 90, /* Expression BitOr operator */
OP_BITXOR = 91, /* Expression XOR operator */ OP_BITXOR = 91, /* Expression XOR operator */
OP_BITNOT = 92, /* Expression Complement operator*/ OP_BITNOT = 92, /* Expression Complement operator*/
OP_CNTIN = 93, /* Scalar function Count In */ OP_CNTIN = 93, /* Scalar function Count In */
OP_FDISK = 94, /* Scalar function Disk of fileid*/ OP_FDISK = 94, /* Scalar function Disk of fileid*/
OP_FPATH = 95, /* Scalar function Path of fileid*/ OP_FPATH = 95, /* Scalar function Path of fileid*/
OP_FNAME = 96, /* Scalar function Name of fileid*/ OP_FNAME = 96, /* Scalar function Name of fileid*/
OP_FTYPE = 97, /* Scalar function Type of fileid*/ OP_FTYPE = 97, /* Scalar function Type of fileid*/
OP_XDATE = 98, /* Scalar function Op Fmt Date */ OP_XDATE = 98, /* Scalar function Op Fmt Date */
OP_SWITCH = 99, /* Scalar function Op Switch */ OP_SWITCH = 99, /* Scalar function Op Switch */
OP_EXIT = 100, /* Scalar function Op Exit */ OP_EXIT = 100, /* Scalar function Op Exit */
OP_LIT = 101, /* Scalar function Op Literal */ OP_LIT = 101, /* Scalar function Op Literal */
OP_LOCALE = 102, /* Scalar function Op Locale */ OP_LOCALE = 102, /* Scalar function Op Locale */
OP_FRNCH = 103, /* Scalar function Op French */ OP_FRNCH = 103, /* Scalar function Op French */
OP_ENGLSH = 104, /* Scalar function Op English */ OP_ENGLSH = 104, /* Scalar function Op English */
OP_RAND = 105, /* Scalar function Op Rand(om) */ OP_RAND = 105, /* Scalar function Op Rand(om) */
OP_FIRST = 106, /* Index operator Find First */ OP_FIRST = 106, /* Index operator Find First */
OP_NEXT = 107, /* Index operator Find Next */ OP_NEXT = 107, /* Index operator Find Next */
OP_SAME = 108, /* Index operator Find Next Same */ OP_SAME = 108, /* Index operator Find Next Same */
OP_FSTDIF = 109, /* Index operator Find First dif */ OP_FSTDIF = 109, /* Index operator Find First dif */
OP_NXTDIF = 110, /* Index operator Find Next dif */ OP_NXTDIF = 110, /* Index operator Find Next dif */
OP_VAL = 111, /* Scalar function Op Valist */ OP_VAL = 111, /* Scalar function Op Valist */
OP_QUART = 112, /* Scalar function Op QUARTER */ OP_QUART = 112, /* Scalar function Op QUARTER */
OP_CURDT = 113, /* Scalar function Op CurDate */ OP_CURDT = 113, /* Scalar function Op CurDate */
OP_NWEEK = 114, /* Scalar function Op Week number*/ OP_NWEEK = 114, /* Scalar function Op Week number*/
OP_ROW = 115, /* Scalar function Op Row */ OP_ROW = 115, /* Scalar function Op Row */
OP_SYSTEM = 200, /* Scalar function Op System */ OP_PREV = 116, /* Index operator Find Previous */
OP_REMOVE = 201, /* Scalar function Op Remove */ OP_SYSTEM = 200, /* Scalar function Op System */
OP_RENAME = 202, /* Scalar function Op Rename */ OP_REMOVE = 201, /* Scalar function Op Remove */
OP_FCOMP = 203}; /* Scalar function Op Compare */ OP_RENAME = 202, /* Scalar function Op Rename */
OP_FCOMP = 203}; /* Scalar function Op Compare */
enum TUSE {USE_NO = 0, /* Table is not yet linearized */
USE_LIN = 1, /* Table is linearized */ enum TUSE {USE_NO = 0, /* Table is not yet linearized */
USE_READY = 2, /* Column buffers are allocated */ USE_LIN = 1, /* Table is linearized */
USE_OPEN = 3, /* Table is open */ USE_READY = 2, /* Column buffers are allocated */
USE_CNT = 4, /* Specific to LNA */ USE_OPEN = 3, /* Table is open */
USE_NOKEY = 5}; /* Specific to SqlToHql */ USE_CNT = 4, /* Specific to LNA */
USE_NOKEY = 5}; /* Specific to SqlToHql */
/***********************************************************************/
/* Following definitions are used to indicate the status of a column. */ /***********************************************************************/
/***********************************************************************/ /* Following definitions are used to indicate the status of a column. */
enum STATUS {BUF_NO = 0x00, /* Column buffer not allocated */ /***********************************************************************/
BUF_EMPTY = 0x01, /* Column buffer is empty */ enum STATUS {BUF_NO = 0x00, /* Column buffer not allocated */
BUF_READY = 0x02, /* Column buffer is ready */ BUF_EMPTY = 0x01, /* Column buffer is empty */
BUF_READ = 0x04, /* Column buffer has read value */ BUF_READY = 0x02, /* Column buffer is ready */
BUF_MAPPED = 0x08}; /* Used by the VMPFAM class */ BUF_READ = 0x04, /* Column buffer has read value */
BUF_MAPPED = 0x08}; /* Used by the VMPFAM class */
/***********************************************************************/
/* Following definitions are used to indicate how a column is used. */ /***********************************************************************/
/* Corresponding bits are ON if the column is used in: */ /* Following definitions are used to indicate how a column is used. */
/***********************************************************************/ /* Corresponding bits are ON if the column is used in: */
enum COLUSE {U_P = 0x01, /* the projection list. */ /***********************************************************************/
U_J_EXT = 0x02, /* a join filter. */ enum COLUSE {U_P = 0x01, /* the projection list. */
U_J_INT = 0x04, /* a join after linearisation. */ U_J_EXT = 0x02, /* a join filter. */
/*-- Such a column have a constant value throughout a subquery eval. --*/ U_J_INT = 0x04, /* a join after linearisation. */
U_CORREL = 0x08, /* a correlated sub-query */ /*-- Such a column have a constant value throughout a subquery eval. --*/
/*-------------------- additional values used by CONNECT --------------*/ U_CORREL = 0x08, /* a correlated sub-query */
U_VAR = 0x10, /* a VARCHAR column */ /*-------------------- additional values used by CONNECT --------------*/
U_VIRTUAL = 0x20, /* a VIRTUAL column */ U_VAR = 0x10, /* a VARCHAR column */
U_NULLS = 0x40, /* The column may have nulls */ U_VIRTUAL = 0x20, /* a VIRTUAL column */
U_IS_NULL = 0x80, /* The column has a null value */ U_NULLS = 0x40, /* The column may have nulls */
U_SPECIAL = 0x100, /* The column is special */ U_IS_NULL = 0x80, /* The column has a null value */
U_UNSIGNED = 0x200, /* The column type is unsigned */ U_SPECIAL = 0x100, /* The column is special */
U_ZEROFILL = 0x400}; /* The column is zero filled */ U_UNSIGNED = 0x200, /* The column type is unsigned */
U_ZEROFILL = 0x400}; /* The column is zero filled */
/***********************************************************************/
/* DB description class and block pointer definitions. */ /***********************************************************************/
/***********************************************************************/ /* DB description class and block pointer definitions. */
typedef class XTAB *PTABLE; /***********************************************************************/
typedef class COLUMN *PCOLUMN; typedef class XTAB *PTABLE;
typedef class XOBJECT *PXOB; typedef class COLUMN *PCOLUMN;
typedef class COLBLK *PCOL; typedef class XOBJECT *PXOB;
typedef class TDB *PTDB; typedef class COLBLK *PCOL;
typedef class TDBASE *PTDBASE; typedef class TDB *PTDB;
typedef class TDBDOS *PTDBDOS; typedef class TDBASE *PTDBASE;
typedef class TDBFIX *PTDBFIX; typedef class TDBDOS *PTDBDOS;
typedef class TDBFMT *PTDBFMT; typedef class TDBFIX *PTDBFIX;
typedef class TDBCSV *PTDBCSV; typedef class TDBFMT *PTDBFMT;
typedef class TDBDOM *PTDBDOM; typedef class TDBCSV *PTDBCSV;
typedef class TDBDIR *PTDBDIR; typedef class TDBDOM *PTDBDOM;
typedef class DOSCOL *PDOSCOL; typedef class TDBDIR *PTDBDIR;
typedef class CSVCOL *PCSVCOL; typedef class DOSCOL *PDOSCOL;
typedef class MAPCOL *PMAPCOL; typedef class CSVCOL *PCSVCOL;
typedef class TDBMFT *PTDBMFT; typedef class MAPCOL *PMAPCOL;
typedef class TDBMCV *PTDBMCV; typedef class TDBMFT *PTDBMFT;
typedef class MCVCOL *PMCVCOL; typedef class TDBMCV *PTDBMCV;
typedef class RESCOL *PRESCOL; typedef class MCVCOL *PMCVCOL;
typedef class XXBASE *PKXBASE; typedef class RESCOL *PRESCOL;
typedef class KXYCOL *PXCOL; typedef class XXBASE *PKXBASE;
typedef class CATALOG *PCATLG; typedef class KXYCOL *PXCOL;
typedef class RELDEF *PRELDEF; typedef class CATALOG *PCATLG;
typedef class TABDEF *PTABDEF; typedef class RELDEF *PRELDEF;
typedef class DOSDEF *PDOSDEF; typedef class TABDEF *PTABDEF;
typedef class CSVDEF *PCSVDEF; typedef class DOSDEF *PDOSDEF;
typedef class VCTDEF *PVCTDEF; typedef class CSVDEF *PCSVDEF;
typedef class PIVOTDEF *PPIVOTDEF; typedef class VCTDEF *PVCTDEF;
typedef class DOMDEF *PDOMDEF; typedef class PIVOTDEF *PPIVOTDEF;
typedef class DIRDEF *PDIRDEF; typedef class DOMDEF *PDOMDEF;
typedef class OEMDEF *POEMDEF; typedef class DIRDEF *PDIRDEF;
typedef class COLCRT *PCOLCRT; typedef class OEMDEF *POEMDEF;
typedef class COLDEF *PCOLDEF; typedef class COLCRT *PCOLCRT;
typedef class CONSTANT *PCONST; typedef class COLDEF *PCOLDEF;
typedef class VALUE *PVAL; typedef class CONSTANT *PCONST;
typedef class VALBLK *PVBLK; typedef class VALUE *PVAL;
typedef class FILTER *PFIL; typedef class VALBLK *PVBLK;
typedef class FILTER *PFIL;
typedef struct _fblock *PFBLOCK;
typedef struct _mblock *PMBLOCK; typedef struct _fblock *PFBLOCK;
typedef struct _cblock *PCBLOCK; typedef struct _mblock *PMBLOCK;
typedef struct _tabs *PTABS; typedef struct _cblock *PCBLOCK;
typedef struct _qryres *PQRYRES; typedef struct _tabs *PTABS;
typedef struct _colres *PCOLRES; typedef struct _qryres *PQRYRES;
typedef struct _datpar *PDTP; typedef struct _colres *PCOLRES;
typedef struct indx_used *PXUSED; typedef struct _datpar *PDTP;
typedef struct indx_used *PXUSED;
/***********************************************************************/
/* Utility blocks for file and storage. */ /***********************************************************************/
/***********************************************************************/ /* Utility blocks for file and storage. */
typedef struct _fblock { /* Opened (mapped) file block */ /***********************************************************************/
struct _fblock *Next; typedef struct _fblock { /* Opened (mapped) file block */
LPCSTR Fname; /* Point on file name */ struct _fblock *Next;
size_t Length; /* File length (<4GB) */ LPCSTR Fname; /* Point on file name */
short Count; /* Nb of times map is used */ size_t Length; /* File length (<4GB) */
short Type; /* TYPE_FB_FILE or TYPE_FB_MAP */ short Count; /* Nb of times map is used */
MODE Mode; /* Open mode */ short Type; /* TYPE_FB_FILE or TYPE_FB_MAP */
char *Memory; /* Pointer to file mapping view */ MODE Mode; /* Open mode */
void *File; /* FILE pointer */ char *Memory; /* Pointer to file mapping view */
HANDLE Handle; /* File handle */ void *File; /* FILE pointer */
} FBLOCK; HANDLE Handle; /* File handle */
} FBLOCK;
typedef struct _mblock { /* Memory block */
PMBLOCK Next; typedef struct _mblock { /* Memory block */
bool Inlist; /* True if in mblock list */ PMBLOCK Next;
size_t Size; /* Size of allocation */ bool Inlist; /* True if in mblock list */
bool Sub; /* True if suballocated */ size_t Size; /* Size of allocation */
void *Memp; /* Memory pointer */ bool Sub; /* True if suballocated */
} MBLOCK; void *Memp; /* Memory pointer */
} MBLOCK;
/***********************************************************************/
/* The QUERY application User Block. */ /***********************************************************************/
/***********************************************************************/ /* The QUERY application User Block. */
typedef struct { /* User application block */ /***********************************************************************/
NAME Name; /* User application name */ typedef struct { /* User application block */
char Server[17]; /* Server name */ NAME Name; /* User application name */
char DBName[17]; /* Current database name */ char Server[17]; /* Server name */
PCATLG Catalog; /* To CATALOG class */ char DBName[17]; /* Current database name */
PQRYRES Result; /* To query result blocks */ PCATLG Catalog; /* To CATALOG class */
PFBLOCK Openlist; /* To file/map open list */ PQRYRES Result; /* To query result blocks */
PMBLOCK Memlist; /* To memory block list */ PFBLOCK Openlist; /* To file/map open list */
PXUSED Xlist; /* To used index list */ PMBLOCK Memlist; /* To memory block list */
int Maxbmp; /* Maximum XDB2 bitmap size */ PXUSED Xlist; /* To used index list */
int Check; /* General level of checking */ int Maxbmp; /* Maximum XDB2 bitmap size */
int Numlines; /* Number of lines involved */ int Check; /* General level of checking */
USETEMP UseTemp; /* Use temporary file */ int Numlines; /* Number of lines involved */
int Vtdbno; /* Used for TDB number setting */ USETEMP UseTemp; /* Use temporary file */
bool Remote; /* true: if remotely called */ int Vtdbno; /* Used for TDB number setting */
bool Proginfo; /* true: return progress info */ bool Remote; /* true: if remotely called */
bool Subcor; /* Used for Progress info */ bool Proginfo; /* true: return progress info */
size_t ProgMax; /* Used for Progress info */ bool Subcor; /* Used for Progress info */
size_t ProgCur; /* Used for Progress info */ size_t ProgMax; /* Used for Progress info */
size_t ProgSav; /* Used for Progress info */ size_t ProgCur; /* Used for Progress info */
LPCSTR Step; /* Execution step name */ size_t ProgSav; /* Used for Progress info */
} DBUSERBLK, *PDBUSER; LPCSTR Step; /* Execution step name */
} DBUSERBLK, *PDBUSER;
/***********************************************************************/
/* Column output format. */ /***********************************************************************/
/***********************************************************************/ /* Column output format. */
typedef struct _format { /* Format descriptor block */ /***********************************************************************/
char Type[2]; /* C:char, F:double, N:int, Dx: date */ typedef struct _format { /* Format descriptor block */
ushort Length; /* Output length */ char Type[2]; /* C:char, F:double, N:int, Dx: date */
short Prec; /* Output precision */ ushort Length; /* Output length */
} FORMAT, *PFORMAT; short Prec; /* Output precision */
} FORMAT, *PFORMAT;
/***********************************************************************/
/* Definition of blocks used in type and copy routines. */ /***********************************************************************/
/***********************************************************************/ /* Definition of blocks used in type and copy routines. */
typedef struct _tabptr { /* start=P1 */ /***********************************************************************/
struct _tabptr *Next; typedef struct _tabptr { /* start=P1 */
int Num; /* alignement */ struct _tabptr *Next;
void *Old[50]; int Num; /* alignement */
void *New[50]; /* old and new values of copied ptrs */ void *Old[50];
} TABPTR, *PTABPTR; void *New[50]; /* old and new values of copied ptrs */
} TABPTR, *PTABPTR;
typedef struct _tabadr { /* start=P3 */
struct _tabadr *Next; typedef struct _tabadr { /* start=P3 */
int Num; struct _tabadr *Next;
void *Adx[50]; /* addr of pointers to be reset */ int Num;
} TABADR, *PTABADR; void *Adx[50]; /* addr of pointers to be reset */
} TABADR, *PTABADR;
typedef struct _tabs {
PGLOBAL G; typedef struct _tabs {
PTABPTR P1; PGLOBAL G;
PTABADR P3; PTABPTR P1;
} TABS; PTABADR P3;
} TABS;
/***********************************************************************/
/* Argument of expression, function, filter etc. (Xobject) */ /***********************************************************************/
/***********************************************************************/ /* Argument of expression, function, filter etc. (Xobject) */
typedef struct _arg { /* Argument */ /***********************************************************************/
PXOB To_Obj; /* To the argument object */ typedef struct _arg { /* Argument */
PVAL Value; /* Argument value */ PXOB To_Obj; /* To the argument object */
bool Conv; /* TRUE if conversion is required */ PVAL Value; /* Argument value */
} ARGBLK, *PARG; bool Conv; /* TRUE if conversion is required */
} ARGBLK, *PARG;
typedef struct _oper { /* Operator */
PSZ Name; /* The input/output operator name */ typedef struct _oper { /* Operator */
OPVAL Val; /* Operator numeric value */ PSZ Name; /* The input/output operator name */
int Mod; /* The modificator */ OPVAL Val; /* Operator numeric value */
} OPER, *POPER; int Mod; /* The modificator */
} OPER, *POPER;
/***********************************************************************/
/* Following definitions are used to define table fields (columns). */ /***********************************************************************/
/***********************************************************************/ /* Following definitions are used to define table fields (columns). */
enum XFLD {FLD_NO = 0, /* Not a field definition item */ /***********************************************************************/
FLD_NAME = 1, /* Item name */ enum XFLD {FLD_NO = 0, /* Not a field definition item */
FLD_TYPE = 2, /* Field type */ FLD_NAME = 1, /* Item name */
FLD_TYPENAME = 3, /* Field type name */ FLD_TYPE = 2, /* Field type */
FLD_PREC = 4, /* Field precision (length?) */ FLD_TYPENAME = 3, /* Field type name */
FLD_LENGTH = 5, /* Field length (?) */ FLD_PREC = 4, /* Field precision (length?) */
FLD_SCALE = 6, /* Field scale (precision) */ FLD_LENGTH = 5, /* Field length (?) */
FLD_RADIX = 7, /* Field radix */ FLD_SCALE = 6, /* Field scale (precision) */
FLD_NULL = 8, /* Field nullable property */ FLD_RADIX = 7, /* Field radix */
FLD_REM = 9, /* Field comment (remark) */ FLD_NULL = 8, /* Field nullable property */
FLD_CHARSET = 10, /* Field collation */ FLD_REM = 9, /* Field comment (remark) */
FLD_KEY = 11, /* Field key property */ FLD_CHARSET = 10, /* Field collation */
FLD_DEFAULT = 12, /* Field default value */ FLD_KEY = 11, /* Field key property */
FLD_EXTRA = 13, /* Field extra info */ FLD_DEFAULT = 12, /* Field default value */
FLD_PRIV = 14, /* Field priviledges */ FLD_EXTRA = 13, /* Field extra info */
FLD_DATEFMT = 15, /* Field date format */ FLD_PRIV = 14, /* Field priviledges */
FLD_CAT = 16, /* Table catalog */ FLD_DATEFMT = 15, /* Field date format */
FLD_SCHEM = 17, /* Table schema */ FLD_CAT = 16, /* Table catalog */
FLD_TABNAME = 18}; /* Column Table name */ FLD_SCHEM = 17, /* Table schema */
FLD_TABNAME = 18}; /* Column Table name */
/***********************************************************************/
/* Result of last SQL noconv query. */ /***********************************************************************/
/***********************************************************************/ /* Result of last SQL noconv query. */
typedef struct _qryres { /***********************************************************************/
PCOLRES Colresp; /* Points to columns of result */ typedef struct _qryres {
bool Continued; /* true when more rows to fetch */ PCOLRES Colresp; /* Points to columns of result */
bool Truncated; /* true when truncated by maxres */ bool Continued; /* true when more rows to fetch */
bool Suball; /* true when entirely suballocated */ bool Truncated; /* true when truncated by maxres */
bool Info; /* true when info msg generated */ bool Suball; /* true when entirely suballocated */
int Maxsize; /* Max query number of lines */ bool Info; /* true when info msg generated */
int Maxres; /* Allocation size */ int Maxsize; /* Max query number of lines */
int Nblin; /* Number of rows in result set */ int Maxres; /* Allocation size */
int Nbcol; /* Number of columns in result set */ int Nblin; /* Number of rows in result set */
int Cursor; /* Starting position to get data */ int Nbcol; /* Number of columns in result set */
int BadLines; /* Skipped bad lines in table file */ int Cursor; /* Starting position to get data */
} QRYRES, *PQRYRES; int BadLines; /* Skipped bad lines in table file */
} QRYRES, *PQRYRES;
typedef struct _colres {
PCOLRES Next; /* To next result column */ typedef struct _colres {
PCOL Colp; /* To matching column block */ PCOLRES Next; /* To next result column */
PSZ Name; /* Column header */ PCOL Colp; /* To matching column block */
PVBLK Kdata; /* Column block of values */ PSZ Name; /* Column header */
char *Nulls; /* Column null value array */ PVBLK Kdata; /* Column block of values */
int Type; /* Internal type */ char *Nulls; /* Column null value array */
int Datasize; /* Overall data size */ int Type; /* Internal type */
int Ncol; /* Column number */ int Datasize; /* Overall data size */
int Clen; /* Data individual internal size */ int Ncol; /* Column number */
int Length; /* Data individual print length */ int Clen; /* Data individual internal size */
int Prec; /* Precision */ int Length; /* Data individual print length */
int Flag; /* Flag option value */ int Prec; /* Precision */
XFLD Fld; /* Type of field info */ int Flag; /* Flag option value */
char Var; /* Type added information */ XFLD Fld; /* Type of field info */
} COLRES; char Var; /* Type added information */
} COLRES;
#if defined(WIN32) && !defined(NOEX)
#define DllExport __declspec( dllexport ) #if defined(WIN32) && !defined(NOEX)
#else // !WIN32 #define DllExport __declspec( dllexport )
#define DllExport #else // !WIN32
#endif // !WIN32 #define DllExport
#endif // !WIN32
/***********************************************************************/
/* Utility routines. */ /***********************************************************************/
/***********************************************************************/ /* Utility routines. */
PPARM Vcolist(PGLOBAL, PTDB, PSZ, bool); /***********************************************************************/
void PlugPutOut(PGLOBAL, FILE *, short, void *, uint); PPARM Vcolist(PGLOBAL, PTDB, PSZ, bool);
void PlugLineDB(PGLOBAL, PSZ, short, void *, uint); void PlugPutOut(PGLOBAL, FILE *, short, void *, uint);
char *PlgGetDataPath(PGLOBAL g); void PlugLineDB(PGLOBAL, PSZ, short, void *, uint);
void AddPointer(PTABS, void *); char *PlgGetDataPath(PGLOBAL g);
PDTP MakeDateFormat(PGLOBAL, PSZ, bool, bool, int); void AddPointer(PTABS, void *);
int ExtractDate(char *, PDTP, int, int val[6]); PDTP MakeDateFormat(PGLOBAL, PSZ, bool, bool, int);
int ExtractDate(char *, PDTP, int, int val[6]);
/**************************************************************************/
/* Allocate the result structure that will contain result data. */ /**************************************************************************/
/**************************************************************************/ /* Allocate the result structure that will contain result data. */
DllExport PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids, /**************************************************************************/
int *buftyp, XFLD *fldtyp, DllExport PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
unsigned int *length, int *buftyp, XFLD *fldtyp,
bool blank, bool nonull); unsigned int *length,
bool blank, bool nonull);
/***********************************************************************/
/* Exported utility routines. */ /***********************************************************************/
/***********************************************************************/ /* Exported utility routines. */
DllExport FILE *PlugOpenFile(PGLOBAL, LPCSTR, LPCSTR); /***********************************************************************/
DllExport int PlugCloseFile(PGLOBAL, PFBLOCK, bool all = false); DllExport FILE *PlugOpenFile(PGLOBAL, LPCSTR, LPCSTR);
DllExport void PlugCleanup(PGLOBAL, bool); DllExport int PlugCloseFile(PGLOBAL, PFBLOCK, bool all = false);
DllExport bool GetPromptAnswer(PGLOBAL, char *); DllExport void PlugCleanup(PGLOBAL, bool);
DllExport char *GetAmName(PGLOBAL g, AMT am, void *memp = NULL); DllExport bool GetPromptAnswer(PGLOBAL, char *);
DllExport PDBUSER PlgMakeUser(PGLOBAL g); DllExport char *GetAmName(PGLOBAL g, AMT am, void *memp = NULL);
DllExport PDBUSER PlgGetUser(PGLOBAL g); DllExport PDBUSER PlgMakeUser(PGLOBAL g);
DllExport PCATLG PlgGetCatalog(PGLOBAL g, bool jump = true); DllExport PDBUSER PlgGetUser(PGLOBAL g);
DllExport bool PlgSetXdbPath(PGLOBAL g, PSZ, PSZ, char *, int, char *, int); DllExport PCATLG PlgGetCatalog(PGLOBAL g, bool jump = true);
DllExport void PlgDBfree(MBLOCK&); DllExport bool PlgSetXdbPath(PGLOBAL g, PSZ, PSZ, char *, int, char *, int);
DllExport void *PlgDBSubAlloc(PGLOBAL g, void *memp, size_t size); DllExport void PlgDBfree(MBLOCK&);
DllExport void *PlgDBalloc(PGLOBAL, void *, MBLOCK&); DllExport void *PlgDBSubAlloc(PGLOBAL g, void *memp, size_t size);
DllExport void *PlgDBrealloc(PGLOBAL, void *, MBLOCK&, size_t); DllExport void *PlgDBalloc(PGLOBAL, void *, MBLOCK&);
DllExport void NewPointer(PTABS, void *, void *); DllExport void *PlgDBrealloc(PGLOBAL, void *, MBLOCK&, size_t);
DllExport char *GetIni(int n= 0); DllExport void NewPointer(PTABS, void *, void *);
DllExport void SetTrc(void); DllExport char *GetIni(int n= 0);
DllExport char *GetListOption(PGLOBAL, const char *, const char *, DllExport void SetTrc(void);
const char *def=NULL); DllExport char *GetListOption(PGLOBAL, const char *, const char *,
const char *def=NULL);
#define MSGID_NONE 0
#define MSGID_CANNOT_OPEN 1 #define MSGID_NONE 0
#define MSGID_OPEN_MODE_ERROR 2 #define MSGID_CANNOT_OPEN 1
#define MSGID_OPEN_STRERROR 3 #define MSGID_OPEN_MODE_ERROR 2
#define MSGID_OPEN_ERROR_AND_STRERROR 4 #define MSGID_OPEN_STRERROR 3
#define MSGID_OPEN_MODE_STRERROR 5 #define MSGID_OPEN_ERROR_AND_STRERROR 4
#define MSGID_OPEN_EMPTY_FILE 6 #define MSGID_OPEN_MODE_STRERROR 5
#define MSGID_OPEN_EMPTY_FILE 6
FILE *global_fopen(GLOBAL *g, int msgid, const char *path, const char *mode);
int global_open(GLOBAL *g, int msgid, const char *filename, int flags); FILE *global_fopen(GLOBAL *g, int msgid, const char *path, const char *mode);
int global_open(GLOBAL *g, int msgid, const char *filename, int flags, int mode); int global_open(GLOBAL *g, int msgid, const char *filename, int flags);
DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR name, LPCSTR dir); int global_open(GLOBAL *g, int msgid, const char *filename, int flags, int mode);
char *MakeEscape(PGLOBAL g, char* str, char q); DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR name, LPCSTR dir);
char *MakeEscape(PGLOBAL g, char* str, char q);
DllExport bool PushWarning(PGLOBAL, PTDBASE, int level = 1);
DllExport bool PushWarning(PGLOBAL, PTDBASE, int level = 1);
...@@ -115,11 +115,6 @@ void htrc(char const *fmt, ...) ...@@ -115,11 +115,6 @@ void htrc(char const *fmt, ...)
va_list ap; va_list ap;
va_start (ap, fmt); va_start (ap, fmt);
//if (trace == 0 || (trace == 1 && !debug) || !fmt) {
// printf("In %s wrong trace=%d debug=%p fmt=%p\n",
// __FILE__, trace, debug, fmt);
// trace = 0;
// } // endif trace
//if (trace == 1) //if (trace == 1)
// vfprintf(debug, fmt, ap); // vfprintf(debug, fmt, ap);
...@@ -256,7 +251,20 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath) ...@@ -256,7 +251,20 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath)
strcpy(pBuff, FileName); // FileName includes absolute path strcpy(pBuff, FileName); // FileName includes absolute path
return pBuff; return pBuff;
} // endif } // endif
#if !defined(WIN32)
if (*FileName == '~') {
if (_fullpath(pBuff, FileName, _MAX_PATH)) {
if (trace > 1)
htrc("pbuff='%s'\n", pBuff);
return pBuff;
} else
return FileName; // Error, return unchanged name
} // endif FileName
#endif // !WIN32
if (strcmp(prefix, ".") && !PlugIsAbsolutePath(defpath)) if (strcmp(prefix, ".") && !PlugIsAbsolutePath(defpath))
{ {
char tmp[_MAX_PATH]; char tmp[_MAX_PATH];
...@@ -478,10 +486,9 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) ...@@ -478,10 +486,9 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
size = ((size + 7) / 8) * 8; /* Round up size to multiple of 8 */ size = ((size + 7) / 8) * 8; /* Round up size to multiple of 8 */
pph = (PPOOLHEADER)memp; pph = (PPOOLHEADER)memp;
#if defined(DEBUG2) || defined(DEBUG3) if (trace > 2)
htrc("SubAlloc in %p size=%d used=%d free=%d\n", htrc("SubAlloc in %p size=%d used=%d free=%d\n",
memp, size, pph->To_Free, pph->FreeBlk); memp, size, pph->To_Free, pph->FreeBlk);
#endif
if ((uint)size > pph->FreeBlk) { /* Not enough memory left in pool */ if ((uint)size > pph->FreeBlk) { /* Not enough memory left in pool */
char *pname = "Work"; char *pname = "Work";
...@@ -490,9 +497,8 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) ...@@ -490,9 +497,8 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
"Not enough memory in %s area for request of %u (used=%d free=%d)", "Not enough memory in %s area for request of %u (used=%d free=%d)",
pname, (uint) size, pph->To_Free, pph->FreeBlk); pname, (uint) size, pph->To_Free, pph->FreeBlk);
#if defined(DEBUG2) || defined(DEBUG3) if (trace)
htrc("%s\n", g->Message); htrc("PlugSubAlloc: %s\n", g->Message);
#endif
longjmp(g->jumper[g->jump_level], 1); longjmp(g->jumper[g->jump_level], 1);
} /* endif size OS32 code */ } /* endif size OS32 code */
...@@ -503,10 +509,11 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) ...@@ -503,10 +509,11 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
memp = MakePtr(memp, pph->To_Free); /* Points to suballocated block */ memp = MakePtr(memp, pph->To_Free); /* Points to suballocated block */
pph->To_Free += size; /* New offset of pool free block */ pph->To_Free += size; /* New offset of pool free block */
pph->FreeBlk -= size; /* New size of pool free block */ pph->FreeBlk -= size; /* New size of pool free block */
#if defined(DEBUG2) || defined(DEBUG3)
htrc("Done memp=%p used=%d free=%d\n", if (trace > 2)
memp, pph->To_Free, pph->FreeBlk); htrc("Done memp=%p used=%d free=%d\n",
#endif memp, pph->To_Free, pph->FreeBlk);
return (memp); return (memp);
} /* end of PlugSubAlloc */ } /* end of PlugSubAlloc */
......
...@@ -1134,10 +1134,13 @@ MYSQLCOL::MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am) ...@@ -1134,10 +1134,13 @@ MYSQLCOL::MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
MYSQLCOL::MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am) MYSQLCOL::MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am)
: COLBLK(NULL, tdbp, i) : COLBLK(NULL, tdbp, i)
{ {
const char *chset = get_charset_name(fld->charsetnr);
char v = (!strcmp(chset, "binary")) ? 'B' : 0;
Name = fld->name; Name = fld->name;
Opt = 0; Opt = 0;
Precision = Long = fld->length; Precision = Long = fld->length;
Buf_Type = MYSQLtoPLG(fld->type); Buf_Type = MYSQLtoPLG(fld->type, &v);
strcpy(Format.Type, GetFormatType(Buf_Type)); strcpy(Format.Type, GetFormatType(Buf_Type));
Format.Length = Long; Format.Length = Long;
Format.Prec = fld->decimals; Format.Prec = fld->decimals;
...@@ -1616,5 +1619,5 @@ TDBMCL::TDBMCL(PMYDEF tdp) : TDBCAT(tdp) ...@@ -1616,5 +1619,5 @@ TDBMCL::TDBMCL(PMYDEF tdp) : TDBCAT(tdp)
/***********************************************************************/ /***********************************************************************/
PQRYRES TDBMCL::GetResult(PGLOBAL g) PQRYRES TDBMCL::GetResult(PGLOBAL g)
{ {
return MyColumns(g, Host, Db, User, Pwd, Tab, NULL, Port, false); return MyColumns(g, NULL, Host, Db, User, Pwd, Tab, NULL, Port, false);
} // end of GetResult } // end of GetResult
...@@ -96,10 +96,21 @@ PIVAID::PIVAID(const char *tab, const char *src, const char *picol, ...@@ -96,10 +96,21 @@ PIVAID::PIVAID(const char *tab, const char *src, const char *picol,
PQRYRES PIVAID::MakePivotColumns(PGLOBAL g) PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
{ {
char *query, *colname, buf[64]; char *query, *colname, buf[64];
int ndif, nblin, w = 0; int rc, ndif, nblin, w = 0;
bool b = false;
PVAL valp; PVAL valp;
PCOLRES *pcrp, crp, fncrp = NULL; PCOLRES *pcrp, crp, fncrp = NULL;
// Save stack and allocation environment and prepare error return
if (g->jump_level == MAX_JUMP) {
strcpy(g->Message, MSG(TOO_MANY_JUMPS));
return NULL;
} // endif jump_level
if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
goto err;
} // endif rc
if (!Tabsrc && Tabname) { if (!Tabsrc && Tabname) {
// Locate the query // Locate the query
query = (char*)PlugSubAlloc(g, NULL, strlen(Tabname) + 16); query = (char*)PlugSubAlloc(g, NULL, strlen(Tabname) + 16);
...@@ -113,16 +124,17 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g) ...@@ -113,16 +124,17 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
// Open a MySQL connection for this table // Open a MySQL connection for this table
if (Myc.Open(g, Host, Database, User, Pwd, Port)) if (Myc.Open(g, Host, Database, User, Pwd, Port))
return NULL; return NULL;
else
b = true;
// Send the source command to MySQL // Send the source command to MySQL
if (Myc.ExecSQL(g, query, &w) == RC_FX) { if (Myc.ExecSQL(g, query, &w) == RC_FX)
Myc.Close(); goto err;
return NULL;
} // endif Exec
// We must have a storage query to get pivot column values // We must have a storage query to get pivot column values
Qryp = Myc.GetResult(g, true); Qryp = Myc.GetResult(g, true);
Myc.Close(); Myc.Close();
b = false;
if (!Fncol) { if (!Fncol) {
for (crp = Qryp->Colresp; crp; crp = crp->Next) for (crp = Qryp->Colresp; crp; crp = crp->Next)
...@@ -152,6 +164,11 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g) ...@@ -152,6 +164,11 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
// Prepare the column list // Prepare the column list
for (pcrp = &Qryp->Colresp; crp = *pcrp; ) for (pcrp = &Qryp->Colresp; crp = *pcrp; )
if (!stricmp(Picol, crp->Name)) { if (!stricmp(Picol, crp->Name)) {
if (crp->Nulls) {
sprintf(g->Message, "Pivot column %s cannot be nullable", Picol);
return NULL;
} // endif Nulls
Rblkp = crp->Kdata; Rblkp = crp->Kdata;
*pcrp = crp->Next; *pcrp = crp->Next;
} else if (!stricmp(Fncol, crp->Name)) { } else if (!stricmp(Fncol, crp->Name)) {
...@@ -218,6 +235,12 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g) ...@@ -218,6 +235,12 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
// We added ndif columns and removed 2 (picol and fncol) // We added ndif columns and removed 2 (picol and fncol)
Qryp->Nbcol += (ndif - 2); Qryp->Nbcol += (ndif - 2);
return Qryp; return Qryp;
err:
if (b)
Myc.Close();
return NULL;
} // end of MakePivotColumns } // end of MakePivotColumns
/***********************************************************************/ /***********************************************************************/
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#include "ha_connect.h" #include "ha_connect.h"
extern "C" int trace; extern "C" int trace;
extern "C" int zconv;
/************************************************************************/ /************************************************************************/
/* Used by MYSQL tables to get MySQL parameters from the calling proxy */ /* Used by MYSQL tables to get MySQL parameters from the calling proxy */
...@@ -129,7 +130,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, ...@@ -129,7 +130,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
FLD_LENGTH, FLD_SCALE, FLD_RADIX, FLD_NULL, FLD_LENGTH, FLD_SCALE, FLD_RADIX, FLD_NULL,
FLD_REM, FLD_NO, FLD_CHARSET}; FLD_REM, FLD_NO, FLD_CHARSET};
unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 32, 32}; unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 32, 32};
char *fld, *fmt, v; char *fld, *colname, *chset, *fmt, v;
int i, n, ncol = sizeof(buftyp) / sizeof(int); int i, n, ncol = sizeof(buftyp) / sizeof(int);
int prec, len, type, scale; int prec, len, type, scale;
bool mysql; bool mysql;
...@@ -176,21 +177,37 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, ...@@ -176,21 +177,37 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
/**********************************************************************/ /**********************************************************************/
/* Now get the results into blocks. */ /* Now get the results into blocks. */
/**********************************************************************/ /**********************************************************************/
for (i = 0, field= s->field; *field; i++, field++) { for (i = 0, field= s->field; *field; field++) {
fp= *field; fp= *field;
// Get column name // Get column name
crp = qrp->Colresp; // Column_Name crp = qrp->Colresp; // Column_Name
fld = (char *)fp->field_name; colname = (char *)fp->field_name;
crp->Kdata->SetValue(fld, i); crp->Kdata->SetValue(colname, i);
v = 0;
chset = (char *)fp->charset()->name;
v = (!strcmp(chset, "binary")) ? 'B' : 0;
if ((type = MYSQLtoPLG(fp->type(), &v)) == TYPE_ERROR) { if ((type = MYSQLtoPLG(fp->type(), &v)) == TYPE_ERROR) {
sprintf(g->Message, "Unsupported column type %s", GetTypeName(type)); if (v == 'K') {
// Skip this column
sprintf(g->Message, "Column %s skipped (unsupported type)", colname);
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
continue;
} // endif v
sprintf(g->Message, "Column %s unsupported type", colname);
qrp = NULL; qrp = NULL;
break; break;
} // endif type } // endif type
if (v == 'X') {
len = zconv;
sprintf(g->Message, "Column %s converted to varchar(%d)",
colname, len);
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
} // endif v
crp = crp->Next; // Data_Type crp = crp->Next; // Data_Type
crp->Kdata->SetValue(type, i); crp->Kdata->SetValue(type, i);
...@@ -198,11 +215,12 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, ...@@ -198,11 +215,12 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
crp->Nulls[i] = 'Z'; crp->Nulls[i] = 'Z';
else if (fp->flags & UNSIGNED_FLAG) else if (fp->flags & UNSIGNED_FLAG)
crp->Nulls[i] = 'U'; crp->Nulls[i] = 'U';
else else // X means TEXT field
crp->Nulls[i] = v; crp->Nulls[i] = (v == 'X') ? 'V' : v;
crp = crp->Next; // Type_Name crp = crp->Next; // Type_Name
crp->Kdata->SetValue(GetTypeName(type), i); crp->Kdata->SetValue(GetTypeName(type), i);
fmt = NULL;
if (type == TYPE_DATE) { if (type == TYPE_DATE) {
// When creating tables we do need info about date columns // When creating tables we do need info about date columns
...@@ -214,7 +232,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, ...@@ -214,7 +232,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
prec = len = fp->field_length; prec = len = fp->field_length;
} // endif mysql } // endif mysql
} else { } else if (v != 'X') {
if (type == TYPE_DECIM) if (type == TYPE_DECIM)
prec = ((Field_new_decimal*)fp)->precision; prec = ((Field_new_decimal*)fp)->precision;
else else
...@@ -222,8 +240,8 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, ...@@ -222,8 +240,8 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
// prec = (prec(???) == NOT_FIXED_DEC) ? 0 : fp->field_length; // prec = (prec(???) == NOT_FIXED_DEC) ? 0 : fp->field_length;
len = fp->char_length(); len = fp->char_length();
fmt = NULL; } else
} // endif type prec = len = zconv;
crp = crp->Next; // Precision crp = crp->Next; // Precision
crp->Kdata->SetValue(prec, i); crp->Kdata->SetValue(prec, i);
...@@ -259,6 +277,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, ...@@ -259,6 +277,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
// Add this item // Add this item
qrp->Nblin++; qrp->Nblin++;
i++; // Can be skipped
} // endfor field } // endfor field
/**********************************************************************/ /**********************************************************************/
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include "mycat.h" #include "mycat.h"
extern "C" int trace; extern "C" int trace;
extern uint worksize;
/****************************************************************************/ /****************************************************************************/
/* Initialize the user_connect static member. */ /* Initialize the user_connect static member. */
...@@ -94,8 +95,9 @@ bool user_connect::user_init() ...@@ -94,8 +95,9 @@ bool user_connect::user_init()
PDBUSER dup= NULL; PDBUSER dup= NULL;
// Areasize= 64M because of VEC tables. Should be parameterisable // Areasize= 64M because of VEC tables. Should be parameterisable
g= PlugInit(NULL, 67108864); //g= PlugInit(NULL, 67108864);
//g= PlugInit(NULL, 134217728); // 128M was because of old embedded tests //g= PlugInit(NULL, 134217728); // 128M was because of old embedded tests
g= PlugInit(NULL, worksize);
// Check whether the initialization is complete // Check whether the initialization is complete
if (!g || !g->Sarea || PlugSubSet(g, g->Sarea, g->Sarea_Size) if (!g || !g->Sarea || PlugSubSet(g, g->Sarea, g->Sarea_Size)
...@@ -142,6 +144,20 @@ bool user_connect::CheckCleanup(void) ...@@ -142,6 +144,20 @@ bool user_connect::CheckCleanup(void)
{ {
if (thdp->query_id > last_query_id) { if (thdp->query_id > last_query_id) {
PlugCleanup(g, true); PlugCleanup(g, true);
if (g->Sarea_Size != worksize) {
if (g->Sarea)
free(g->Sarea);
// Check whether the work area size was changed
if (!(g->Sarea = PlugAllocMem(g, worksize))) {
g->Sarea = PlugAllocMem(g, g->Sarea_Size);
worksize = g->Sarea_Size; // Was too big
} else
g->Sarea_Size = worksize; // Ok
} // endif worksize
PlugSubSet(g, g->Sarea, g->Sarea_Size); PlugSubSet(g, g->Sarea, g->Sarea_Size);
g->Xchk = NULL; g->Xchk = NULL;
g->Createas = 0; g->Createas = 0;
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#define CheckParms(V, N) ChkIndx(N); ChkTyp(V); #define CheckParms(V, N) ChkIndx(N); ChkTyp(V);
extern "C" int trace; extern "C" int trace;
extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */
/***********************************************************************/ /***********************************************************************/
/* AllocValBlock: allocate a VALBLK according to type. */ /* AllocValBlock: allocate a VALBLK according to type. */
...@@ -105,8 +106,7 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len, ...@@ -105,8 +106,7 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
return NULL; return NULL;
} // endswitch Type } // endswitch Type
blkp->Init(g, check); return (blkp->Init(g, check)) ? NULL : blkp;
return blkp;
} // end of AllocValBlock } // end of AllocValBlock
/* -------------------------- Class VALBLK --------------------------- */ /* -------------------------- Class VALBLK --------------------------- */
...@@ -116,6 +116,7 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len, ...@@ -116,6 +116,7 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
/***********************************************************************/ /***********************************************************************/
VALBLK::VALBLK(void *mp, int type, int nval, bool un) VALBLK::VALBLK(void *mp, int type, int nval, bool un)
{ {
Mblk = Nmblk;
Blkp = mp; Blkp = mp;
To_Nulls = NULL; To_Nulls = NULL;
Check = true; Check = true;
...@@ -179,6 +180,22 @@ void VALBLK::SetNullable(bool b) ...@@ -179,6 +180,22 @@ void VALBLK::SetNullable(bool b)
} // end of SetNullable } // end of SetNullable
/***********************************************************************/
/* Buffer allocation routine. */
/***********************************************************************/
bool VALBLK::AllocBuff(PGLOBAL g, size_t size)
{
Mblk.Size = size;
if (!(Blkp = PlgDBalloc(g, NULL, Mblk))) {
sprintf(g->Message, MSG(MEM_ALLOC_ERR), "Blkp", Mblk.Size);
fprintf(stderr, "%s\n", g->Message);
return true;
} // endif Blkp
return false;
} // end of AllocBuff
/***********************************************************************/ /***********************************************************************/
/* Check functions. */ /* Check functions. */
/***********************************************************************/ /***********************************************************************/
...@@ -229,13 +246,15 @@ TYPBLK<TYPE>::TYPBLK(void *mp, int nval, int type, int prec, bool un) ...@@ -229,13 +246,15 @@ TYPBLK<TYPE>::TYPBLK(void *mp, int nval, int type, int prec, bool un)
/* Initialization routine. */ /* Initialization routine. */
/***********************************************************************/ /***********************************************************************/
template <class TYPE> template <class TYPE>
void TYPBLK<TYPE>::Init(PGLOBAL g, bool check) bool TYPBLK<TYPE>::Init(PGLOBAL g, bool check)
{ {
if (!Blkp) if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * sizeof(TYPE)); if (AllocBuff(g, Nval * sizeof(TYPE)))
return true;
Check = check; Check = check;
Global = g; Global = g;
return false;
} // end of Init } // end of Init
/***********************************************************************/ /***********************************************************************/
...@@ -606,16 +625,18 @@ CHRBLK::CHRBLK(void *mp, int nval, int len, int prec, bool blank) ...@@ -606,16 +625,18 @@ CHRBLK::CHRBLK(void *mp, int nval, int len, int prec, bool blank)
/***********************************************************************/ /***********************************************************************/
/* Initialization routine. */ /* Initialization routine. */
/***********************************************************************/ /***********************************************************************/
void CHRBLK::Init(PGLOBAL g, bool check) bool CHRBLK::Init(PGLOBAL g, bool check)
{ {
Valp = (char*)PlugSubAlloc(g, NULL, Long + 1); Valp = (char*)PlugSubAlloc(g, NULL, Long + 1);
Valp[Long] = '\0'; Valp[Long] = '\0';
if (!Blkp) if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * Long); if (AllocBuff(g, Nval * Long))
return true;
Check = check; Check = check;
Global = g; Global = g;
return false;
} // end of Init } // end of Init
/***********************************************************************/ /***********************************************************************/
...@@ -996,13 +1017,15 @@ STRBLK::STRBLK(PGLOBAL g, void *mp, int nval) ...@@ -996,13 +1017,15 @@ STRBLK::STRBLK(PGLOBAL g, void *mp, int nval)
/***********************************************************************/ /***********************************************************************/
/* Initialization routine. */ /* Initialization routine. */
/***********************************************************************/ /***********************************************************************/
void STRBLK::Init(PGLOBAL g, bool check) bool STRBLK::Init(PGLOBAL g, bool check)
{ {
if (!Blkp) if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * sizeof(PSZ)); if (AllocBuff(g, Nval * sizeof(PSZ)))
return true;
Check = check; Check = check;
Global = g; Global = g;
return false;
} // end of Init } // end of Init
/***********************************************************************/ /***********************************************************************/
......
/*************** Valblk H Declares Source Code File (.H) ***************/ /*************** Valblk H Declares Source Code File (.H) ***************/
/* Name: VALBLK.H Version 2.1 */ /* Name: VALBLK.H Version 2.1 */
/* */ /* */
/* (C) Copyright to the author Olivier BERTRAND 2005-2014 */ /* (C) Copyright to the author Olivier BERTRAND 2005-2014 */
/* */ /* */
/* This file contains the VALBLK and derived classes declares. */ /* This file contains the VALBLK and derived classes declares. */
/***********************************************************************/ /***********************************************************************/
/***********************************************************************/ /***********************************************************************/
/* Include required application header files */ /* Include required application header files */
/* assert.h is header required when using the assert function. */ /* assert.h is header required when using the assert function. */
/* block.h is header containing Block global declarations. */ /* block.h is header containing Block global declarations. */
/***********************************************************************/ /***********************************************************************/
#ifndef __VALBLK__H__ #ifndef __VALBLK__H__
#define __VALBLK__H__ #define __VALBLK__H__
#include "value.h" #include "value.h"
/***********************************************************************/ /***********************************************************************/
/* Utility used to allocate value blocks. */ /* Utility used to allocate value blocks. */
/***********************************************************************/ /***********************************************************************/
DllExport PVBLK AllocValBlock(PGLOBAL, void*, int, int, int, int, DllExport PVBLK AllocValBlock(PGLOBAL, void*, int, int, int, int,
bool, bool, bool); bool, bool, bool);
const char *GetFmt(int type, bool un = false); const char *GetFmt(int type, bool un = false);
/***********************************************************************/ /***********************************************************************/
/* DB static external variables. */ /* DB static external variables. */
/***********************************************************************/ /***********************************************************************/
...@@ -52,280 +52,282 @@ class MBVALS : public BLOCK { ...@@ -52,280 +52,282 @@ class MBVALS : public BLOCK {
typedef class MBVALS *PMBV; typedef class MBVALS *PMBV;
/***********************************************************************/ /***********************************************************************/
/* Class VALBLK represent a base class for variable blocks. */ /* Class VALBLK represent a base class for variable blocks. */
/***********************************************************************/ /***********************************************************************/
class VALBLK : public BLOCK { class VALBLK : public BLOCK {
public: public:
// Constructors // Constructors
VALBLK(void *mp, int type, int nval, bool un = false); VALBLK(void *mp, int type, int nval, bool un = false);
// Implementation // Implementation
int GetNval(void) {return Nval;} int GetNval(void) {return Nval;}
void SetNval(int n) {Nval = n;} void SetNval(int n) {Nval = n;}
void *GetValPointer(void) {return Blkp;} void *GetValPointer(void) {return Blkp;}
void SetValPointer(void *mp) {Blkp = mp;} void SetValPointer(void *mp) {Blkp = mp;}
int GetType(void) {return Type;} int GetType(void) {return Type;}
int GetPrec(void) {return Prec;} int GetPrec(void) {return Prec;}
void SetCheck(bool b) {Check = b;} void SetCheck(bool b) {Check = b;}
void MoveNull(int i, int j) void MoveNull(int i, int j)
{if (To_Nulls) To_Nulls[j] = To_Nulls[j];} {if (To_Nulls) To_Nulls[j] = To_Nulls[j];}
virtual void SetNull(int n, bool b) virtual void SetNull(int n, bool b)
{if (To_Nulls) {To_Nulls[n] = (b) ? '*' : 0;}} {if (To_Nulls) {To_Nulls[n] = (b) ? '*' : 0;}}
virtual bool IsNull(int n) {return To_Nulls && To_Nulls[n];} virtual bool IsNull(int n) {return To_Nulls && To_Nulls[n];}
virtual void SetNullable(bool b); virtual void SetNullable(bool b);
virtual bool IsUnsigned(void) {return Unsigned;} virtual bool IsUnsigned(void) {return Unsigned;}
virtual void Init(PGLOBAL g, bool check) = 0; virtual bool Init(PGLOBAL g, bool check) = 0;
virtual int GetVlen(void) = 0; virtual int GetVlen(void) = 0;
virtual PSZ GetCharValue(int n); virtual PSZ GetCharValue(int n);
virtual char GetTinyValue(int n) = 0; virtual char GetTinyValue(int n) = 0;
virtual uchar GetUTinyValue(int n) = 0; virtual uchar GetUTinyValue(int n) = 0;
virtual short GetShortValue(int n) = 0; virtual short GetShortValue(int n) = 0;
virtual ushort GetUShortValue(int n) = 0; virtual ushort GetUShortValue(int n) = 0;
virtual int GetIntValue(int n) = 0; virtual int GetIntValue(int n) = 0;
virtual uint GetUIntValue(int n) = 0; virtual uint GetUIntValue(int n) = 0;
virtual longlong GetBigintValue(int n) = 0; virtual longlong GetBigintValue(int n) = 0;
virtual ulonglong GetUBigintValue(int n) = 0; virtual ulonglong GetUBigintValue(int n) = 0;
virtual double GetFloatValue(int n) = 0; virtual double GetFloatValue(int n) = 0;
virtual char *GetCharString(char *p, int n) = 0; virtual char *GetCharString(char *p, int n) = 0;
virtual void ReAlloc(void *mp, int n) {Blkp = mp; Nval = n;} virtual void ReAlloc(void *mp, int n) {Blkp = mp; Nval = n;}
virtual void Reset(int n) = 0; virtual void Reset(int n) = 0;
virtual bool SetFormat(PGLOBAL g, PSZ fmt, int len, int year = 0); virtual bool SetFormat(PGLOBAL g, PSZ fmt, int len, int year = 0);
virtual void SetPrec(int p) {} virtual void SetPrec(int p) {}
virtual bool IsCi(void) {return false;} virtual bool IsCi(void) {return false;}
// Methods // Methods
virtual void SetValue(short sval, int n) {assert(false);} virtual void SetValue(short sval, int n) {assert(false);}
virtual void SetValue(ushort sval, int n) {assert(false);} virtual void SetValue(ushort sval, int n) {assert(false);}
virtual void SetValue(int lval, int n) {assert(false);} virtual void SetValue(int lval, int n) {assert(false);}
virtual void SetValue(uint lval, int n) {assert(false);} virtual void SetValue(uint lval, int n) {assert(false);}
virtual void SetValue(longlong lval, int n) {assert(false);} virtual void SetValue(longlong lval, int n) {assert(false);}
virtual void SetValue(ulonglong lval, int n) {assert(false);} virtual void SetValue(ulonglong lval, int n) {assert(false);}
virtual void SetValue(double fval, int n) {assert(false);} virtual void SetValue(double fval, int n) {assert(false);}
virtual void SetValue(char cval, int n) {assert(false);} virtual void SetValue(char cval, int n) {assert(false);}
virtual void SetValue(uchar cval, int n) {assert(false);} virtual void SetValue(uchar cval, int n) {assert(false);}
virtual void SetValue(PSZ sp, int n) {assert(false);} virtual void SetValue(PSZ sp, int n) {assert(false);}
virtual void SetValue(char *sp, uint len, int n) {assert(false);} virtual void SetValue(char *sp, uint len, int n) {assert(false);}
virtual void SetValue(PVAL valp, int n) = 0; virtual void SetValue(PVAL valp, int n) = 0;
virtual void SetValue(PVBLK pv, int n1, int n2) = 0; virtual void SetValue(PVBLK pv, int n1, int n2) = 0;
virtual void SetMin(PVAL valp, int n) = 0; virtual void SetMin(PVAL valp, int n) = 0;
virtual void SetMax(PVAL valp, int n) = 0; virtual void SetMax(PVAL valp, int n) = 0;
virtual void Move(int i, int j) = 0; virtual void Move(int i, int j) = 0;
virtual int CompVal(PVAL vp, int n) = 0; virtual int CompVal(PVAL vp, int n) = 0;
virtual int CompVal(int i1, int i2) = 0; virtual int CompVal(int i1, int i2) = 0;
virtual void *GetValPtr(int n) = 0; virtual void *GetValPtr(int n) = 0;
virtual void *GetValPtrEx(int n) = 0; virtual void *GetValPtrEx(int n) = 0;
virtual int Find(PVAL vp) = 0; virtual int Find(PVAL vp) = 0;
virtual int GetMaxLength(void) = 0; virtual int GetMaxLength(void) = 0;
bool Locate(PVAL vp, int& i); bool Locate(PVAL vp, int& i);
protected: protected:
void ChkIndx(int n); bool AllocBuff(PGLOBAL g, size_t size);
void ChkTyp(PVAL v); void ChkIndx(int n);
void ChkTyp(PVBLK vb); void ChkTyp(PVAL v);
void ChkTyp(PVBLK vb);
// Members
PGLOBAL Global; // Used for messages and allocation // Members
char *To_Nulls; // Null values array PGLOBAL Global; // Used for messages and allocation
void *Blkp; // To value block MBLOCK Mblk; // Used to allocate buffer
bool Check; // If true SetValue types must match char *To_Nulls; // Null values array
bool Nullable; // True if values can be null void *Blkp; // To value block
bool Unsigned; // True if values are unsigned bool Check; // If true SetValue types must match
int Type; // Type of individual values bool Nullable; // True if values can be null
int Nval; // Max number of values in block bool Unsigned; // True if values are unsigned
int Prec; // Precision of float values int Type; // Type of individual values
}; // end of class VALBLK int Nval; // Max number of values in block
int Prec; // Precision of float values
/***********************************************************************/ }; // end of class VALBLK
/* Class TYPBLK: represents a block of typed values. */
/***********************************************************************/ /***********************************************************************/
template <class TYPE> /* Class TYPBLK: represents a block of typed values. */
class TYPBLK : public VALBLK { /***********************************************************************/
public: template <class TYPE>
// Constructors class TYPBLK : public VALBLK {
TYPBLK(void *mp, int size, int type, int prec = 0, bool un = false); public:
// Constructors
// Implementation TYPBLK(void *mp, int size, int type, int prec = 0, bool un = false);
virtual void Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return sizeof(TYPE);} // Implementation
virtual char GetTinyValue(int n) {return (char)Typp[n];} virtual bool Init(PGLOBAL g, bool check);
virtual uchar GetUTinyValue(int n) {return (uchar)Typp[n];} virtual int GetVlen(void) {return sizeof(TYPE);}
virtual short GetShortValue(int n) {return (short)Typp[n];} virtual char GetTinyValue(int n) {return (char)Typp[n];}
virtual ushort GetUShortValue(int n) {return (ushort)Typp[n];} virtual uchar GetUTinyValue(int n) {return (uchar)Typp[n];}
virtual int GetIntValue(int n) {return (int)Typp[n];} virtual short GetShortValue(int n) {return (short)Typp[n];}
virtual uint GetUIntValue(int n) {return (uint)Typp[n];} virtual ushort GetUShortValue(int n) {return (ushort)Typp[n];}
virtual longlong GetBigintValue(int n) {return (longlong)Typp[n];} virtual int GetIntValue(int n) {return (int)Typp[n];}
virtual ulonglong GetUBigintValue(int n) {return (ulonglong)Typp[n];} virtual uint GetUIntValue(int n) {return (uint)Typp[n];}
virtual double GetFloatValue(int n) {return (double)Typp[n];} virtual longlong GetBigintValue(int n) {return (longlong)Typp[n];}
virtual char *GetCharString(char *p, int n); virtual ulonglong GetUBigintValue(int n) {return (ulonglong)Typp[n];}
virtual void Reset(int n) {Typp[n] = 0;} virtual double GetFloatValue(int n) {return (double)Typp[n];}
virtual char *GetCharString(char *p, int n);
// Methods virtual void Reset(int n) {Typp[n] = 0;}
virtual void SetValue(PSZ sp, int n);
virtual void SetValue(char *sp, uint len, int n); // Methods
virtual void SetValue(short sval, int n) virtual void SetValue(PSZ sp, int n);
{Typp[n] = (TYPE)sval; SetNull(n, false);} virtual void SetValue(char *sp, uint len, int n);
virtual void SetValue(ushort sval, int n) virtual void SetValue(short sval, int n)
{Typp[n] = (TYPE)sval; SetNull(n, false);} {Typp[n] = (TYPE)sval; SetNull(n, false);}
virtual void SetValue(int lval, int n) virtual void SetValue(ushort sval, int n)
{Typp[n] = (TYPE)lval; SetNull(n, false);} {Typp[n] = (TYPE)sval; SetNull(n, false);}
virtual void SetValue(uint lval, int n) virtual void SetValue(int lval, int n)
{Typp[n] = (TYPE)lval; SetNull(n, false);} {Typp[n] = (TYPE)lval; SetNull(n, false);}
virtual void SetValue(longlong lval, int n) virtual void SetValue(uint lval, int n)
{Typp[n] = (TYPE)lval; SetNull(n, false);} {Typp[n] = (TYPE)lval; SetNull(n, false);}
virtual void SetValue(ulonglong lval, int n) virtual void SetValue(longlong lval, int n)
{Typp[n] = (TYPE)lval; SetNull(n, false);} {Typp[n] = (TYPE)lval; SetNull(n, false);}
virtual void SetValue(double fval, int n) virtual void SetValue(ulonglong lval, int n)
{Typp[n] = (TYPE)fval; SetNull(n, false);} {Typp[n] = (TYPE)lval; SetNull(n, false);}
virtual void SetValue(char cval, int n) virtual void SetValue(double fval, int n)
{Typp[n] = (TYPE)cval; SetNull(n, false);} {Typp[n] = (TYPE)fval; SetNull(n, false);}
virtual void SetValue(uchar cval, int n) virtual void SetValue(char cval, int n)
{Typp[n] = (TYPE)cval; SetNull(n, false);} {Typp[n] = (TYPE)cval; SetNull(n, false);}
virtual void SetValue(PVAL valp, int n); virtual void SetValue(uchar cval, int n)
virtual void SetValue(PVBLK pv, int n1, int n2); {Typp[n] = (TYPE)cval; SetNull(n, false);}
virtual void SetMin(PVAL valp, int n); virtual void SetValue(PVAL valp, int n);
virtual void SetMax(PVAL valp, int n); virtual void SetValue(PVBLK pv, int n1, int n2);
virtual void Move(int i, int j); virtual void SetMin(PVAL valp, int n);
virtual int CompVal(PVAL vp, int n); virtual void SetMax(PVAL valp, int n);
virtual int CompVal(int i1, int i2); virtual void Move(int i, int j);
virtual void *GetValPtr(int n); virtual int CompVal(PVAL vp, int n);
virtual void *GetValPtrEx(int n); virtual int CompVal(int i1, int i2);
virtual int Find(PVAL vp); virtual void *GetValPtr(int n);
virtual int GetMaxLength(void); virtual void *GetValPtrEx(int n);
virtual int Find(PVAL vp);
protected: virtual int GetMaxLength(void);
// Specialized functions
static ulonglong MaxVal(void); protected:
TYPE GetTypedValue(PVAL vp); // Specialized functions
TYPE GetTypedValue(PVBLK blk, int n); static ulonglong MaxVal(void);
TYPE GetTypedValue(PVAL vp);
// Members TYPE GetTypedValue(PVBLK blk, int n);
TYPE* const &Typp;
const char *Fmt; // Members
}; // end of class TYPBLK TYPE* const &Typp;
const char *Fmt;
/***********************************************************************/ }; // end of class TYPBLK
/* Class CHRBLK: represent a block of fixed length strings. */
/***********************************************************************/ /***********************************************************************/
class CHRBLK : public VALBLK { /* Class CHRBLK: represent a block of fixed length strings. */
public: /***********************************************************************/
// Constructors class CHRBLK : public VALBLK {
CHRBLK(void *mp, int size, int len, int prec, bool b); public:
// Constructors
// Implementation CHRBLK(void *mp, int size, int len, int prec, bool b);
virtual void Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return Long;} // Implementation
virtual PSZ GetCharValue(int n); virtual bool Init(PGLOBAL g, bool check);
virtual char GetTinyValue(int n); virtual int GetVlen(void) {return Long;}
virtual uchar GetUTinyValue(int n); virtual PSZ GetCharValue(int n);
virtual short GetShortValue(int n); virtual char GetTinyValue(int n);
virtual ushort GetUShortValue(int n); virtual uchar GetUTinyValue(int n);
virtual int GetIntValue(int n); virtual short GetShortValue(int n);
virtual uint GetUIntValue(int n); virtual ushort GetUShortValue(int n);
virtual longlong GetBigintValue(int n); virtual int GetIntValue(int n);
virtual ulonglong GetUBigintValue(int n); virtual uint GetUIntValue(int n);
virtual double GetFloatValue(int n); virtual longlong GetBigintValue(int n);
virtual char *GetCharString(char *p, int n); virtual ulonglong GetUBigintValue(int n);
virtual void Reset(int n); virtual double GetFloatValue(int n);
virtual void SetPrec(int p) {Ci = (p != 0);} virtual char *GetCharString(char *p, int n);
virtual bool IsCi(void) {return Ci;} virtual void Reset(int n);
virtual void SetPrec(int p) {Ci = (p != 0);}
// Methods virtual bool IsCi(void) {return Ci;}
virtual void SetValue(PSZ sp, int n);
virtual void SetValue(char *sp, uint len, int n); // Methods
virtual void SetValue(PVAL valp, int n); virtual void SetValue(PSZ sp, int n);
virtual void SetValue(PVBLK pv, int n1, int n2); virtual void SetValue(char *sp, uint len, int n);
virtual void SetMin(PVAL valp, int n); virtual void SetValue(PVAL valp, int n);
virtual void SetMax(PVAL valp, int n); virtual void SetValue(PVBLK pv, int n1, int n2);
virtual void Move(int i, int j); virtual void SetMin(PVAL valp, int n);
virtual int CompVal(PVAL vp, int n); virtual void SetMax(PVAL valp, int n);
virtual int CompVal(int i1, int i2); virtual void Move(int i, int j);
virtual void *GetValPtr(int n); virtual int CompVal(PVAL vp, int n);
virtual void *GetValPtrEx(int n); virtual int CompVal(int i1, int i2);
virtual int Find(PVAL vp); virtual void *GetValPtr(int n);
virtual int GetMaxLength(void); virtual void *GetValPtrEx(int n);
virtual int Find(PVAL vp);
protected: virtual int GetMaxLength(void);
// Members
char* const &Chrp; // Pointer to char buffer protected:
PSZ Valp; // Used to make a zero ended value // Members
bool Blanks; // True for right filling with blanks char* const &Chrp; // Pointer to char buffer
bool Ci; // True if case insensitive PSZ Valp; // Used to make a zero ended value
int Long; // Length of each string bool Blanks; // True for right filling with blanks
}; // end of class CHRBLK bool Ci; // True if case insensitive
int Long; // Length of each string
/***********************************************************************/ }; // end of class CHRBLK
/* Class STRBLK: represent a block of string pointers. */
/* Currently this class is used only by the DECODE scalar function */ /***********************************************************************/
/* and by the MyColumn function to store date formats. */ /* Class STRBLK: represent a block of string pointers. */
/***********************************************************************/ /* Currently this class is used only by the DECODE scalar function */
class STRBLK : public VALBLK { /* and by the MyColumn function to store date formats. */
public: /***********************************************************************/
// Constructors class STRBLK : public VALBLK {
STRBLK(PGLOBAL g, void *mp, int size); public:
// Constructors
// Implementation STRBLK(PGLOBAL g, void *mp, int size);
virtual void SetNull(int n, bool b) {if (b) {Strp[n] = NULL;}}
virtual bool IsNull(int n) {return Strp[n] == NULL;} // Implementation
virtual void SetNullable(bool b) {} // Always nullable virtual void SetNull(int n, bool b) {if (b) {Strp[n] = NULL;}}
virtual void Init(PGLOBAL g, bool check); virtual bool IsNull(int n) {return Strp[n] == NULL;}
virtual int GetVlen(void) {return sizeof(PSZ);} virtual void SetNullable(bool b) {} // Always nullable
virtual PSZ GetCharValue(int n) {return Strp[n];} virtual bool Init(PGLOBAL g, bool check);
virtual char GetTinyValue(int n); virtual int GetVlen(void) {return sizeof(PSZ);}
virtual uchar GetUTinyValue(int n); virtual PSZ GetCharValue(int n) {return Strp[n];}
virtual short GetShortValue(int n); virtual char GetTinyValue(int n);
virtual ushort GetUShortValue(int n); virtual uchar GetUTinyValue(int n);
virtual int GetIntValue(int n); virtual short GetShortValue(int n);
virtual uint GetUIntValue(int n); virtual ushort GetUShortValue(int n);
virtual longlong GetBigintValue(int n); virtual int GetIntValue(int n);
virtual ulonglong GetUBigintValue(int n); virtual uint GetUIntValue(int n);
virtual double GetFloatValue(int n) {return atof(Strp[n]);} virtual longlong GetBigintValue(int n);
virtual char *GetCharString(char *p, int n) {return Strp[n];} virtual ulonglong GetUBigintValue(int n);
virtual void Reset(int n) {Strp[n] = NULL;} virtual double GetFloatValue(int n) {return atof(Strp[n]);}
virtual char *GetCharString(char *p, int n) {return Strp[n];}
// Methods virtual void Reset(int n) {Strp[n] = NULL;}
virtual void SetValue(PSZ sp, int n);
virtual void SetValue(char *sp, uint len, int n); // Methods
virtual void SetValue(PVAL valp, int n); virtual void SetValue(PSZ sp, int n);
virtual void SetValue(PVBLK pv, int n1, int n2); virtual void SetValue(char *sp, uint len, int n);
virtual void SetMin(PVAL valp, int n); virtual void SetValue(PVAL valp, int n);
virtual void SetMax(PVAL valp, int n); virtual void SetValue(PVBLK pv, int n1, int n2);
virtual void Move(int i, int j); virtual void SetMin(PVAL valp, int n);
virtual int CompVal(PVAL vp, int n); virtual void SetMax(PVAL valp, int n);
virtual int CompVal(int i1, int i2); virtual void Move(int i, int j);
virtual void *GetValPtr(int n); virtual int CompVal(PVAL vp, int n);
virtual void *GetValPtrEx(int n); virtual int CompVal(int i1, int i2);
virtual int Find(PVAL vp); virtual void *GetValPtr(int n);
virtual int GetMaxLength(void); virtual void *GetValPtrEx(int n);
virtual int Find(PVAL vp);
// Specific virtual int GetMaxLength(void);
void SetSorted(bool b) {Sorted = b;}
// Specific
protected: void SetSorted(bool b) {Sorted = b;}
// Members
PSZ* const &Strp; // Pointer to PSZ buffer protected:
bool Sorted; // Values are (semi?) sorted // Members
}; // end of class STRBLK PSZ* const &Strp; // Pointer to PSZ buffer
bool Sorted; // Values are (semi?) sorted
/***********************************************************************/ }; // end of class STRBLK
/* Class DATBLK: represents a block of time stamp values. */
/***********************************************************************/ /***********************************************************************/
class DATBLK : public TYPBLK<int> { /* Class DATBLK: represents a block of time stamp values. */
public: /***********************************************************************/
// Constructor class DATBLK : public TYPBLK<int> {
DATBLK(void *mp, int size); public:
// Constructor
// Implementation DATBLK(void *mp, int size);
virtual bool SetFormat(PGLOBAL g, PSZ fmt, int len, int year = 0);
virtual char *GetCharString(char *p, int n); // Implementation
virtual bool SetFormat(PGLOBAL g, PSZ fmt, int len, int year = 0);
// Methods virtual char *GetCharString(char *p, int n);
virtual void SetValue(PSZ sp, int n);
// Methods
protected: virtual void SetValue(PSZ sp, int n);
// Members
PVAL Dvalp; // Date value used to convert string protected:
}; // end of class DATBLK // Members
PVAL Dvalp; // Date value used to convert string
#endif // __VALBLK__H__ }; // end of class DATBLK
#endif // __VALBLK__H__
/************* Value C++ Functions Source Code File (.CPP) *************/ /************* Value C++ Functions Source Code File (.CPP) *************/
/* Name: VALUE.CPP Version 2.4 */ /* Name: VALUE.CPP Version 2.5 */
/* */ /* */
/* (C) Copyright to the author Olivier BERTRAND 2001-2014 */ /* (C) Copyright to the author Olivier BERTRAND 2001-2014 */
/* */ /* */
...@@ -183,6 +183,7 @@ PSZ GetTypeName(int type) ...@@ -183,6 +183,7 @@ PSZ GetTypeName(int type)
case TYPE_DOUBLE: name = "DOUBLE"; break; case TYPE_DOUBLE: name = "DOUBLE"; break;
case TYPE_TINY: name = "TINY"; break; case TYPE_TINY: name = "TINY"; break;
case TYPE_DECIM: name = "DECIMAL"; break; case TYPE_DECIM: name = "DECIMAL"; break;
case TYPE_BIN: name = "BINARY"; break;
default: name = "UNKNOWN"; break; default: name = "UNKNOWN"; break;
} // endswitch type } // endswitch type
...@@ -196,6 +197,7 @@ int GetTypeSize(int type, int len) ...@@ -196,6 +197,7 @@ int GetTypeSize(int type, int len)
{ {
switch (type) { switch (type) {
case TYPE_DECIM: case TYPE_DECIM:
case TYPE_BIN:
case TYPE_STRING: len = len * sizeof(char); break; case TYPE_STRING: len = len * sizeof(char); break;
case TYPE_SHORT: len = sizeof(short); break; case TYPE_SHORT: len = sizeof(short); break;
case TYPE_INT: len = sizeof(int); break; case TYPE_INT: len = sizeof(int); break;
...@@ -225,6 +227,7 @@ char *GetFormatType(int type) ...@@ -225,6 +227,7 @@ char *GetFormatType(int type)
case TYPE_DATE: c = "D"; break; case TYPE_DATE: c = "D"; break;
case TYPE_TINY: c = "T"; break; case TYPE_TINY: c = "T"; break;
case TYPE_DECIM: c = "M"; break; case TYPE_DECIM: c = "M"; break;
case TYPE_BIN: c = "B"; break;
} // endswitch type } // endswitch type
return c; return c;
...@@ -246,6 +249,7 @@ int GetFormatType(char c) ...@@ -246,6 +249,7 @@ int GetFormatType(char c)
case 'D': type = TYPE_DATE; break; case 'D': type = TYPE_DATE; break;
case 'T': type = TYPE_TINY; break; case 'T': type = TYPE_TINY; break;
case 'M': type = TYPE_DECIM; break; case 'M': type = TYPE_DECIM; break;
case 'B': type = TYPE_BIN; break;
} // endswitch type } // endswitch type
return type; return type;
...@@ -298,6 +302,7 @@ const char *GetFmt(int type, bool un) ...@@ -298,6 +302,7 @@ const char *GetFmt(int type, bool un)
case TYPE_SHORT: fmt = (un) ? "%hu" : "%hd"; break; case TYPE_SHORT: fmt = (un) ? "%hu" : "%hd"; break;
case TYPE_BIGINT: fmt = (un) ? "%llu" : "%lld"; break; case TYPE_BIGINT: fmt = (un) ? "%llu" : "%lld"; break;
case TYPE_DOUBLE: fmt = "%.*lf"; break; case TYPE_DOUBLE: fmt = "%.*lf"; break;
case TYPE_BIN: fmt = "%*x"; break;
default: fmt = (un) ? "%u" : "%d"; break; default: fmt = (un) ? "%u" : "%d"; break;
} // endswitch Type } // endswitch Type
...@@ -438,6 +443,9 @@ PVAL AllocateValue(PGLOBAL g, int type, int len, int prec, ...@@ -438,6 +443,9 @@ PVAL AllocateValue(PGLOBAL g, int type, int len, int prec,
case TYPE_DECIM: case TYPE_DECIM:
valp = new(g) DECVAL(g, (PSZ)NULL, len, prec, uns); valp = new(g) DECVAL(g, (PSZ)NULL, len, prec, uns);
break; break;
case TYPE_BIN:
valp = new(g) BINVAL(g, (void*)NULL, len, prec);
break;
default: default:
sprintf(g->Message, MSG(BAD_VALUE_TYPE), type); sprintf(g->Message, MSG(BAD_VALUE_TYPE), type);
return NULL; return NULL;
...@@ -544,6 +552,7 @@ const char *VALUE::GetXfmt(void) ...@@ -544,6 +552,7 @@ const char *VALUE::GetXfmt(void)
case TYPE_SHORT: fmt = (Unsigned) ? "%*hu" : "%*hd"; break; case TYPE_SHORT: fmt = (Unsigned) ? "%*hu" : "%*hd"; break;
case TYPE_BIGINT: fmt = (Unsigned) ? "%*llu" : "%*lld"; break; case TYPE_BIGINT: fmt = (Unsigned) ? "%*llu" : "%*lld"; break;
case TYPE_DOUBLE: fmt = "%*.*lf"; break; case TYPE_DOUBLE: fmt = "%*.*lf"; break;
case TYPE_BIN: fmt = "%*x"; break;
default: fmt = (Unsigned) ? "%*u" : "%*d"; break; default: fmt = (Unsigned) ? "%*u" : "%*d"; break;
} // endswitch Type } // endswitch Type
...@@ -1695,6 +1704,426 @@ bool DECVAL::SetConstFormat(PGLOBAL g, FORMAT& fmt) ...@@ -1695,6 +1704,426 @@ bool DECVAL::SetConstFormat(PGLOBAL g, FORMAT& fmt)
} // end of SetConstFormat } // end of SetConstFormat
#endif // 0 #endif // 0
/* -------------------------- Class BINVAL --------------------------- */
/***********************************************************************/
/* BINVAL public constructor from bytes. */
/***********************************************************************/
BINVAL::BINVAL(PGLOBAL g, void *p, int cl, int n) : VALUE(TYPE_BIN)
{
assert(g);
Len = n;
Clen = cl;
Binp = PlugSubAlloc(g, NULL, Clen + 1);
memset(Binp, 0, Clen + 1);
if (p)
memcpy(Binp, p, Len);
Chrp = NULL;
} // end of BINVAL constructor
/***********************************************************************/
/* BINVAL: Check whether the hexadecimal value is equal to 0. */
/***********************************************************************/
bool BINVAL::IsZero(void)
{
for (int i = 0; i < Len; i++)
if (((char*)Binp)[i] != 0)
return false;
return true;
} // end of IsZero
/***********************************************************************/
/* BINVAL: Reset value to zero. */
/***********************************************************************/
void BINVAL::Reset(void)
{
memset(Binp, 0, Clen);
Len = 0;
} // end of Reset
/***********************************************************************/
/* Get the tiny value pointed by Binp. */
/***********************************************************************/
char BINVAL::GetTinyValue(void)
{
return *(char*)Binp;
} // end of GetTinyValue
/***********************************************************************/
/* Get the unsigned tiny value pointed by Binp. */
/***********************************************************************/
uchar BINVAL::GetUTinyValue(void)
{
return *(uchar*)Binp;
} // end of GetUTinyValue
/***********************************************************************/
/* Get the short value pointed by Binp. */
/***********************************************************************/
short BINVAL::GetShortValue(void)
{
if (Len >= 2)
return *(short*)Binp;
else
return (short)GetTinyValue();
} // end of GetShortValue
/***********************************************************************/
/* Get the unsigned short value pointed by Binp. */
/***********************************************************************/
ushort BINVAL::GetUShortValue(void)
{
return (ushort)GetShortValue();
} // end of GetUshortValue
/***********************************************************************/
/* Get the integer value pointed by Binp. */
/***********************************************************************/
int BINVAL::GetIntValue(void)
{
if (Len >= 4)
return *(int*)Binp;
else
return (int)GetShortValue();
} // end of GetIntValue
/***********************************************************************/
/* Get the unsigned integer value pointed by Binp. */
/***********************************************************************/
uint BINVAL::GetUIntValue(void)
{
return (uint)GetIntValue();
} // end of GetUintValue
/***********************************************************************/
/* Get the big integer value pointed by Binp. */
/***********************************************************************/
longlong BINVAL::GetBigintValue(void)
{
if (Len >= 8)
return *(longlong*)Binp;
else
return (longlong)GetIntValue();
} // end of GetBigintValue
/***********************************************************************/
/* Get the unsigned big integer value pointed by Binp. */
/***********************************************************************/
ulonglong BINVAL::GetUBigintValue(void)
{
return (ulonglong)GetBigintValue();
} // end of GetUBigintValue
/***********************************************************************/
/* Get the double value pointed by Binp. */
/***********************************************************************/
double BINVAL::GetFloatValue(void)
{
if (Len >= 8)
return *(double*)Binp;
else if (Len >= 4)
return (double)(*(float*)Binp);
else
return 0.0;
} // end of GetFloatValue
/***********************************************************************/
/* BINVAL SetValue: copy the value of another Value object. */
/***********************************************************************/
bool BINVAL::SetValue_pval(PVAL valp, bool chktype)
{
if (chktype && (valp->GetType() != Type || valp->GetSize() > Clen))
return true;
bool rc = false;
if (!(Null = valp->IsNull() && Nullable)) {
if ((rc = (Len = valp->GetSize()) > Clen))
Len = Clen;
memcpy(Binp, valp->GetTo_Val(), Len);
} else
Reset();
return rc;
} // end of SetValue_pval
/***********************************************************************/
/* BINVAL SetValue: fill value with chars extracted from a line. */
/***********************************************************************/
bool BINVAL::SetValue_char(char *p, int n)
{
bool rc;
if (p) {
rc = n > Clen;
Len = min(n, Clen);
memcpy(Binp, p, Len);
Null = false;
} else {
rc = false;
Reset();
Null = Nullable;
} // endif p
return rc;
} // end of SetValue_char
/***********************************************************************/
/* BINVAL SetValue: fill value with another string. */
/***********************************************************************/
void BINVAL::SetValue_psz(PSZ s)
{
if (s) {
Len = min(Clen, (signed)strlen(s));
memcpy(Binp, s, Len);
Null = false;
} else {
Reset();
Null = Nullable;
} // endif s
} // end of SetValue_psz
/***********************************************************************/
/* BINVAL SetValue: fill value with bytes extracted from a block. */
/***********************************************************************/
void BINVAL::SetValue_pvblk(PVBLK blk, int n)
{
// STRBLK's can return a NULL pointer
void *vp = blk->GetValPtrEx(n);
if (!vp || blk->IsNull(n)) {
Reset();
Null = Nullable;
} else if (vp != Binp) {
if (blk->GetType() == TYPE_STRING)
Len = strlen((char*)vp);
else
Len = blk->GetVlen();
Len = min(Clen, Len);
memcpy(Binp, vp, Len);
Null = false;
} // endif vp
} // end of SetValue_pvblk
/***********************************************************************/
/* BINVAL SetValue: get the binary representation of an integer. */
/***********************************************************************/
void BINVAL::SetValue(int n)
{
if (Clen >= 4) {
*((int*)Binp) = n;
Len = 4;
} else
SetValue((short)n);
} // end of SetValue
/***********************************************************************/
/* BINVAL SetValue: get the binary representation of an uint. */
/***********************************************************************/
void BINVAL::SetValue(uint n)
{
if (Clen >= 4) {
*((uint*)Binp) = n;
Len = 4;
} else
SetValue((ushort)n);
} // end of SetValue
/***********************************************************************/
/* BINVAL SetValue: get the binary representation of a short int. */
/***********************************************************************/
void BINVAL::SetValue(short i)
{
if (Clen >= 2) {
*((int*)Binp) = i;
Len = 2;
} else
SetValue((char)i);
} // end of SetValue
/***********************************************************************/
/* BINVAL SetValue: get the binary representation of a ushort int. */
/***********************************************************************/
void BINVAL::SetValue(ushort i)
{
if (Clen >= 2) {
*((uint*)Binp) = i;
Len = 2;
} else
SetValue((uchar)i);
} // end of SetValue
/***********************************************************************/
/* BINVAL SetValue: get the binary representation of a big integer. */
/***********************************************************************/
void BINVAL::SetValue(longlong n)
{
if (Clen >= 8) {
*((longlong*)Binp) = n;
Len = 8;
} else
SetValue((int)n);
} // end of SetValue
/***********************************************************************/
/* BINVAL SetValue: get the binary representation of a big integer. */
/***********************************************************************/
void BINVAL::SetValue(ulonglong n)
{
if (Clen >= 8) {
*((ulonglong*)Binp) = n;
Len = 8;
} else
SetValue((uint)n);
} // end of SetValue
/***********************************************************************/
/* BINVAL SetValue: get the binary representation of a double. */
/***********************************************************************/
void BINVAL::SetValue(double n)
{
if (Clen >= 8) {
*((double*)Binp) = n;
Len = 8;
} else if (Clen >= 4) {
*((float*)Binp) = (float)n;
Len = 4;
} else
Len = 0;
} // end of SetValue
/***********************************************************************/
/* BINVAL SetValue: get the character binary of a tiny int. */
/***********************************************************************/
void BINVAL::SetValue(char c)
{
*((char*)Binp) = c;
Len = 1;
} // end of SetValue
/***********************************************************************/
/* BINVAL SetValue: get the binary representation of a tiny int. */
/***********************************************************************/
void BINVAL::SetValue(uchar c)
{
*((uchar*)Binp) = c;
Len = 1;
} // end of SetValue
/***********************************************************************/
/* BINVAL SetBinValue: fill string with bytes extracted from a line. */
/***********************************************************************/
void BINVAL::SetBinValue(void *p)
{
memcpy(Binp, p, Clen);
} // end of SetBinValue
/***********************************************************************/
/* GetBinValue: fill a buffer with the internal binary value. */
/* This function checks whether the buffer length is enough and */
/* returns true if not. Actual filling occurs only if go is true. */
/* Currently used by WriteColumn of binary files. */
/***********************************************************************/
bool BINVAL::GetBinValue(void *buf, int buflen, bool go)
{
if (Len > buflen)
return true;
else if (go) {
memset(buf, 0, buflen);
memcpy(buf, Binp, Len);
} // endif go
return false;
} // end of GetBinValue
/***********************************************************************/
/* BINVAL ShowValue: get string representation of a binary value. */
/***********************************************************************/
char *BINVAL::ShowValue(char *buf, int len)
{
int n = min(Len, len / 2);
sprintf(buf, GetXfmt(), n, Binp);
return buf;
} // end of ShowValue
/***********************************************************************/
/* BINVAL GetCharString: get string representation of a binary value. */
/***********************************************************************/
char *BINVAL::GetCharString(char *p)
{
if (!Chrp)
Chrp = (char*)PlugSubAlloc(Global, NULL, Clen * 2 + 1);
sprintf(Chrp, GetXfmt(), Len, Binp);
return Chrp;
} // end of GetCharString
/***********************************************************************/
/* BINVAL compare value with another Value. */
/***********************************************************************/
bool BINVAL::IsEqual(PVAL vp, bool chktype)
{
if (this == vp)
return true;
else if (chktype && Type != vp->GetType())
return false;
else if (Null || vp->IsNull())
return false;
else if (Len != vp->GetSize())
return false;
char *v1 = (char*)Binp;
char *v2 = (char*)vp->GetTo_Val();
for (int i = 0; i < Len; i++)
if (v1[i] != v2[i])
return false;
return true;
} // end of IsEqual
/***********************************************************************/
/* FormatValue: This function set vp (a STRING value) to the string */
/* constructed from its own value formated using the fmt format. */
/* This function assumes that the format matches the value type. */
/***********************************************************************/
bool BINVAL::FormatValue(PVAL vp, char *fmt)
{
char *buf = (char*)vp->GetTo_Val(); // Should be big enough
int n = sprintf(buf, fmt, Len, Binp);
return (n > vp->GetValLen());
} // end of FormatValue
/***********************************************************************/
/* BINVAL SetFormat function (used to set SELECT output format). */
/***********************************************************************/
bool BINVAL::SetConstFormat(PGLOBAL g, FORMAT& fmt)
{
fmt.Type[0] = 'B';
fmt.Length = Clen;
fmt.Prec = 0;
return false;
} // end of SetConstFormat
/* -------------------------- Class DTVAL ---------------------------- */ /* -------------------------- Class DTVAL ---------------------------- */
/***********************************************************************/ /***********************************************************************/
......
/**************** Value H Declares Source Code File (.H) ***************/ /**************** Value H Declares Source Code File (.H) ***************/
/* Name: VALUE.H Version 2.0 */ /* Name: VALUE.H Version 2.1 */
/* */ /* */
/* (C) Copyright to the author Olivier BERTRAND 2001-2013 */ /* (C) Copyright to the author Olivier BERTRAND 2001-2014 */
/* */ /* */
/* This file contains the VALUE and derived classes declares. */ /* This file contains the VALUE and derived classes declares. */
/***********************************************************************/ /***********************************************************************/
#ifndef __VALUE__H__ #ifndef __VALUE__H__
#define __VALUE__H__ #define __VALUE__H__
/***********************************************************************/ /***********************************************************************/
/* Include required application header files */ /* Include required application header files */
/* assert.h is header required when using the assert function. */ /* assert.h is header required when using the assert function. */
/* block.h is header containing Block global declarations. */ /* block.h is header containing Block global declarations. */
/***********************************************************************/ /***********************************************************************/
#include "assert.h" #include "assert.h"
#include "block.h" #include "block.h"
/***********************************************************************/ /***********************************************************************/
/* Types used in some class definitions. */ /* Types used in some class definitions. */
/***********************************************************************/ /***********************************************************************/
enum CONV {CNV_ANY = 0, /* Convert to any type */ enum CONV {CNV_ANY = 0, /* Convert to any type */
CNV_CHAR = 1, /* Convert to character type */ CNV_CHAR = 1, /* Convert to character type */
CNV_NUM = 2}; /* Convert to numeric type */ CNV_NUM = 2}; /* Convert to numeric type */
/***********************************************************************/ /***********************************************************************/
/* Types used in some class definitions. */ /* Types used in some class definitions. */
/***********************************************************************/ /***********************************************************************/
class CONSTANT; // For friend setting class CONSTANT; // For friend setting
typedef struct _datpar *PDTP; // For DTVAL typedef struct _datpar *PDTP; // For DTVAL
/***********************************************************************/ /***********************************************************************/
/* Utilities used to test types and to allocated values. */ /* Utilities used to test types and to allocated values. */
/***********************************************************************/ /***********************************************************************/
PVAL AllocateValue(PGLOBAL, void *, short); PVAL AllocateValue(PGLOBAL, void *, short);
// Exported functions // Exported functions
DllExport PSZ GetTypeName(int); DllExport PSZ GetTypeName(int);
DllExport int GetTypeSize(int, int); DllExport int GetTypeSize(int, int);
#ifdef ODBC_SUPPORT #ifdef ODBC_SUPPORT
/* This function is exported for use in EOM table type DLLs */ /* This function is exported for use in EOM table type DLLs */
DllExport int TranslateSQLType(int stp, int prec, int& len, char& v); DllExport int TranslateSQLType(int stp, int prec, int& len, char& v);
#endif #endif
DllExport char *GetFormatType(int); DllExport char *GetFormatType(int);
DllExport int GetFormatType(char); DllExport int GetFormatType(char);
DllExport bool IsTypeChar(int type); DllExport bool IsTypeChar(int type);
DllExport bool IsTypeNum(int type); DllExport bool IsTypeNum(int type);
DllExport int ConvertType(int, int, CONV, bool match = false); DllExport int ConvertType(int, int, CONV, bool match = false);
DllExport PVAL AllocateValue(PGLOBAL, PVAL, int = TYPE_VOID, int = 0); DllExport PVAL AllocateValue(PGLOBAL, PVAL, int = TYPE_VOID, int = 0);
DllExport PVAL AllocateValue(PGLOBAL, int, int len = 0, int prec = 0, DllExport PVAL AllocateValue(PGLOBAL, int, int len = 0, int prec = 0,
bool uns = false, PSZ fmt = NULL); bool uns = false, PSZ fmt = NULL);
DllExport ulonglong CharToNumber(char *, int, ulonglong, bool, DllExport ulonglong CharToNumber(char *, int, ulonglong, bool,
bool *minus = NULL, bool *rc = NULL); bool *minus = NULL, bool *rc = NULL);
/***********************************************************************/ /***********************************************************************/
/* Class VALUE represents a constant or variable of any valid type. */ /* Class VALUE represents a constant or variable of any valid type. */
/***********************************************************************/ /***********************************************************************/
class DllExport VALUE : public BLOCK { class DllExport VALUE : public BLOCK {
friend class CONSTANT; // The only object allowed to use SetConstFormat friend class CONSTANT; // The only object allowed to use SetConstFormat
public: public:
// Constructors // Constructors
// Implementation // Implementation
virtual bool IsTypeNum(void) = 0; virtual bool IsTypeNum(void) = 0;
virtual bool IsZero(void) = 0; virtual bool IsZero(void) = 0;
virtual bool IsCi(void) {return false;} virtual bool IsCi(void) {return false;}
virtual bool IsUnsigned(void) {return Unsigned;} virtual bool IsUnsigned(void) {return Unsigned;}
virtual void Reset(void) = 0; virtual void Reset(void) = 0;
virtual int GetSize(void) = 0; virtual int GetSize(void) = 0;
virtual int GetValLen(void) = 0; virtual int GetValLen(void) = 0;
virtual int GetValPrec(void) = 0; virtual int GetValPrec(void) = 0;
virtual int GetLength(void) {return 1;} virtual int GetLength(void) {return 1;}
virtual PSZ GetCharValue(void) {assert(false); return NULL;} virtual PSZ GetCharValue(void) {assert(false); return NULL;}
virtual char GetTinyValue(void) {assert(false); return 0;} virtual char GetTinyValue(void) {assert(false); return 0;}
virtual uchar GetUTinyValue(void) {assert(false); return 0;} virtual uchar GetUTinyValue(void) {assert(false); return 0;}
virtual short GetShortValue(void) {assert(false); return 0;} virtual short GetShortValue(void) {assert(false); return 0;}
virtual ushort GetUShortValue(void) {assert(false); return 0;} virtual ushort GetUShortValue(void) {assert(false); return 0;}
virtual int GetIntValue(void) = 0; virtual int GetIntValue(void) = 0;
virtual uint GetUIntValue(void) = 0; virtual uint GetUIntValue(void) = 0;
virtual longlong GetBigintValue(void) = 0; virtual longlong GetBigintValue(void) = 0;
virtual ulonglong GetUBigintValue(void) = 0; virtual ulonglong GetUBigintValue(void) = 0;
virtual double GetFloatValue(void) = 0; virtual double GetFloatValue(void) = 0;
virtual void *GetTo_Val(void) = 0; virtual void *GetTo_Val(void) = 0;
virtual void SetPrec(int prec) {Prec = prec;} virtual void SetPrec(int prec) {Prec = prec;}
bool IsNull(void) {return Null;} bool IsNull(void) {return Null;}
void SetNull(bool b) {Null = b;} void SetNull(bool b) {Null = b;}
bool GetNullable(void) {return Nullable;} bool GetNullable(void) {return Nullable;}
void SetNullable(bool b) {Nullable = b;} void SetNullable(bool b) {Nullable = b;}
int GetType(void) {return Type;} int GetType(void) {return Type;}
int GetClen(void) {return Clen;} int GetClen(void) {return Clen;}
void SetGlobal(PGLOBAL g) {Global = g;} void SetGlobal(PGLOBAL g) {Global = g;}
// Methods // Methods
virtual bool SetValue_pval(PVAL valp, bool chktype = false) = 0; virtual bool SetValue_pval(PVAL valp, bool chktype = false) = 0;
virtual bool SetValue_char(char *p, int n) = 0; virtual bool SetValue_char(char *p, int n) = 0;
virtual void SetValue_psz(PSZ s) = 0; virtual void SetValue_psz(PSZ s) = 0;
virtual void SetValue_bool(bool b) {assert(FALSE);} virtual void SetValue_bool(bool b) {assert(FALSE);}
virtual int CompareValue(PVAL vp) = 0; virtual int CompareValue(PVAL vp) = 0;
virtual BYTE TestValue(PVAL vp); virtual BYTE TestValue(PVAL vp);
virtual void SetValue(char c) {assert(false);} virtual void SetValue(char c) {assert(false);}
virtual void SetValue(uchar c) {assert(false);} virtual void SetValue(uchar c) {assert(false);}
virtual void SetValue(short i) {assert(false);} virtual void SetValue(short i) {assert(false);}
virtual void SetValue(ushort i) {assert(false);} virtual void SetValue(ushort i) {assert(false);}
virtual void SetValue(int n) {assert(false);} virtual void SetValue(int n) {assert(false);}
virtual void SetValue(uint n) {assert(false);} virtual void SetValue(uint n) {assert(false);}
virtual void SetValue(longlong n) {assert(false);} virtual void SetValue(longlong n) {assert(false);}
virtual void SetValue(ulonglong n) {assert(false);} virtual void SetValue(ulonglong n) {assert(false);}
virtual void SetValue(double f) {assert(false);} virtual void SetValue(double f) {assert(false);}
virtual void SetValue_pvblk(PVBLK blk, int n) = 0; virtual void SetValue_pvblk(PVBLK blk, int n) = 0;
virtual void SetBinValue(void *p) = 0; virtual void SetBinValue(void *p) = 0;
virtual bool GetBinValue(void *buf, int buflen, bool go) = 0; virtual bool GetBinValue(void *buf, int buflen, bool go) = 0;
virtual char *ShowValue(char *buf, int len = 0) = 0; virtual char *ShowValue(char *buf, int len = 0) = 0;
virtual char *GetCharString(char *p) = 0; virtual char *GetCharString(char *p) = 0;
virtual bool IsEqual(PVAL vp, bool chktype) = 0; virtual bool IsEqual(PVAL vp, bool chktype) = 0;
virtual bool FormatValue(PVAL vp, char *fmt) = 0; virtual bool FormatValue(PVAL vp, char *fmt) = 0;
protected: protected:
virtual bool SetConstFormat(PGLOBAL, FORMAT&) = 0; virtual bool SetConstFormat(PGLOBAL, FORMAT&) = 0;
const char *GetXfmt(void); const char *GetXfmt(void);
// Constructor used by derived classes // Constructor used by derived classes
VALUE(int type, bool un = false); VALUE(int type, bool un = false);
// Members // Members
PGLOBAL Global; // To reduce arglist PGLOBAL Global; // To reduce arglist
const char *Fmt; const char *Fmt;
const char *Xfmt; const char *Xfmt;
bool Nullable; // True if value can be null bool Nullable; // True if value can be null
bool Null; // True if value is null bool Null; // True if value is null
bool Unsigned; // True if unsigned bool Unsigned; // True if unsigned
int Type; // The value type int Type; // The value type
int Clen; // Internal value length int Clen; // Internal value length
int Prec; int Prec;
}; // end of class VALUE }; // end of class VALUE
/***********************************************************************/ /***********************************************************************/
/* Class TYPVAL: represents a typed value. */ /* Class TYPVAL: represents a typed value. */
/***********************************************************************/ /***********************************************************************/
template <class TYPE> template <class TYPE>
class DllExport TYPVAL : public VALUE { class DllExport TYPVAL : public VALUE {
public: public:
// Constructor // Constructor
TYPVAL(TYPE n, int type, int prec = 0, bool un = false); TYPVAL(TYPE n, int type, int prec = 0, bool un = false);
// Implementation // Implementation
virtual bool IsTypeNum(void) {return true;} virtual bool IsTypeNum(void) {return true;}
virtual bool IsZero(void) {return Tval == 0;} virtual bool IsZero(void) {return Tval == 0;}
virtual void Reset(void) {Tval = 0;} virtual void Reset(void) {Tval = 0;}
virtual int GetValLen(void); virtual int GetValLen(void);
virtual int GetValPrec() {return 0;} virtual int GetValPrec() {return 0;}
virtual int GetSize(void) {return sizeof(TYPE);} virtual int GetSize(void) {return sizeof(TYPE);}
virtual PSZ GetCharValue(void) {return VALUE::GetCharValue();} virtual PSZ GetCharValue(void) {return VALUE::GetCharValue();}
virtual char GetTinyValue(void) {return (char)Tval;} virtual char GetTinyValue(void) {return (char)Tval;}
virtual uchar GetUTinyValue(void) {return (uchar)Tval;} virtual uchar GetUTinyValue(void) {return (uchar)Tval;}
virtual short GetShortValue(void) {return (short)Tval;} virtual short GetShortValue(void) {return (short)Tval;}
virtual ushort GetUShortValue(void) {return (ushort)Tval;} virtual ushort GetUShortValue(void) {return (ushort)Tval;}
virtual int GetIntValue(void) {return (int)Tval;} virtual int GetIntValue(void) {return (int)Tval;}
virtual uint GetUIntValue(void) {return (uint)Tval;} virtual uint GetUIntValue(void) {return (uint)Tval;}
virtual longlong GetBigintValue(void) {return (longlong)Tval;} virtual longlong GetBigintValue(void) {return (longlong)Tval;}
virtual ulonglong GetUBigintValue(void) {return (ulonglong)Tval;} virtual ulonglong GetUBigintValue(void) {return (ulonglong)Tval;}
virtual double GetFloatValue(void) {return (double)Tval;} virtual double GetFloatValue(void) {return (double)Tval;}
virtual void *GetTo_Val(void) {return &Tval;} virtual void *GetTo_Val(void) {return &Tval;}
// Methods // Methods
virtual bool SetValue_pval(PVAL valp, bool chktype); virtual bool SetValue_pval(PVAL valp, bool chktype);
virtual bool SetValue_char(char *p, int n); virtual bool SetValue_char(char *p, int n);
virtual void SetValue_psz(PSZ s); virtual void SetValue_psz(PSZ s);
virtual void SetValue_bool(bool b) {Tval = (b) ? 1 : 0;} virtual void SetValue_bool(bool b) {Tval = (b) ? 1 : 0;}
virtual int CompareValue(PVAL vp); virtual int CompareValue(PVAL vp);
virtual void SetValue(char c) {Tval = (TYPE)c; Null = false;} virtual void SetValue(char c) {Tval = (TYPE)c; Null = false;}
virtual void SetValue(uchar c) {Tval = (TYPE)c; Null = false;} virtual void SetValue(uchar c) {Tval = (TYPE)c; Null = false;}
virtual void SetValue(short i) {Tval = (TYPE)i; Null = false;} virtual void SetValue(short i) {Tval = (TYPE)i; Null = false;}
virtual void SetValue(ushort i) {Tval = (TYPE)i; Null = false;} virtual void SetValue(ushort i) {Tval = (TYPE)i; Null = false;}
virtual void SetValue(int n) {Tval = (TYPE)n; Null = false;} virtual void SetValue(int n) {Tval = (TYPE)n; Null = false;}
virtual void SetValue(uint n) {Tval = (TYPE)n; Null = false;} virtual void SetValue(uint n) {Tval = (TYPE)n; Null = false;}
virtual void SetValue(longlong n) {Tval = (TYPE)n; Null = false;} virtual void SetValue(longlong n) {Tval = (TYPE)n; Null = false;}
virtual void SetValue(ulonglong n) {Tval = (TYPE)n; Null = false;} virtual void SetValue(ulonglong n) {Tval = (TYPE)n; Null = false;}
virtual void SetValue(double f) {Tval = (TYPE)f; Null = false;} virtual void SetValue(double f) {Tval = (TYPE)f; Null = false;}
virtual void SetValue_pvblk(PVBLK blk, int n); virtual void SetValue_pvblk(PVBLK blk, int n);
virtual void SetBinValue(void *p); virtual void SetBinValue(void *p);
virtual bool GetBinValue(void *buf, int buflen, bool go); virtual bool GetBinValue(void *buf, int buflen, bool go);
virtual char *ShowValue(char *buf, int); virtual char *ShowValue(char *buf, int);
virtual char *GetCharString(char *p); virtual char *GetCharString(char *p);
virtual bool IsEqual(PVAL vp, bool chktype); virtual bool IsEqual(PVAL vp, bool chktype);
virtual bool SetConstFormat(PGLOBAL, FORMAT&); virtual bool SetConstFormat(PGLOBAL, FORMAT&);
virtual bool FormatValue(PVAL vp, char *fmt); virtual bool FormatValue(PVAL vp, char *fmt);
virtual void Print(PGLOBAL g, FILE *, uint); virtual void Print(PGLOBAL g, FILE *, uint);
virtual void Print(PGLOBAL g, char *, uint); virtual void Print(PGLOBAL g, char *, uint);
protected: protected:
// Default constructor not to be used // Default constructor not to be used
TYPVAL(void) : VALUE(TYPE_ERROR) {} TYPVAL(void) : VALUE(TYPE_ERROR) {}
// Specialized functions // Specialized functions
static ulonglong MaxVal(void); static ulonglong MaxVal(void);
TYPE GetTypedValue(PVAL vp); TYPE GetTypedValue(PVAL vp);
TYPE GetTypedValue(PVBLK blk, int n); TYPE GetTypedValue(PVBLK blk, int n);
// TYPE GetTypedValue(PSZ s); // TYPE GetTypedValue(PSZ s);
// Members // Members
TYPE Tval; TYPE Tval;
}; // end of class TYPVAL }; // end of class TYPVAL
/***********************************************************************/ /***********************************************************************/
/* Specific STRING class. */ /* Specific STRING class. */
/***********************************************************************/ /***********************************************************************/
template <> template <>
class DllExport TYPVAL<PSZ>: public VALUE { class DllExport TYPVAL<PSZ>: public VALUE {
public: public:
// Constructors // Constructors
TYPVAL(PSZ s); TYPVAL(PSZ s);
TYPVAL(PGLOBAL g, PSZ s, int n, int c); TYPVAL(PGLOBAL g, PSZ s, int n, int c);
// Implementation // Implementation
virtual bool IsTypeNum(void) {return false;} virtual bool IsTypeNum(void) {return false;}
virtual bool IsZero(void) {return *Strp == 0;} virtual bool IsZero(void) {return *Strp == 0;}
virtual void Reset(void) {*Strp = 0;} virtual void Reset(void) {*Strp = 0;}
virtual int GetValLen(void) {return Len;}; virtual int GetValLen(void) {return Len;};
virtual int GetValPrec() {return (Ci) ? 1 : 0;} virtual int GetValPrec() {return (Ci) ? 1 : 0;}
virtual int GetSize(void) {return (Strp) ? strlen(Strp) : 0;} virtual int GetSize(void) {return (Strp) ? strlen(Strp) : 0;}
virtual PSZ GetCharValue(void) {return Strp;} virtual PSZ GetCharValue(void) {return Strp;}
virtual char GetTinyValue(void); virtual char GetTinyValue(void);
virtual uchar GetUTinyValue(void); virtual uchar GetUTinyValue(void);
virtual short GetShortValue(void); virtual short GetShortValue(void);
virtual ushort GetUShortValue(void); virtual ushort GetUShortValue(void);
virtual int GetIntValue(void); virtual int GetIntValue(void);
virtual uint GetUIntValue(void); virtual uint GetUIntValue(void);
virtual longlong GetBigintValue(void); virtual longlong GetBigintValue(void);
virtual ulonglong GetUBigintValue(void); virtual ulonglong GetUBigintValue(void);
virtual double GetFloatValue(void) {return atof(Strp);} virtual double GetFloatValue(void) {return atof(Strp);}
virtual void *GetTo_Val(void) {return Strp;} virtual void *GetTo_Val(void) {return Strp;}
virtual void SetPrec(int prec) {Ci = prec != 0;} virtual void SetPrec(int prec) {Ci = prec != 0;}
// Methods // Methods
virtual bool SetValue_pval(PVAL valp, bool chktype); virtual bool SetValue_pval(PVAL valp, bool chktype);
virtual bool SetValue_char(char *p, int n); virtual bool SetValue_char(char *p, int n);
virtual void SetValue_psz(PSZ s); virtual void SetValue_psz(PSZ s);
virtual void SetValue_pvblk(PVBLK blk, int n); virtual void SetValue_pvblk(PVBLK blk, int n);
virtual void SetValue(char c); virtual void SetValue(char c);
virtual void SetValue(uchar c); virtual void SetValue(uchar c);
virtual void SetValue(short i); virtual void SetValue(short i);
virtual void SetValue(ushort i); virtual void SetValue(ushort i);
virtual void SetValue(int n); virtual void SetValue(int n);
virtual void SetValue(uint n); virtual void SetValue(uint n);
virtual void SetValue(longlong n); virtual void SetValue(longlong n);
virtual void SetValue(ulonglong n); virtual void SetValue(ulonglong n);
virtual void SetValue(double f); virtual void SetValue(double f);
virtual void SetBinValue(void *p); virtual void SetBinValue(void *p);
virtual int CompareValue(PVAL vp); virtual int CompareValue(PVAL vp);
virtual bool GetBinValue(void *buf, int buflen, bool go); virtual bool GetBinValue(void *buf, int buflen, bool go);
virtual char *ShowValue(char *buf, int); virtual char *ShowValue(char *buf, int);
virtual char *GetCharString(char *p); virtual char *GetCharString(char *p);
virtual bool IsEqual(PVAL vp, bool chktype); virtual bool IsEqual(PVAL vp, bool chktype);
virtual bool FormatValue(PVAL vp, char *fmt); virtual bool FormatValue(PVAL vp, char *fmt);
virtual bool SetConstFormat(PGLOBAL, FORMAT&); virtual bool SetConstFormat(PGLOBAL, FORMAT&);
// Members // Members
PSZ Strp; PSZ Strp;
bool Ci; // true if case insensitive bool Ci; // true if case insensitive
int Len; int Len;
}; // end of class TYPVAL<PSZ> }; // end of class TYPVAL<PSZ>
/***********************************************************************/ /***********************************************************************/
/* Specific DECIMAL class. */ /* Specific DECIMAL class. */
/***********************************************************************/ /***********************************************************************/
class DllExport DECVAL: public TYPVAL<PSZ> { class DllExport DECVAL: public TYPVAL<PSZ> {
public: public:
// Constructors // Constructors
DECVAL(PSZ s); DECVAL(PSZ s);
DECVAL(PGLOBAL g, PSZ s, int n, int prec, bool uns); DECVAL(PGLOBAL g, PSZ s, int n, int prec, bool uns);
// Implementation // Implementation
virtual bool IsTypeNum(void) {return true;} virtual bool IsTypeNum(void) {return true;}
virtual bool IsZero(void); virtual bool IsZero(void);
virtual void Reset(void); virtual void Reset(void);
virtual int GetValPrec() {return Prec;} virtual int GetValPrec() {return Prec;}
// Methods // Methods
virtual bool GetBinValue(void *buf, int buflen, bool go); virtual bool GetBinValue(void *buf, int buflen, bool go);
virtual char *ShowValue(char *buf, int); virtual char *ShowValue(char *buf, int);
virtual bool IsEqual(PVAL vp, bool chktype); virtual bool IsEqual(PVAL vp, bool chktype);
virtual int CompareValue(PVAL vp); virtual int CompareValue(PVAL vp);
// Members // Members
}; // end of class DECVAL }; // end of class DECVAL
/***********************************************************************/ /***********************************************************************/
/* Class DTVAL: represents a time stamp value. */ /* Specific BINARY class. */
/***********************************************************************/ /***********************************************************************/
class DllExport DTVAL : public TYPVAL<int> { class DllExport BINVAL: public VALUE {
public: public:
// Constructors // Constructors
DTVAL(PGLOBAL g, int n, int p, PSZ fmt); //BINVAL(void *p);
DTVAL(PGLOBAL g, PSZ s, int n); BINVAL(PGLOBAL g, void *p, int cl, int n);
DTVAL(PGLOBAL g, short i);
DTVAL(PGLOBAL g, int n); // Implementation
DTVAL(PGLOBAL g, longlong n); virtual bool IsTypeNum(void) {return false;}
DTVAL(PGLOBAL g, double f); virtual bool IsZero(void);
virtual void Reset(void);
// Implementation virtual int GetValLen(void) {return Clen;};
virtual bool SetValue_pval(PVAL valp, bool chktype); virtual int GetValPrec() {return 0;}
virtual bool SetValue_char(char *p, int n); virtual int GetSize(void) {return Len;}
virtual void SetValue_psz(PSZ s); virtual PSZ GetCharValue(void) {return (PSZ)Binp;}
virtual void SetValue_pvblk(PVBLK blk, int n); virtual char GetTinyValue(void);
virtual char *GetCharString(char *p); virtual uchar GetUTinyValue(void);
virtual char *ShowValue(char *buf, int); virtual short GetShortValue(void);
virtual bool FormatValue(PVAL vp, char *fmt); virtual ushort GetUShortValue(void);
bool SetFormat(PGLOBAL g, PSZ fmt, int len, int year = 0); virtual int GetIntValue(void);
bool SetFormat(PGLOBAL g, PVAL valp); virtual uint GetUIntValue(void);
bool IsFormatted(void) {return Pdtp != NULL;} virtual longlong GetBigintValue(void);
bool MakeTime(struct tm *ptm); virtual ulonglong GetUBigintValue(void);
static void SetTimeShift(void); virtual double GetFloatValue(void);
static int GetShift(void) {return Shift;} virtual void *GetTo_Val(void) {return Binp;}
// Methods // Methods
bool MakeDate(PGLOBAL g, int *val, int nval); virtual bool SetValue_pval(PVAL valp, bool chktype);
virtual bool SetValue_char(char *p, int n);
struct tm *GetGmTime(struct tm *); virtual void SetValue_psz(PSZ s);
virtual void SetValue_pvblk(PVBLK blk, int n);
protected: virtual void SetValue(char c);
// Default constructor not to be used virtual void SetValue(uchar c);
DTVAL(void) : TYPVAL<int>() {} virtual void SetValue(short i);
virtual void SetValue(ushort i);
// Members virtual void SetValue(int n);
static int Shift; // Time zone shift in seconds virtual void SetValue(uint n);
PDTP Pdtp; // To the DATPAR structure virtual void SetValue(longlong n);
char *Sdate; // Utility char buffer virtual void SetValue(ulonglong n);
int DefYear; // Used by ExtractDate virtual void SetValue(double f);
int Len; // Used by CHAR scalar function virtual void SetBinValue(void *p);
}; // end of class DTVAL virtual bool GetBinValue(void *buf, int buflen, bool go);
virtual int CompareValue(PVAL vp) {assert(false); return 0;}
#endif // __VALUE__H__ virtual char *ShowValue(char *buf, int);
virtual char *GetCharString(char *p);
virtual bool IsEqual(PVAL vp, bool chktype);
virtual bool FormatValue(PVAL vp, char *fmt);
virtual bool SetConstFormat(PGLOBAL, FORMAT&);
// Members
void *Binp;
char *Chrp;
int Len;
}; // end of class BINVAL
/***********************************************************************/
/* Class DTVAL: represents a time stamp value. */
/***********************************************************************/
class DllExport DTVAL : public TYPVAL<int> {
public:
// Constructors
DTVAL(PGLOBAL g, int n, int p, PSZ fmt);
DTVAL(PGLOBAL g, PSZ s, int n);
DTVAL(PGLOBAL g, short i);
DTVAL(PGLOBAL g, int n);
DTVAL(PGLOBAL g, longlong n);
DTVAL(PGLOBAL g, double f);
// Implementation
virtual bool SetValue_pval(PVAL valp, bool chktype);
virtual bool SetValue_char(char *p, int n);
virtual void SetValue_psz(PSZ s);
virtual void SetValue_pvblk(PVBLK blk, int n);
virtual char *GetCharString(char *p);
virtual char *ShowValue(char *buf, int);
virtual bool FormatValue(PVAL vp, char *fmt);
bool SetFormat(PGLOBAL g, PSZ fmt, int len, int year = 0);
bool SetFormat(PGLOBAL g, PVAL valp);
bool IsFormatted(void) {return Pdtp != NULL;}
bool MakeTime(struct tm *ptm);
static void SetTimeShift(void);
static int GetShift(void) {return Shift;}
// Methods
bool MakeDate(PGLOBAL g, int *val, int nval);
struct tm *GetGmTime(struct tm *);
protected:
// Default constructor not to be used
DTVAL(void) : TYPVAL<int>() {}
// Members
static int Shift; // Time zone shift in seconds
PDTP Pdtp; // To the DATPAR structure
char *Sdate; // Utility char buffer
int DefYear; // Used by ExtractDate
int Len; // Used by CHAR scalar function
}; // end of class DTVAL
#endif // __VALUE__H__
...@@ -61,6 +61,9 @@ ...@@ -61,6 +61,9 @@
/***********************************************************************/ /***********************************************************************/
extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */ extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */
extern "C" int trace; extern "C" int trace;
#if defined(XMAP)
extern bool xmap;
#endif // XMAP
/***********************************************************************/ /***********************************************************************/
/* Last two parameters are true to enable type checking, and last one */ /* Last two parameters are true to enable type checking, and last one */
...@@ -810,12 +813,16 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp) ...@@ -810,12 +813,16 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp)
return rc; return rc;
} // end of SaveIndex } // end of SaveIndex
#if !defined(XMAP)
/***********************************************************************/ /***********************************************************************/
/* Init: Open and Initialize a Key Index. */ /* Init: Open and Initialize a Key Index. */
/***********************************************************************/ /***********************************************************************/
bool XINDEX::Init(PGLOBAL g) bool XINDEX::Init(PGLOBAL g)
{ {
#if defined(XMAP)
if (xmap)
return MapInit(g);
#endif // XMAP
/*********************************************************************/ /*********************************************************************/
/* Table will be accessed through an index table. */ /* Table will be accessed through an index table. */
/* If sorting is required, this will be done later. */ /* If sorting is required, this will be done later. */
...@@ -1051,11 +1058,11 @@ err: ...@@ -1051,11 +1058,11 @@ err:
return true; return true;
} // end of Init } // end of Init
#else // XMAP #if defined(XMAP)
/***********************************************************************/ /***********************************************************************/
/* Init: Open and Initialize a Key Index. */ /* Init: Open and Initialize a Key Index. */
/***********************************************************************/ /***********************************************************************/
bool XINDEX::Init(PGLOBAL g) bool XINDEX::MapInit(PGLOBAL g)
{ {
/*********************************************************************/ /*********************************************************************/
/* Table will be accessed through an index table. */ /* Table will be accessed through an index table. */
...@@ -1256,7 +1263,7 @@ bool XINDEX::Init(PGLOBAL g) ...@@ -1256,7 +1263,7 @@ bool XINDEX::Init(PGLOBAL g)
err: err:
Close(); Close();
return true; return true;
} // end of Init } // end of MapInit
#endif // XMAP #endif // XMAP
/***********************************************************************/ /***********************************************************************/
...@@ -1563,6 +1570,46 @@ bool XINDEX::NextVal(bool eq) ...@@ -1563,6 +1570,46 @@ bool XINDEX::NextVal(bool eq)
return (Cur_K == Num_K || (eq && neq <= Nval)); return (Cur_K == Num_K || (eq && neq <= Nval));
} // end of NextVal } // end of NextVal
/***********************************************************************/
/* XINDEX: Find Cur_K and Val_K's of previous index entry. */
/* Returns false if Ok, true if there are no more values. */
/***********************************************************************/
bool XINDEX::PrevVal(void)
{
int n, neq = Nk + 1, curk;
PXCOL kcp;
if (Cur_K == 0)
return true;
else
curk = --Cur_K;
for (n = Nk, kcp = To_LastCol; kcp; n--, kcp = kcp->Previous) {
if (kcp->Kof) {
if (curk < kcp->Kof[kcp->Val_K])
neq = n;
} else {
#ifdef _DEBUG
assert(curk == kcp->Val_K -1);
#endif // _DEBUG
neq = n;
} // endif Kof
#ifdef _DEBUG
assert(kcp->Val_K >= 0);
#endif // _DEBUG
// If this is not a break...
if (neq > n)
break; // all previous columns have same value
curk = --kcp->Val_K; // This is a break, get new column value
} // endfor kcp
return false;
} // end of PrevVal
/***********************************************************************/ /***********************************************************************/
/* XINDEX: Fetch a physical or logical record. */ /* XINDEX: Fetch a physical or logical record. */
/***********************************************************************/ /***********************************************************************/
...@@ -1615,6 +1662,12 @@ int XINDEX::Fetch(PGLOBAL g) ...@@ -1615,6 +1662,12 @@ int XINDEX::Fetch(PGLOBAL g)
Op = (Mul || Nval < Nk) ? OP_NXTDIF : OP_NEXT; Op = (Mul || Nval < Nk) ? OP_NXTDIF : OP_NEXT;
break; break;
case OP_LAST: // Read last key
for (Cur_K = Num_K - 1, kp = To_KeyCol; kp; kp = kp->Next)
kp->Val_K = kp->Kblp->GetNval() - 1;
Op = OP_NEXT;
break;
default: // Should be OP_EQ default: // Should be OP_EQ
// if (Tbxp->Key_Rank < 0) { // if (Tbxp->Key_Rank < 0) {
/***************************************************************/ /***************************************************************/
...@@ -1851,6 +1904,25 @@ int XINDXS::GroupSize(void) ...@@ -1851,6 +1904,25 @@ int XINDXS::GroupSize(void)
: 1; : 1;
} // end of GroupSize } // end of GroupSize
/***********************************************************************/
/* XINDXS: Find Cur_K and Val_K of previous index value. */
/* Returns false if Ok, true if there are no more values. */
/***********************************************************************/
bool XINDXS::PrevVal(void)
{
if (--Cur_K < 0)
return true;
if (Mul) {
if (Cur_K < Pof[To_KeyCol->Val_K])
To_KeyCol->Val_K--;
} else
To_KeyCol->Val_K = Cur_K;
return false;
} // end of PrevVal
/***********************************************************************/ /***********************************************************************/
/* XINDXS: Find Cur_K and Val_K of next index value. */ /* XINDXS: Find Cur_K and Val_K of next index value. */
/* If b is true next value must be equal to last one. */ /* If b is true next value must be equal to last one. */
...@@ -1895,12 +1967,12 @@ int XINDXS::Fetch(PGLOBAL g) ...@@ -1895,12 +1967,12 @@ int XINDXS::Fetch(PGLOBAL g)
/* Table read through a sorted index. */ /* Table read through a sorted index. */
/*********************************************************************/ /*********************************************************************/
switch (Op) { switch (Op) {
case OP_NEXT: // Read next case OP_NEXT: // Read next
if (NextVal(false)) if (NextVal(false))
return -1; // End of indexed file return -1; // End of indexed file
break; break;
case OP_FIRST: // Read first case OP_FIRST: // Read first
To_KeyCol->Val_K = Cur_K = 0; To_KeyCol->Val_K = Cur_K = 0;
Op = OP_NEXT; Op = OP_NEXT;
break; break;
...@@ -1914,7 +1986,7 @@ int XINDXS::Fetch(PGLOBAL g) ...@@ -1914,7 +1986,7 @@ int XINDXS::Fetch(PGLOBAL g)
} // endif Mul } // endif Mul
break; break;
case OP_NXTDIF: // Read next dif case OP_NXTDIF: // Read next dif
if (++To_KeyCol->Val_K == Ndif) if (++To_KeyCol->Val_K == Ndif)
return -1; // End of indexed file return -1; // End of indexed file
...@@ -1924,7 +1996,17 @@ int XINDXS::Fetch(PGLOBAL g) ...@@ -1924,7 +1996,17 @@ int XINDXS::Fetch(PGLOBAL g)
To_KeyCol->Val_K = Cur_K = 0; To_KeyCol->Val_K = Cur_K = 0;
Op = (Mul) ? OP_NXTDIF : OP_NEXT; Op = (Mul) ? OP_NXTDIF : OP_NEXT;
break; break;
default: // Should OP_EQ case OP_LAST: // Read first
Cur_K = Num_K - 1;
To_KeyCol->Val_K = Ndif - 1;
Op = OP_PREV;
break;
case OP_PREV: // Read previous
if (PrevVal())
return -1; // End of indexed file
break;
default: // Should be OP_EQ
/*****************************************************************/ /*****************************************************************/
/* Look for the first key equal to the link column values */ /* Look for the first key equal to the link column values */
/* and return its rank whithin the index table. */ /* and return its rank whithin the index table. */
...@@ -2837,7 +2919,8 @@ BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m) ...@@ -2837,7 +2919,8 @@ BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m)
} // endif n[1] } // endif n[1]
Ndf = n[0]; Ndf = n[0];
IsSorted = colp->GetOpt() < 0; //IsSorted = colp->GetOpt() < 0;
IsSorted = false;
return m + Bkeys.Size + Keys.Size + Koff.Size; return m + Bkeys.Size + Keys.Size + Koff.Size;
} // end of MapInit } // end of MapInit
#endif // XMAP #endif // XMAP
......
...@@ -192,9 +192,13 @@ class DllExport XXBASE : public CSORT, public BLOCK { ...@@ -192,9 +192,13 @@ class DllExport XXBASE : public CSORT, public BLOCK {
virtual void Print(PGLOBAL g, FILE *f, uint n); virtual void Print(PGLOBAL g, FILE *f, uint n);
virtual void Print(PGLOBAL g, char *ps, uint z); virtual void Print(PGLOBAL g, char *ps, uint z);
virtual bool Init(PGLOBAL g) = 0; virtual bool Init(PGLOBAL g) = 0;
#if defined(XMAP)
virtual bool MapInit(PGLOBAL g) = 0;
#endif // XMAP
virtual int MaxRange(void) {return 1;} virtual int MaxRange(void) {return 1;}
virtual int Fetch(PGLOBAL g) = 0; virtual int Fetch(PGLOBAL g) = 0;
virtual bool NextVal(bool eq) {return true;} virtual bool NextVal(bool eq) {return true;}
virtual bool PrevVal(void) {return true;}
virtual int FastFind(int nk) = 0; virtual int FastFind(int nk) = 0;
virtual bool Reorder(PGLOBAL g) {return true;} virtual bool Reorder(PGLOBAL g) {return true;}
virtual int Range(PGLOBAL g, int limit = 0, bool incl = true) virtual int Range(PGLOBAL g, int limit = 0, bool incl = true)
...@@ -206,22 +210,22 @@ class DllExport XXBASE : public CSORT, public BLOCK { ...@@ -206,22 +210,22 @@ class DllExport XXBASE : public CSORT, public BLOCK {
protected: protected:
// Members // Members
PTDBASE Tbxp; // Points to calling table TDB PTDBASE Tbxp; // Points to calling table TDB
PXCOL To_KeyCol; // To KeyCol class list PXCOL To_KeyCol; // To KeyCol class list
MBLOCK Record; // Record allocation block MBLOCK Record; // Record allocation block
int* &To_Rec; // We are using ftell, fseek int* &To_Rec; // We are using ftell, fseek
int Cur_K; // Index of current record int Cur_K; // Index of current record
int Old_K; // Index of last record int Old_K; // Index of last record
int Num_K; // Size of Rec_K pointer array int Num_K; // Size of Rec_K pointer array
int Ndif; // Number of distinct values int Ndif; // Number of distinct values
int Bot; // Bottom of research index int Bot; // Bottom of research index
int Top; // Top of research index int Top; // Top of research index
int Inf, Sup; // Used for block optimization int Inf, Sup; // Used for block optimization
OPVAL Op; // Search operator OPVAL Op; // Search operator
bool Mul; // true if multiple bool Mul; // true if multiple
bool Srtd; // true for sorted column bool Srtd; // true for sorted column
int Val_K; // Index of current value int Val_K; // Index of current value
int Nblk; // Number of blocks int Nblk; // Number of blocks
int Sblk; // Block size int Sblk; // Block size
int Thresh; // Thresh for sorting join indexes int Thresh; // Thresh for sorting join indexes
int ID; // Index ID number int ID; // Index ID number
int Nth; // Nth constant to fetch int Nth; // Nth constant to fetch
...@@ -248,6 +252,9 @@ class DllExport XINDEX : public XXBASE { ...@@ -248,6 +252,9 @@ class DllExport XINDEX : public XXBASE {
// Methods // Methods
virtual void Reset(void); virtual void Reset(void);
virtual bool Init(PGLOBAL g); virtual bool Init(PGLOBAL g);
#if defined(XMAP)
virtual bool MapInit(PGLOBAL g);
#endif // XMAP
virtual int Qcompare(int *, int *); virtual int Qcompare(int *, int *);
virtual int Fetch(PGLOBAL g); virtual int Fetch(PGLOBAL g);
virtual int FastFind(int nk); virtual int FastFind(int nk);
...@@ -257,6 +264,7 @@ class DllExport XINDEX : public XXBASE { ...@@ -257,6 +264,7 @@ class DllExport XINDEX : public XXBASE {
virtual int ColMaxSame(PXCOL kp); virtual int ColMaxSame(PXCOL kp);
virtual void Close(void); virtual void Close(void);
virtual bool NextVal(bool eq); virtual bool NextVal(bool eq);
virtual bool PrevVal(void);
virtual bool Make(PGLOBAL g, PIXDEF sxp); virtual bool Make(PGLOBAL g, PIXDEF sxp);
virtual bool SaveIndex(PGLOBAL g, PIXDEF sxp); virtual bool SaveIndex(PGLOBAL g, PIXDEF sxp);
virtual bool Reorder(PGLOBAL g); virtual bool Reorder(PGLOBAL g);
...@@ -296,6 +304,7 @@ class DllExport XINDXS : public XINDEX { ...@@ -296,6 +304,7 @@ class DllExport XINDXS : public XINDEX {
virtual int Fetch(PGLOBAL g); virtual int Fetch(PGLOBAL g);
virtual int FastFind(int nk); virtual int FastFind(int nk);
virtual bool NextVal(bool eq); virtual bool NextVal(bool eq);
virtual bool PrevVal(void);
virtual int Range(PGLOBAL g, int limit = 0, bool incl = true); virtual int Range(PGLOBAL g, int limit = 0, bool incl = true);
virtual int GroupSize(void); virtual int GroupSize(void);
...@@ -403,6 +412,9 @@ class DllExport XXROW : public XXBASE { ...@@ -403,6 +412,9 @@ class DllExport XXROW : public XXBASE {
// Methods // Methods
virtual bool Init(PGLOBAL g); virtual bool Init(PGLOBAL g);
#if defined(XMAP)
virtual bool MapInit(PGLOBAL g) {return true;}
#endif // XMAP
virtual int Fetch(PGLOBAL g); virtual int Fetch(PGLOBAL g);
virtual int FastFind(int nk); virtual int FastFind(int nk);
virtual int MaxRange(void) {return 1;} virtual int MaxRange(void) {return 1;}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment