diff options
author | Alexander Barkov <bar@mariadb.org> | 2013-07-08 17:21:47 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2013-07-08 17:21:47 +0400 |
commit | 17f3ae267f3b8c189be1671f86902f24ae79cdeb (patch) | |
tree | 24881fdc74435298e37750fb92be6cfaa0bc0f14 | |
parent | 0b116de7c58db3e483964d00e6a3803947bfaf4f (diff) | |
parent | f3078f01b24bed421c015aec2c1646fa25934c13 (diff) | |
download | mariadb-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
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 |