summaryrefslogtreecommitdiff
path: root/storage/connect
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2019-01-27 15:16:15 +0100
committerSergei Golubchik <serg@mariadb.org>2019-04-26 16:49:25 +0200
commite049f923924f89cb621abe2ab001d955d97d6020 (patch)
tree4c7a9c2eccbd84272441ea65934f02892d6dd812 /storage/connect
parent52eb4f172cc85bf2c9dcc515f747d9bd23089c65 (diff)
downloadmariadb-git-e049f923924f89cb621abe2ab001d955d97d6020.tar.gz
Squashed commit of connect/10.0:
commit ac275d0b4ad (connect/10.0) Author: Olivier Bertrand <bertrandop@gmail.com> Date: Wed Mar 27 12:46:20 2019 +0100 Comment out unrecognized command line options: Modified CMakeLists.txt commit 592f1f75ad6 Author: Olivier Bertrand <bertrandop@gmail.com> Date: Tue Mar 26 19:52:33 2019 +0100 Replace Command not recognized by CMake modified: CMakeLists.txt commit 00f72199b16 Author: Olivier Bertrand <bertrandop@gmail.com> Date: Tue Mar 26 18:15:08 2019 +0100 - Fix MDEV-15793: Server crash in PlugCloseFile with sql_mode='' Fixed by replacing sprinf by snprintf in ShowValue to avoid buffer overflow. It nows always use a buffer and returns int. modified: storage/connect/tabdos.cpp modified: storage/connect/tabfmt.cpp modified: storage/connect/value.cpp modified: storage/connect/value.h - Fix MDEV-18292: CONNECT Engine JDBC not able to issue simple UPDATE statement from trigger or stored procedure Was not fixed when the same table was called several times with different modes. Fixed by checking if a new statement is compatible in the start_stmt function. It nows do the same checks than external_lock. modified: storage/connect/ha_connect.cc modified: storage/connect/ha_connect.h - typo modified: storage/connect/user_connect.cc - Fix GetTableName that returned wrong value under Windows modified: storage/connect/ha_connect.cc - Fix MDEV-13136: enhance CREATE SERVER MyServerName FOREIGN DATA WRAPPER to work with CONNECT engine modified: storage/connect/tabjdbc.cpp - Add a function to retrieve User variable value (DEVELOPMENT only) modified: storage/connect/ha_connect.cc modified: storage/connect/jsonudf.cpp modified: storage/connect/jsonudf.h modified: storage/connect/tabjdbc.cpp - Fix MDEV-18192: CONNECT Engine JDBC not able to issue simple UPDATE statement from trigger or stored procedure modified: storage/connect/tabext.cpp modified: storage/connect/tabext.h modified: storage/connect/tabjdbc.cpp - Enable CONNECT tables to have triggers Update version number modified: storage/connect/ha_connect.cc - Make user and password defined in CREATE TABLE have precedence on the ones specified in a Federated Server. modified: storage/connect/tabjdbc.cpp - JSONColumns: Copy locally constant strings to fix error in OEM modules modified: storage/connect/tabjson.cpp commit 99de7f4e486 Author: Olivier Bertrand <bertrandop@gmail.com> Date: Sun Jan 27 15:16:15 2019 +0100 - Fix MDEV-18192: CONNECT Engine JDBC not able to issue simple UPDATE statement from trigger or stored procedure modified: storage/connect/tabext.cpp modified: storage/connect/tabext.h modified: storage/connect/tabjdbc.cpp - Enable CONNECT tables to have triggers Update version number modified: storage/connect/ha_connect.cc - Make user and password defined in CREATE TABLE have precedence on the ones specified in a Federated Server. modified: storage/connect/tabjdbc.cpp - JSONColumns: Copy locally constant strings to fix error in OEM modules modified: storage/connect/tabjson.cpp
Diffstat (limited to 'storage/connect')
-rw-r--r--storage/connect/CMakeLists.txt5
-rw-r--r--storage/connect/ha_connect.cc123
-rw-r--r--storage/connect/ha_connect.h3
-rw-r--r--storage/connect/json.h1
-rw-r--r--storage/connect/jsonudf.cpp50
-rw-r--r--storage/connect/tabdos.cpp42
-rw-r--r--storage/connect/tabext.cpp43
-rw-r--r--storage/connect/tabext.h5
-rw-r--r--storage/connect/tabfmt.cpp13
-rw-r--r--storage/connect/tabjdbc.cpp67
-rw-r--r--storage/connect/tabjson.cpp8
-rw-r--r--storage/connect/user_connect.cc3
-rw-r--r--storage/connect/value.cpp97
-rw-r--r--storage/connect/value.h16
14 files changed, 296 insertions, 180 deletions
diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt
index e0d05808a38..e524088623d 100644
--- a/storage/connect/CMakeLists.txt
+++ b/storage/connect/CMakeLists.txt
@@ -130,7 +130,6 @@ IF(WIN32)
OPTION(CONNECT_WITH_MSXML "Compile CONNECT storage engine with MSXML support" ON)
IF(CONNECT_WITH_MSXML)
add_definitions(-DMSX6 -DDOMDOC_SUPPORT)
- message(STATUS "MSXML library version: msxml6")
SET(MSXML_FOUND 1)
SET(CONNECT_SOURCES ${CONNECT_SOURCES} domdoc.cpp domdoc.h)
ENDIF(CONNECT_WITH_MSXML)
@@ -238,7 +237,7 @@ ENDIF(CONNECT_WITH_ODBC)
#
# JDBC with MongoDB Java Driver included but disabled if without MONGO
#
-#OPTION(CONNECT_WITH_MONGO "Compile CONNECT storage engine with MONGO support" ON)
+OPTION(CONNECT_WITH_MONGO "Compile CONNECT storage engine with MONGO support" ON)
OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON)
IF(CONNECT_WITH_JDBC)
@@ -293,7 +292,7 @@ IF(CONNECT_WITH_MONGO)
C:/mongo-c-driver/lib
D:/mongo-c-driver/lib)
ENDIF(WIN32)
- FIND_PACKAGE(libmongoc-1.0 1.7)
+ FIND_PACKAGE(libmongoc-1.0 1.7 QUIET)
IF (libmongoc-1.0_FOUND)
INCLUDE_DIRECTORIES(${MONGOC_INCLUDE_DIRS})
SET(MONGOC_LIBRARY ${MONGOC_LIBRARIES})
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 135e51e0ac1..8838bb7e696 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -170,9 +170,9 @@
#define JSONMAX 10 // JSON Default max grp size
extern "C" {
- char version[]= "Version 1.06.0008 October 06, 2018";
+ char version[]= "Version 1.06.0009 January 27, 2019";
#if defined(__WIN__)
- char compver[]= "Version 1.06.0008 " __DATE__ " " __TIME__;
+ char compver[]= "Version 1.06.0009 " __DATE__ " " __TIME__;
char slash= '\\';
#else // !__WIN__
char slash= '/';
@@ -204,6 +204,26 @@ pthread_mutex_t parmut;
pthread_mutex_t usrmut;
pthread_mutex_t tblmut;
+#if defined(DEVELOPMENT)
+char *GetUserVariable(PGLOBAL g, const uchar *varname);
+
+char *GetUserVariable(PGLOBAL g, const uchar *varname)
+{
+ char buf[1024];
+ bool b;
+ THD *thd = current_thd;
+ CHARSET_INFO *cs = system_charset_info;
+ String *str = NULL, tmp(buf, sizeof(buf), cs);
+ HASH uvars = thd->user_vars;
+ user_var_entry *uvar = (user_var_entry*)my_hash_search(&uvars, varname, 0);
+
+ if (uvar)
+ str = uvar->val_str(&b, &tmp, NOT_FIXED_DEC);
+
+ return str ? PlugDup(g, str->ptr()) : NULL;
+}; // end of GetUserVariable
+#endif // DEVELOPMENT
+
/***********************************************************************/
/* Utility functions. */
/***********************************************************************/
@@ -1795,7 +1815,9 @@ PCSZ ha_connect::GetDBName(PCSZ name)
const char *ha_connect::GetTableName(void)
{
- return tshp ? tshp->table_name.str : table_share->table_name.str;
+ const char *path= tshp ? tshp->path.str : table_share->path.str;
+ const char *name= strrchr(path, slash);
+ return name ? name+1 : path;
} // end of GetTableName
char *ha_connect::GetPartName(void)
@@ -1914,9 +1936,11 @@ int ha_connect::OpenTable(PGLOBAL g, bool del)
break;
} // endswitch xmode
- if (xmod != MODE_INSERT || tdbp->GetAmType() == TYPE_AM_MYSQL
- || tdbp->GetAmType() == TYPE_AM_ODBC
- || tdbp->GetAmType() == TYPE_AM_JDBC) {
+ // g->More is 1 when executing commands from triggers
+ if (!g->More && (xmod != MODE_INSERT
+ || tdbp->GetAmType() == TYPE_AM_MYSQL
+ || tdbp->GetAmType() == TYPE_AM_ODBC
+ || tdbp->GetAmType() == TYPE_AM_JDBC)) {
// Get the list of used fields (columns)
char *p;
unsigned int k1, k2, n1, n2;
@@ -4631,7 +4655,9 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
break;
case SQLCOM_CREATE_VIEW:
case SQLCOM_DROP_VIEW:
- newmode= MODE_ANY;
+ case SQLCOM_CREATE_TRIGGER:
+ case SQLCOM_DROP_TRIGGER:
+ newmode= MODE_ANY;
break;
case SQLCOM_ALTER_TABLE:
*chk= true;
@@ -4701,8 +4727,24 @@ int ha_connect::start_stmt(THD *thd, thr_lock_type lock_type)
break;
} // endswitch mode
- xmod= CheckMode(g, thd, newmode, &chk, &cras);
- DBUG_RETURN((xmod == MODE_ERROR) ? HA_ERR_INTERNAL_ERROR : 0);
+ if (newmode == MODE_ANY) {
+ if (CloseTable(g)) {
+ // Make error a warning to avoid crash
+ push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
+ rc = 0;
+ } // endif Close
+
+ locked = 0;
+ xmod = MODE_ANY; // For info commands
+ DBUG_RETURN(rc);
+ } // endif MODE_ANY
+
+ newmode = CheckMode(g, thd, newmode, &chk, &cras);
+
+ if (newmode == MODE_ERROR)
+ DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+
+ DBUG_RETURN(check_stmt(g, newmode, cras));
} // end of start_stmt
/**
@@ -4884,21 +4926,16 @@ int ha_connect::external_lock(THD *thd, int lock_type)
// Make it a warning to avoid crash
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
rc= 0;
- //my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
- //rc = HA_ERR_INTERNAL_ERROR;
} // endif Close
locked= 0;
-// m_lock_type= lock_type;
xmod= MODE_ANY; // For info commands
DBUG_RETURN(rc);
- } // endif MODE_ANY
- else
- if (check_privileges(thd, options, table->s->db.str)) {
- strcpy(g->Message, "This operation requires the FILE privilege");
- htrc("%s\n", g->Message);
- DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
- } // endif check_privileges
+ } else if (check_privileges(thd, options, table->s->db.str)) {
+ strcpy(g->Message, "This operation requires the FILE privilege");
+ htrc("%s\n", g->Message);
+ DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+ } // endif check_privileges
DBUG_ASSERT(table && table->s);
@@ -4909,43 +4946,31 @@ int ha_connect::external_lock(THD *thd, int lock_type)
if (newmode == MODE_ERROR)
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
- // If this is the start of a new query, cleanup the previous one
+ DBUG_RETURN(check_stmt(g, newmode, cras));
+} // end of external_lock
+
+
+int ha_connect::check_stmt(PGLOBAL g, MODE newmode, bool cras)
+{
+ int rc = 0;
+ DBUG_ENTER("ha_connect::check_stmt");
+
+ // If this is the start of a new query, cleanup the previous one
if (xp->CheckCleanup()) {
tdbp= NULL;
valid_info= false;
- } // endif CheckCleanup
-
-#if 0
- if (xcheck) {
- // This must occur after CheckCleanup
- if (!g->Xchk) {
- g->Xchk= new(g) XCHK;
- ((PCHK)g->Xchk)->oldsep= GetBooleanOption("Sepindex", false);
- ((PCHK)g->Xchk)->oldpix= GetIndexInfo();
- } // endif Xchk
-
- } else
- g->Xchk= NULL;
-#endif // 0
+ } // endif CheckCleanup
if (cras)
g->Createas= 1; // To tell external tables of a multi-table command
- if (trace(1)) {
-#if 0
- htrc("xcheck=%d cras=%d\n", xcheck, cras);
-
- if (xcheck)
- htrc("oldsep=%d oldpix=%p\n",
- ((PCHK)g->Xchk)->oldsep, ((PCHK)g->Xchk)->oldpix);
-#endif // 0
- htrc("Calling CntCheckDB db=%s cras=%d\n", GetDBName(NULL), cras);
- } // endif trace
+ if (trace(1))
+ htrc("Calling CntCheckDB db=%s cras=%d\n", GetDBName(NULL), cras);
// Set or reset the good database environment
if (CntCheckDB(g, this, GetDBName(NULL))) {
- htrc("%p external_lock: %s\n", this, g->Message);
- rc= HA_ERR_INTERNAL_ERROR;
+ htrc("%p check_stmt: %s\n", this, g->Message);
+ rc= HA_ERR_INTERNAL_ERROR;
// This can NOT be called without open called first, but
// the table can have been closed since then
} else if (!tdbp || xp->CheckQuery(valid_query_id) || xmod != newmode) {
@@ -4965,10 +4990,10 @@ int ha_connect::external_lock(THD *thd, int lock_type)
} // endif tdbp
if (trace(1))
- htrc("external_lock: rc=%d\n", rc);
+ htrc("check_stmt: rc=%d\n", rc);
DBUG_RETURN(rc);
-} // end of external_lock
+} // end of check_stmt
/**
@@ -7310,7 +7335,7 @@ maria_declare_plugin(connect)
0x0106, /* version number (1.06) */
NULL, /* status variables */
connect_system_variables, /* system variables */
- "1.06.0008", /* string version */
+ "1.06.0009", /* string version */
MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
}
maria_declare_plugin_end;
diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h
index 13c9aa4835b..de61f868038 100644
--- a/storage/connect/ha_connect.h
+++ b/storage/connect/ha_connect.h
@@ -511,7 +511,8 @@ private:
protected:
bool check_privileges(THD *thd, PTOS options, char *dbn, bool quick=false);
MODE CheckMode(PGLOBAL g, THD *thd, MODE newmode, bool *chk, bool *cras);
- char *GetDBfromName(const char *name);
+ int check_stmt(PGLOBAL g, MODE newmode, bool cras);
+ char *GetDBfromName(const char *name);
// Members
static ulong num; // Tracable handler number
diff --git a/storage/connect/json.h b/storage/connect/json.h
index cc394401cc3..1d058ad575f 100644
--- a/storage/connect/json.h
+++ b/storage/connect/json.h
@@ -299,4 +299,3 @@ class JVALUE : public JSON {
PJVAL Next; // Next value in array
bool Del; // True when deleted
}; // end of class JVALUE
-
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index d5a3a840173..df9c7200416 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -1666,7 +1666,8 @@ static PCSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i)
if (args->arg_count > (unsigned)i) {
int j = 0, n = args->attribute_lengths[i];
my_bool b; // true if attribute is zero terminated
- PSZ p, s = args->attributes[i];
+ PSZ p;
+ PCSZ s = args->attributes[i];
if (s && *s && (n || *s == '\'')) {
if ((b = (!n || !s[n])))
@@ -5805,6 +5806,52 @@ char *envar(UDF_INIT *initid, UDF_ARGS *args, char *result,
return str;
} // end of envar
+#if defined(DEVELOPMENT)
+extern char *GetUserVariable(PGLOBAL g, const uchar *varname);
+
+/*********************************************************************************/
+/* Utility function returning a user variable value. */
+/*********************************************************************************/
+my_bool uvar_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+ unsigned long reslen, memlen;
+
+ if (args->arg_count != 1) {
+ strcpy(message, "Unique argument must be a user variable name");
+ return true;
+ } else
+ CalcLen(args, false, reslen, memlen, true);
+
+ initid->maybe_null = true;
+ return JsonInit(initid, args, message, true, reslen, memlen, 2048);
+} // end of uvar_init
+
+char *uvar(UDF_INIT *initid, UDF_ARGS *args, char *result,
+ unsigned long *res_length, char *is_null, char *)
+{
+ char *str, varname[256];
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+ int n = MY_MIN(args->lengths[0], sizeof(varname) - 1);
+
+ PlugSubSet(g->Sarea, g->Sarea_Size);
+ memcpy(varname, args->args[0], n);
+ varname[n] = 0;
+
+ if (!(str = GetUserVariable(g, (const uchar*)&varname))) {
+ *res_length = 0;
+ *is_null = 1;
+ } else
+ *res_length = strlen(str);
+
+ return str;
+} // end of uvar
+
+void uvar_deinit(UDF_INIT* initid)
+{
+ JsonFreeMem((PGLOBAL)initid->ptr);
+} // end of uvar_deinit
+#endif // DEVELOPMENT
+
/*********************************************************************************/
/* Returns the distinct number of B occurences in A. */
/*********************************************************************************/
@@ -5851,4 +5898,3 @@ long long countin(UDF_INIT *initid, UDF_ARGS *args, char *result,
free(str2);
return n;
} // end of countin
-
diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp
index 29cbbb35765..4f6e2c81744 100644
--- a/storage/connect/tabdos.cpp
+++ b/storage/connect/tabdos.cpp
@@ -1,11 +1,11 @@
/************* TabDos C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABDOS */
/* ------------- */
-/* Version 4.9.3 */
+/* Version 4.9.4 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 1998-2017 */
+/* (C) Copyright to the author Olivier BERTRAND 1998-2019 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -2492,8 +2492,10 @@ bool DOSCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
} // endif's Value, Buf_Type
// Allocate the buffer used in WriteColumn for numeric columns
- if (!Buf && IsTypeNum(Buf_Type))
- Buf = (char*)PlugSubAlloc(g, NULL, MY_MAX(32, Long + Dcm + 1));
+ if (!Buf && IsTypeNum(Buf_Type))
+ Buf = (char*)PlugSubAlloc(g, NULL, MY_MAX(64, Long + 1));
+ else // Text columns do not need additional buffer
+ Buf = (char*)Value->GetTo_Val();
// Because Colblk's have been made from a copy of the original TDB in
// case of Update, we must reset them to point to the original one.
@@ -2603,8 +2605,8 @@ void DOSCOL::ReadColumn(PGLOBAL g)
/***********************************************************************/
void DOSCOL::WriteColumn(PGLOBAL g)
{
- char *p, *p2, fmt[32];
- int i, k, len, field;
+ char *p, fmt[32];
+ int i, k, n, len, field;
PTDBDOS tdbp = (PTDBDOS)To_Tdb;
if (trace(2))
@@ -2679,8 +2681,8 @@ void DOSCOL::WriteColumn(PGLOBAL g)
case TYPE_DOUBLE:
case TYPE_DECIM:
strcpy(fmt, (Ldz) ? "%0*.*lf" : "%*.*lf");
- sprintf(Buf, fmt, field + ((Nod && Dcm) ? 1 : 0),
- Dcm, Value->GetFloatValue());
+ len = field + ((Nod && Dcm) ? 1 : 0);
+ snprintf(Buf, len, fmt, len, Dcm, Value->GetFloatValue());
len = strlen(Buf);
if (Nod && Dcm)
@@ -2699,35 +2701,37 @@ void DOSCOL::WriteColumn(PGLOBAL g)
throw 31;
} // endswitch BufType
- p2 = Buf;
+ n = strlen(Buf);
} else // Standard CONNECT format
- p2 = Value->ShowValue(Buf, field);
+ n = Value->ShowValue(Buf, field);
if (trace(1))
- htrc("new length(%p)=%d\n", p2, strlen(p2));
+ htrc("new length(%p)=%d\n", Buf, n);
- if ((len = strlen(p2)) > field) {
- sprintf(g->Message, MSG(VALUE_TOO_LONG), p2, Name, field);
+ if ((len = n) > field) {
+ char *p = Value->GetCharString(Buf);
+
+ sprintf(g->Message, MSG(VALUE_TOO_LONG), p, Name, field);
throw 31;
} else if (Dsp)
for (i = 0; i < len; i++)
- if (p2[i] == '.')
- p2[i] = Dsp;
+ if (Buf[i] == '.')
+ Buf[i] = Dsp;
if (trace(2))
- htrc("buffer=%s\n", p2);
+ htrc("buffer=%s\n", Buf);
/*******************************************************************/
/* Updating must be done only when not in checking pass. */
/*******************************************************************/
if (Status) {
memset(p, ' ', field);
- memcpy(p, p2, len);
+ memcpy(p, Buf, len);
if (trace(2))
htrc(" col write: '%.*s'\n", len, p);
- } // endif Use
+ } // endif Status
} else // BIN compressed table
/*******************************************************************/
@@ -2738,7 +2742,7 @@ void DOSCOL::WriteColumn(PGLOBAL g)
sprintf(g->Message, MSG(BIN_F_TOO_LONG),
Name, Value->GetSize(), Long);
throw 31;
- } // endif
+ } // endif
} // end of WriteColumn
diff --git a/storage/connect/tabext.cpp b/storage/connect/tabext.cpp
index f2d5eb0e69d..e9c7b2490d8 100644
--- a/storage/connect/tabext.cpp
+++ b/storage/connect/tabext.cpp
@@ -1,7 +1,7 @@
/************* Tabext C++ Functions Source Code File (.CPP) ************/
-/* Name: TABEXT.CPP Version 1.0 */
+/* Name: TABEXT.CPP Version 1.1 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2017 - 2019 */
/* */
/* This file contains the TBX, TDB and OPJOIN classes functions. */
/***********************************************************************/
@@ -446,6 +446,43 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
} // end of MakeSQL
/***********************************************************************/
+/* Remove the NAME_CONST functions that are added by procedures. */
+/***********************************************************************/
+void TDBEXT::RemoveConst(PGLOBAL g, char *stmt)
+{
+ char *p, *p2;
+ char val[1025], nval[1025];
+ int n, nc;
+
+ while ((p = strstr(stmt, "NAME_CONST")))
+ if ((n = sscanf(p, "%*[^,],%1024[^)])%n", val, &nc))) {
+ if (trace(33))
+ htrc("p=%s\nn=%d val=%s nc=%d\n", p, n, val, nc);
+
+ *p = 0;
+
+ if ((p2 = strstr(val, "'"))) {
+ if ((n = sscanf(p2, "%*['\\]%1024[^'\\]", nval))) {
+ if (trace(33))
+ htrc("p2=%s\nn=%d nval=%s\n", p2, n, nval);
+
+ strcat(strcat(strcat(strcat(stmt, "'"), nval), "'"), p + nc);
+ } else
+ break;
+
+ } else
+ strcat(strcat(strcat(strcat(stmt, "("), val), ")"), p + nc);
+
+ if (trace(33))
+ htrc("stmt=%s\n", stmt);
+
+ } else
+ break;
+
+ return;
+} // end of RemoveConst
+
+/***********************************************************************/
/* MakeCommand: make the Update or Delete statement to send to the */
/* MySQL server. Limited to remote values and filtering. */
/***********************************************************************/
@@ -524,6 +561,8 @@ bool TDBEXT::MakeCommand(PGLOBAL g)
stmt[i++] = (Qrystr[k] == '`') ? q : Qrystr[k];
} while (Qrystr[k++]);
+ RemoveConst(g, stmt);
+
if (body)
strcat(stmt, body);
diff --git a/storage/connect/tabext.h b/storage/connect/tabext.h
index 6b67c2ab5ed..5fef1b9ece0 100644
--- a/storage/connect/tabext.h
+++ b/storage/connect/tabext.h
@@ -1,7 +1,7 @@
/*************** Tabext H Declares Source Code File (.H) ***************/
-/* Name: TABEXT.H Version 1.0 */
+/* Name: TABEXT.H Version 1.1 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2017 - 2019 */
/* */
/* This is the EXTDEF, TABEXT and EXTCOL classes definitions. */
/***********************************************************************/
@@ -130,6 +130,7 @@ protected:
virtual bool MakeSQL(PGLOBAL g, bool cnt);
//virtual bool MakeInsert(PGLOBAL g);
virtual bool MakeCommand(PGLOBAL g);
+ void RemoveConst(PGLOBAL g, char *stmt);
int Decode(PCSZ utf, char *buf, size_t n);
// Members
diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp
index 63fa2a63668..02720a3089a 100644
--- a/storage/connect/tabfmt.cpp
+++ b/storage/connect/tabfmt.cpp
@@ -1485,8 +1485,8 @@ void CSVCOL::ReadColumn(PGLOBAL g)
/***********************************************************************/
void CSVCOL::WriteColumn(PGLOBAL g)
{
- char *p, buf[64];
- int flen;
+ char *p;
+ int n, flen;
PTDBCSV tdbp = (PTDBCSV)To_Tdb;
if (trace(2))
@@ -1508,13 +1508,14 @@ void CSVCOL::WriteColumn(PGLOBAL g)
/*********************************************************************/
/* Get the string representation of the column value. */
/*********************************************************************/
- p = Value->ShowValue(buf);
+ p = Value->GetCharString(Buf);
+ n = strlen(p);
if (trace(2))
- htrc("new length(%p)=%d\n", p, strlen(p));
+ htrc("new length(%p)=%d\n", p, n);
- if ((signed)strlen(p) > flen) {
- sprintf(g->Message, MSG(BAD_FLD_LENGTH), Name, p, flen,
+ if (n > flen) {
+ sprintf(g->Message, MSG(BAD_FLD_LENGTH), Name, p, n,
tdbp->RowNumber(g), tdbp->GetFile(g));
throw 34;
} else if (Dsp)
diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp
index adb3fc4fb51..c6b2802c1f6 100644
--- a/storage/connect/tabjdbc.cpp
+++ b/storage/connect/tabjdbc.cpp
@@ -1,11 +1,11 @@
/************* TabJDBC C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: TABJDBC */
/* ------------- */
-/* Version 1.2 */
+/* Version 1.3 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 2016-2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2016-2019 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -185,10 +185,10 @@ int JDBCDEF::ParseURL(PGLOBAL g, char *url, bool b)
} else // host is a URL
Url = PlugDup(g, server->host);
- if (server->username)
+ if (!Username && server->username)
Username = PlugDup(g, server->username);
- if (server->password)
+ if (!Password && server->password)
Password = PlugDup(g, server->password);
return RC_NF;
@@ -558,33 +558,42 @@ bool TDBJDBC::OpenDB(PGLOBAL g)
this, Tdb_No, Use, Mode);
if (Use == USE_OPEN) {
- /*******************************************************************/
- /* Table already open, just replace it at its beginning. */
- /*******************************************************************/
- if (Memory == 1) {
- if ((Qrp = Jcp->AllocateResult(g, this)))
- Memory = 2; // Must be filled
- else
- Memory = 0; // Allocation failed, don't use it
-
- } else if (Memory == 2)
- Memory = 3; // Ok to use memory result
-
- if (Memory < 3) {
- // Method will depend on cursor type
- if ((Rbuf = Query ? Jcp->Rewind(Query->GetStr()) : 0) < 0)
- if (Mode != MODE_READX) {
- Jcp->Close();
- return true;
- } else
- Rbuf = 0;
+ if (Mode == MODE_READ || Mode == MODE_READX) {
+ /*****************************************************************/
+ /* Table already open, just replace it at its beginning. */
+ /*****************************************************************/
+ if (Memory == 1) {
+ if ((Qrp = Jcp->AllocateResult(g, this)))
+ Memory = 2; // Must be filled
+ else
+ Memory = 0; // Allocation failed, don't use it
- } else
- Rbuf = Qrp->Nblin;
+ } else if (Memory == 2)
+ Memory = 3; // Ok to use memory result
+
+ if (Memory < 3) {
+ // Method will depend on cursor type
+ if ((Rbuf = Query ? Jcp->Rewind(Query->GetStr()) : 0) < 0)
+ if (Mode != MODE_READX) {
+ Jcp->Close();
+ return true;
+ } else
+ Rbuf = 0;
+
+ } else
+ Rbuf = Qrp->Nblin;
+
+ CurNum = 0;
+ Fpos = 0;
+ Curpos = 1;
+ } else if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
+ // new update coming from a trigger or procedure
+ Query = NULL;
+ SetCondFil(NULL);
+ Qrystr = To_Def->GetStringCatInfo(g, "Query_String", "?");
+ } else { //if (Mode == MODE_INSERT)
+ } // endif Mode
- CurNum = 0;
- Fpos = 0;
- Curpos = 1;
return false;
} // endif use
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index c0d36efcf42..afab52aa282 100644
--- a/storage/connect/tabjson.cpp
+++ b/storage/connect/tabjson.cpp
@@ -1,6 +1,6 @@
/************* tabjson C++ Program Source Code File (.CPP) *************/
-/* PROGRAM NAME: tabjson Version 1.6 */
-/* (C) Copyright to the author Olivier BERTRAND 2014 - 2018 */
+/* PROGRAM NAME: tabjson Version 1.7 */
+/* (C) Copyright to the author Olivier BERTRAND 2014 - 2019 */
/* This program are the JSON class DB execution routines. */
/***********************************************************************/
@@ -110,8 +110,8 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
buftyp, fldtyp, length, false, false);
crp = qrp->Colresp->Next->Next->Next->Next->Next->Next;
- crp->Name = "Nullable";
- crp->Next->Name = "Jpath";
+ crp->Name = PlugDup(g, "Nullable");
+ crp->Next->Name = PlugDup(g, "Jpath");
if (info || !qrp)
return qrp;
diff --git a/storage/connect/user_connect.cc b/storage/connect/user_connect.cc
index a2a8faf9b38..d366e0222df 100644
--- a/storage/connect/user_connect.cc
+++ b/storage/connect/user_connect.cc
@@ -177,7 +177,8 @@ bool user_connect::CheckCleanup(bool force)
g->Createas = 0;
g->Alchecked = 0;
g->Mrr = 0;
- last_query_id= thdp->query_id;
+ g->More = 0;
+ last_query_id= thdp->query_id;
if (trace(65) && !force)
printf("=====> Begin new query %llu\n", last_query_id);
diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp
index e159efaa989..d9330a68a15 100644
--- a/storage/connect/value.cpp
+++ b/storage/connect/value.cpp
@@ -1,7 +1,7 @@
/************* Value C++ Functions Source Code File (.CPP) *************/
-/* Name: VALUE.CPP Version 2.8 */
+/* Name: VALUE.CPP Version 2.9 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2001-2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2001-2019 */
/* */
/* This file contains the VALUE and derived classes family functions. */
/* These classes contain values of different types. They are used so */
@@ -882,18 +882,16 @@ bool TYPVAL<TYPE>::GetBinValue(void *buf, int buflen, bool go)
/* TYPVAL ShowValue: get string representation of a typed value. */
/***********************************************************************/
template <class TYPE>
-char *TYPVAL<TYPE>::ShowValue(char *buf, int len)
+int TYPVAL<TYPE>::ShowValue(char *buf, int len)
{
- sprintf(buf, Xfmt, len, Tval);
- return buf;
+ return snprintf(buf, len + 1, Xfmt, len, Tval);
} // end of ShowValue
template <>
-char *TYPVAL<double>::ShowValue(char *buf, int len)
+int TYPVAL<double>::ShowValue(char *buf, int len)
{
- // TODO: use snprintf to avoid possible overflow
- sprintf(buf, Xfmt, len, Prec, Tval);
- return buf;
+ // TODO: use a more appropriate format to avoid possible truncation
+ return snprintf(buf, len + 1, Xfmt, len, Prec, Tval);
} // end of ShowValue
/***********************************************************************/
@@ -1588,10 +1586,17 @@ bool TYPVAL<PSZ>::GetBinValue(void *buf, int buflen, bool go)
/***********************************************************************/
/* STRING ShowValue: get string representation of a char value. */
/***********************************************************************/
-char *TYPVAL<PSZ>::ShowValue(char *, int)
- {
- return Strp;
- } // end of ShowValue
+int TYPVAL<PSZ>::ShowValue(char *buf, int buflen)
+{
+ int len = (Null) ? 0 : strlen(Strp);
+
+ if (buf && buf != Strp) {
+ memset(buf, ' ', buflen + 1);
+ memcpy(buf, Strp, MY_MIN(len, buflen));
+ } // endif buf
+
+ return len;
+} // end of ShowValue
/***********************************************************************/
/* STRING GetCharString: get string representation of a char value. */
@@ -1800,10 +1805,9 @@ void DECVAL::Reset(void)
/***********************************************************************/
/* DECIMAL ShowValue: get string representation right justified. */
/***********************************************************************/
-char *DECVAL::ShowValue(char *buf, int len)
+int DECVAL::ShowValue(char *buf, int len)
{
- sprintf(buf, Xfmt, len, Strp);
- return buf;
+ return snprintf(buf, len + 1, Xfmt, len, Strp);
} // end of ShowValue
/***********************************************************************/
@@ -1868,14 +1872,13 @@ int DECVAL::CompareValue(PVAL vp)
BINVAL::BINVAL(PGLOBAL g, void *p, int cl, int n) : VALUE(TYPE_BIN)
{
assert(g);
-//Len = n;
- Len = (g) ? n : (p) ? strlen((char*)p) : 0;
+ Len = n;
Clen = cl;
Binp = PlugSubAlloc(g, NULL, Clen + 1);
memset(Binp, 0, Clen + 1);
if (p)
- memcpy(Binp, p, Len);
+ memcpy(Binp, p, MY_MIN(Len,Clen));
Chrp = NULL;
} // end of BINVAL constructor
@@ -2264,14 +2267,12 @@ bool BINVAL::GetBinValue(void *buf, int buflen, bool go)
/***********************************************************************/
/* BINVAL ShowValue: get string representation of a binary value. */
/***********************************************************************/
-char *BINVAL::ShowValue(char *buf, int len)
- {
- //int n = MY_MIN(Len, len / 2);
-
- //sprintf(buf, GetXfmt(), n, Binp);
- //return buf;
- return (char*)Binp;
- } // end of ShowValue
+int BINVAL::ShowValue(char *buf, int len)
+{
+ memset(buf, 0, len + 1);
+ memcpy(buf, Binp, MY_MIN(len, Len));
+ return Len;
+} // end of ShowValue
/***********************************************************************/
/* BINVAL GetCharString: get string representation of a binary value. */
@@ -2749,43 +2750,33 @@ char *DTVAL::GetCharString(char *p)
/***********************************************************************/
/* DTVAL ShowValue: get string representation of a date value. */
/***********************************************************************/
-char *DTVAL::ShowValue(char *buf, int len)
- {
- if (Pdtp) {
- char *p;
+int DTVAL::ShowValue(char *buf, int len)
+{
+ int rv = 0;
+ if (Pdtp) {
if (!Null) {
- size_t m, n = 0;
+ size_t n = 0, m = len + 1;
struct tm tm, *ptm = GetGmTime(&tm);
-
-
-
- if (Len < len) {
- p = buf;
- m = len;
- } else {
- p = Sdate;
- m = Len + 1;
- } // endif Len
if (ptm)
- n = strftime(p, m, Pdtp->OutFmt, ptm);
+ n = strftime(buf, m, Pdtp->OutFmt, ptm);
if (!n) {
- *p = '\0';
- strncat(p, "Error", m);
- } // endif n
+ *buf = '\0';
+ strncat(buf, "Error", m);
+ rv = 5;
+ } else
+ rv = (int)n;
- } else {
- p = buf;
- *p = '\0'; // DEFAULT VALUE ???
- } // endif Null
+ } else
+ *buf = '\0'; // DEFAULT VALUE ???
- return p;
} else
- return TYPVAL<int>::ShowValue(buf, len);
+ rv = TYPVAL<int>::ShowValue(buf, len);
- } // end of ShowValue
+ return rv;
+} // end of ShowValue
#if 0 // Not used by CONNECT
/***********************************************************************/
diff --git a/storage/connect/value.h b/storage/connect/value.h
index 6613e25100a..4f7d9a440fa 100644
--- a/storage/connect/value.h
+++ b/storage/connect/value.h
@@ -1,7 +1,7 @@
/**************** Value H Declares Source Code File (.H) ***************/
-/* Name: VALUE.H Version 2.3 */
+/* Name: VALUE.H Version 2.4 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2001-2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2001-2019 */
/* */
/* This file contains the VALUE and derived classes declares. */
/***********************************************************************/
@@ -117,7 +117,7 @@ class DllExport VALUE : public BLOCK {
virtual void SetValue_pvblk(PVBLK blk, int n) = 0;
virtual void SetBinValue(void *p) = 0;
virtual bool GetBinValue(void *buf, int buflen, bool go) = 0;
- virtual char *ShowValue(char *buf, int len = 0) = 0;
+ virtual int ShowValue(char *buf, int len) = 0;
virtual char *GetCharString(char *p) = 0;
virtual bool IsEqual(PVAL vp, bool chktype) = 0;
virtual bool Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op);
@@ -229,7 +229,7 @@ class DllExport TYPVAL : public VALUE {
virtual void SetValue_pvblk(PVBLK blk, int n);
virtual void SetBinValue(void *p);
virtual bool GetBinValue(void *buf, int buflen, bool go);
- virtual char *ShowValue(char *buf, int);
+ virtual int ShowValue(char *buf, int len);
virtual char *GetCharString(char *p);
virtual bool IsEqual(PVAL vp, bool chktype);
virtual bool Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op);
@@ -302,7 +302,7 @@ class DllExport TYPVAL<PSZ>: public VALUE {
virtual void SetBinValue(void *p);
virtual int CompareValue(PVAL vp);
virtual bool GetBinValue(void *buf, int buflen, bool go);
- virtual char *ShowValue(char *buf, int);
+ virtual int ShowValue(char *buf, int len);
virtual char *GetCharString(char *p);
virtual bool IsEqual(PVAL vp, bool chktype);
virtual bool Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op);
@@ -334,7 +334,7 @@ class DllExport DECVAL: public TYPVAL<PSZ> {
// Methods
virtual bool GetBinValue(void *buf, int buflen, bool go);
- virtual char *ShowValue(char *buf, int);
+ virtual int ShowValue(char *buf, int len);
virtual bool IsEqual(PVAL vp, bool chktype);
virtual int CompareValue(PVAL vp);
@@ -387,7 +387,7 @@ class DllExport BINVAL: public VALUE {
virtual void SetBinValue(void *p);
virtual bool GetBinValue(void *buf, int buflen, bool go);
virtual int CompareValue(PVAL) {assert(false); return 0;}
- virtual char *ShowValue(char *buf, int);
+ virtual int ShowValue(char *buf, int len);
virtual char *GetCharString(char *p);
virtual bool IsEqual(PVAL vp, bool chktype);
virtual bool FormatValue(PVAL vp, PCSZ fmt);
@@ -415,7 +415,7 @@ class DllExport DTVAL : public TYPVAL<int> {
virtual void SetValue_psz(PCSZ s);
virtual void SetValue_pvblk(PVBLK blk, int n);
virtual char *GetCharString(char *p);
- virtual char *ShowValue(char *buf, int);
+ virtual int ShowValue(char *buf, int len);
virtual bool FormatValue(PVAL vp, PCSZ fmt);
bool SetFormat(PGLOBAL g, PCSZ fmt, int len, int year = 0);
bool SetFormat(PGLOBAL g, PVAL valp);