1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

- 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
This commit is contained in:
Olivier Bertrand
2014-04-19 11:11:30 +02:00
24 changed files with 8874 additions and 7986 deletions

View File

@@ -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() {
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)
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})

View File

@@ -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);

View File

@@ -1,258 +1,259 @@
/***********************************************************************/ /***********************************************************************/
/* 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 --------------------------*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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)
/* 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,
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,
/**********************************************************************/ /**********************************************************************/
/* 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,
} // 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,
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,
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)
/***********************************************************************/ /***********************************************************************/
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)
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)
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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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 { };

View File

@@ -1,163 +1,163 @@
-- 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

View File

@@ -1,9 +1,9 @@
/************** 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 @@
#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)
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)
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)
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)
#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;

View File

@@ -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)
// 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);

File diff suppressed because it is too large Load Diff

View File

@@ -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)
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)
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)
"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)
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 */

View File

@@ -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)
/***********************************************************************/ /***********************************************************************/
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

View File

@@ -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)
// 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)
// 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)
// 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
/***********************************************************************/ /***********************************************************************/

View File

@@ -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,
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,
/**********************************************************************/ /**********************************************************************/
/* 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,
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,
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,
// 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,
// Add this item // Add this item
qrp->Nblin++; qrp->Nblin++;
i++; // Can be skipped
} // endfor field } // endfor field
/**********************************************************************/ /**********************************************************************/

View File

@@ -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()
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)
{ {
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;

View File

@@ -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,
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,
/***********************************************************************/ /***********************************************************************/
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)
} // 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)
/* 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)
/***********************************************************************/ /***********************************************************************/
/* 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)
/***********************************************************************/ /***********************************************************************/
/* 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
/***********************************************************************/ /***********************************************************************/

View File

@@ -1,27 +1,27 @@
/*************** 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 {
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__

View File

@@ -1,5 +1,5 @@
/************* 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)
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)
{ {
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)
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)
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)
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,
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)
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)
} // 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 ---------------------------- */
/***********************************************************************/ /***********************************************************************/

View File

@@ -1,333 +1,390 @@
/**************** 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__

View File

@@ -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)
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:
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)
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)
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)
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)
: 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)
/* 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)
} // 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)
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)
} // 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

View File

@@ -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 {
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 {
// 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 {
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 {
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 {
// 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;}