summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2013-07-08 17:21:47 +0400
committerAlexander Barkov <bar@mariadb.org>2013-07-08 17:21:47 +0400
commit17f3ae267f3b8c189be1671f86902f24ae79cdeb (patch)
tree24881fdc74435298e37750fb92be6cfaa0bc0f14
parent0b116de7c58db3e483964d00e6a3803947bfaf4f (diff)
parentf3078f01b24bed421c015aec2c1646fa25934c13 (diff)
downloadmariadb-git-17f3ae267f3b8c189be1671f86902f24ae79cdeb.tar.gz
Merging from 10.0-connect
added: storage/connect/mysql-test/connect/r/mul.result storage/connect/mysql-test/connect/t/mul.test modified: storage/connect/domdoc.h storage/connect/filamfix.cpp storage/connect/filamtxt.cpp storage/connect/filamvct.cpp storage/connect/fmdlex.c storage/connect/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h storage/connect/inihandl.c storage/connect/inihandl.h storage/connect/libdoc.cpp storage/connect/libdoc.h storage/connect/mycat.cc storage/connect/myconn.cpp storage/connect/mysql-test/connect/r/dbf.result storage/connect/mysql-test/connect/t/odbc_sqlite3.test storage/connect/myutil.cpp storage/connect/odbconn.cpp storage/connect/osutil.c storage/connect/plgdbsem.h storage/connect/plgdbutl.cpp storage/connect/plgxml.h storage/connect/plugutil.c storage/connect/tabdos.cpp storage/connect/tabfix.cpp storage/connect/tabmul.cpp* storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/taboccur.cpp storage/connect/taboccur.h storage/connect/tabodbc.cpp storage/connect/tabpivot.h storage/connect/tabsys.cpp storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabvct.cpp storage/connect/tabxml.cpp storage/connect/valblk.cpp storage/connect/value.cpp storage/connect/xindex.cpp pending merges: Olivier Bertrand 2013-07-08 - Suppressing wrong code (INI tables are not... Alexander Barkov 2013-07-08 Adding instructions on how to install sq... Alexander Barkov 2013-07-08 Fixing some of the memory leaks in ODBCC... Alexander Barkov 2013-07-08 Fixing a warning: Alexander Barkov 2013-07-08 Fixing warnings: Alexander Barkov 2013-07-08 Fixing a warning: Alexander Barkov 2013-07-08 Fixing warnings: Alexander Barkov 2013-07-08 Fixing a warning: Alexander Barkov 2013-07-08 Fixing warnings: Alexander Barkov 2013-07-08 Fixing warnings: Alexander Barkov 2013-07-08 fixing warnings: Alexander Barkov 2013-07-08 Fixing a typo in the previous push Alexander Barkov 2013-07-08 fixing warnings: Alexander Barkov 2013-07-08 Fixing the "no previous declaration for ... Alexander Barkov 2013-07-08 Fixing numerous "variable is set but nev... Olivier Bertrand 2013-07-06 - Remove unuseful option causing valgrin... Olivier Bertrand 2013-07-05 - Try to fix a uninitialised valgrind wa... Olivier Bertrand 2013-07-04 - Make sure Remark is initialised Olivier Bertrand 2013-07-04 - Make sure Remark is initialised in ha_... Olivier Bertrand 2013-07-03 - Makes memory check conditionally Olivier Bertrand 2013-07-03 - Make sure result are ordered the same ... Olivier Bertrand 2013-07-02 - Fix memory leak in libdoc.cpp in LIBXM... Olivier Bertrand 2013-06-30 - Working on eliminating valgrind warnin... Olivier Bertrand 2013-06-30 - Trying to get rid of some valgrind war... Olivier Bertrand 2013-06-29 - Release storage allocated by flex Olivier Bertrand 2013-06-29 - Add the PROFILE_End function in inihan... Olivier Bertrand 2013-06-28 - Release memory allocated by inihandl i... Olivier Bertrand 2013-06-26 - Trying to remove those warnings about ... Olivier Bertrand 2013-06-26 - In connect_assisted_discovery the test... Olivier Bertrand 2013-06-26 - Fix potential bug in MYSQLCOL::WriteCo... Olivier Bertrand 2013-06-16 - Implemented: The use of Federated serv... Olivier Bertrand 2013-06-14 - Add a test case for multiple tables Olivier Bertrand 2013-06-14 - Fix regression error for multiple 2 ta... Olivier Bertrand 2013-06-12 - To avoid crashing in debug mode, the e... Olivier Bertrand 2013-06-12 - Suballocate filename in TDBMUL::InitFi... Olivier Bertrand 2013-06-12 - Add trace in TDBMUL::GetMaxSize. Olivier Bertrand 2013-06-12 - Fix MDEV-4638 Olivier Bertrand 2013-06-08 [merge] - Commit merged changes Alexander Barkov 2013-06-08 Enabling Connect tests Olivier Bertrand 2013-06-08 - Set timeout values in MYSQLC::Open
-rw-r--r--storage/connect/domdoc.h1
-rw-r--r--storage/connect/filamfix.cpp4
-rw-r--r--storage/connect/filamtxt.cpp4
-rwxr-xr-xstorage/connect/filamvct.cpp37
-rw-r--r--storage/connect/fmdlex.c31
-rw-r--r--storage/connect/global.h1
-rw-r--r--storage/connect/ha_connect.cc79
-rw-r--r--storage/connect/ha_connect.h2
-rw-r--r--storage/connect/inihandl.c25
-rw-r--r--storage/connect/inihandl.h1
-rw-r--r--storage/connect/libdoc.cpp312
-rw-r--r--storage/connect/libdoc.h150
-rw-r--r--storage/connect/mycat.cc4
-rw-r--r--storage/connect/myconn.cpp11
-rw-r--r--storage/connect/mysql-test/connect/r/dbf.result8
-rw-r--r--storage/connect/mysql-test/connect/r/mul.result57
-rw-r--r--storage/connect/mysql-test/connect/t/mul.test43
-rw-r--r--storage/connect/mysql-test/connect/t/odbc_sqlite3.test29
-rw-r--r--storage/connect/myutil.cpp1
-rw-r--r--storage/connect/odbconn.cpp27
-rw-r--r--storage/connect/osutil.c13
-rw-r--r--storage/connect/plgdbsem.h3
-rw-r--r--storage/connect/plgdbutl.cpp4
-rw-r--r--storage/connect/plgxml.h1
-rw-r--r--storage/connect/plugutil.c17
-rw-r--r--storage/connect/tabdos.cpp2
-rw-r--r--storage/connect/tabfix.cpp2
-rwxr-xr-x[-rw-r--r--]storage/connect/tabmul.cpp79
-rw-r--r--storage/connect/tabmysql.cpp163
-rw-r--r--storage/connect/tabmysql.h1
-rw-r--r--storage/connect/taboccur.cpp2
-rw-r--r--storage/connect/taboccur.h6
-rw-r--r--storage/connect/tabodbc.cpp6
-rw-r--r--storage/connect/tabpivot.h6
-rw-r--r--storage/connect/tabsys.cpp13
-rw-r--r--storage/connect/tabtbl.cpp20
-rw-r--r--storage/connect/tabtbl.h3
-rw-r--r--storage/connect/tabvct.cpp1
-rw-r--r--storage/connect/tabxml.cpp1
-rw-r--r--storage/connect/valblk.cpp9
-rw-r--r--storage/connect/value.cpp65
-rwxr-xr-xstorage/connect/xindex.cpp3
42 files changed, 853 insertions, 394 deletions
diff --git a/storage/connect/domdoc.h b/storage/connect/domdoc.h
index fc157950df8..0fd0a58ffdb 100644
--- a/storage/connect/domdoc.h
+++ b/storage/connect/domdoc.h
@@ -35,6 +35,7 @@ class DOMDOC : public XMLDOCUMENT {
// Properties
virtual short GetDocType(void) {return TYPE_FB_XML;}
virtual void *GetDocPtr(void) {return Docp;}
+ virtual void SetNofree(bool b) {} // Only libxml2
// Methods
virtual bool Initialize(PGLOBAL g);
diff --git a/storage/connect/filamfix.cpp b/storage/connect/filamfix.cpp
index b7cbc76a553..d493a2f2568 100644
--- a/storage/connect/filamfix.cpp
+++ b/storage/connect/filamfix.cpp
@@ -425,9 +425,9 @@ int FIXFAM::DeleteRecords(PGLOBAL g, int irc)
/* for compatibility with Text files and other OS's. */
/*****************************************************************/
char filename[_MAX_PATH];
- int rc, h;
+ int h;
- rc = PlugCloseFile(g, To_Fb);
+ /*rc= */PlugCloseFile(g, To_Fb);
PlugSetPath(filename, To_File, Tdbp->GetPath());
if ((h= global_open(g, MSGID_OPEN_STRERROR, filename, O_WRONLY)) <= 0)
diff --git a/storage/connect/filamtxt.cpp b/storage/connect/filamtxt.cpp
index ed4467b6392..2291f2c2b00 100644
--- a/storage/connect/filamtxt.cpp
+++ b/storage/connect/filamtxt.cpp
@@ -786,10 +786,10 @@ int DOSFAM::DeleteRecords(PGLOBAL g, int irc)
/* for compatibility with Text files and other OS's. */
/*****************************************************************/
char filename[_MAX_PATH];
- int h, rc; // File handle, return code
+ int h; // File handle, return code
PlugSetPath(filename, To_File, Tdbp->GetPath());
- rc = PlugCloseFile(g, To_Fb);
+ /*rc=*/ PlugCloseFile(g, To_Fb);
if ((h= global_open(g, MSGID_OPEN_STRERROR, filename, O_WRONLY)) <= 0)
return RC_FX;
diff --git a/storage/connect/filamvct.cpp b/storage/connect/filamvct.cpp
index 47ac07c6554..2b66437d127 100755
--- a/storage/connect/filamvct.cpp
+++ b/storage/connect/filamvct.cpp
@@ -10,15 +10,15 @@
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
/* This program are the VCT file access method classes. */
-/* Added in version 2: F */
+/* Added in version 2: F */
/* - Split Vec format. */
/* - Partial delete. */
-/* - Use of tempfile for update. */
+/* - Use of tempfile for update. */
/* */
/***********************************************************************/
/***********************************************************************/
-/* Include relevant MariaDB header file. */
+/* Include relevant MariaDB header file. */
/***********************************************************************/
#include "my_global.h"
#if defined(WIN32)
@@ -35,7 +35,6 @@
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
-//#define strerror(X) _strerror(X)
#define NO_ERROR 0
#else // !UNIX
#include <io.h>
@@ -204,7 +203,6 @@ bool VCTFAM::SetBlockInfo(PGLOBAL g)
{
char filename[_MAX_PATH];
bool rc = false;
- int k;
size_t n;
VECHEADER vh;
FILE *s;
@@ -216,7 +214,7 @@ bool VCTFAM::SetBlockInfo(PGLOBAL g)
s = Stream;
if (Header == 1)
- k = fseek(s, 0, SEEK_SET);
+ /*k =*/ fseek(s, 0, SEEK_SET);
} else
s= global_fopen(g, MSGID_CANNOT_OPEN, filename, "r+b");
@@ -230,7 +228,7 @@ bool VCTFAM::SetBlockInfo(PGLOBAL g)
sprintf(g->Message, "Error opening header file %s", filename);
return true;
} else if (Header == 3)
- k = fseek(s, -(int)sizeof(VECHEADER), SEEK_END);
+ /*k =*/ fseek(s, -(int)sizeof(VECHEADER), SEEK_END);
vh.MaxRec = MaxBlk * Bsize;
vh.NumRec = (Block - 1) * Nrec + Last;
@@ -775,10 +773,10 @@ int VCTFAM::DeleteRecords(PGLOBAL g, int irc)
/* checked for compatibility with Text files and other OS's. */
/***************************************************************/
char filename[_MAX_PATH];
- int rc, h;
+ int h;
- rc = CleanUnusedSpace(g); // Clean last block
- rc = PlugCloseFile(g, To_Fb);
+ /*rc =*/ CleanUnusedSpace(g); // Clean last block
+ /*rc =*/ PlugCloseFile(g, To_Fb);
Stream = NULL; // For SetBlockInfo
PlugSetPath(filename, To_File, Tdbp->GetPath());
@@ -1705,7 +1703,7 @@ int VCMFAM::DeleteRecords(PGLOBAL g, int irc)
/***********************************************************************/
void VCMFAM::CloseTableFile(PGLOBAL g)
{
- int rc = 0, wrc = RC_OK;
+ int wrc = RC_OK;
MODE mode = Tdbp->GetMode();
if (mode == MODE_INSERT) {
@@ -1728,7 +1726,7 @@ void VCMFAM::CloseTableFile(PGLOBAL g)
PlugCloseFile(g, To_Fb);
if (wrc != RC_FX)
- rc = ResetTableSize(g, Block, Last);
+ /*rc =*/ ResetTableSize(g, Block, Last);
} else if (mode != MODE_DELETE)
PlugCloseFile(g, To_Fb);
@@ -1823,7 +1821,7 @@ bool VECFAM::OpenTableFile(PGLOBAL g)
{
char opmode[4];
int i;
- bool b;
+ bool b= false;
PCOLDEF cdp;
PVCTCOL cp;
MODE mode = Tdbp->GetMode();
@@ -2205,11 +2203,11 @@ int VECFAM::DeleteRecords(PGLOBAL g, int irc)
/* for compatibility with other OS's. */
/*****************************************************************/
char filename[_MAX_PATH];
- int h, rc; // File handle, return code
+ int h; // File handle, return code
for (int i = 0; i < Ncol; i++) {
sprintf(filename, Colfn, i + 1);
- rc = PlugCloseFile(g, To_Fbs[i]);
+ /*rc =*/ PlugCloseFile(g, To_Fbs[i]);
if ((h= global_open(g, MSGID_OPEN_STRERROR, filename, O_WRONLY)) <= 0)
return RC_FX;
@@ -3118,7 +3116,6 @@ int BGVFAM::GetBlockInfo(PGLOBAL g)
{
char filename[_MAX_PATH];
int n;
- bool b;
VECHEADER vh;
HANDLE h;
@@ -3162,7 +3159,7 @@ int BGVFAM::GetBlockInfo(PGLOBAL g)
return n;
} else if (Header == 3)
- b = BigSeek(g, h, -(BIGINT)sizeof(vh), true);
+ /*b = */ BigSeek(g, h, -(BIGINT)sizeof(vh), true);
if (BigRead(g, h, &vh, sizeof(vh))) {
sprintf(g->Message, "Error reading header file %s", filename);
@@ -3190,7 +3187,7 @@ int BGVFAM::GetBlockInfo(PGLOBAL g)
bool BGVFAM::SetBlockInfo(PGLOBAL g)
{
char filename[_MAX_PATH];
- bool bk, b = false, rc = false;
+ bool b = false, rc = false;
VECHEADER vh;
HANDLE h = INVALID_HANDLE_VALUE;
@@ -3201,7 +3198,7 @@ bool BGVFAM::SetBlockInfo(PGLOBAL g)
h = Hfile;
if (Header == 1)
- bk = BigSeek(g, h, (BIGINT)0);
+ /*bk =*/ BigSeek(g, h, (BIGINT)0);
} else
b = true;
@@ -3230,7 +3227,7 @@ bool BGVFAM::SetBlockInfo(PGLOBAL g)
} // endif h
if (Header == 3)
- bk = BigSeek(g, h, -(BIGINT)sizeof(vh), true);
+ /*bk =*/ BigSeek(g, h, -(BIGINT)sizeof(vh), true);
vh.MaxRec = MaxBlk * Bsize;
vh.NumRec = (Block - 1) * Nrec + Last;
diff --git a/storage/connect/fmdlex.c b/storage/connect/fmdlex.c
index 9ab8f2e03c5..a7213b1ed57 100644
--- a/storage/connect/fmdlex.c
+++ b/storage/connect/fmdlex.c
@@ -20,12 +20,13 @@
*/
#define FLEX_SCANNER
-
#if WIN32
#define __STDC__ 1
#endif
-
#include <stdio.h>
+#ifndef WIN32
+#include <unistd.h>
+#endif
/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
@@ -47,7 +48,7 @@
/* The "const" storage-class-modifier is valid. */
#define YY_USE_CONST
-#else /* ! __cplusplus */
+#else /* ! __cplusplus */
#ifdef __STDC__
@@ -131,7 +132,7 @@ extern "C" {
* int a single C statement (which needs a semi-colon terminator). This
* avoids problems with code like:
*
- * if ( condition_holds )
+ * if ( condition_holds )
* yyless( 5 );
* else
* do_something_else();
@@ -161,7 +162,7 @@ struct yy_buffer_state
FILE *yy_input_file;
char *yy_ch_buf; /* input buffer */
- char *yy_buf_pos; /* current position in input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
/* Size of input buffer in bytes, not including room for EOB
* characters.
@@ -220,7 +221,7 @@ int yyleng;
/* Points to current character in buffer. */
static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 1; /* whether we need to initialize */
+static int yy_init = 1; /* whether we need to initialize */
static int yy_start = 0; /* start state number */
/* Flag which is used to allow yywrap()'s to do buffer switches
@@ -394,7 +395,6 @@ char *yytext;
#include <string.h>
#include "preparse.h"
-#define isatty _isatty
#define fileno _fileno
#undef YY_DECL
#define YY_DECL int yylex YY_PROTO((PDTP ppp))
@@ -406,6 +406,8 @@ char *yytext;
#undef yywrap
#define yywrap ddwrap
#endif /* UNIX */
+int yywrap(void);
+
static PDTP pp;
static void MakeParm(int n);
static void MakeMMDD(int n);
@@ -520,10 +522,7 @@ YY_DECL
if (pp->InFmt) {*pp->InFmt = '\0'; pp->InFmt[pp->Outsize -1] = '\0'; }
if (pp->OutFmt) {*pp->OutFmt = '\0'; pp->OutFmt[pp->Outsize -1] = '\0'; }
pp->Curp = pp->Format;
- if (!yy_init) { /* Restart that stupid Flex otherwise parsing last input */
- yy_init_buffer( yy_current_buffer, yyin );
- yy_load_buffer_state();
- } // endif yy_init
+ yy_init = 1; /* This is a new input */
if ( yy_init )
@@ -533,7 +532,7 @@ YY_DECL
#endif
if ( ! yy_start )
- yy_start = 1; /* first start state */
+ yy_start = 1; /* first start state */
if ( ! yyin )
yyin = stdin;
@@ -552,7 +551,7 @@ YY_DECL
yy_init = 0;
}
- while ( 1 ) /* loops until end-of-file is reached */
+ while ( 1 ) /* loops until end-of-file is reached */
{
yy_cp = yy_c_buf_p;
@@ -1114,7 +1113,7 @@ static int input()
}
c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
- *yy_c_buf_p = '\0'; /* preserve yytext */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
yy_hold_char = *++yy_c_buf_p;
return c;
@@ -1520,6 +1519,10 @@ void Quotout(char *text)
int yywrap(void)
{
+ /* Avoid memory leak */
+ if (yy_current_buffer)
+ yy_delete_buffer(yy_current_buffer);
+
return 1;
} /* end of yywrap */
diff --git a/storage/connect/global.h b/storage/connect/global.h
index 303078f5a18..3702f050501 100644
--- a/storage/connect/global.h
+++ b/storage/connect/global.h
@@ -244,6 +244,7 @@ DllExport BOOL PlugIsAbsolutePath(LPCSTR path);
DllExport void *PlugAllocMem(PGLOBAL, uint);
DllExport BOOL PlugSubSet(PGLOBAL, void *, uint);
DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t);
+DllExport char *PlugDup(PGLOBAL g, const char *str);
DllExport void *MakePtr(void *, OFFSET);
DllExport void htrc(char const *fmt, ...);
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 7d37b79bae8..786997cc76d 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -146,10 +146,13 @@
#define my_stricmp(a,b) my_strcasecmp(default_charset_info, (a), (b))
#ifdef LIBXML2_SUPPORT
-void XmlInitParserLib(void);
-void XmlCleanupParserLib(void);
+#include "libdoc.h"
#endif // LIBXML2_SUPPORT
+#include "taboccur.h"
+#include "tabpivot.h"
+
+
/***********************************************************************/
/* DB static variables. */
/***********************************************************************/
@@ -167,16 +170,6 @@ extern "C" {
int trace= 0; // The general trace value
} // extern "C"
-bool OcrColumns(PGLOBAL g, PQRYRES qrp, const char *col,
- const char *ocr, const char *rank);
-bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col,
- const char *ocr, const char *rank);
-PQRYRES PivotColumns(PGLOBAL g, const char *tab, const char *src,
- const char *picol, const char *fncol,
- const char *host, const char *db,
- const char *user, const char *pwd,
- int port);
-
/****************************************************************************/
/* Initialize the ha_connect static members. */
/****************************************************************************/
@@ -360,6 +353,9 @@ static int connect_init_func(void *p)
trace= xtrace;
} // endif xtrace
+#if !defined(WIN32)
+ PROFILE_Close(connectini);
+#endif // !WIN32
init_connect_psi_keys();
@@ -394,6 +390,10 @@ static int connect_done_func(void *p)
XmlCleanupParserLib();
#endif // LIBXML2_SUPPORT
+#if !defined(WIN32)
+ PROFILE_End();
+#endif // !WIN32
+
for (pc= user_connect::to_users; pc; pc= pn) {
if (pc->g)
PlugCleanup(pc->g, true);
@@ -666,8 +666,7 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
else if (!stricmp(opname, "Separator"))
opval= (char*)options->separator;
else if (!stricmp(opname, "Connect"))
-// opval= (char*)options->connect;
- opval= table->s->connect_string.str;
+ opval= (tshp) ? tshp->connect_string.str : table->s->connect_string.str;
else if (!stricmp(opname, "Qchar"))
opval= (char*)options->qchar;
else if (!stricmp(opname, "Module"))
@@ -845,7 +844,7 @@ PFOS ha_connect::GetFieldOptionStruct(Field *fdp)
/****************************************************************************/
/* Returns the column description structure used to make the column. */
/****************************************************************************/
-void *ha_connect::GetColumnOption(void *field, PCOLINFO pcf)
+void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
{
const char *cp;
ha_field_option_struct *fop;
@@ -900,6 +899,7 @@ void *ha_connect::GetColumnOption(void *field, PCOLINFO pcf)
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_VAR_STRING:
pcf->Flags |= U_VAR;
+ /* no break */
case MYSQL_TYPE_STRING:
pcf->Type= TYPE_STRING;
@@ -963,6 +963,7 @@ void *ha_connect::GetColumnOption(void *field, PCOLINFO pcf)
break;
default:
pcf->Type=TYPE_ERROR;
+ break;
} // endswitch type
// This is used to skip null bit
@@ -974,7 +975,15 @@ void *ha_connect::GetColumnOption(void *field, PCOLINFO pcf)
pcf->Flags |= U_VIRTUAL;
pcf->Key= 0; // Not used when called from MySQL
- pcf->Remark= fp->comment.str;
+
+ // Get the comment if any
+ if (fp->comment.str && fp->comment.length) {
+ pcf->Remark= (char*)PlugSubAlloc(g, NULL, fp->comment.length + 1);
+ memcpy(pcf->Remark, fp->comment.str, fp->comment.length);
+ pcf->Remark[fp->comment.length] = 0;
+ } else
+ pcf->Remark= NULL;
+
return fldp;
} // end of GetColumnOption
@@ -1324,6 +1333,7 @@ int ha_connect::MakeRecord(char *buf)
break;
default:
fmt= "%Y-%m-%d %H:%M:%S";
+ break;
} // endswitch type
// Get date in the format required by MySQL fields
@@ -1337,6 +1347,7 @@ int ha_connect::MakeRecord(char *buf)
// Passthru
default:
p= value->GetCharString(val);
+ break;
} // endswitch Type
if (p) {
@@ -1456,6 +1467,7 @@ int ha_connect::ScanRecord(PGLOBAL g, uchar *buf)
attribute.charset(), charset, &cnv_errors);
value->SetValue_psz(data_charset_value.c_ptr_safe());
}
+ break;
} // endswitch Type
#ifdef NEWCHANGE
@@ -1563,6 +1575,7 @@ const char *ha_connect::GetValStr(OPVAL vop, bool neg)
break;
default:
val= " ? ";
+ break;
} /* endswitch */
return val;
@@ -2165,6 +2178,7 @@ int ha_connect::ReadIndexed(uchar *buf, OPVAL op, const uchar *key, uint key_len
DBUG_PRINT("ReadIndexed", ("%s", xp->g->Message));
printf("ReadIndexed: %s\n", xp->g->Message);
rc= HA_ERR_INTERNAL_ERROR;
+ break;
} // endswitch RC
if (xtrace > 1)
@@ -2207,7 +2221,7 @@ int ha_connect::index_read(uchar * buf, const uchar * key, uint key_len,
case HA_READ_KEY_EXACT: op= OP_EQ; break;
case HA_READ_AFTER_KEY: op= OP_GT; break;
case HA_READ_KEY_OR_NEXT: op= OP_GE; break;
- default: DBUG_RETURN(-1);
+ default: DBUG_RETURN(-1); break;
} // endswitch find_flag
if (xtrace > 1)
@@ -2830,6 +2844,7 @@ int ha_connect::external_lock(THD *thd, int lock_type)
case F_UNLCK:
default:
newmode= MODE_ANY;
+ break;
} // endswitch mode
if (newmode == MODE_ANY) {
@@ -2920,8 +2935,17 @@ int ha_connect::external_lock(THD *thd, int lock_type)
} // endelse Xchk
- if (CloseTable(g))
+ if (CloseTable(g)) {
+ // This is an error while builing index
+#if defined(_DEBUG)
+ // Make it a warning to avoid crash
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, g->Message);
+ rc= 0;
+#else // !_DEBUG
+ my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
rc= HA_ERR_INTERNAL_ERROR;
+#endif // !DEBUG
+ } // endif Close
DBUG_RETURN(rc);
} // endif MODE_ANY
@@ -2978,6 +3002,7 @@ int ha_connect::external_lock(THD *thd, int lock_type)
printf("Unsupported sql_command=%d", thd_sql_command(thd));
sprintf(g->Message, "Unsupported sql_command=%d", thd_sql_command(thd));
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+ break;
} // endswitch newmode
} else if (newmode == MODE_READ) {
@@ -3015,6 +3040,7 @@ int ha_connect::external_lock(THD *thd, int lock_type)
printf("Unsupported sql_command=%d", thd_sql_command(thd));
sprintf(g->Message, "Unsupported sql_command=%d", thd_sql_command(thd));
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+ break;
} // endswitch newmode
} // endif's newmode
@@ -3432,7 +3458,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
fnc= GetFuncID(fncn);
sep= topt->separator;
spc= (!sep || !strcmp(sep, "\\t")) ? '\t' : *sep;
- qch= topt->qchar ? *topt->qchar : topt->quoted >= 0 ? '"' : 0;
+ qch= topt->qchar ? *topt->qchar : (signed)topt->quoted >= 0 ? '"' : 0;
hdr= (int)topt->header;
tbl= topt->tablist;
col= topt->colist;
@@ -3571,6 +3597,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
break;
default:
sprintf(g->Message, "Cannot get column info for table type %s", topt->type);
+ break;
} // endif ttp
// Check for supported catalog function
@@ -3631,6 +3658,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
break;
default:
sprintf(g->Message, "invalid catfunc %s", fncn);
+ break;
} // endswitch info
break;
@@ -3967,7 +3995,8 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} // endif tabname
default: /* do nothing */;
- } // endswitch ttp
+ break;
+ } // endswitch ttp
if (type == TAB_XML) {
bool dom; // True: MS-DOM, False libxml2
@@ -3989,6 +4018,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
break;
default:
dom= false;
+ break;
} // endswitch xsup
#if !defined(DOMDOC_SUPPORT)
@@ -4027,6 +4057,14 @@ int ha_connect::create(const char *name, TABLE *table_arg,
DBUG_RETURN(rc);
} // endif flags
+ if (fp->flags & (BLOB_FLAG | ENUM_FLAG | SET_FLAG)) {
+ sprintf(g->Message, "Unsupported type for column %s",
+ fp->field_name);
+ my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
+ rc= HA_ERR_INTERNAL_ERROR;
+ DBUG_RETURN(rc);
+ } // endif flags
+
switch (fp->type()) {
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_LONG:
@@ -4066,6 +4104,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
"Unsupported type for column '%s'",
MYF(0), fp->field_name);
DBUG_RETURN(rc);
+ break;
} // endswitch type
if ((fp)->real_maybe_null() && !IsTypeNullable(type)) {
diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h
index 0d6354ca078..abf82b2d1a8 100644
--- a/storage/connect/ha_connect.h
+++ b/storage/connect/ha_connect.h
@@ -154,7 +154,7 @@ public:
int GetIntegerOption(char *opname);
bool SetIntegerOption(char *opname, int n);
PFOS GetFieldOptionStruct(Field *fp);
- void *GetColumnOption(void *field, PCOLINFO pcf);
+ void *GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf);
PIXDEF GetIndexInfo(void);
const char *GetDBName(const char *name);
const char *GetTableName(void);
diff --git a/storage/connect/inihandl.c b/storage/connect/inihandl.c
index 60b72bd2604..0dc7a53faf3 100644
--- a/storage/connect/inihandl.c
+++ b/storage/connect/inihandl.c
@@ -609,6 +609,31 @@ void PROFILE_Close(LPCSTR filename)
/***********************************************************************
+ * PROFILE_End
+ *
+ * Terminate and release the cache.
+ ***********************************************************************/
+void PROFILE_End(void)
+{
+ int i;
+
+ if (trace)
+ htrc("PROFILE_End: CurProfile=%p N=%d\n", CurProfile, N_CACHED_PROFILES);
+
+ /* Close all opened files and free the cache structure */
+ for (i = 0; i < N_CACHED_PROFILES; i++) {
+ if (trace)
+ htrc("MRU=%s i=%d\n", SVP(MRUProfile[i]->filename), i);
+
+ CurProfile = MRUProfile[i];
+ PROFILE_ReleaseFile();
+ free(MRUProfile[i]);
+ } // endfor i
+
+} // end of PROFILE_End
+
+
+/***********************************************************************
* PROFILE_DeleteSection
*
* Delete a section from a profile tree.
diff --git a/storage/connect/inihandl.h b/storage/connect/inihandl.h
index 7f6fcb1f582..f0b7c9afe5c 100644
--- a/storage/connect/inihandl.h
+++ b/storage/connect/inihandl.h
@@ -8,6 +8,7 @@ extern "C" {
#endif
void PROFILE_Close(LPCSTR filename);
+void PROFILE_End(void);
int GetPrivateProfileString(
LPCTSTR lpAppName, // section name
diff --git a/storage/connect/libdoc.cpp b/storage/connect/libdoc.cpp
index 95b98931680..45f379350f5 100644
--- a/storage/connect/libdoc.cpp
+++ b/storage/connect/libdoc.cpp
@@ -25,11 +25,207 @@
#include "sql_string.h"
+/******************************************************************/
+/* Declaration of XML document processing using libxml2 */
+/* Author: Olivier Bertrand 2007-2012 */
+/******************************************************************/
+#include "plgxml.h"
+
+typedef class LIBXMLDOC *PXDOC2;
+typedef class XML2NODE *PNODE2;
+typedef class XML2ATTR *PATTR2;
+typedef class XML2NODELIST *PLIST2;
+
+/******************************************************************/
+/* XML2 block. Must have the same layout than FBLOCK up to Type. */
+/******************************************************************/
+typedef struct _x2block { /* Loaded XML file block */
+ struct _x2block *Next;
+ LPCSTR Fname; /* Point on file name */
+ size_t Length; /* Used to tell if read mode */
+ short Count; /* Nb of times file is used */
+ short Type; /* TYPE_FB_XML */
+ int Retcode; /* Return code from Load */
+ xmlDocPtr Docp; /* Document interface pointer */
+// xmlXPathContextPtr Ctxp;
+// xmlXPathObjectPtr Xop;
+ } X2BLOCK, *PX2BLOCK;
+
+/******************************************************************/
+/* Declaration of libxml2 document. */
+/******************************************************************/
+class LIBXMLDOC : public XMLDOCUMENT {
+ friend class XML2NODE;
+ friend class XML2ATTR;
+ public:
+ // Constructor
+ LIBXMLDOC(char *nsl, char *nsdf, char *enc, PFBLOCK fp);
+
+ // Properties
+ virtual short GetDocType(void) {return TYPE_FB_XML2;}
+ virtual void *GetDocPtr(void) {return Docp;}
+ virtual void SetNofree(bool b) {Nofreelist = b;}
+
+ // Methods
+ virtual bool Initialize(PGLOBAL g);
+ virtual bool ParseFile(char *fn);
+ virtual bool NewDoc(PGLOBAL g, char *ver);
+ virtual void AddComment(PGLOBAL g, char *com);
+ virtual PXNODE GetRoot(PGLOBAL g);
+ virtual PXNODE NewRoot(PGLOBAL g, char *name);
+ virtual PXNODE NewPnode(PGLOBAL g, char *name);
+ virtual PXATTR NewPattr(PGLOBAL g);
+ virtual PXLIST NewPlist(PGLOBAL g);
+ virtual int DumpDoc(PGLOBAL g, char *ofn);
+ virtual void CloseDoc(PGLOBAL g, PFBLOCK xp);
+ virtual PFBLOCK LinkXblock(PGLOBAL g, MODE m, int rc, char *fn);
+
+ protected:
+// bool CheckDocument(FILE *of, xmlNodePtr np);
+ xmlNodeSetPtr GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp);
+ int Decode(xmlChar *cnt, char *buf, int n);
+ xmlChar *Encode(PGLOBAL g, char *txt);
+
+ // Members
+ xmlDocPtr Docp;
+ xmlNodeSetPtr Nlist;
+ xmlXPathContextPtr Ctxp;
+ xmlXPathObjectPtr Xop;
+ char *Buf; // Temporary
+ bool Nofreelist;
+}; // end of class LIBXMLDOC
+
+/******************************************************************/
+/* Declaration of libxml2 node. */
+/******************************************************************/
+class XML2NODE : public XMLNODE {
+ friend class LIBXMLDOC;
+ friend class XML2NODELIST;
+ public:
+ // Properties
+ virtual char *GetName(PGLOBAL g) {return (char*)Nodep->name;}
+ virtual int GetType(void);
+ virtual PXNODE GetNext(PGLOBAL g);
+ virtual PXNODE GetChild(PGLOBAL g);
+
+ // Methods
+ virtual RCODE GetContent(PGLOBAL g, char *buf, int len);
+ virtual bool SetContent(PGLOBAL g, char *txtp, int len);
+ virtual PXNODE Clone(PGLOBAL g, PXNODE np);
+ virtual PXLIST GetChildElements(PGLOBAL g, char *xp, PXLIST lp);
+ virtual PXLIST SelectNodes(PGLOBAL g, char *xp, PXLIST lp);
+ virtual PXNODE SelectSingleNode(PGLOBAL g, char *xp, PXNODE np);
+ virtual PXATTR GetAttribute(PGLOBAL g, char *name, PXATTR ap);
+ virtual PXNODE AddChildNode(PGLOBAL g, char *name, PXNODE np);
+ virtual PXATTR AddProperty(PGLOBAL g, char *name, PXATTR ap);
+ virtual void AddText(PGLOBAL g, char *txtp);
+ virtual void DeleteChild(PGLOBAL g, PXNODE dnp);
+
+ protected:
+ // Constructor
+ XML2NODE(PXDOC dp, xmlNodePtr np);
+
+ // Members
+ xmlDocPtr Docp;
+ xmlChar *Content;
+ xmlNodePtr Nodep;
+}; // end of class XML2NODE
+
+/******************************************************************/
+/* Declaration of libxml2 node list. */
+/******************************************************************/
+class XML2NODELIST : public XMLNODELIST {
+ friend class LIBXMLDOC;
+ friend class XML2NODE;
+ public:
+ // Methods
+ virtual int GetLength(void);
+ virtual PXNODE GetItem(PGLOBAL g, int n, PXNODE np);
+
+ protected:
+ // Constructor
+ XML2NODELIST(PXDOC dp, xmlNodeSetPtr lp);
+
+ // Members
+ xmlNodeSetPtr Listp;
+}; // end of class XML2NODELIST
+
+/******************************************************************/
+/* Declaration of libxml2 attribute. */
+/******************************************************************/
+class XML2ATTR : public XMLATTRIBUTE {
+ friend class LIBXMLDOC;
+ friend class XML2NODE;
+ public:
+ // Properties
+//virtual char *GetText(void);
+
+ // Methods
+ virtual bool SetText(PGLOBAL g, char *txtp, int len);
+
+ protected:
+ // Constructor
+ XML2ATTR(PXDOC dp, xmlAttrPtr ap, xmlNodePtr np);
+
+ // Members
+ xmlAttrPtr Atrp;
+ xmlNodePtr Parent;
+}; // end of class XML2ATTR
+
+
+
extern "C" {
extern char version[];
extern int trace;
} // "C"
+#if defined(MEMORY_TRACE)
+static xmlFreeFunc Free;
+static xmlMallocFunc Malloc;
+static xmlMallocFunc MallocA;
+static xmlReallocFunc Realloc;
+static xmlStrdupFunc Strdup;
+
+void xmlMyFree(void *mem)
+{
+ if (trace)
+ htrc("Freeing at %p\n", mem);
+ Free(mem);
+} // end of xmlMyFree
+
+void *xmlMyMalloc(size_t size)
+{
+ void *p = Malloc(size);
+ if (trace)
+ htrc("Allocating %.5d at %p\n", size, p);
+ return p;
+} // end of xmlMyMalloc
+
+void *xmlMyMallocAtomic(size_t size)
+{
+ void *p = MallocA(size);
+ if (trace)
+ htrc("Atom alloc %.5d at %p\n", size, p);
+ return p;
+} // end of xmlMyMallocAtomic
+
+void *xmlMyRealloc(void *mem, size_t size)
+{
+ void *p = Realloc(mem, size);
+ if (trace)
+ htrc("ReAlloc %.5d to %p from %p\n", size, p, mem);
+ return p;
+} // end of xmlMyRealloc
+
+char *xmlMyStrdup(const char *str)
+{
+ char *p = Strdup(str);
+ if (trace)
+ htrc("Duplicating to %p from %p %s\n", p, str, str);
+ return p;
+} // end of xmlMyStrdup
+#endif // MEMORY_TRACE
+
/******************************************************************/
/* Return a LIBXMLDOC as a XMLDOC. */
/******************************************************************/
@@ -44,6 +240,17 @@ PXDOC GetLibxmlDoc(PGLOBAL g, char *nsl, char *nsdf,
/******************************************************************/
void XmlInitParserLib(void)
{
+#if defined(MEMORY_TRACE)
+int rc = xmlGcMemGet(&Free, &Malloc, &MallocA, &Realloc, &Strdup);
+
+if (!rc)
+ rc = xmlGcMemSetup(xmlMyFree,
+ xmlMyMalloc,
+ xmlMyMallocAtomic,
+ xmlMyRealloc,
+ xmlMyStrdup);
+
+#endif // MEMORY_TRACE
xmlInitParser();
} // end of XmlInitParserLib
@@ -63,6 +270,9 @@ void CloseXML2File(PGLOBAL g, PFBLOCK fp, bool all)
{
PX2BLOCK xp = (PX2BLOCK)fp;
+ if (trace)
+ htrc("CloseXML2File: xp=%p count=%d\n", xp, (xp) ? xp->Count : 0);
+
if (xp && xp->Count > 1 && !all) {
xp->Count--;
} else if (xp && xp->Count > 0) {
@@ -85,6 +295,8 @@ LIBXMLDOC::LIBXMLDOC(char *nsl, char *nsdf, char *enc, PFBLOCK fp)
Nlist = NULL;
Ctxp = NULL;
Xop = NULL;
+ Buf = NULL;
+ Nofreelist = false;
} // end of LIBXMLDOC constructor
/******************************************************************/
@@ -101,6 +313,9 @@ bool LIBXMLDOC::Initialize(PGLOBAL g)
/******************************************************************/
bool LIBXMLDOC::ParseFile(char *fn)
{
+ if (trace)
+ htrc("ParseFile\n");
+
if ((Docp = xmlParseFile(fn))) {
if (Docp->encoding)
Encoding = (char*)Docp->encoding;
@@ -149,6 +364,9 @@ bool LIBXMLDOC::NewDoc(PGLOBAL g, char *ver)
/******************************************************************/
void LIBXMLDOC::AddComment(PGLOBAL g, char *txtp)
{
+ if (trace)
+ htrc("AddComment: %s\n", txtp);
+
xmlNodePtr cp = xmlNewDocComment(Docp, BAD_CAST txtp);
xmlAddChild((xmlNodePtr)Docp, cp);
} // end of AddText
@@ -158,6 +376,9 @@ void LIBXMLDOC::AddComment(PGLOBAL g, char *txtp)
/******************************************************************/
PXNODE LIBXMLDOC::GetRoot(PGLOBAL g)
{
+ if (trace)
+ htrc("GetRoot\n");
+
xmlNodePtr root = xmlDocGetRootElement(Docp);
if (!root)
@@ -171,6 +392,9 @@ PXNODE LIBXMLDOC::GetRoot(PGLOBAL g)
/******************************************************************/
PXNODE LIBXMLDOC::NewRoot(PGLOBAL g, char *name)
{
+ if (trace)
+ htrc("NewRoot: %s\n", name);
+
xmlNodePtr root = xmlNewDocNode(Docp, NULL, BAD_CAST name, NULL);
if (root) {
@@ -186,6 +410,9 @@ PXNODE LIBXMLDOC::NewRoot(PGLOBAL g, char *name)
/******************************************************************/
PXNODE LIBXMLDOC::NewPnode(PGLOBAL g, char *name)
{
+ if (trace)
+ htrc("NewNode: %s\n", name);
+
xmlNodePtr nop;
if (name) {
@@ -224,6 +451,9 @@ int LIBXMLDOC::DumpDoc(PGLOBAL g, char *ofn)
int rc = 0;
FILE *of;
+ if (trace)
+ htrc("DumpDoc: %s\n", ofn);
+
if (!(of= global_fopen(g, MSGID_CANNOT_OPEN, ofn, "w")))
return -1;
@@ -264,7 +494,13 @@ int LIBXMLDOC::DumpDoc(PGLOBAL g, char *ofn)
/******************************************************************/
void LIBXMLDOC::CloseDoc(PGLOBAL g, PFBLOCK xp)
{
+ if (trace)
+ htrc("CloseDoc: xp=%p count=%d\n", xp, (xp) ? xp->Count : 0);
+
if (xp && xp->Count == 1) {
+ if (Nlist)
+ xmlXPathFreeNodeSet(Nlist);
+
if (Xop)
xmlXPathFreeObject(Xop);
@@ -284,12 +520,18 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp)
xmlNodeSetPtr nl;
if (trace)
- htrc("GetNodeList %s np=%p\n", xp, np);
+ htrc("GetNodeList: %s np=%p\n", xp, np);
if (!Ctxp) {
// Init Xpath
+ if (trace)
+ htrc("Calling xmlPathInit\n");
+
xmlXPathInit();
+ if (trace)
+ htrc("Calling xmlXPathNewContext Docp=%p\n", Docp);
+
// Create xpath evaluation context
if (!(Ctxp = xmlXPathNewContext(Docp))) {
strcpy(g->Message, MSG(XPATH_CNTX_ERR));
@@ -301,7 +543,11 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp)
} // endif xpathCtx
// Register namespaces from list (if any)
- for (PNS nsp = Namespaces; nsp; nsp = nsp->Next)
+ for (PNS nsp = Namespaces; nsp; nsp = nsp->Next) {
+ if (trace)
+ htrc("Calling xmlXPathRegisterNs Prefix=%s Uri=%s\n",
+ nsp->Prefix, nsp->Uri);
+
if (xmlXPathRegisterNs(Ctxp, BAD_CAST nsp->Prefix,
BAD_CAST nsp->Uri)) {
sprintf(g->Message, MSG(REGISTER_ERR), nsp->Prefix, nsp->Uri);
@@ -312,12 +558,27 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp)
return NULL;
} // endif Registering
- } else
- xmlXPathFreeNodeSetList(Xop); // To be checked
+ } // endfor nsp
+
+ } else {
+ if (trace)
+ htrc("Calling xmlXPathFreeNodeSetList Xop=%p\n", Xop);
+
+ if (Nofreelist) {
+ // Making Nlist that must not be freed yet
+ xmlXPathFreeNodeSetList(Xop); // Caused memory leak
+ Nofreelist = false;
+ } else
+ xmlXPathFreeObject(Xop); // Caused node not found
+
+ } // endif Ctxp
// Set the context to the calling node
Ctxp->node = np;
+ if (trace)
+ htrc("Calling xmlXPathEval %s Ctxp=%p\n", xp, Ctxp);
+
// Evaluate table xpath
if (!(Xop = xmlXPathEval(BAD_CAST xp, Ctxp))) {
sprintf(g->Message, MSG(XPATH_EVAL_ERR), xp);
@@ -439,6 +700,9 @@ int XML2NODE::GetType(void)
/******************************************************************/
PXNODE XML2NODE::GetNext(PGLOBAL g)
{
+ if (trace)
+ htrc("GetNext\n");
+
if (!Nodep->next)
Next = NULL;
else if (!Next)
@@ -452,6 +716,9 @@ PXNODE XML2NODE::GetNext(PGLOBAL g)
/******************************************************************/
PXNODE XML2NODE::GetChild(PGLOBAL g)
{
+ if (trace)
+ htrc("GetChild\n");
+
if (!Nodep->children)
Children = NULL;
else if (!Children)
@@ -467,6 +734,9 @@ RCODE XML2NODE::GetContent(PGLOBAL g, char *buf, int len)
{
RCODE rc = RC_OK;
+ if (trace)
+ htrc("GetContent\n");
+
if (Content)
xmlFree(Content);
@@ -505,18 +775,24 @@ RCODE XML2NODE::GetContent(PGLOBAL g, char *buf, int len)
} else
*buf = '\0';
+ if (trace)
+ htrc("GetContent: %s\n", buf);
+
return rc;
- } // end of GetText
+ } // end of GetContent
/******************************************************************/
/* Set the content of a node. */
/******************************************************************/
bool XML2NODE::SetContent(PGLOBAL g, char *txtp, int len)
{
+ if (trace)
+ htrc("SetContent: %s\n", txtp);
+
xmlChar *buf = xmlEncodeEntitiesReentrant(Docp, BAD_CAST txtp);
if (trace)
- htrc("SetContent %s -> %s\n", txtp, buf);
+ htrc("SetContent: %s -> %s\n", txtp, buf);
xmlNodeSetContent(Nodep, buf);
xmlFree(buf);
@@ -528,6 +804,9 @@ bool XML2NODE::SetContent(PGLOBAL g, char *txtp, int len)
/******************************************************************/
PXNODE XML2NODE::Clone(PGLOBAL g, PXNODE np)
{
+ if (trace)
+ htrc("Clone: np=%p\n", np);
+
if (np) {
((PNODE2)np)->Nodep = Nodep;
return np;
@@ -542,7 +821,7 @@ PXNODE XML2NODE::Clone(PGLOBAL g, PXNODE np)
PXLIST XML2NODE::GetChildElements(PGLOBAL g, char *xp, PXLIST lp)
{
if (trace)
- htrc("GetChildElements %s\n", xp);
+ htrc("GetChildElements: %s\n", xp);
return SelectNodes(g, (xp) ? xp : (char*)"*", lp);
} // end of GetChildElements
@@ -553,7 +832,7 @@ PXLIST XML2NODE::GetChildElements(PGLOBAL g, char *xp, PXLIST lp)
PXLIST XML2NODE::SelectNodes(PGLOBAL g, char *xp, PXLIST lp)
{
if (trace)
- htrc("SelectNodes %s\n", xp);
+ htrc("SelectNodes: %s\n", xp);
xmlNodeSetPtr nl = ((PXDOC2)Doc)->GetNodeList(g, Nodep, xp);
@@ -571,7 +850,7 @@ PXLIST XML2NODE::SelectNodes(PGLOBAL g, char *xp, PXLIST lp)
PXNODE XML2NODE::SelectSingleNode(PGLOBAL g, char *xp, PXNODE np)
{
if (trace)
- htrc("SelectSingleNode %s\n", xp);
+ htrc("SelectSingleNode: %s\n", xp);
xmlNodeSetPtr nl = ((PXDOC2)Doc)->GetNodeList(g, Nodep, xp);
@@ -593,7 +872,7 @@ PXNODE XML2NODE::SelectSingleNode(PGLOBAL g, char *xp, PXNODE np)
PXATTR XML2NODE::GetAttribute(PGLOBAL g, char *name, PXATTR ap)
{
if (trace)
- htrc("GetAttribute %s\n", name);
+ htrc("GetAttribute: %s\n", name);
xmlAttrPtr atp = xmlHasProp(Nodep, BAD_CAST name);
@@ -618,7 +897,7 @@ PXNODE XML2NODE::AddChildNode(PGLOBAL g, char *name, PXNODE np)
char *p, *pn, *pf = NULL;
if (trace)
- htrc("AddChildNode %s\n", name);
+ htrc("AddChildNode: %s\n", name);
// Is a prefix specified
if ((pn = strchr(name, ':'))) {
@@ -669,7 +948,7 @@ PXNODE XML2NODE::AddChildNode(PGLOBAL g, char *name, PXNODE np)
PXATTR XML2NODE::AddProperty(PGLOBAL g, char *name, PXATTR ap)
{
if (trace)
- htrc("AddProperty %s\n", name);
+ htrc("AddProperty: %s\n", name);
xmlAttrPtr atp = xmlNewProp(Nodep, BAD_CAST name, NULL);
@@ -692,7 +971,7 @@ PXATTR XML2NODE::AddProperty(PGLOBAL g, char *name, PXATTR ap)
void XML2NODE::AddText(PGLOBAL g, char *txtp)
{
if (trace)
- htrc("AddText %s\n", txtp);
+ htrc("AddText: %s\n", txtp);
// This is to avoid a blank line when inserting a new line
xmlNodePtr np = xmlGetLastChild(Nodep);
@@ -711,6 +990,9 @@ void XML2NODE::AddText(PGLOBAL g, char *txtp)
/******************************************************************/
void XML2NODE::DeleteChild(PGLOBAL g, PXNODE dnp)
{
+ if (trace)
+ htrc("DeleteChild: node=%p\n", dnp);
+
xmlNodePtr np = ((PNODE2)dnp)->Nodep;
xmlNodePtr text = np->next;
@@ -750,7 +1032,7 @@ int XML2NODELIST::GetLength(void)
PXNODE XML2NODELIST::GetItem(PGLOBAL g, int n, PXNODE np)
{
if (trace)
- htrc("GetItem %d\n", n);
+ htrc("GetItem: %d\n", n);
if (!Listp || Listp->nodeNr <= n)
return NULL;
@@ -781,7 +1063,7 @@ XML2ATTR::XML2ATTR(PXDOC dp, xmlAttrPtr ap, xmlNodePtr np)
bool XML2ATTR::SetText(PGLOBAL g, char *txtp, int len)
{
if (trace)
- htrc("SetText %s %d\n", txtp, len);
+ htrc("SetText: %s %d\n", txtp, len);
xmlSetProp(Parent, Atrp->name, BAD_CAST txtp);
return false;
diff --git a/storage/connect/libdoc.h b/storage/connect/libdoc.h
index 97f97f99ccc..a0cead4e904 100644
--- a/storage/connect/libdoc.h
+++ b/storage/connect/libdoc.h
@@ -1,144 +1,6 @@
-/******************************************************************/
-/* Declaration of XML document processing using libxml2 */
-/* Author: Olivier Bertrand 2007-2012 */
-/******************************************************************/
-#include "plgxml.h"
-
-typedef class LIBXMLDOC *PXDOC2;
-typedef class XML2NODE *PNODE2;
-typedef class XML2ATTR *PATTR2;
-typedef class XML2NODELIST *PLIST2;
-
-/******************************************************************/
-/* XML2 block. Must have the same layout than FBLOCK up to Type. */
-/******************************************************************/
-typedef struct _x2block { /* Loaded XML file block */
- struct _x2block *Next;
- LPCSTR Fname; /* Point on file name */
- size_t Length; /* Used to tell if read mode */
- short Count; /* Nb of times file is used */
- short Type; /* TYPE_FB_XML */
- int Retcode; /* Return code from Load */
- xmlDocPtr Docp; /* Document interface pointer */
-// xmlXPathContextPtr Ctxp;
-// xmlXPathObjectPtr Xop;
- } X2BLOCK, *PX2BLOCK;
-
-/******************************************************************/
-/* Declaration of libxml2 document. */
-/******************************************************************/
-class LIBXMLDOC : public XMLDOCUMENT {
- friend class XML2NODE;
- friend class XML2ATTR;
- public:
- // Constructor
- LIBXMLDOC(char *nsl, char *nsdf, char *enc, PFBLOCK fp);
-
- // Properties
- virtual short GetDocType(void) {return TYPE_FB_XML2;}
- virtual void *GetDocPtr(void) {return Docp;}
-
- // Methods
- virtual bool Initialize(PGLOBAL g);
- virtual bool ParseFile(char *fn);
- virtual bool NewDoc(PGLOBAL g, char *ver);
- virtual void AddComment(PGLOBAL g, char *com);
- virtual PXNODE GetRoot(PGLOBAL g);
- virtual PXNODE NewRoot(PGLOBAL g, char *name);
- virtual PXNODE NewPnode(PGLOBAL g, char *name);
- virtual PXATTR NewPattr(PGLOBAL g);
- virtual PXLIST NewPlist(PGLOBAL g);
- virtual int DumpDoc(PGLOBAL g, char *ofn);
- virtual void CloseDoc(PGLOBAL g, PFBLOCK xp);
- virtual PFBLOCK LinkXblock(PGLOBAL g, MODE m, int rc, char *fn);
-
- protected:
-// bool CheckDocument(FILE *of, xmlNodePtr np);
- xmlNodeSetPtr GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp);
- int Decode(xmlChar *cnt, char *buf, int n);
- xmlChar *Encode(PGLOBAL g, char *txt);
-
- // Members
- xmlDocPtr Docp;
- xmlNodeSetPtr Nlist;
- xmlXPathContextPtr Ctxp;
- xmlXPathObjectPtr Xop;
- char *Buf; // Temporary
-}; // end of class LIBXMLDOC
-
-/******************************************************************/
-/* Declaration of libxml2 node. */
-/******************************************************************/
-class XML2NODE : public XMLNODE {
- friend class LIBXMLDOC;
- friend class XML2NODELIST;
- public:
- // Properties
- virtual char *GetName(PGLOBAL g) {return (char*)Nodep->name;}
- virtual int GetType(void);
- virtual PXNODE GetNext(PGLOBAL g);
- virtual PXNODE GetChild(PGLOBAL g);
-
- // Methods
- virtual RCODE GetContent(PGLOBAL g, char *buf, int len);
- virtual bool SetContent(PGLOBAL g, char *txtp, int len);
- virtual PXNODE Clone(PGLOBAL g, PXNODE np);
- virtual PXLIST GetChildElements(PGLOBAL g, char *xp, PXLIST lp);
- virtual PXLIST SelectNodes(PGLOBAL g, char *xp, PXLIST lp);
- virtual PXNODE SelectSingleNode(PGLOBAL g, char *xp, PXNODE np);
- virtual PXATTR GetAttribute(PGLOBAL g, char *name, PXATTR ap);
- virtual PXNODE AddChildNode(PGLOBAL g, char *name, PXNODE np);
- virtual PXATTR AddProperty(PGLOBAL g, char *name, PXATTR ap);
- virtual void AddText(PGLOBAL g, char *txtp);
- virtual void DeleteChild(PGLOBAL g, PXNODE dnp);
-
- protected:
- // Constructor
- XML2NODE(PXDOC dp, xmlNodePtr np);
-
- // Members
- xmlDocPtr Docp;
- xmlChar *Content;
- xmlNodePtr Nodep;
-}; // end of class XML2NODE
-
-/******************************************************************/
-/* Declaration of libxml2 node list. */
-/******************************************************************/
-class XML2NODELIST : public XMLNODELIST {
- friend class LIBXMLDOC;
- friend class XML2NODE;
- public:
- // Methods
- virtual int GetLength(void);
- virtual PXNODE GetItem(PGLOBAL g, int n, PXNODE np);
-
- protected:
- // Constructor
- XML2NODELIST(PXDOC dp, xmlNodeSetPtr lp);
-
- // Members
- xmlNodeSetPtr Listp;
-}; // end of class XML2NODELIST
-
-/******************************************************************/
-/* Declaration of libxml2 attribute. */
-/******************************************************************/
-class XML2ATTR : public XMLATTRIBUTE {
- friend class LIBXMLDOC;
- friend class XML2NODE;
- public:
- // Properties
-//virtual char *GetText(void);
-
- // Methods
- virtual bool SetText(PGLOBAL g, char *txtp, int len);
-
- protected:
- // Constructor
- XML2ATTR(PXDOC dp, xmlAttrPtr ap, xmlNodePtr np);
-
- // Members
- xmlAttrPtr Atrp;
- xmlNodePtr Parent;
-}; // end of class XML2ATTR
+#ifndef LIBDOC_H_INCLUDED
+#define LIBDOC_H_INCLUDED
+void XmlInitParserLib(void);
+void XmlCleanupParserLib(void);
+void CloseXML2File(PGLOBAL, PFBLOCK, bool);
+#endif
diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc
index e243a706f01..fe93751d600 100644
--- a/storage/connect/mycat.cc
+++ b/storage/connect/mycat.cc
@@ -426,6 +426,8 @@ int MYCAT::GetColCatInfo(PGLOBAL g, PTABDEF defp)
PCOLDEF cdp, lcdp= NULL, tocols= NULL;
PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO));
+ memset(pcf, 0, sizeof(COLINFO));
+
// Get a unique char identifier for type
tc= (defp->Catfunc == FNC_NO) ? GetTypeID(type) : TAB_PRX;
@@ -468,7 +470,7 @@ int MYCAT::GetColCatInfo(PGLOBAL g, PTABDEF defp)
} // endswitch tc
do {
- field= Hc->GetColumnOption(field, pcf);
+ field= Hc->GetColumnOption(g, field, pcf);
} while (field && (*pcf->Name =='*' /*|| pcf->Flags & U_VIRTUAL*/));
if (tc == TAB_DBF && pcf->Type == TYPE_DATE && !pcf->Datefmt) {
diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp
index 9ebf77ff35a..4cad68a9a1e 100644
--- a/storage/connect/myconn.cpp
+++ b/storage/connect/myconn.cpp
@@ -311,6 +311,8 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
const char *user, const char *pwd,
int pt)
{
+ uint cto = 60, nrt = 120;
+
m_DB = mysql_init(NULL);
if (!m_DB) {
@@ -318,11 +320,12 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
return RC_FX;
} // endif m_DB
- // Notice that the client and server use separate group names.
- // This is critical, because the server will not accept the
- // client's options, and vice versa.
- mysql_options(m_DB, MYSQL_READ_DEFAULT_GROUP, "PlugDB_CLIENT");
+ // Removed to do like FEDERATED do
+//mysql_options(m_DB, MYSQL_READ_DEFAULT_GROUP, "client-mariadb");
mysql_options(m_DB, MYSQL_OPT_USE_REMOTE_CONNECTION, NULL);
+ mysql_options(m_DB, MYSQL_OPT_CONNECT_TIMEOUT, &cto);
+ mysql_options(m_DB, MYSQL_OPT_READ_TIMEOUT, &nrt);
+//mysql_options(m_DB, MYSQL_OPT_WRITE_TIMEOUT, ...);
#if 0
if (pwd && !strcmp(pwd, "*")) {
diff --git a/storage/connect/mysql-test/connect/r/dbf.result b/storage/connect/mysql-test/connect/r/dbf.result
index 2e84c5b3090..cbe4f4db620 100644
--- a/storage/connect/mysql-test/connect/r/dbf.result
+++ b/storage/connect/mysql-test/connect/r/dbf.result
@@ -394,22 +394,22 @@ CREATE TABLE t1
(
a BLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
-ERROR HY000: Unsupported type for column 'a'
+ERROR HY000: Unsupported type for column a
CREATE TABLE t1
(
a TINYBLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
-ERROR HY000: Unsupported type for column 'a'
+ERROR HY000: Unsupported type for column a
CREATE TABLE t1
(
a MEDIUMBLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
-ERROR HY000: Unsupported type for column 'a'
+ERROR HY000: Unsupported type for column a
CREATE TABLE t1
(
a LONGBLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
-ERROR HY000: Unsupported type for column 'a'
+ERROR HY000: Unsupported type for column a
#
# Testing DATE
#
diff --git a/storage/connect/mysql-test/connect/r/mul.result b/storage/connect/mysql-test/connect/r/mul.result
new file mode 100644
index 00000000000..d362da13739
--- /dev/null
+++ b/storage/connect/mysql-test/connect/r/mul.result
@@ -0,0 +1,57 @@
+#
+# Testing multiple 1
+#
+CREATE TABLE `t1` (
+`a` char(10) DEFAULT NULL,
+`b` char(10) DEFAULT NULL
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=CSV `sep_char`=';';
+Warnings:
+Warning 1105 No file name. Table will use t1.csv
+INSERT INTO t1 VALUES('test1','bla');
+SELECT * FROM t1;
+a b
+test1 bla
+CREATE TABLE `t2` (
+`a` char(10) DEFAULT NULL,
+`b` char(10) DEFAULT NULL
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=CSV `sep_char`=';';
+Warnings:
+Warning 1105 No file name. Table will use t2.csv
+INSERT INTO t2 VALUES('test2','blub');
+SELECT * FROM t2;
+a b
+test2 blub
+CREATE TABLE `t_all` (
+`a` char(10) DEFAULT NULL,
+`b` char(10) DEFAULT NULL
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=CSV `file_name`='t*.csv' `sep_char`=';' `multiple`=1;
+SELECT * FROM t_all order by `a`;
+a b
+test1 bla
+test2 blub
+#
+# Testing multiple 2
+#
+CREATE table fnlist (
+fn char(8) not null
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 table_type=DOS;
+Warnings:
+Warning 1105 No file name. Table will use fnlist.dos
+INSERT INTO fnlist VALUES('t1.csv'),('t2.csv');
+SELECT fn FROM fnlist;
+fn
+t1.csv
+t2.csv
+CREATE TABLE `tblist` (
+`a` char(10) DEFAULT NULL,
+`b` char(10) DEFAULT NULL
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=CSV `file_name`='fnlist.dos' `sep_char`=';' `multiple`=2;
+SELECT * FROM tblist;
+a b
+test1 bla
+test2 blub
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t_all;
+DROP TABLE fnlist;
+DROP TABLE tblist;
diff --git a/storage/connect/mysql-test/connect/t/mul.test b/storage/connect/mysql-test/connect/t/mul.test
new file mode 100644
index 00000000000..451b38799ad
--- /dev/null
+++ b/storage/connect/mysql-test/connect/t/mul.test
@@ -0,0 +1,43 @@
+--echo #
+--echo # Testing multiple 1
+--echo #
+CREATE TABLE `t1` (
+ `a` char(10) DEFAULT NULL,
+ `b` char(10) DEFAULT NULL
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=CSV `sep_char`=';';
+INSERT INTO t1 VALUES('test1','bla');
+SELECT * FROM t1;
+
+CREATE TABLE `t2` (
+ `a` char(10) DEFAULT NULL,
+ `b` char(10) DEFAULT NULL
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=CSV `sep_char`=';';
+INSERT INTO t2 VALUES('test2','blub');
+SELECT * FROM t2;
+
+CREATE TABLE `t_all` (
+ `a` char(10) DEFAULT NULL,
+ `b` char(10) DEFAULT NULL
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=CSV `file_name`='t*.csv' `sep_char`=';' `multiple`=1;
+SELECT * FROM t_all order by `a`;
+
+--echo #
+--echo # Testing multiple 2
+--echo #
+CREATE table fnlist (
+fn char(8) not null
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 table_type=DOS;
+INSERT INTO fnlist VALUES('t1.csv'),('t2.csv');
+SELECT fn FROM fnlist;
+
+CREATE TABLE `tblist` (
+ `a` char(10) DEFAULT NULL,
+ `b` char(10) DEFAULT NULL
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=CSV `file_name`='fnlist.dos' `sep_char`=';' `multiple`=2;
+SELECT * FROM tblist;
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t_all;
+DROP TABLE fnlist;
+DROP TABLE tblist;
diff --git a/storage/connect/mysql-test/connect/t/odbc_sqlite3.test b/storage/connect/mysql-test/connect/t/odbc_sqlite3.test
index f32196e3f04..2705b4f47fb 100644
--- a/storage/connect/mysql-test/connect/t/odbc_sqlite3.test
+++ b/storage/connect/mysql-test/connect/t/odbc_sqlite3.test
@@ -3,21 +3,40 @@
#
# To run this test, install SQLite3 ODBC Driver from
# http://www.ch-werner.de/sqliteodbc/
-# The installer file is sqliteodbc.exe
+#
+# Note, the test does not need a DSN to be created
+# (only the driver is required)
+#
+#
+# On Windows:
+# -----------
+# Download and run the installer file sqliteodbc.exe
# Version sqliteodbc-0.991 is known to Work.
+# After running the installer the test should start working automatically.
+#
+# On Linux:
+# --------
+# 1. Download the source tarball, e.g.: sqliteodbc-0.993.tar.gz
+# 2. Unpack the sources:
+# tar -zxf sqliteodbc-0.993.tar.gz
+# 3. Compile the source and install:
+# cd sqliteodbc-0.993
+# ./configure --prefix=/opt/sqliteodbc
+# make
+# sudo make install
#
-# On Windows the test should start working automatically
+# (you can use a different --prefix, according to your preferences)
#
-# On Linux add these lines into /etc/odbcinst.ini
+# 4. Add these lines into /etc/odbcinst.ini
#
#[SQLite3 ODBC Driver]
#Description=SQLite3 ODBC Driver
#Driver=/opt/sqliteodbc/libsqlite3odbc.so
#Setup=/opt/sqliteodbc/libsqlite3odbc.so
#
-# (adjust the directory "/opt/sqliteodbc/" according to your OS settings)
+# Adjust the directory "/opt/sqliteodbc/" according to --prefix
+# that you chose on step #3.
#
-# Note, the test does not need a DSN to be created.
#
SET NAMES utf8;
diff --git a/storage/connect/myutil.cpp b/storage/connect/myutil.cpp
index 19c478ecbd8..b266b7b79c1 100644
--- a/storage/connect/myutil.cpp
+++ b/storage/connect/myutil.cpp
@@ -23,6 +23,7 @@
#include "plgdbsem.h"
//#include "value.h"
//#include "valblk.h"
+#include "myutil.h"
#define DLL_EXPORT // Items are exported from this DLL
/************************************************************************/
diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp
index b39f1c9ba5b..5808bf266bd 100644
--- a/storage/connect/odbconn.cpp
+++ b/storage/connect/odbconn.cpp
@@ -304,6 +304,9 @@ PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *table,
} else
qrp = NULL;
+ /* Cleanup */
+ ocp->Close();
+
/************************************************************************/
/* Return the result pointer for use by GetData routines. */
/************************************************************************/
@@ -954,17 +957,17 @@ int ODBConn::Open(PSZ ConnectString, DWORD options)
// Allocate the HDBC and make connection
try {
- PSZ ver;
+ /*PSZ ver;*/
AllocConnect(options);
- ver = GetStringInfo(SQL_ODBC_VER);
+ /*ver = GetStringInfo(SQL_ODBC_VER);*/
if (Connect(options)) {
strcpy(g->Message, MSG(CONNECT_CANCEL));
return 0;
} // endif
- ver = GetStringInfo(SQL_DRIVER_ODBC_VER);
+ /*ver = GetStringInfo(SQL_DRIVER_ODBC_VER);*/
} catch(DBX *xp) {
// strcpy(g->Message, xp->m_ErrMsg[0]);
strcpy(g->Message, xp->GetErrorMessage(0));
@@ -1213,13 +1216,13 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols)
b = false;
if (m_hstmt) {
- RETCODE rc;
+ /*RETCODE rc;*/
// All this did not seems to make sense and was been commented out
// if (IsOpen())
// Close(SQL_CLOSE);
- rc = SQLFreeStmt(m_hstmt, SQL_CLOSE);
+ /*rc =*/ SQLFreeStmt(m_hstmt, SQL_CLOSE);
hstmt = m_hstmt;
m_hstmt = NULL;
ThrowDBX(MSG(SEQUENCE_ERROR));
@@ -1673,8 +1676,10 @@ int ODBConn::GetCatInfo(CATPARM *cap)
// Attempt to set rowset size.
// In case of failure reset it to 0 to use Fetch.
if (m_Catver == 3) // ODBC Ver 3
- rc = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE,
- (SQLPOINTER)m_RowsetSize, 0);
+ {
+ SQLULEN tmp= m_RowsetSize;
+ rc = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, &tmp, 0);
+ }
else
rc = SQLSetStmtOption(hstmt, SQL_ROWSET_SIZE, m_RowsetSize);
@@ -1831,7 +1836,7 @@ int ODBConn::GetCatInfo(CATPARM *cap)
/***********************************************************************/
void ODBConn::Close()
{
- RETCODE rc;
+ /*RETCODE rc;*/
#if 0
// Close any open recordsets
@@ -1856,13 +1861,13 @@ void ODBConn::Close()
if (m_hstmt) {
// Is required for multiple tables
- rc = SQLFreeStmt(m_hstmt, SQL_DROP);
+ /*rc =*/ SQLFreeStmt(m_hstmt, SQL_DROP);
m_hstmt = NULL;
} // endif m_hstmt
if (m_hdbc != SQL_NULL_HDBC) {
- rc = SQLDisconnect(m_hdbc);
- rc = SQLFreeConnect(m_hdbc);
+ /*rc =*/ SQLDisconnect(m_hdbc);
+ /*rc =*/ SQLFreeConnect(m_hdbc);
m_hdbc = SQL_NULL_HDBC;
// AfxLockGlobals(CRIT_ODBC);
diff --git a/storage/connect/osutil.c b/storage/connect/osutil.c
index 1b7332357e6..4cdd7c560f0 100644
--- a/storage/connect/osutil.c
+++ b/storage/connect/osutil.c
@@ -202,19 +202,6 @@ BOOL MessageBeep(uint i)
return TRUE;
} /* end of MessageBeep */
-LPSTR _strerror(int errn)
- {
- static char buff[256];
-
- sprintf(buff,"error: %d", errn);
- return buff;
- } /* end of _strerror */
-
-int _isatty(int fileNo)
- {
- return isatty(fileNo);
- } /* end of _isatty */
-
#if 0
/* This function is ridiculous and should be revisited */
DWORD FormatMessage(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId,
diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h
index 919f3452a4d..44ad8605747 100644
--- a/storage/connect/plgdbsem.h
+++ b/storage/connect/plgdbsem.h
@@ -565,7 +565,8 @@ DllExport void PlgDBfree(MBLOCK&);
//lExport int GetIniSize(char *, char *, char *, char *);
//lExport bool WritePrivateProfileInt(LPCSTR, LPCSTR, int, LPCSTR);
DllExport void NewPointer(PTABS, void *, void *);
-
+DllExport char *GetIni(int n= 0);
+DllExport void SetTrc(void);
#define MSGID_NONE 0
#define MSGID_CANNOT_OPEN 1
diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp
index 73b468c9209..5ea8457f25e 100644
--- a/storage/connect/plgdbutl.cpp
+++ b/storage/connect/plgdbutl.cpp
@@ -127,7 +127,7 @@ void CloseXMLFile(PGLOBAL, PFBLOCK, bool);
#endif // DOMDOC_SUPPORT
#ifdef LIBXML2_SUPPORT
-void CloseXML2File(PGLOBAL, PFBLOCK, bool);
+#include "libdoc.h"
#endif // LIBXML2_SUPPORT
@@ -222,7 +222,7 @@ int global_open(GLOBAL *g, int msgid, const char *path, int flags, int mode)
/**************************************************************************/
/* Utility for external callers (such as XDB) */
/**************************************************************************/
-DllExport char *GetIni(int n = 0)
+DllExport char *GetIni(int n)
{
switch (n) {
case 1: return plgxini; break;
diff --git a/storage/connect/plgxml.h b/storage/connect/plgxml.h
index 8fc95eabef7..b8352c36c14 100644
--- a/storage/connect/plgxml.h
+++ b/storage/connect/plgxml.h
@@ -69,6 +69,7 @@ class XMLDOCUMENT : public BLOCK {
// Properties
virtual short GetDocType(void) = 0;
virtual void *GetDocPtr(void) = 0;
+ virtual void SetNofree(bool b) = 0;
// Methods
virtual bool Initialize(PGLOBAL) = 0;
diff --git a/storage/connect/plugutil.c b/storage/connect/plugutil.c
index e8098bb2512..7910f1ea318 100644
--- a/storage/connect/plugutil.c
+++ b/storage/connect/plugutil.c
@@ -512,6 +512,23 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
} /* end of PlugSubAlloc */
/***********************************************************************/
+/* This routine suballocate a copy of the passed string. */
+/***********************************************************************/
+char *PlugDup(PGLOBAL g, const char *str)
+ {
+ char *buf;
+ size_t len;
+
+ if (str && (len = strlen(str))) {
+ buf = (char*)PlugSubAlloc(g, NULL, len + 1);
+ strcpy(buf, str);
+ } else
+ buf = NULL;
+
+ return(buf);
+ } /* end of PlugDup */
+
+/***********************************************************************/
/* This routine makes a pointer from an offset to a memory pointer. */
/***********************************************************************/
void *MakePtr(void *memp, OFFSET offset)
diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp
index 288396276bc..b828c44d648 100644
--- a/storage/connect/tabdos.cpp
+++ b/storage/connect/tabdos.cpp
@@ -1047,7 +1047,7 @@ bool DOSCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
/***********************************************************************/
void DOSCOL::ReadColumn(PGLOBAL g)
{
- char *p;
+ char *p = NULL;
int i, rc;
int field;
double dval;
diff --git a/storage/connect/tabfix.cpp b/storage/connect/tabfix.cpp
index 801de79aad9..4cad405452e 100644
--- a/storage/connect/tabfix.cpp
+++ b/storage/connect/tabfix.cpp
@@ -327,7 +327,7 @@ BINCOL::BINCOL(BINCOL *col1, PTDB tdbp) : DOSCOL(col1, tdbp)
/***********************************************************************/
void BINCOL::ReadColumn(PGLOBAL g)
{
- char *p;
+ char *p = NULL;
int rc;
PTDBFIX tdbp = (PTDBFIX)To_Tdb;
diff --git a/storage/connect/tabmul.cpp b/storage/connect/tabmul.cpp
index 5fe18ef5b1d..146e2891ec7 100644..100755
--- a/storage/connect/tabmul.cpp
+++ b/storage/connect/tabmul.cpp
@@ -68,6 +68,8 @@
#include "tabdos.h" // TDBDOS and DOSCOL class dcls
#include "tabmul.h" // TDBMUL and MULCOL classes dcls
+extern "C" int trace;
+
/* ------------------------- Class TDBMUL ---------------------------- */
/***********************************************************************/
@@ -122,15 +124,25 @@ PTDB TDBMUL::Duplicate(PGLOBAL g)
/***********************************************************************/
bool TDBMUL::InitFileNames(PGLOBAL g)
{
-#define PFNZ 8192
- char *pfn[PFNZ], filename[_MAX_DRIVE+_MAX_DIR+_MAX_FNAME+_MAX_EXT];
+#define PFNZ 4096
+#define FNSZ _MAX_DRIVE+_MAX_DIR+_MAX_FNAME+_MAX_EXT
+ char *pfn[PFNZ];
+ char *filename;
int rc, n = 0;
+ if (trace)
+ htrc("in InitFileName: fn[]=%d\n", FNSZ);
+
+ filename = (char*)PlugSubAlloc(g, NULL, FNSZ);
+
// The sub table may need to refer to the Table original block
Tdbp->SetTable(To_Table); // Was not set at construction
PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath());
+ if (trace)
+ htrc("InitFileName: fn='%s'\n", filename);
+
if (Mul == 1) {
/*******************************************************************/
/* To_File is a multiple name with special characters */
@@ -194,15 +206,28 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
_splitpath(filename, NULL, direc, pattern, ftype);
strcat(pattern, ftype);
+ if (trace)
+ htrc("direc=%s pattern=%s ftype=%s\n", direc, pattern, ftype);
+
// Start searching files in the target directory.
if (!(dir = opendir(direc))) {
sprintf(g->Message, MSG(BAD_DIRECTORY), direc, strerror(errno));
+
+ if (trace)
+ htrc("%s\n", g->Message);
+
return true;
} // endif dir
+ if (trace)
+ htrc("dir opened: reading files\n");
+
while ((entry = readdir(dir)) && n < PFNZ) {
strcat(strcpy(fn, direc), entry->d_name);
+ if (trace)
+ htrc("%s read\n", fn);
+
if (lstat(fn, &fileinfo) < 0) {
sprintf(g->Message, "%s: %s", fn, strerror(errno));
return true;
@@ -218,6 +243,10 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
strcat(strcpy(filename, direc), entry->d_name);
pfn[n] = (char*)PlugSubAlloc(g, NULL, strlen(filename) + 1);
strcpy(pfn[n++], filename);
+
+ if (trace)
+ htrc("Adding pfn[%d] %s\n", n, filename);
+
} // endwhile readdir
// Close the dir handle.
@@ -235,7 +264,7 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
return true;
while (n < PFNZ) {
- if (!fgets(filename, sizeof(filename), stream)) {
+ if (!fgets(filename, FNSZ, stream)) {
fclose(stream);
break;
} // endif fgets
@@ -364,9 +393,12 @@ int TDBMUL::Cardinality(PGLOBAL g)
int TDBMUL::GetMaxSize(PGLOBAL g)
{
if (MaxSize < 0) {
- int i;
+ int i;
int mxsz;
+ if (trace)
+ htrc("TDBMUL::GetMaxSize: Filenames=%p\n", Filenames);
+
if (!Filenames && InitFileNames(g))
return -1;
@@ -420,10 +452,9 @@ int TDBMUL::RowNumber(PGLOBAL g, bool b)
/***********************************************************************/
bool TDBMUL::OpenDB(PGLOBAL g)
{
-#ifdef DEBTRACE
- htrc("MUL OpenDB: tdbp=%p tdb=R%d use=%d key=%p mode=%d\n",
- this, Tdb_No, Use, To_Key_Col, Mode);
-#endif
+ if (trace)
+ htrc("MUL OpenDB: tdbp=%p tdb=R%d use=%d key=%p mode=%d\n",
+ this, Tdb_No, Use, To_Key_Col, Mode);
if (Use == USE_OPEN) {
/*******************************************************************/
@@ -451,7 +482,7 @@ bool TDBMUL::OpenDB(PGLOBAL g)
/*********************************************************************/
/* Open the first table file of the list. */
/*********************************************************************/
-//if (!Filenames && InitFileNames(g)) done in GetMaxSize
+//if (!Filenames && InitFileNames(g)) // was done in GetMaxSize
// return true;
if (Filenames[iFile = 0]) {
@@ -735,10 +766,9 @@ int TDBDIR::GetMaxSize(PGLOBAL g)
/***********************************************************************/
bool TDBDIR::OpenDB(PGLOBAL g)
{
-#ifdef DEBTRACE
- htrc("DIR OpenDB: tdbp=%p tdb=R%d use=%d mode=%d\n",
- this, Tdb_No, Use, Mode);
-#endif
+ if (trace)
+ htrc("DIR OpenDB: tdbp=%p tdb=R%d use=%d mode=%d\n",
+ this, Tdb_No, Use, Mode);
if (Use == USE_OPEN) {
/*******************************************************************/
@@ -898,11 +928,9 @@ void DIRCOL::ReadColumn(PGLOBAL g)
{
PTDBDIR tdbp = (PTDBDIR)To_Tdb;
-#ifdef DEBTRACE
- fprintf(debug,
- "DIR ReadColumn: col %s R%d use=%.4X status=%.4X type=%d N=%d\n",
- Name, tdbp->GetTdb_No(), ColUse, Status, Buf_Type, N);
-#endif
+ if (trace)
+ htrc("DIR ReadColumn: col %s R%d use=%.4X status=%.4X type=%d N=%d\n",
+ Name, tdbp->GetTdb_No(), ColUse, Status, Buf_Type, N);
/*********************************************************************/
/* Retrieve the information corresponding to the column number. */
@@ -1304,10 +1332,9 @@ int TDBDHR::GetMaxSize(PGLOBAL g)
/***********************************************************************/
bool TDBDHR::OpenDB(PGLOBAL g)
{
-#ifdef DEBTRACE
- htrc("DHR OpenDB: tdbp=%p tdb=R%d use=%d mode=%d\n",
- this, Tdb_No, Use, Mode);
-#endif
+ if (trace)
+ htrc("DHR OpenDB: tdbp=%p tdb=R%d use=%d mode=%d\n",
+ this, Tdb_No, Use, Mode);
if (Use == USE_OPEN) {
/*******************************************************************/
@@ -1442,11 +1469,9 @@ void DHRCOL::ReadColumn(PGLOBAL g)
int rc;
PTDBDHR tdbp = (PTDBDHR)To_Tdb;
-#ifdef DEBTRACE
- fprintf(debug,
- "DHR ReadColumn: col %s R%d use=%.4X status=%.4X type=%d N=%d\n",
- Name, tdbp->GetTdb_No(), ColUse, Status, Buf_Type, N);
-#endif
+ if (trace)
+ htrc("DHR ReadColumn: col %s R%d use=%.4X status=%.4X type=%d N=%d\n",
+ Name, tdbp->GetTdb_No(), ColUse, Status, Buf_Type, N);
/*********************************************************************/
/* Retrieve the information corresponding to the column number. */
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index 1a19b4cbf33..030f5760601 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -31,7 +31,10 @@
/* IBM, Borland, GNU or Microsoft C++ Compiler and Linker */
/* */
/************************************************************************/
+#define MYSQL_SERVER 1
#include "my_global.h"
+#include "sql_class.h"
+#include "sql_servers.h"
#if defined(WIN32)
//#include <windows.h>
#else // !WIN32
@@ -64,7 +67,6 @@ void PrintResult(PGLOBAL, PSEM, PQRYRES);
#endif // _CONSOLE
extern "C" int trace;
-extern MYSQL_PLUGIN_IMPORT uint mysqld_port;
/* -------------- Implementation of the MYSQLDEF class --------------- */
@@ -87,6 +89,45 @@ MYSQLDEF::MYSQLDEF(void)
} // end of MYSQLDEF constructor
/***********************************************************************/
+/* Get connection info from the declared server. */
+/***********************************************************************/
+bool MYSQLDEF::GetServerInfo(PGLOBAL g, const char *server_name)
+{
+ THD *thd= current_thd;
+ MEM_ROOT *mem= thd->mem_root;
+ FOREIGN_SERVER *server, server_buffer;
+ DBUG_ENTER("GetServerInfo");
+ DBUG_PRINT("info", ("server_name %s", server_name));
+
+ if (!server_name || !strlen(server_name)) {
+ DBUG_PRINT("info", ("server_name not defined!"));
+ strcpy(g->Message, "server_name not defined!");
+ DBUG_RETURN(true);
+ } // endif server_name
+
+ // get_server_by_name() clones the server if exists and allocates
+ // copies of strings in the supplied mem_root
+ if (!(server= get_server_by_name(mem, server_name, &server_buffer))) {
+ DBUG_PRINT("info", ("get_server_by_name returned > 0 error condition!"));
+ /* need to come up with error handling */
+ strcpy(g->Message, "get_server_by_name returned > 0 error condition!");
+ DBUG_RETURN(true);
+ } // endif server
+
+ DBUG_PRINT("info", ("get_server_by_name returned server at %lx",
+ (long unsigned int) server));
+
+ // TODO: We need to examine which of these can really be NULL
+ Hostname = PlugDup(g, server->host);
+ Database = PlugDup(g, server->db);
+ Username = PlugDup(g, server->username);
+ Password = PlugDup(g, server->password);
+ Portnumber = (server->port) ? server->port : GetDefaultPort();
+
+ DBUG_RETURN(false);
+} // end of GetServerInfo
+
+/***********************************************************************/
/* Parse connection string */
/* */
/* SYNOPSIS */
@@ -135,54 +176,25 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
if ((!strstr(url, "://") && (!strchr(url, '@')))) {
// No :// or @ in connection string. Must be a straight
// connection name of either "server" or "server/table"
- strcpy(g->Message, "Using Federated server not implemented yet");
- return true;
-#if 0
- /* ok, so we do a little parsing, but not completely! */
- share->parsed= FALSE;
- /*
- If there is a single '/' in the connection string, this means the user is
- specifying a table name
- */
-
- if ((share->table_name= strchr(share->connection_string, '/')))
- {
- *share->table_name++= '\0';
- share->table_name_length= strlen(share->table_name);
-
- DBUG_PRINT("info",
- ("internal format, parsed table_name "
- "share->connection_string: %s share->table_name: %s",
- share->connection_string, share->table_name));
-
- /*
- there better not be any more '/'s !
- */
- if (strchr(share->table_name, '/'))
- goto error;
- }
- /*
- Otherwise, straight server name, use tablename of federatedx table
- as remote table name
- */
- else
- {
- /*
- Connection specifies everything but, resort to
- expecting remote and foreign table names to match
- */
- share->table_name= strmake_root(mem_root, table->s->table_name.str,
- (share->table_name_length=
- table->s->table_name.length));
- DBUG_PRINT("info",
- ("internal format, default table_name "
- "share->connection_string: %s share->table_name: %s",
- share->connection_string, share->table_name));
- }
-
- if ((error_num= get_connection(mem_root, share)))
- goto error;
-#endif // 0
+ // ok, so we do a little parsing, but not completely!
+ if ((Tabname= strchr(url, '/'))) {
+ // If there is a single '/' in the connection string,
+ // this means the user is specifying a table name
+ *Tabname++= '\0';
+
+ // there better not be any more '/'s !
+ if (strchr(Tabname, '/'))
+ return true;
+
+ } else
+ // Otherwise, straight server name,
+ // use tablename of federatedx table as remote table name
+ Tabname= Name;
+
+ if (trace)
+ htrc("server: %s Tabname: %s", url, Tabname);
+
+ return GetServerInfo(g, url);
} else {
// URL, parse it
char *sport, *scheme = url;
@@ -247,7 +259,7 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
if ((sport = strchr(Hostname, ':')))
*sport++ = 0;
- Portnumber = (sport && sport[0]) ? atoi(sport) : mysqld_port;
+ Portnumber = (sport && sport[0]) ? atoi(sport) : GetDefaultPort();
if (Username[0] == 0)
Username = Cat->GetStringCatInfo(g, "User", "*");
@@ -279,12 +291,14 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
/***********************************************************************/
bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
- char *url = Cat->GetStringCatInfo(g, "Connect", NULL);
+ char *url;
Desc = "MySQL Table";
if (stricmp(am, "MYPRX")) {
// Normal case of specific MYSQL table
+ url = Cat->GetStringCatInfo(g, "Connect", NULL);
+
if (!url || !*url) {
// Not using the connection URL
Hostname = Cat->GetStringCatInfo(g, "Host", "localhost");
@@ -293,24 +307,36 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname);
Username = Cat->GetStringCatInfo(g, "User", "*");
Password = Cat->GetStringCatInfo(g, "Password", NULL);
- Portnumber = Cat->GetIntCatInfo("Port", mysqld_port);
+ Portnumber = Cat->GetIntCatInfo("Port", GetDefaultPort());
} else if (ParseURL(g, url))
return TRUE;
Bind = !!Cat->GetIntCatInfo("Bind", 0);
Delayed = !!Cat->GetIntCatInfo("Delayed", 0);
} else {
- // MYSQL access from a PROXY table, not using URL
+ // MYSQL access from a PROXY table
Database = Cat->GetStringCatInfo(g, "Database", "*");
- Tabname = Name;
Isview = Cat->GetBoolCatInfo("View", FALSE);
- // We must get connection parms from the calling table
+ // We must get other connection parms from the calling table
Remove_tshp(Cat);
- Hostname = Cat->GetStringCatInfo(g, "Host", "localhost");
- Username = Cat->GetStringCatInfo(g, "User", "*");
- Password = Cat->GetStringCatInfo(g, "Password", NULL);
- Portnumber = Cat->GetIntCatInfo("Port", mysqld_port);
+ url = Cat->GetStringCatInfo(g, "Connect", NULL);
+
+ if (!url || !*url) {
+ Hostname = Cat->GetStringCatInfo(g, "Host", "localhost");
+ Username = Cat->GetStringCatInfo(g, "User", "*");
+ Password = Cat->GetStringCatInfo(g, "Password", NULL);
+ Portnumber = Cat->GetIntCatInfo("Port", GetDefaultPort());
+ } else {
+ char *locdb = Database;
+
+ if (ParseURL(g, url))
+ return TRUE;
+
+ Database = locdb;
+ } // endif url
+
+ Tabname = Name;
} // endif am
if ((Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL)))
@@ -741,11 +767,6 @@ int TDBMYSQL::BindColumns(PGLOBAL g)
} // endif prep
#endif // MYSQL_PREPARED_STATEMENTS
- for (PMYCOL colp = (PMYCOL)Columns; colp; colp = (PMYCOL)colp->Next)
- if (colp->Buf_Type == TYPE_DATE)
- // Format must match DATETIME MySQL type
- ((DTVAL*)colp->GetValue())->SetFormat(g, "YYYY-MM-DD hh:mm:ss", 19);
-
return RC_OK;
} // end of BindColumns
@@ -776,6 +797,14 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
} // endif Connected
/*********************************************************************/
+ /* Take care of DATE columns. */
+ /*********************************************************************/
+ for (PMYCOL colp = (PMYCOL)Columns; colp; colp = (PMYCOL)colp->Next)
+ if (colp->Buf_Type == TYPE_DATE)
+ // Format must match DATETIME MySQL type
+ ((DTVAL*)colp->GetValue())->SetFormat(g, "YYYY-MM-DD hh:mm:ss", 19);
+
+ /*********************************************************************/
/* Allocate whatever is used for getting results. */
/*********************************************************************/
if (Mode == MODE_READ) {
@@ -1165,10 +1194,6 @@ void MYSQLCOL::InitBind(PGLOBAL g)
memset(Bind, 0, sizeof(MYSQL_BIND));
if (Buf_Type == TYPE_DATE) {
- // Default format must match DATETIME MySQL type
-// if (!((DTVAL*)Value)->IsFormatted())
- ((DTVAL*)Value)->SetFormat(g, "YYYY-MM-DD hh:mm:ss", 19);
-
Bind->buffer_type = PLGtoMYSQL(TYPE_STRING, false);
Bind->buffer = (char *)PlugSubAlloc(g,NULL, 20);
Bind->buffer_length = 20;
@@ -1231,7 +1256,7 @@ void MYSQLCOL::WriteColumn(PGLOBAL g)
#if defined(MYSQL_PREPARED_STATEMENTS)
if (((PTDBMY)To_Tdb)->Prep) {
if (Buf_Type == TYPE_DATE) {
- Value->ShowValue((char *)Bind->buffer, (int)*Bind->length);
+ Value->ShowValue((char *)Bind->buffer, (int)Bind->buffer_length);
Slen = strlen((char *)Bind->buffer);
} else if (IsTypeChar(Buf_Type))
Slen = strlen(Value->GetCharValue());
diff --git a/storage/connect/tabmysql.h b/storage/connect/tabmysql.h
index 24f8c4cdef2..16e2d650229 100644
--- a/storage/connect/tabmysql.h
+++ b/storage/connect/tabmysql.h
@@ -39,6 +39,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE m);
bool ParseURL(PGLOBAL g, char *url);
+ bool GetServerInfo(PGLOBAL g, const char *server_name);
protected:
// Members
diff --git a/storage/connect/taboccur.cpp b/storage/connect/taboccur.cpp
index 065da269caa..478edb14f9e 100644
--- a/storage/connect/taboccur.cpp
+++ b/storage/connect/taboccur.cpp
@@ -56,7 +56,7 @@ extern "C" int trace;
/***********************************************************************/
/* Prepare and count columns in the column list. */
/***********************************************************************/
-int PrepareColist(char *colist)
+static int PrepareColist(char *colist)
{
char *p, *pn;
int n = 0;
diff --git a/storage/connect/taboccur.h b/storage/connect/taboccur.h
index 10f94329703..6cfece5634e 100644
--- a/storage/connect/taboccur.h
+++ b/storage/connect/taboccur.h
@@ -137,3 +137,9 @@ class XCOLDEF: public COLDEF {
friend class TDBOCCUR;
}; // end of class XCOLDEF
+
+bool OcrColumns(PGLOBAL g, PQRYRES qrp, const char *col,
+ const char *ocr, const char *rank);
+
+bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col,
+ const char *ocr, const char *rank);
diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp
index 599f9c7e80f..ae6817344b8 100644
--- a/storage/connect/tabodbc.cpp
+++ b/storage/connect/tabodbc.cpp
@@ -324,7 +324,7 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
{
char *colist, *tabname, *sql, buf[64];
LPCSTR ownp = NULL, qualp = NULL;
- int rc, len, ncol = 0;
+ int len, ncol = 0;
bool first = true;
PTABLE tablep = To_Table;
PCOL colp;
@@ -341,7 +341,7 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
for (colp = Columns; colp; colp = colp->GetNext())
if (!colp->IsSpecial()) {
// Column name can be in UTF-8 encoding
- rc= Decode(colp->GetName(), buf, sizeof(buf));
+ /*rc=*/ Decode(colp->GetName(), buf, sizeof(buf));
if (Quote) {
if (first) {
@@ -376,7 +376,7 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
} // endif cnt
// Table name can be encoded in UTF-8
- rc = Decode(TableName, buf, sizeof(buf));
+ /*rc = */Decode(TableName, buf, sizeof(buf));
// Put table name between identifier quotes in case in contains blanks
tabname = (char*)PlugSubAlloc(g, NULL, strlen(buf) + 3);
diff --git a/storage/connect/tabpivot.h b/storage/connect/tabpivot.h
index 170c6b67ea4..0b5bf50d13b 100644
--- a/storage/connect/tabpivot.h
+++ b/storage/connect/tabpivot.h
@@ -188,3 +188,9 @@ class SRCCOL : public PRXCOL {
// Members
}; // end of class SRCCOL
+
+PQRYRES PivotColumns(PGLOBAL g, const char *tab, const char *src,
+ const char *picol, const char *fncol,
+ const char *host, const char *db,
+ const char *user, const char *pwd,
+ int port);
diff --git a/storage/connect/tabsys.cpp b/storage/connect/tabsys.cpp
index 6434e011882..c5186f42666 100644
--- a/storage/connect/tabsys.cpp
+++ b/storage/connect/tabsys.cpp
@@ -223,12 +223,13 @@ bool TDBINI::OpenDB(PGLOBAL g)
PINICOL colp;
if (Use == USE_OPEN) {
+#if 0
if (To_Kindex)
/*****************************************************************/
/* Table is to be accessed through a sorted index table. */
/*****************************************************************/
To_Kindex->Reset();
-
+#endif // 0
Section = NULL;
N = 0;
return false;
@@ -262,6 +263,7 @@ int TDBINI::ReadDB(PGLOBAL g)
/*********************************************************************/
/* Now start the pseudo reading process. */
/*********************************************************************/
+#if 0 // INI tables are not indexable
if (To_Kindex) {
/*******************************************************************/
/* Reading is by an index table. */
@@ -276,10 +278,11 @@ int TDBINI::ReadDB(PGLOBAL g)
case -3: // Same record as last non null one
return RC_OK;
default:
- Section = (char*)recpos;
+ Section = (char*)recpos; // No good on 64 bit machines
} // endswitch recpos
} else {
+#endif // 0
if (!Section)
Section = Seclist;
else
@@ -289,7 +292,7 @@ int TDBINI::ReadDB(PGLOBAL g)
htrc("INI ReadDB: section=%s N=%d\n", Section, N);
N++;
- } // endif To_Kindex
+//} // endif To_Kindex
return (*Section) ? RC_OK : RC_EF;
} // end of ReadDB
@@ -655,6 +658,7 @@ int TDBXIN::ReadDB(PGLOBAL g)
/*********************************************************************/
/* Now start the pseudo reading process. */
/*********************************************************************/
+#if 0 // XIN tables are not indexable
if (To_Kindex) {
/*******************************************************************/
/* Reading is by an index table. */
@@ -673,6 +677,7 @@ int TDBXIN::ReadDB(PGLOBAL g)
} // endswitch recpos
} else {
+#endif // 0
do {
if (!Keycur || !*Keycur) {
if (!Section)
@@ -691,7 +696,7 @@ int TDBXIN::ReadDB(PGLOBAL g)
} while (!*Keycur);
N++;
- } // endif To_Kindex
+//} // endif To_Kindex
return RC_OK;
} // end of ReadDB
diff --git a/storage/connect/tabtbl.cpp b/storage/connect/tabtbl.cpp
index 89acc53fd4a..6b90b3861aa 100644
--- a/storage/connect/tabtbl.cpp
+++ b/storage/connect/tabtbl.cpp
@@ -109,11 +109,12 @@ TBLDEF::TBLDEF(void)
/**************************************************************************/
bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
- char *tablist, *dbname;
+ char *tablist, *dbname, *def = NULL;
Desc = "Table list table";
tablist = Cat->GetStringCatInfo(g, "Tablist", "");
dbname = Cat->GetStringCatInfo(g, "Dbname", "*");
+ def = Cat->GetStringCatInfo(g, "Srcdef", NULL);
Ntables = 0;
if (*tablist) {
@@ -134,7 +135,7 @@ bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
} // endif p
// Allocate the TBLIST block for that table
- tbl = new(g) XTAB(pn);
+ tbl = new(g) XTAB(pn, def);
tbl->SetQualifier(pdb);
if (trace)
@@ -231,16 +232,28 @@ PCOL TDBTBL::InsertSpecialColumn(PGLOBAL g, PCOL scp)
bool TDBTBL::InitTableList(PGLOBAL g)
{
int n;
+ uint sln;
+ char *scs;
PTABLE tp, tabp;
PCOL colp;
PTBLDEF tdp = (PTBLDEF)To_Def;
+ PCATLG cat = To_Def->GetCat();
+ PHC hc = ((MYCAT*)cat)->GetHandler();
+ scs = hc->get_table()->s->connect_string.str;
+ sln = hc->get_table()->s->connect_string.length;
// PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath());
for (n = 0, tp = tdp->Tablep; tp; tp = tp->GetNext()) {
if (TestFil(g, To_Filter, tp)) {
tabp = new(g) XTAB(tp);
+ if (tabp->GetSrc()) {
+ // Table list is a list of connections
+ hc->get_table()->s->connect_string.str = (char*)tabp->GetName();
+ hc->get_table()->s->connect_string.length = strlen(tabp->GetName());
+ } // endif Src
+
// Get the table description block of this table
if (!(Tdbp = GetSubTable(g, tabp))) {
if (++Nbc > Maxerr)
@@ -269,6 +282,9 @@ bool TDBTBL::InitTableList(PGLOBAL g)
} // endfor tp
+ hc->get_table()->s->connect_string.str = scs;
+ hc->get_table()->s->connect_string.length = sln;
+
//NumTables = n;
To_Filter = NULL; // To avoid doing it several times
return FALSE;
diff --git a/storage/connect/tabtbl.h b/storage/connect/tabtbl.h
index 7cc2ff0b92c..6b29e8eed6e 100644
--- a/storage/connect/tabtbl.h
+++ b/storage/connect/tabtbl.h
@@ -163,3 +163,6 @@ class DllExport TDBTBM : public TDBTBL {
int Nrc; // Number of remote connections
int Nlc; // Number of local connections
}; // end of class TDBTBM
+
+
+pthread_handler_t ThreadOpen(void *p);
diff --git a/storage/connect/tabvct.cpp b/storage/connect/tabvct.cpp
index 7a16d2baf0c..8c2474d61a2 100644
--- a/storage/connect/tabvct.cpp
+++ b/storage/connect/tabvct.cpp
@@ -49,7 +49,6 @@
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
-//#define strerror(X) _strerror(X)
#define NO_ERROR 0
#else
#include <io.h>
diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp
index 9b8db7abbab..69ad6711638 100644
--- a/storage/connect/tabxml.cpp
+++ b/storage/connect/tabxml.cpp
@@ -547,6 +547,7 @@ bool TDBXML::Initialize(PGLOBAL g)
else
Nlist = TabNode->GetChildElements(g);
+ Docp->SetNofree(true); // For libxml2
#if defined(WIN32)
} catch(_com_error e) {
// We come here if a DOM command threw an error
diff --git a/storage/connect/valblk.cpp b/storage/connect/valblk.cpp
index a96dec2565c..cee4571bc0d 100644
--- a/storage/connect/valblk.cpp
+++ b/storage/connect/valblk.cpp
@@ -592,7 +592,7 @@ void CHRBLK::SetValue(char *sp, uint len, int n)
#endif
if (sp)
- memcpy(p, sp, len);
+ memcpy(p, sp, Long);
if (Blanks) {
// Suppress eventual ending zero and right fill with blanks
@@ -654,8 +654,11 @@ void CHRBLK::SetValues(PVBLK pv, int k, int n)
/***********************************************************************/
void CHRBLK::Move(int i, int j)
{
- memcpy(Chrp + j * Long, Chrp + i * Long, Long);
- MoveNull(i, j);
+ if (i != j) {
+ memcpy(Chrp + j * Long, Chrp + i * Long, Long);
+ MoveNull(i, j);
+ } // endif i
+
} // end of Move
/***********************************************************************/
diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp
index e60f3889ef5..e75a6e41557 100644
--- a/storage/connect/value.cpp
+++ b/storage/connect/value.cpp
@@ -578,19 +578,25 @@ void TYPVAL<TYPE>::SetValue_char(char *p, int n)
template <>
void TYPVAL<double>::SetValue_char(char *p, int n)
{
- char *p2, buf[32];
+ if (p) {
+ char *p2, buf[32];
- for (p2 = p + n; p < p2 && *p == ' '; p++) ;
+ for (p2 = p + n; p < p2 && *p == ' '; p++) ;
- n = min(p2 - p, 31);
- memcpy(buf, p, n);
- buf[n] = '\0';
- Tval = atof(buf);
+ n = min(p2 - p, 31);
+ memcpy(buf, p, n);
+ buf[n] = '\0';
+ Tval = atof(buf);
- if (trace > 1)
- htrc(" setting double: '%s' -> %lf\n", buf, Tval);
+ if (trace > 1)
+ htrc(" setting double: '%s' -> %lf\n", buf, Tval);
+
+ Null = false;
+ } else {
+ Reset();
+ Null = Nullable;
+ } // endif p
- Null = false;
} // end of SetValue
/***********************************************************************/
@@ -599,8 +605,14 @@ void TYPVAL<double>::SetValue_char(char *p, int n)
template <class TYPE>
void TYPVAL<TYPE>::SetValue_psz(PSZ s)
{
- Tval = GetTypedValue(s);
- Null = false;
+ if (s) {
+ Tval = GetTypedValue(s);
+ Null = false;
+ } else {
+ Reset();
+ Null = Nullable;
+ } // endif p
+
} // end of SetValue
template <>
@@ -895,17 +907,23 @@ bool TYPVAL<PSZ>::SetValue_pval(PVAL valp, bool chktype)
/***********************************************************************/
void TYPVAL<PSZ>::SetValue_char(char *p, int n)
{
- n = min(n, Len);
- strncpy(Strp, p, n);
+ if (p) {
+ n = min(n, Len);
+ strncpy(Strp, p, n);
- for (p = Strp + n - 1; (*p == ' ' || *p == '\0') && p >= Strp; p--) ;
+ for (p = Strp + n - 1; (*p == ' ' || *p == '\0') && p >= Strp; p--) ;
- *(++p) = '\0';
+ *(++p) = '\0';
- if (trace > 1)
- htrc(" Setting string to: '%s'\n", Strp);
+ if (trace > 1)
+ htrc(" Setting string to: '%s'\n", Strp);
+
+ Null = false;
+ } else {
+ Reset();
+ Null = Nullable;
+ } // endif p
- Null = false;
} // end of SetValue_char
/***********************************************************************/
@@ -913,8 +931,14 @@ void TYPVAL<PSZ>::SetValue_char(char *p, int n)
/***********************************************************************/
void TYPVAL<PSZ>::SetValue_psz(PSZ s)
{
- strncpy(Strp, s, Len);
- Null = false;
+ if (s) {
+ strncpy(Strp, s, Len);
+ Null = false;
+ } else {
+ Reset();
+ Null = Nullable;
+ } // endif s
+
} // end of SetValue_psz
/***********************************************************************/
@@ -1010,7 +1034,6 @@ void TYPVAL<PSZ>::SetValue(char c)
void TYPVAL<PSZ>::SetBinValue(void *p)
{
SetValue_char((char *)p, Len);
- Null = false;
} // end of SetBinValue
/***********************************************************************/
diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp
index 68a6bba47ec..4a0067e30be 100755
--- a/storage/connect/xindex.cpp
+++ b/storage/connect/xindex.cpp
@@ -2368,7 +2368,6 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
} // endif Mode
#else // UNIX
- int rc = 0;
int oflag = O_LARGEFILE; // Enable file size > 2G
mode_t pmod = 0;
@@ -2394,7 +2393,7 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
Hfile= global_open(g, MSGID_OPEN_ERROR_AND_STRERROR, filename, oflag, pmod);
if (Hfile == INVALID_HANDLE_VALUE) {
- rc = errno;
+ /*rc = errno;*/
#if defined(TRACE)
printf("Open: %s\n", g->Message);
#endif // TRACE