Commit 81252031 authored by Olivier Bertrand's avatar Olivier Bertrand

- Commit merged files

modified:
  storage/connect/CMakeLists.txt
  storage/connect/connect.h
  storage/connect/global.h
  storage/connect/ha_connect.cc
  storage/connect/ha_connect.h
  storage/connect/myconn.cpp
  storage/connect/myconn.h
  storage/connect/mysql-test/connect/r/pivot.result
  storage/connect/mysql-test/connect/suite.pm
  storage/connect/mysql-test/connect/t/pivot.test
  storage/connect/myutil.cpp
  storage/connect/osutil.c
  storage/connect/plgdbsem.h
  storage/connect/plugutil.c
  storage/connect/tabmysql.cpp
  storage/connect/tabpivot.cpp
  storage/connect/tabutil.cpp
  storage/connect/user_connect.cc
  storage/connect/valblk.cpp
  storage/connect/valblk.h
  storage/connect/value.cpp
  storage/connect/value.h
  storage/connect/xindex.cpp
  storage/connect/xindex.h
parents cc7a08c9 b43e82dc
...@@ -264,6 +264,17 @@ int main() { ...@@ -264,6 +264,17 @@ int main() {
ENDIF(UNIX) ENDIF(UNIX)
ENDIF(CONNECT_WITH_ODBC) ENDIF(CONNECT_WITH_ODBC)
#
# XMAP
#
OPTION(CONNECT_WITH_XMAP "Compile CONNECT storage engine with index file mapping support" ON)
IF(CONNECT_WITH_XMAP)
add_definitions(-DXMAP)
ENDIF(CONNECT_WITH_XMAP)
# #
# Plugin definition # Plugin definition
# #
...@@ -271,6 +282,7 @@ ENDIF(CONNECT_WITH_ODBC) ...@@ -271,6 +282,7 @@ ENDIF(CONNECT_WITH_ODBC)
MYSQL_ADD_PLUGIN(connect ${CONNECT_SOURCES} MYSQL_ADD_PLUGIN(connect ${CONNECT_SOURCES}
STORAGE_ENGINE STORAGE_ENGINE
COMPONENT connect-engine COMPONENT connect-engine
RECOMPILE_FOR_EMBEDDED
LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY} LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY}
${ODBC_LIBRARY} ${IPHLPAPI_LIBRARY}) ${ODBC_LIBRARY} ${IPHLPAPI_LIBRARY})
...@@ -36,8 +36,7 @@ bool CntRewindTable(PGLOBAL g, PTDB tdbp); ...@@ -36,8 +36,7 @@ bool CntRewindTable(PGLOBAL g, PTDB tdbp);
int CntCloseTable(PGLOBAL g, PTDB tdbp); int CntCloseTable(PGLOBAL g, PTDB tdbp);
int CntIndexInit(PGLOBAL g, PTDB tdbp, int id); int CntIndexInit(PGLOBAL g, PTDB tdbp, int id);
RCODE CntReadNext(PGLOBAL g, PTDB tdbp); RCODE CntReadNext(PGLOBAL g, PTDB tdbp);
RCODE CntIndexRead(PGLOBAL g, PTDB, OPVAL op, const void *k, int n, RCODE CntIndexRead(PGLOBAL g, PTDB, OPVAL op, const void *k, int n, bool mrr);
bool mrr = false);
RCODE CntWriteRow(PGLOBAL g, PTDB tdbp); RCODE CntWriteRow(PGLOBAL g, PTDB tdbp);
RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp); RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp);
RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all); RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all);
......
/***********************************************************************/ /***********************************************************************/
/* GLOBAL.H: Declaration file used by all CONNECT implementations. */ /* GLOBAL.H: Declaration file used by all CONNECT implementations. */
/* (C) Copyright Olivier Bertrand 1993-2012 */ /* (C) Copyright Olivier Bertrand 1993-2014 */
/***********************************************************************/ /***********************************************************************/
/***********************************************************************/ /***********************************************************************/
...@@ -84,6 +84,7 @@ ...@@ -84,6 +84,7 @@
#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) #if defined(OS32)
#define SYS_STAMP "OS32" #define SYS_STAMP "OS32"
......
This diff is collapsed.
...@@ -256,7 +256,8 @@ public: ...@@ -256,7 +256,8 @@ public:
*/ */
ulong index_flags(uint inx, uint part, bool all_parts) const ulong index_flags(uint inx, uint part, bool all_parts) const
{ {
return HA_READ_NEXT | HA_READ_RANGE | HA_READ_ORDER | HA_KEYREAD_ONLY; return HA_READ_NEXT | HA_READ_RANGE | HA_READ_ORDER
| HA_KEYREAD_ONLY | HA_KEY_SCAN_NOT_ROR;
} // end of index_flags } // end of index_flags
/** @brief /** @brief
...@@ -432,7 +433,7 @@ PFIL CondFilter(PGLOBAL g, Item *cond); ...@@ -432,7 +433,7 @@ PFIL CondFilter(PGLOBAL g, Item *cond);
We implement this in ha_connect.cc. It's not an obligatory method; We implement this in ha_connect.cc. It's not an obligatory method;
skip it and and MySQL will treat it as not implemented. skip it and and MySQL will treat it as not implemented.
*/ */
//int index_last(uchar *buf); int index_last(uchar *buf);
/* Index condition pushdown implementation */ /* Index condition pushdown implementation */
//Item *idx_cond_push(uint keyno, Item* idx_cond); //Item *idx_cond_push(uint keyno, Item* idx_cond);
......
...@@ -47,9 +47,12 @@ ...@@ -47,9 +47,12 @@
#include "myconn.h" #include "myconn.h"
extern "C" int trace; extern "C" int trace;
extern "C" int zconv;
extern MYSQL_PLUGIN_IMPORT uint mysqld_port; extern MYSQL_PLUGIN_IMPORT uint mysqld_port;
extern MYSQL_PLUGIN_IMPORT char *mysqld_unix_port; extern MYSQL_PLUGIN_IMPORT char *mysqld_unix_port;
DllExport void PushWarning(PGLOBAL, THD*, int level = 1);
// Returns the current used port // Returns the current used port
uint GetDefaultPort(void) uint GetDefaultPort(void)
{ {
...@@ -61,7 +64,7 @@ uint GetDefaultPort(void) ...@@ -61,7 +64,7 @@ uint GetDefaultPort(void)
/* of a MySQL table or view. */ /* of a MySQL table or view. */
/* info = TRUE to get catalog column informations. */ /* info = TRUE to get catalog column informations. */
/************************************************************************/ /************************************************************************/
PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
const char *user, const char *pwd, const char *user, const char *pwd,
const char *table, const char *colpat, const char *table, const char *colpat,
int port, bool info) int port, bool info)
...@@ -75,7 +78,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, ...@@ -75,7 +78,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
FLD_REM, FLD_NO, FLD_DEFAULT, FLD_EXTRA, FLD_REM, FLD_NO, FLD_DEFAULT, FLD_EXTRA,
FLD_CHARSET}; FLD_CHARSET};
unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0}; unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0};
char *fld, *fmt, v, cmd[128], uns[16], zero[16]; char *fld, *colname, *chset, *fmt, v, cmd[128], uns[16], zero[16];
int i, n, nf, ncol = sizeof(buftyp) / sizeof(int); int i, n, nf, ncol = sizeof(buftyp) / sizeof(int);
int len, type, prec, rc, k = 0; int len, type, prec, rc, k = 0;
PQRYRES qrp; PQRYRES qrp;
...@@ -144,23 +147,24 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, ...@@ -144,23 +147,24 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
/**********************************************************************/ /**********************************************************************/
/* Now get the results into blocks. */ /* Now get the results into blocks. */
/**********************************************************************/ /**********************************************************************/
for (i = 0; i < n; i++) { for (i = 0; i < n; /*i++*/) {
if ((rc = myc.Fetch(g, -1) == RC_FX)) { if ((rc = myc.Fetch(g, -1)) == RC_FX) {
myc.Close(); myc.Close();
return NULL; return NULL;
} else if (rc == RC_NF) } else if (rc == RC_EF)
break; break;
// Get column name // Get column name
fld = myc.GetCharField(0); colname = myc.GetCharField(0);
crp = qrp->Colresp; // Column_Name crp = qrp->Colresp; // Column_Name
crp->Kdata->SetValue(fld, i); crp->Kdata->SetValue(colname, i);
// Get type, type name, precision, unsigned and zerofill // Get type, type name, precision, unsigned and zerofill
chset = myc.GetCharField(2);
fld = myc.GetCharField(1); fld = myc.GetCharField(1);
prec = 0; prec = 0;
len = 0; len = 0;
v = 0; v = (chset && !strcmp(chset, "binary")) ? 'B' : 0;
*uns = 0; *uns = 0;
*zero = 0; *zero = 0;
...@@ -181,12 +185,29 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, ...@@ -181,12 +185,29 @@ 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) {
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); len = min(len, 4096);
} // endif type
qrp->Nblin++; qrp->Nblin++;
crp = crp->Next; // Data_Type crp = crp->Next; // Data_Type
crp->Kdata->SetValue(type, i); crp->Kdata->SetValue(type, i);
...@@ -241,8 +262,10 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, ...@@ -241,8 +262,10 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
crp->Kdata->SetValue(fld, i); crp->Kdata->SetValue(fld, i);
crp = crp->Next; // New (charset) crp = crp->Next; // New (charset)
fld = myc.GetCharField(2); fld = chset;
crp->Kdata->SetValue(fld, i); crp->Kdata->SetValue(fld, i);
i++; // Can be skipped
} // endfor i } // endfor i
#if 0 #if 0
......
...@@ -34,7 +34,7 @@ typedef class MYSQLC *PMYC; ...@@ -34,7 +34,7 @@ typedef class MYSQLC *PMYC;
/***********************************************************************/ /***********************************************************************/
/* Prototypes of info functions. */ /* Prototypes of info functions. */
/***********************************************************************/ /***********************************************************************/
PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
const char *user, const char *pwd, const char *user, const char *pwd,
const char *table, const char *colpat, const char *table, const char *colpat,
int port, bool info); int port, bool info);
......
...@@ -229,7 +229,7 @@ DROP TABLE pets; ...@@ -229,7 +229,7 @@ DROP TABLE pets;
# #
CREATE TABLE fruit ( CREATE TABLE fruit (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(32) DEFAULT NULL, `name` varchar(32) NOT NULL,
`cnt` int(11) DEFAULT NULL, `cnt` int(11) DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1; ) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
......
...@@ -5,6 +5,11 @@ package My::Suite::Connect; ...@@ -5,6 +5,11 @@ package My::Suite::Connect;
return "No CONNECT engine" unless $ENV{HA_CONNECT_SO} or return "No CONNECT engine" unless $ENV{HA_CONNECT_SO} or
$::mysqld_variables{'connect'} eq "ON"; $::mysqld_variables{'connect'} eq "ON";
# RECOMPILE_FOR_EMBEDDED also means that a plugin
# cannot be dynamically loaded into embedded
return "Not run for embedded server" if $::opt_embedded_server and
$ENV{HA_CONNECT_SO};
sub is_default { 1 } sub is_default { 1 }
bless { }; bless { };
......
...@@ -149,7 +149,7 @@ DROP TABLE pets; ...@@ -149,7 +149,7 @@ DROP TABLE pets;
--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;
......
/************** MyUtil C++ Program Source Code File (.CPP) **************/ /************** MyUtil C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: MYUTIL */ /* PROGRAM NAME: MYUTIL */
/* ------------- */ /* ------------- */
/* Version 1.1 */ /* Version 1.2 */
/* */ /* */
/* Author Olivier BERTRAND 2013 */ /* Author Olivier BERTRAND 2014 */
/* */ /* */
/* WHAT THIS PROGRAM DOES: */ /* WHAT THIS PROGRAM DOES: */
/* ----------------------- */ /* ----------------------- */
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include "myutil.h" #include "myutil.h"
#define DLL_EXPORT // Items are exported from this DLL #define DLL_EXPORT // Items are exported from this DLL
extern "C" int xconv;
/************************************************************************/ /************************************************************************/
/* Convert from MySQL type name to PlugDB type number */ /* Convert from MySQL type name to PlugDB type number */
/************************************************************************/ /************************************************************************/
...@@ -38,8 +40,7 @@ int MYSQLtoPLG(char *typname, char *var) ...@@ -38,8 +40,7 @@ int MYSQLtoPLG(char *typname, char *var)
type = TYPE_INT; type = TYPE_INT;
else if (!stricmp(typname, "smallint")) else if (!stricmp(typname, "smallint"))
type = TYPE_SHORT; type = TYPE_SHORT;
else if (!stricmp(typname, "char") || !stricmp(typname, "varchar") || else if (!stricmp(typname, "char") || !stricmp(typname, "varchar"))
!stricmp(typname, "text") || !stricmp(typname, "blob"))
type = TYPE_STRING; type = TYPE_STRING;
else if (!stricmp(typname, "double") || !stricmp(typname, "float") || else if (!stricmp(typname, "double") || !stricmp(typname, "float") ||
!stricmp(typname, "real")) !stricmp(typname, "real"))
...@@ -54,7 +55,20 @@ int MYSQLtoPLG(char *typname, char *var) ...@@ -54,7 +55,20 @@ int MYSQLtoPLG(char *typname, char *var)
type = TYPE_BIGINT; type = TYPE_BIGINT;
else if (!stricmp(typname, "tinyint")) else if (!stricmp(typname, "tinyint"))
type = TYPE_TINY; type = TYPE_TINY;
else else if (!stricmp(typname, "text") && var) {
switch (xconv) {
case 1:
type = TYPE_STRING;
*var = 'X';
break;
case 2:
*var = 'K';
default:
type = TYPE_ERROR;
} // endswitch xconv
return type;
} else
type = TYPE_ERROR; type = TYPE_ERROR;
if (var) { if (var) {
...@@ -71,9 +85,11 @@ int MYSQLtoPLG(char *typname, char *var) ...@@ -71,9 +85,11 @@ int MYSQLtoPLG(char *typname, char *var)
else if (!stricmp(typname, "year")) else if (!stricmp(typname, "year"))
*var = 'Y'; *var = 'Y';
} else if (type == TYPE_STRING && stricmp(typname, "char")) } else if (type == TYPE_STRING && !stricmp(typname, "varchar"))
// This is to make the difference between CHAR and VARCHAR // This is to make the difference between CHAR and VARCHAR
*var = 'V'; *var = 'V';
else if (type == TYPE_ERROR && xconv == 2)
*var = 'K';
else else
*var = 0; *var = 0;
...@@ -196,27 +212,43 @@ int MYSQLtoPLG(int mytype, char *var) ...@@ -196,27 +212,43 @@ 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) {
switch (xconv) {
case 1:
if (*var != 'B') {
// This is a TEXT column
type = TYPE_STRING; type = TYPE_STRING;
*var = 'X';
} else
type = TYPE_ERROR;
break; 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;
......
...@@ -16,6 +16,7 @@ my_bool CloseFileHandle(HANDLE h) ...@@ -16,6 +16,7 @@ my_bool CloseFileHandle(HANDLE h)
#include <sys/stat.h> #include <sys/stat.h>
#include <ctype.h> #include <ctype.h>
#include <fcntl.h> #include <fcntl.h>
#include <pwd.h>
extern FILE *debug; extern FILE *debug;
...@@ -172,16 +173,23 @@ char *_fullpath(char *absPath, const char *relPath, size_t maxLength) ...@@ -172,16 +173,23 @@ char *_fullpath(char *absPath, const char *relPath, size_t maxLength)
// Fixme // Fixme
char *p; char *p;
if( *relPath == '\\' || *relPath == '/' ) { if ( *relPath == '\\' || *relPath == '/' ) {
strncpy(absPath, relPath, maxLength); strncpy(absPath, relPath, maxLength);
} else if(*relPath == '~') { } else if (*relPath == '~') {
// get the path to the home directory // get the path to the home directory
// Fixme struct passwd *pw = getpwuid(getuid());
const char *homedir = pw->pw_dir;
if (homedir)
strcat(strncpy(absPath, homedir, maxLength), relPath + 1);
else
strncpy(absPath, relPath, maxLength); strncpy(absPath, relPath, maxLength);
} else { } 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);
......
...@@ -293,6 +293,7 @@ enum OPVAL {OP_EQ = 1, /* Filtering operator = */ ...@@ -293,6 +293,7 @@ enum OPVAL {OP_EQ = 1, /* Filtering operator = */
OP_CURDT = 113, /* Scalar function Op CurDate */ OP_CURDT = 113, /* Scalar function Op CurDate */
OP_NWEEK = 114, /* Scalar function Op Week number*/ OP_NWEEK = 114, /* Scalar function Op Week number*/
OP_ROW = 115, /* Scalar function Op Row */ OP_ROW = 115, /* Scalar function Op Row */
OP_PREV = 116, /* Index operator Find Previous */
OP_SYSTEM = 200, /* Scalar function Op System */ OP_SYSTEM = 200, /* Scalar function Op System */
OP_REMOVE = 201, /* Scalar function Op Remove */ OP_REMOVE = 201, /* Scalar function Op Remove */
OP_RENAME = 202, /* Scalar function Op Rename */ OP_RENAME = 202, /* Scalar function Op Rename */
......
...@@ -115,11 +115,6 @@ void htrc(char const *fmt, ...) ...@@ -115,11 +115,6 @@ void htrc(char const *fmt, ...)
va_list ap; va_list ap;
va_start (ap, fmt); va_start (ap, fmt);
//if (trace == 0 || (trace == 1 && !debug) || !fmt) {
// printf("In %s wrong trace=%d debug=%p fmt=%p\n",
// __FILE__, trace, debug, fmt);
// trace = 0;
// } // endif trace
//if (trace == 1) //if (trace == 1)
// vfprintf(debug, fmt, ap); // vfprintf(debug, fmt, ap);
...@@ -257,6 +252,19 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath) ...@@ -257,6 +252,19 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath)
return pBuff; return pBuff;
} // endif } // endif
#if !defined(WIN32)
if (*FileName == '~') {
if (_fullpath(pBuff, FileName, _MAX_PATH)) {
if (trace > 1)
htrc("pbuff='%s'\n", pBuff);
return pBuff;
} else
return FileName; // Error, return unchanged name
} // endif FileName
#endif // !WIN32
if (strcmp(prefix, ".") && !PlugIsAbsolutePath(defpath)) if (strcmp(prefix, ".") && !PlugIsAbsolutePath(defpath))
{ {
char tmp[_MAX_PATH]; char tmp[_MAX_PATH];
...@@ -478,10 +486,9 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) ...@@ -478,10 +486,9 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
size = ((size + 7) / 8) * 8; /* Round up size to multiple of 8 */ size = ((size + 7) / 8) * 8; /* Round up size to multiple of 8 */
pph = (PPOOLHEADER)memp; pph = (PPOOLHEADER)memp;
#if defined(DEBUG2) || defined(DEBUG3) if (trace > 2)
htrc("SubAlloc in %p size=%d used=%d free=%d\n", htrc("SubAlloc in %p size=%d used=%d free=%d\n",
memp, size, pph->To_Free, pph->FreeBlk); memp, size, pph->To_Free, pph->FreeBlk);
#endif
if ((uint)size > pph->FreeBlk) { /* Not enough memory left in pool */ if ((uint)size > pph->FreeBlk) { /* Not enough memory left in pool */
char *pname = "Work"; char *pname = "Work";
...@@ -490,9 +497,8 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) ...@@ -490,9 +497,8 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
"Not enough memory in %s area for request of %u (used=%d free=%d)", "Not enough memory in %s area for request of %u (used=%d free=%d)",
pname, (uint) size, pph->To_Free, pph->FreeBlk); pname, (uint) size, pph->To_Free, pph->FreeBlk);
#if defined(DEBUG2) || defined(DEBUG3) if (trace)
htrc("%s\n", g->Message); htrc("PlugSubAlloc: %s\n", g->Message);
#endif
longjmp(g->jumper[g->jump_level], 1); longjmp(g->jumper[g->jump_level], 1);
} /* endif size OS32 code */ } /* endif size OS32 code */
...@@ -503,10 +509,11 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) ...@@ -503,10 +509,11 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
memp = MakePtr(memp, pph->To_Free); /* Points to suballocated block */ memp = MakePtr(memp, pph->To_Free); /* Points to suballocated block */
pph->To_Free += size; /* New offset of pool free block */ pph->To_Free += size; /* New offset of pool free block */
pph->FreeBlk -= size; /* New size of pool free block */ pph->FreeBlk -= size; /* New size of pool free block */
#if defined(DEBUG2) || defined(DEBUG3)
if (trace > 2)
htrc("Done memp=%p used=%d free=%d\n", htrc("Done memp=%p used=%d free=%d\n",
memp, pph->To_Free, pph->FreeBlk); memp, pph->To_Free, pph->FreeBlk);
#endif
return (memp); return (memp);
} /* end of PlugSubAlloc */ } /* end of PlugSubAlloc */
......
...@@ -1134,10 +1134,13 @@ MYSQLCOL::MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am) ...@@ -1134,10 +1134,13 @@ MYSQLCOL::MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
MYSQLCOL::MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am) MYSQLCOL::MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am)
: COLBLK(NULL, tdbp, i) : COLBLK(NULL, tdbp, i)
{ {
const char *chset = get_charset_name(fld->charsetnr);
char v = (!strcmp(chset, "binary")) ? 'B' : 0;
Name = fld->name; Name = fld->name;
Opt = 0; Opt = 0;
Precision = Long = fld->length; Precision = Long = fld->length;
Buf_Type = MYSQLtoPLG(fld->type); Buf_Type = MYSQLtoPLG(fld->type, &v);
strcpy(Format.Type, GetFormatType(Buf_Type)); strcpy(Format.Type, GetFormatType(Buf_Type));
Format.Length = Long; Format.Length = Long;
Format.Prec = fld->decimals; Format.Prec = fld->decimals;
...@@ -1616,5 +1619,5 @@ TDBMCL::TDBMCL(PMYDEF tdp) : TDBCAT(tdp) ...@@ -1616,5 +1619,5 @@ TDBMCL::TDBMCL(PMYDEF tdp) : TDBCAT(tdp)
/***********************************************************************/ /***********************************************************************/
PQRYRES TDBMCL::GetResult(PGLOBAL g) PQRYRES TDBMCL::GetResult(PGLOBAL g)
{ {
return MyColumns(g, Host, Db, User, Pwd, Tab, NULL, Port, false); return MyColumns(g, NULL, Host, Db, User, Pwd, Tab, NULL, Port, false);
} // end of GetResult } // end of GetResult
...@@ -96,10 +96,21 @@ PIVAID::PIVAID(const char *tab, const char *src, const char *picol, ...@@ -96,10 +96,21 @@ PIVAID::PIVAID(const char *tab, const char *src, const char *picol,
PQRYRES PIVAID::MakePivotColumns(PGLOBAL g) PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
{ {
char *query, *colname, buf[64]; char *query, *colname, buf[64];
int ndif, nblin, w = 0; int rc, ndif, nblin, w = 0;
bool b = false;
PVAL valp; PVAL valp;
PCOLRES *pcrp, crp, fncrp = NULL; PCOLRES *pcrp, crp, fncrp = NULL;
// Save stack and allocation environment and prepare error return
if (g->jump_level == MAX_JUMP) {
strcpy(g->Message, MSG(TOO_MANY_JUMPS));
return NULL;
} // endif jump_level
if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
goto err;
} // endif rc
if (!Tabsrc && Tabname) { if (!Tabsrc && Tabname) {
// Locate the query // Locate the query
query = (char*)PlugSubAlloc(g, NULL, strlen(Tabname) + 16); query = (char*)PlugSubAlloc(g, NULL, strlen(Tabname) + 16);
...@@ -113,16 +124,17 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g) ...@@ -113,16 +124,17 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
// Open a MySQL connection for this table // Open a MySQL connection for this table
if (Myc.Open(g, Host, Database, User, Pwd, Port)) if (Myc.Open(g, Host, Database, User, Pwd, Port))
return NULL; return NULL;
else
b = true;
// Send the source command to MySQL // Send the source command to MySQL
if (Myc.ExecSQL(g, query, &w) == RC_FX) { if (Myc.ExecSQL(g, query, &w) == RC_FX)
Myc.Close(); goto err;
return NULL;
} // endif Exec
// We must have a storage query to get pivot column values // We must have a storage query to get pivot column values
Qryp = Myc.GetResult(g, true); Qryp = Myc.GetResult(g, true);
Myc.Close(); Myc.Close();
b = false;
if (!Fncol) { if (!Fncol) {
for (crp = Qryp->Colresp; crp; crp = crp->Next) for (crp = Qryp->Colresp; crp; crp = crp->Next)
...@@ -152,6 +164,11 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g) ...@@ -152,6 +164,11 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
// Prepare the column list // Prepare the column list
for (pcrp = &Qryp->Colresp; crp = *pcrp; ) for (pcrp = &Qryp->Colresp; crp = *pcrp; )
if (!stricmp(Picol, crp->Name)) { if (!stricmp(Picol, crp->Name)) {
if (crp->Nulls) {
sprintf(g->Message, "Pivot column %s cannot be nullable", Picol);
return NULL;
} // endif Nulls
Rblkp = crp->Kdata; Rblkp = crp->Kdata;
*pcrp = crp->Next; *pcrp = crp->Next;
} else if (!stricmp(Fncol, crp->Name)) { } else if (!stricmp(Fncol, crp->Name)) {
...@@ -218,6 +235,12 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g) ...@@ -218,6 +235,12 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
// We added ndif columns and removed 2 (picol and fncol) // We added ndif columns and removed 2 (picol and fncol)
Qryp->Nbcol += (ndif - 2); Qryp->Nbcol += (ndif - 2);
return Qryp; return Qryp;
err:
if (b)
Myc.Close();
return NULL;
} // end of MakePivotColumns } // end of MakePivotColumns
/***********************************************************************/ /***********************************************************************/
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#include "ha_connect.h" #include "ha_connect.h"
extern "C" int trace; extern "C" int trace;
extern "C" int zconv;
/************************************************************************/ /************************************************************************/
/* Used by MYSQL tables to get MySQL parameters from the calling proxy */ /* Used by MYSQL tables to get MySQL parameters from the calling proxy */
...@@ -129,7 +130,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, ...@@ -129,7 +130,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
FLD_LENGTH, FLD_SCALE, FLD_RADIX, FLD_NULL, FLD_LENGTH, FLD_SCALE, FLD_RADIX, FLD_NULL,
FLD_REM, FLD_NO, FLD_CHARSET}; FLD_REM, FLD_NO, FLD_CHARSET};
unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 32, 32}; unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 32, 32};
char *fld, *fmt, v; char *fld, *colname, *chset, *fmt, v;
int i, n, ncol = sizeof(buftyp) / sizeof(int); int i, n, ncol = sizeof(buftyp) / sizeof(int);
int prec, len, type, scale; int prec, len, type, scale;
bool mysql; bool mysql;
...@@ -176,21 +177,37 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, ...@@ -176,21 +177,37 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
/**********************************************************************/ /**********************************************************************/
/* Now get the results into blocks. */ /* Now get the results into blocks. */
/**********************************************************************/ /**********************************************************************/
for (i = 0, field= s->field; *field; i++, field++) { for (i = 0, field= s->field; *field; field++) {
fp= *field; fp= *field;
// Get column name // Get column name
crp = qrp->Colresp; // Column_Name crp = qrp->Colresp; // Column_Name
fld = (char *)fp->field_name; colname = (char *)fp->field_name;
crp->Kdata->SetValue(fld, i); crp->Kdata->SetValue(colname, i);
v = 0;
chset = (char *)fp->charset()->name;
v = (!strcmp(chset, "binary")) ? 'B' : 0;
if ((type = MYSQLtoPLG(fp->type(), &v)) == TYPE_ERROR) { if ((type = MYSQLtoPLG(fp->type(), &v)) == TYPE_ERROR) {
sprintf(g->Message, "Unsupported column type %s", GetTypeName(type)); if (v == 'K') {
// Skip this column
sprintf(g->Message, "Column %s skipped (unsupported type)", colname);
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
continue;
} // endif v
sprintf(g->Message, "Column %s unsupported type", colname);
qrp = NULL; qrp = NULL;
break; break;
} // endif type } // endif type
if (v == 'X') {
len = zconv;
sprintf(g->Message, "Column %s converted to varchar(%d)",
colname, len);
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
} // endif v
crp = crp->Next; // Data_Type crp = crp->Next; // Data_Type
crp->Kdata->SetValue(type, i); crp->Kdata->SetValue(type, i);
...@@ -198,11 +215,12 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, ...@@ -198,11 +215,12 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
crp->Nulls[i] = 'Z'; crp->Nulls[i] = 'Z';
else if (fp->flags & UNSIGNED_FLAG) else if (fp->flags & UNSIGNED_FLAG)
crp->Nulls[i] = 'U'; crp->Nulls[i] = 'U';
else else // X means TEXT field
crp->Nulls[i] = v; crp->Nulls[i] = (v == 'X') ? 'V' : v;
crp = crp->Next; // Type_Name crp = crp->Next; // Type_Name
crp->Kdata->SetValue(GetTypeName(type), i); crp->Kdata->SetValue(GetTypeName(type), i);
fmt = NULL;
if (type == TYPE_DATE) { if (type == TYPE_DATE) {
// When creating tables we do need info about date columns // When creating tables we do need info about date columns
...@@ -214,7 +232,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, ...@@ -214,7 +232,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
prec = len = fp->field_length; prec = len = fp->field_length;
} // endif mysql } // endif mysql
} else { } else if (v != 'X') {
if (type == TYPE_DECIM) if (type == TYPE_DECIM)
prec = ((Field_new_decimal*)fp)->precision; prec = ((Field_new_decimal*)fp)->precision;
else else
...@@ -222,8 +240,8 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, ...@@ -222,8 +240,8 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
// prec = (prec(???) == NOT_FIXED_DEC) ? 0 : fp->field_length; // prec = (prec(???) == NOT_FIXED_DEC) ? 0 : fp->field_length;
len = fp->char_length(); len = fp->char_length();
fmt = NULL; } else
} // endif type prec = len = zconv;
crp = crp->Next; // Precision crp = crp->Next; // Precision
crp->Kdata->SetValue(prec, i); crp->Kdata->SetValue(prec, i);
...@@ -259,6 +277,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, ...@@ -259,6 +277,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
// Add this item // Add this item
qrp->Nblin++; qrp->Nblin++;
i++; // Can be skipped
} // endfor field } // endfor field
/**********************************************************************/ /**********************************************************************/
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include "mycat.h" #include "mycat.h"
extern "C" int trace; extern "C" int trace;
extern uint worksize;
/****************************************************************************/ /****************************************************************************/
/* Initialize the user_connect static member. */ /* Initialize the user_connect static member. */
...@@ -94,8 +95,9 @@ bool user_connect::user_init() ...@@ -94,8 +95,9 @@ bool user_connect::user_init()
PDBUSER dup= NULL; PDBUSER dup= NULL;
// Areasize= 64M because of VEC tables. Should be parameterisable // Areasize= 64M because of VEC tables. Should be parameterisable
g= PlugInit(NULL, 67108864); //g= PlugInit(NULL, 67108864);
//g= PlugInit(NULL, 134217728); // 128M was because of old embedded tests //g= PlugInit(NULL, 134217728); // 128M was because of old embedded tests
g= PlugInit(NULL, worksize);
// Check whether the initialization is complete // Check whether the initialization is complete
if (!g || !g->Sarea || PlugSubSet(g, g->Sarea, g->Sarea_Size) if (!g || !g->Sarea || PlugSubSet(g, g->Sarea, g->Sarea_Size)
...@@ -142,6 +144,20 @@ bool user_connect::CheckCleanup(void) ...@@ -142,6 +144,20 @@ bool user_connect::CheckCleanup(void)
{ {
if (thdp->query_id > last_query_id) { if (thdp->query_id > last_query_id) {
PlugCleanup(g, true); PlugCleanup(g, true);
if (g->Sarea_Size != worksize) {
if (g->Sarea)
free(g->Sarea);
// Check whether the work area size was changed
if (!(g->Sarea = PlugAllocMem(g, worksize))) {
g->Sarea = PlugAllocMem(g, g->Sarea_Size);
worksize = g->Sarea_Size; // Was too big
} else
g->Sarea_Size = worksize; // Ok
} // endif worksize
PlugSubSet(g, g->Sarea, g->Sarea_Size); PlugSubSet(g, g->Sarea, g->Sarea_Size);
g->Xchk = NULL; g->Xchk = NULL;
g->Createas = 0; g->Createas = 0;
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#define CheckParms(V, N) ChkIndx(N); ChkTyp(V); #define CheckParms(V, N) ChkIndx(N); ChkTyp(V);
extern "C" int trace; extern "C" int trace;
extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */
/***********************************************************************/ /***********************************************************************/
/* AllocValBlock: allocate a VALBLK according to type. */ /* AllocValBlock: allocate a VALBLK according to type. */
...@@ -105,8 +106,7 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len, ...@@ -105,8 +106,7 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
return NULL; return NULL;
} // endswitch Type } // endswitch Type
blkp->Init(g, check); return (blkp->Init(g, check)) ? NULL : blkp;
return blkp;
} // end of AllocValBlock } // end of AllocValBlock
/* -------------------------- Class VALBLK --------------------------- */ /* -------------------------- Class VALBLK --------------------------- */
...@@ -116,6 +116,7 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len, ...@@ -116,6 +116,7 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
/***********************************************************************/ /***********************************************************************/
VALBLK::VALBLK(void *mp, int type, int nval, bool un) VALBLK::VALBLK(void *mp, int type, int nval, bool un)
{ {
Mblk = Nmblk;
Blkp = mp; Blkp = mp;
To_Nulls = NULL; To_Nulls = NULL;
Check = true; Check = true;
...@@ -179,6 +180,22 @@ void VALBLK::SetNullable(bool b) ...@@ -179,6 +180,22 @@ void VALBLK::SetNullable(bool b)
} // end of SetNullable } // end of SetNullable
/***********************************************************************/
/* Buffer allocation routine. */
/***********************************************************************/
bool VALBLK::AllocBuff(PGLOBAL g, size_t size)
{
Mblk.Size = size;
if (!(Blkp = PlgDBalloc(g, NULL, Mblk))) {
sprintf(g->Message, MSG(MEM_ALLOC_ERR), "Blkp", Mblk.Size);
fprintf(stderr, "%s\n", g->Message);
return true;
} // endif Blkp
return false;
} // end of AllocBuff
/***********************************************************************/ /***********************************************************************/
/* Check functions. */ /* Check functions. */
/***********************************************************************/ /***********************************************************************/
...@@ -229,13 +246,15 @@ TYPBLK<TYPE>::TYPBLK(void *mp, int nval, int type, int prec, bool un) ...@@ -229,13 +246,15 @@ TYPBLK<TYPE>::TYPBLK(void *mp, int nval, int type, int prec, bool un)
/* Initialization routine. */ /* Initialization routine. */
/***********************************************************************/ /***********************************************************************/
template <class TYPE> template <class TYPE>
void TYPBLK<TYPE>::Init(PGLOBAL g, bool check) bool TYPBLK<TYPE>::Init(PGLOBAL g, bool check)
{ {
if (!Blkp) if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * sizeof(TYPE)); if (AllocBuff(g, Nval * sizeof(TYPE)))
return true;
Check = check; Check = check;
Global = g; Global = g;
return false;
} // end of Init } // end of Init
/***********************************************************************/ /***********************************************************************/
...@@ -606,16 +625,18 @@ CHRBLK::CHRBLK(void *mp, int nval, int len, int prec, bool blank) ...@@ -606,16 +625,18 @@ CHRBLK::CHRBLK(void *mp, int nval, int len, int prec, bool blank)
/***********************************************************************/ /***********************************************************************/
/* Initialization routine. */ /* Initialization routine. */
/***********************************************************************/ /***********************************************************************/
void CHRBLK::Init(PGLOBAL g, bool check) bool CHRBLK::Init(PGLOBAL g, bool check)
{ {
Valp = (char*)PlugSubAlloc(g, NULL, Long + 1); Valp = (char*)PlugSubAlloc(g, NULL, Long + 1);
Valp[Long] = '\0'; Valp[Long] = '\0';
if (!Blkp) if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * Long); if (AllocBuff(g, Nval * Long))
return true;
Check = check; Check = check;
Global = g; Global = g;
return false;
} // end of Init } // end of Init
/***********************************************************************/ /***********************************************************************/
...@@ -996,13 +1017,15 @@ STRBLK::STRBLK(PGLOBAL g, void *mp, int nval) ...@@ -996,13 +1017,15 @@ STRBLK::STRBLK(PGLOBAL g, void *mp, int nval)
/***********************************************************************/ /***********************************************************************/
/* Initialization routine. */ /* Initialization routine. */
/***********************************************************************/ /***********************************************************************/
void STRBLK::Init(PGLOBAL g, bool check) bool STRBLK::Init(PGLOBAL g, bool check)
{ {
if (!Blkp) if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * sizeof(PSZ)); if (AllocBuff(g, Nval * sizeof(PSZ)))
return true;
Check = check; Check = check;
Global = g; Global = g;
return false;
} // end of Init } // end of Init
/***********************************************************************/ /***********************************************************************/
......
...@@ -75,7 +75,7 @@ class VALBLK : public BLOCK { ...@@ -75,7 +75,7 @@ class VALBLK : public BLOCK {
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;
...@@ -120,12 +120,14 @@ class VALBLK : public BLOCK { ...@@ -120,12 +120,14 @@ class VALBLK : public BLOCK {
bool Locate(PVAL vp, int& i); bool Locate(PVAL vp, int& i);
protected: protected:
bool AllocBuff(PGLOBAL g, size_t size);
void ChkIndx(int n); void ChkIndx(int n);
void ChkTyp(PVAL v); void ChkTyp(PVAL v);
void ChkTyp(PVBLK vb); void ChkTyp(PVBLK vb);
// Members // Members
PGLOBAL Global; // Used for messages and allocation PGLOBAL Global; // Used for messages and allocation
MBLOCK Mblk; // Used to allocate buffer
char *To_Nulls; // Null values array char *To_Nulls; // Null values array
void *Blkp; // To value block void *Blkp; // To value block
bool Check; // If true SetValue types must match bool Check; // If true SetValue types must match
...@@ -146,7 +148,7 @@ class TYPBLK : public VALBLK { ...@@ -146,7 +148,7 @@ class TYPBLK : public VALBLK {
TYPBLK(void *mp, int size, int type, int prec = 0, bool un = false); TYPBLK(void *mp, int size, int type, int prec = 0, bool un = false);
// Implementation // Implementation
virtual void Init(PGLOBAL g, bool check); virtual bool Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return sizeof(TYPE);} virtual int GetVlen(void) {return sizeof(TYPE);}
virtual char GetTinyValue(int n) {return (char)Typp[n];} virtual char GetTinyValue(int n) {return (char)Typp[n];}
virtual uchar GetUTinyValue(int n) {return (uchar)Typp[n];} virtual uchar GetUTinyValue(int n) {return (uchar)Typp[n];}
...@@ -213,7 +215,7 @@ class CHRBLK : public VALBLK { ...@@ -213,7 +215,7 @@ class CHRBLK : public VALBLK {
CHRBLK(void *mp, int size, int len, int prec, bool b); CHRBLK(void *mp, int size, int len, int prec, bool b);
// Implementation // Implementation
virtual void Init(PGLOBAL g, bool check); virtual bool Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return Long;} virtual int GetVlen(void) {return Long;}
virtual PSZ GetCharValue(int n); virtual PSZ GetCharValue(int n);
virtual char GetTinyValue(int n); virtual char GetTinyValue(int n);
...@@ -268,7 +270,7 @@ class STRBLK : public VALBLK { ...@@ -268,7 +270,7 @@ class STRBLK : public VALBLK {
virtual void SetNull(int n, bool b) {if (b) {Strp[n] = NULL;}} virtual void SetNull(int n, bool b) {if (b) {Strp[n] = NULL;}}
virtual bool IsNull(int n) {return Strp[n] == NULL;} virtual bool IsNull(int n) {return Strp[n] == NULL;}
virtual void SetNullable(bool b) {} // Always nullable virtual void SetNullable(bool b) {} // Always nullable
virtual void Init(PGLOBAL g, bool check); virtual bool Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return sizeof(PSZ);} virtual int GetVlen(void) {return sizeof(PSZ);}
virtual PSZ GetCharValue(int n) {return Strp[n];} virtual PSZ GetCharValue(int n) {return Strp[n];}
virtual char GetTinyValue(int n); virtual char GetTinyValue(int n);
......
This diff is collapsed.
/**************** 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. */
/***********************************************************************/ /***********************************************************************/
...@@ -285,6 +285,63 @@ class DllExport DECVAL: public TYPVAL<PSZ> { ...@@ -285,6 +285,63 @@ class DllExport DECVAL: public TYPVAL<PSZ> {
// Members // Members
}; // end of class DECVAL }; // end of class DECVAL
/***********************************************************************/
/* Specific BINARY class. */
/***********************************************************************/
class DllExport BINVAL: public VALUE {
public:
// Constructors
//BINVAL(void *p);
BINVAL(PGLOBAL g, void *p, int cl, int n);
// Implementation
virtual bool IsTypeNum(void) {return false;}
virtual bool IsZero(void);
virtual void Reset(void);
virtual int GetValLen(void) {return Clen;};
virtual int GetValPrec() {return 0;}
virtual int GetSize(void) {return Len;}
virtual PSZ GetCharValue(void) {return (PSZ)Binp;}
virtual char GetTinyValue(void);
virtual uchar GetUTinyValue(void);
virtual short GetShortValue(void);
virtual ushort GetUShortValue(void);
virtual int GetIntValue(void);
virtual uint GetUIntValue(void);
virtual longlong GetBigintValue(void);
virtual ulonglong GetUBigintValue(void);
virtual double GetFloatValue(void);
virtual void *GetTo_Val(void) {return Binp;}
// Methods
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 void SetValue(char c);
virtual void SetValue(uchar c);
virtual void SetValue(short i);
virtual void SetValue(ushort i);
virtual void SetValue(int n);
virtual void SetValue(uint n);
virtual void SetValue(longlong n);
virtual void SetValue(ulonglong n);
virtual void SetValue(double f);
virtual void SetBinValue(void *p);
virtual bool GetBinValue(void *buf, int buflen, bool go);
virtual int CompareValue(PVAL vp) {assert(false); return 0;}
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 DTVAL: represents a time stamp value. */
/***********************************************************************/ /***********************************************************************/
......
...@@ -61,6 +61,9 @@ ...@@ -61,6 +61,9 @@
/***********************************************************************/ /***********************************************************************/
extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */ extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */
extern "C" int trace; extern "C" int trace;
#if defined(XMAP)
extern bool xmap;
#endif // XMAP
/***********************************************************************/ /***********************************************************************/
/* Last two parameters are true to enable type checking, and last one */ /* Last two parameters are true to enable type checking, and last one */
...@@ -810,12 +813,16 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp) ...@@ -810,12 +813,16 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp)
return rc; return rc;
} // end of SaveIndex } // end of SaveIndex
#if !defined(XMAP)
/***********************************************************************/ /***********************************************************************/
/* Init: Open and Initialize a Key Index. */ /* Init: Open and Initialize a Key Index. */
/***********************************************************************/ /***********************************************************************/
bool XINDEX::Init(PGLOBAL g) bool XINDEX::Init(PGLOBAL g)
{ {
#if defined(XMAP)
if (xmap)
return MapInit(g);
#endif // XMAP
/*********************************************************************/ /*********************************************************************/
/* Table will be accessed through an index table. */ /* Table will be accessed through an index table. */
/* If sorting is required, this will be done later. */ /* If sorting is required, this will be done later. */
...@@ -1051,11 +1058,11 @@ err: ...@@ -1051,11 +1058,11 @@ err:
return true; return true;
} // end of Init } // end of Init
#else // XMAP #if defined(XMAP)
/***********************************************************************/ /***********************************************************************/
/* Init: Open and Initialize a Key Index. */ /* Init: Open and Initialize a Key Index. */
/***********************************************************************/ /***********************************************************************/
bool XINDEX::Init(PGLOBAL g) bool XINDEX::MapInit(PGLOBAL g)
{ {
/*********************************************************************/ /*********************************************************************/
/* Table will be accessed through an index table. */ /* Table will be accessed through an index table. */
...@@ -1256,7 +1263,7 @@ bool XINDEX::Init(PGLOBAL g) ...@@ -1256,7 +1263,7 @@ bool XINDEX::Init(PGLOBAL g)
err: err:
Close(); Close();
return true; return true;
} // end of Init } // end of MapInit
#endif // XMAP #endif // XMAP
/***********************************************************************/ /***********************************************************************/
...@@ -1563,6 +1570,46 @@ bool XINDEX::NextVal(bool eq) ...@@ -1563,6 +1570,46 @@ bool XINDEX::NextVal(bool eq)
return (Cur_K == Num_K || (eq && neq <= Nval)); return (Cur_K == Num_K || (eq && neq <= Nval));
} // end of NextVal } // end of NextVal
/***********************************************************************/
/* XINDEX: Find Cur_K and Val_K's of previous index entry. */
/* Returns false if Ok, true if there are no more values. */
/***********************************************************************/
bool XINDEX::PrevVal(void)
{
int n, neq = Nk + 1, curk;
PXCOL kcp;
if (Cur_K == 0)
return true;
else
curk = --Cur_K;
for (n = Nk, kcp = To_LastCol; kcp; n--, kcp = kcp->Previous) {
if (kcp->Kof) {
if (curk < kcp->Kof[kcp->Val_K])
neq = n;
} else {
#ifdef _DEBUG
assert(curk == kcp->Val_K -1);
#endif // _DEBUG
neq = n;
} // endif Kof
#ifdef _DEBUG
assert(kcp->Val_K >= 0);
#endif // _DEBUG
// If this is not a break...
if (neq > n)
break; // all previous columns have same value
curk = --kcp->Val_K; // This is a break, get new column value
} // endfor kcp
return false;
} // end of PrevVal
/***********************************************************************/ /***********************************************************************/
/* XINDEX: Fetch a physical or logical record. */ /* XINDEX: Fetch a physical or logical record. */
/***********************************************************************/ /***********************************************************************/
...@@ -1615,6 +1662,12 @@ int XINDEX::Fetch(PGLOBAL g) ...@@ -1615,6 +1662,12 @@ int XINDEX::Fetch(PGLOBAL g)
Op = (Mul || Nval < Nk) ? OP_NXTDIF : OP_NEXT; Op = (Mul || Nval < Nk) ? OP_NXTDIF : OP_NEXT;
break; break;
case OP_LAST: // Read last key
for (Cur_K = Num_K - 1, kp = To_KeyCol; kp; kp = kp->Next)
kp->Val_K = kp->Kblp->GetNval() - 1;
Op = OP_NEXT;
break;
default: // Should be OP_EQ default: // Should be OP_EQ
// if (Tbxp->Key_Rank < 0) { // if (Tbxp->Key_Rank < 0) {
/***************************************************************/ /***************************************************************/
...@@ -1851,6 +1904,25 @@ int XINDXS::GroupSize(void) ...@@ -1851,6 +1904,25 @@ int XINDXS::GroupSize(void)
: 1; : 1;
} // end of GroupSize } // end of GroupSize
/***********************************************************************/
/* XINDXS: Find Cur_K and Val_K of previous index value. */
/* Returns false if Ok, true if there are no more values. */
/***********************************************************************/
bool XINDXS::PrevVal(void)
{
if (--Cur_K < 0)
return true;
if (Mul) {
if (Cur_K < Pof[To_KeyCol->Val_K])
To_KeyCol->Val_K--;
} else
To_KeyCol->Val_K = Cur_K;
return false;
} // end of PrevVal
/***********************************************************************/ /***********************************************************************/
/* XINDXS: Find Cur_K and Val_K of next index value. */ /* XINDXS: Find Cur_K and Val_K of next index value. */
/* If b is true next value must be equal to last one. */ /* If b is true next value must be equal to last one. */
...@@ -1924,7 +1996,17 @@ int XINDXS::Fetch(PGLOBAL g) ...@@ -1924,7 +1996,17 @@ int XINDXS::Fetch(PGLOBAL g)
To_KeyCol->Val_K = Cur_K = 0; To_KeyCol->Val_K = Cur_K = 0;
Op = (Mul) ? OP_NXTDIF : OP_NEXT; Op = (Mul) ? OP_NXTDIF : OP_NEXT;
break; break;
default: // Should OP_EQ case OP_LAST: // Read first
Cur_K = Num_K - 1;
To_KeyCol->Val_K = Ndif - 1;
Op = OP_PREV;
break;
case OP_PREV: // Read previous
if (PrevVal())
return -1; // End of indexed file
break;
default: // Should be OP_EQ
/*****************************************************************/ /*****************************************************************/
/* Look for the first key equal to the link column values */ /* Look for the first key equal to the link column values */
/* and return its rank whithin the index table. */ /* and return its rank whithin the index table. */
...@@ -2837,7 +2919,8 @@ BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m) ...@@ -2837,7 +2919,8 @@ BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m)
} // endif n[1] } // endif n[1]
Ndf = n[0]; Ndf = n[0];
IsSorted = colp->GetOpt() < 0; //IsSorted = colp->GetOpt() < 0;
IsSorted = false;
return m + Bkeys.Size + Keys.Size + Koff.Size; return m + Bkeys.Size + Keys.Size + Koff.Size;
} // end of MapInit } // end of MapInit
#endif // XMAP #endif // XMAP
......
...@@ -192,9 +192,13 @@ class DllExport XXBASE : public CSORT, public BLOCK { ...@@ -192,9 +192,13 @@ class DllExport XXBASE : public CSORT, public BLOCK {
virtual void Print(PGLOBAL g, FILE *f, uint n); virtual void Print(PGLOBAL g, FILE *f, uint n);
virtual void Print(PGLOBAL g, char *ps, uint z); virtual void Print(PGLOBAL g, char *ps, uint z);
virtual bool Init(PGLOBAL g) = 0; virtual bool Init(PGLOBAL g) = 0;
#if defined(XMAP)
virtual bool MapInit(PGLOBAL g) = 0;
#endif // XMAP
virtual int MaxRange(void) {return 1;} virtual int MaxRange(void) {return 1;}
virtual int Fetch(PGLOBAL g) = 0; virtual int Fetch(PGLOBAL g) = 0;
virtual bool NextVal(bool eq) {return true;} virtual bool NextVal(bool eq) {return true;}
virtual bool PrevVal(void) {return true;}
virtual int FastFind(int nk) = 0; virtual int FastFind(int nk) = 0;
virtual bool Reorder(PGLOBAL g) {return true;} virtual bool Reorder(PGLOBAL g) {return true;}
virtual int Range(PGLOBAL g, int limit = 0, bool incl = true) virtual int Range(PGLOBAL g, int limit = 0, bool incl = true)
...@@ -248,6 +252,9 @@ class DllExport XINDEX : public XXBASE { ...@@ -248,6 +252,9 @@ class DllExport XINDEX : public XXBASE {
// Methods // Methods
virtual void Reset(void); virtual void Reset(void);
virtual bool Init(PGLOBAL g); virtual bool Init(PGLOBAL g);
#if defined(XMAP)
virtual bool MapInit(PGLOBAL g);
#endif // XMAP
virtual int Qcompare(int *, int *); virtual int Qcompare(int *, int *);
virtual int Fetch(PGLOBAL g); virtual int Fetch(PGLOBAL g);
virtual int FastFind(int nk); virtual int FastFind(int nk);
...@@ -257,6 +264,7 @@ class DllExport XINDEX : public XXBASE { ...@@ -257,6 +264,7 @@ class DllExport XINDEX : public XXBASE {
virtual int ColMaxSame(PXCOL kp); virtual int ColMaxSame(PXCOL kp);
virtual void Close(void); virtual void Close(void);
virtual bool NextVal(bool eq); virtual bool NextVal(bool eq);
virtual bool PrevVal(void);
virtual bool Make(PGLOBAL g, PIXDEF sxp); virtual bool Make(PGLOBAL g, PIXDEF sxp);
virtual bool SaveIndex(PGLOBAL g, PIXDEF sxp); virtual bool SaveIndex(PGLOBAL g, PIXDEF sxp);
virtual bool Reorder(PGLOBAL g); virtual bool Reorder(PGLOBAL g);
...@@ -296,6 +304,7 @@ class DllExport XINDXS : public XINDEX { ...@@ -296,6 +304,7 @@ class DllExport XINDXS : public XINDEX {
virtual int Fetch(PGLOBAL g); virtual int Fetch(PGLOBAL g);
virtual int FastFind(int nk); virtual int FastFind(int nk);
virtual bool NextVal(bool eq); virtual bool NextVal(bool eq);
virtual bool PrevVal(void);
virtual int Range(PGLOBAL g, int limit = 0, bool incl = true); virtual int Range(PGLOBAL g, int limit = 0, bool incl = true);
virtual int GroupSize(void); virtual int GroupSize(void);
...@@ -403,6 +412,9 @@ class DllExport XXROW : public XXBASE { ...@@ -403,6 +412,9 @@ class DllExport XXROW : public XXBASE {
// Methods // Methods
virtual bool Init(PGLOBAL g); virtual bool Init(PGLOBAL g);
#if defined(XMAP)
virtual bool MapInit(PGLOBAL g) {return true;}
#endif // XMAP
virtual int Fetch(PGLOBAL g); virtual int Fetch(PGLOBAL g);
virtual int FastFind(int nk); virtual int FastFind(int nk);
virtual int MaxRange(void) {return 1;} virtual int MaxRange(void) {return 1;}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment