summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2018-12-02 00:25:05 +0100
committerSergei Golubchik <serg@mariadb.org>2019-01-25 10:06:16 +0100
commite6fcd7230954c6111bba63e7f7201fc81e50178e (patch)
tree7a434fd88521516093d8d82cf3da8a03c6b4a651
parent38ad46e0050939b0c4882eb0a339c84c4db8beb0 (diff)
downloadmariadb-git-e6fcd7230954c6111bba63e7f7201fc81e50178e.tar.gz
Squashed commit of connect/10.0:
commit 6a6a1f37798 Author: Olivier Bertrand <bertrandop@gmail.com> Date: Fri Jan 4 12:31:52 2019 +0100 - Fix a few bug mainly concerning discovery and call from OEM (and prepare new table types) modified: storage/connect/tabjson.cpp modified: storage/connect/tabjson.h modified: storage/connect/tabxml.cpp modified: storage/connect/tabxml.h - Fix wrong line estimate modified: storage/connect/mysql-test/connect/r/part_table.result modified: storage/connect/mysql-test/connect/t/part_table.test commit bd7d2e912d9 Author: Olivier Bertrand <bertrandop@gmail.com> Date: Tue Dec 4 23:35:09 2018 +0100 Fix wrong version number commit 4933680e7ab Author: Olivier Bertrand <bertrandop@gmail.com> Date: Sun Dec 2 00:25:05 2018 +0100 - Make PlugSubAlloc to be exportable Suppress unused parameter from PlugSubSet modified: storage/connect/global.h modified: storage/connect/plugutil.cpp modified: storage/connect/jsonudf.cpp modified: storage/connect/tabjson.cpp modified: storage/connect/user_connect.cc - Fix a bug making column catalog XML tables fail modified: storage/connect/tabxml.cpp - Comment out wrong message modified: storage/connect/ha_connect.cc - Update error message when sorting an ODBC table fails modified: storage/connect/tabodbc.cpp - Add error message when gettting an address from an OEM fails. modified: storage/connect/reldef.cpp - Make some modifications useful for OEM module writting Export discovery functions for CSV, JDBC and XML Remove unuseful include from tabjson.h Move TDBXML::data_charset function from header file to source modified: storage/connect/tabfmt.h modified: storage/connect/tabjson.h modified: storage/connect/tabxml.cpp modified: storage/connect/tabxml.h - Update test result modified: storage/connect/mysql-test/connect/r/jdbc_oracle.result
-rw-r--r--storage/connect/global.h6
-rw-r--r--storage/connect/ha_connect.cc4
-rw-r--r--storage/connect/jsonudf.cpp12
-rw-r--r--storage/connect/mysql-test/connect/r/jdbc_oracle.result18
-rw-r--r--storage/connect/mysql-test/connect/r/jdbc_postgresql.result10
-rw-r--r--storage/connect/mysql-test/connect/r/part_table.result4
-rw-r--r--storage/connect/mysql-test/connect/t/part_table.test2
-rw-r--r--storage/connect/plugutil.cpp28
-rw-r--r--storage/connect/reldef.cpp11
-rw-r--r--storage/connect/tabfmt.h2
-rw-r--r--storage/connect/tabjson.cpp52
-rw-r--r--storage/connect/tabjson.h8
-rw-r--r--storage/connect/tabodbc.cpp317
-rw-r--r--storage/connect/tabxml.cpp292
-rw-r--r--storage/connect/tabxml.h6
-rw-r--r--storage/connect/user_connect.cc4
16 files changed, 426 insertions, 350 deletions
diff --git a/storage/connect/global.h b/storage/connect/global.h
index 36e8a311124..dc1e149745f 100644
--- a/storage/connect/global.h
+++ b/storage/connect/global.h
@@ -219,11 +219,11 @@ DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR prefix, LPCSTR name, LPCSTR dir);
DllExport BOOL PlugIsAbsolutePath(LPCSTR path);
DllExport bool AllocSarea(PGLOBAL, uint);
DllExport void FreeSarea(PGLOBAL);
-DllExport BOOL PlugSubSet(PGLOBAL, void *, uint);
+DllExport BOOL PlugSubSet(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, ...);
-//DllExport int GetTraceValue(void);
DllExport uint GetTraceValue(void);
#if defined(__cplusplus)
@@ -233,6 +233,6 @@ DllExport uint GetTraceValue(void);
/***********************************************************************/
/* Non exported routine declarations. */
/***********************************************************************/
-void *PlugSubAlloc(PGLOBAL, void *, size_t); // Does throw
+//void *PlugSubAlloc(PGLOBAL, void *, size_t); // Does throw
/*-------------------------- End of Global.H --------------------------*/
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index bf890724d5e..1e826f67573 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -4191,7 +4191,7 @@ int ha_connect::rnd_pos(uchar *buf, uchar *pos)
rc= rnd_next(buf);
} else {
PGLOBAL g = GetPlug((table) ? table->in_use : NULL, xp);
- strcpy(g->Message, "Not supported by this table type");
+// strcpy(g->Message, "Not supported by this table type");
my_message(ER_ILLEGAL_HA, g->Message, MYF(0));
rc= HA_ERR_INTERNAL_ERROR;
} // endif SetRecpos
@@ -7307,7 +7307,7 @@ maria_declare_plugin(connect)
PLUGIN_LICENSE_GPL,
connect_init_func, /* Plugin Init */
connect_done_func, /* Plugin Deinit */
- 0x0107, /* version number (1.05) */
+ 0x0106, /* version number (1.06) */
NULL, /* status variables */
connect_system_variables, /* system variables */
"1.06.0008", /* string version */
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index 26455d572b6..d5a3a840173 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -3055,7 +3055,7 @@ my_bool json_array_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
PGLOBAL g = (PGLOBAL)initid->ptr;
- PlugSubSet(g, g->Sarea, g->Sarea_Size);
+ PlugSubSet(g->Sarea, g->Sarea_Size);
g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JAR);
g->N = (int)n;
return false;
@@ -3098,7 +3098,7 @@ void json_array_grp_clear(UDF_INIT *initid, char*, char*)
{
PGLOBAL g = (PGLOBAL)initid->ptr;
- PlugSubSet(g, g->Sarea, g->Sarea_Size);
+ PlugSubSet(g->Sarea, g->Sarea_Size);
g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JAR);
g->N = GetJsonGroupSize();
} // end of json_array_grp_clear
@@ -3132,7 +3132,7 @@ my_bool json_object_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
PGLOBAL g = (PGLOBAL)initid->ptr;
- PlugSubSet(g, g->Sarea, g->Sarea_Size);
+ PlugSubSet(g->Sarea, g->Sarea_Size);
g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JOB);
g->N = (int)n;
return false;
@@ -3169,7 +3169,7 @@ void json_object_grp_clear(UDF_INIT *initid, char*, char*)
{
PGLOBAL g = (PGLOBAL)initid->ptr;
- PlugSubSet(g, g->Sarea, g->Sarea_Size);
+ PlugSubSet(g->Sarea, g->Sarea_Size);
g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JOB);
g->N = GetJsonGroupSize();
} // end of json_object_grp_clear
@@ -4418,7 +4418,7 @@ char *json_file(UDF_INIT *initid, UDF_ARGS *args, char *result,
} else if (initid->const_item)
g->N = 1;
- PlugSubSet(g, g->Sarea, g->Sarea_Size);
+ PlugSubSet(g->Sarea, g->Sarea_Size);
fn = MakePSZ(g, args, 0);
if (args->arg_count > 1) {
@@ -5662,7 +5662,7 @@ char *jbin_file(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (bsp && !bsp->Changed)
goto fin;
- PlugSubSet(g, g->Sarea, g->Sarea_Size);
+ PlugSubSet(g->Sarea, g->Sarea_Size);
g->Xchk = NULL;
fn = MakePSZ(g, args, 0);
pretty = (args->arg_count > 2 && args->args[2]) ? (int)*(longlong*)args->args[2] : 3;
diff --git a/storage/connect/mysql-test/connect/r/jdbc_oracle.result b/storage/connect/mysql-test/connect/r/jdbc_oracle.result
index 2e36891a037..ec314c5f072 100644
--- a/storage/connect/mysql-test/connect/r/jdbc_oracle.result
+++ b/storage/connect/mysql-test/connect/r/jdbc_oracle.result
@@ -8,12 +8,19 @@ SELECT * FROM t2 WHERE command = 'drop table employee';
command number message
drop table employee 0 Execute: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
+Warnings:
+Warning 1105 Execute: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
+
SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary number(8,2))';
command number message
create table employee (id int not null, name varchar(32), title char(16), salary number(8,2)) 0 Affected rows
+Warnings:
+Warning 1105 Affected rows
SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)";
command number message
insert into employee values(4567,'Johnson', 'Engineer', 12560.50) 1 Affected rows
+Warnings:
+Warning 1105 Affected rows
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables
CONNECTION='jdbc:oracle:thin:@localhost:1521:xe'
OPTION_LIST='User=system,Password=manager';
@@ -27,8 +34,8 @@ OPTION_LIST='User=system,Password=manager';
SELECT * FROM t1;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
NULL SYSTEM EMPLOYEE ID 3 NUMBER 38 0 0 10 0 NULL
-NULL SYSTEM EMPLOYEE NAME 12 VARCHAR2 32 0 0 10 1 NULL
-NULL SYSTEM EMPLOYEE TITLE 1 CHAR 16 0 0 10 1 NULL
+NULL SYSTEM EMPLOYEE NAME 12 VARCHAR2 32 0 NULL 10 1 NULL
+NULL SYSTEM EMPLOYEE TITLE 1 CHAR 16 0 NULL 10 1 NULL
NULL SYSTEM EMPLOYEE SALARY 3 NUMBER 8 0 2 10 1 NULL
DROP TABLE t1;
CREATE SERVER 'oracle' FOREIGN DATA WRAPPER 'oracle.jdbc.driver.OracleDriver' OPTIONS (
@@ -52,7 +59,7 @@ Note 1105 EMPLOYEE: 1 affected rows
SELECT * FROM t1;
ID NAME TITLE SALARY
4567 Trump Engineer 12560.50
-6214 Clinton Retired 0.00
+6214 Clinton Retired NULL
DELETE FROM t1 WHERE id = 6214;
Warnings:
Note 1105 EMPLOYEE: 1 affected rows
@@ -63,8 +70,7 @@ DROP TABLE t1;
SELECT * FROM t2 WHERE command = 'drop table employee';
command number message
drop table employee 0 Affected rows
+Warnings:
+Warning 1105 Affected rows
DROP TABLE t2;
DROP SERVER 'oracle';
-SET GLOBAL connect_jvm_path=NULL;
-SET GLOBAL connect_class_path=NULL;
-SET GLOBAL time_zone = SYSTEM;
diff --git a/storage/connect/mysql-test/connect/r/jdbc_postgresql.result b/storage/connect/mysql-test/connect/r/jdbc_postgresql.result
index 7969672dd66..bec1dc8725b 100644
--- a/storage/connect/mysql-test/connect/r/jdbc_postgresql.result
+++ b/storage/connect/mysql-test/connect/r/jdbc_postgresql.result
@@ -1,4 +1,4 @@
-SET GLOBAL connect_class_path='C:/MariaDB-10.2/MariaDB/storage/connect/mysql-test/connect/std_data/JavaWrappers.jar;C:/Jconnectors/postgresql-42.2.1.jar';
+SET GLOBAL connect_class_path='C:/MariaDB-10.0/MariaDB/storage/connect/mysql-test/connect/std_data/JavaWrappers.jar;C:/Jconnectors/postgresql-42.2.1.jar';
CREATE TABLE t2 (
command varchar(128) not null,
number int(5) not null flag=1,
@@ -9,12 +9,18 @@ OPTION_LIST='Execsrc=1';
SELECT * FROM t2 WHERE command='drop table employee';
command number message
drop table employee 0 Execute: org.postgresql.util.PSQLException: ERREUR: la table « employee » n'existe pas
+Warnings:
+Warning 1105 Execute: org.postgresql.util.PSQLException: ERREUR: la table « employee » n'existe pas
SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary decimal(8,2))';
command number message
create table employee (id int not null, name varchar(32), title char(16), salary decimal(8,2)) 0 Affected rows
+Warnings:
+Warning 1105 Affected rows
SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)";
command number message
insert into employee values(4567,'Johnson', 'Engineer', 12560.50) 1 Affected rows
+Warnings:
+Warning 1105 Affected rows
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables
CONNECTION='jdbc:postgresql://localhost/test?user=postgres&password=tinono'
OPTION_LIST='Tabtype=TABLE,Maxres=10';
@@ -63,4 +69,6 @@ DROP SERVER 'postgresql';
SELECT * FROM t2 WHERE command='drop table employee';
command number message
drop table employee 0 Affected rows
+Warnings:
+Warning 1105 Affected rows
DROP TABLE t2;
diff --git a/storage/connect/mysql-test/connect/r/part_table.result b/storage/connect/mysql-test/connect/r/part_table.result
index f3a556ae784..ee17a1d32b9 100644
--- a/storage/connect/mysql-test/connect/r/part_table.result
+++ b/storage/connect/mysql-test/connect/r/part_table.result
@@ -23,7 +23,7 @@ id msg
CREATE TABLE xt3 (
id INT KEY NOT NULL,
msg VARCHAR(32))
-ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=10;
+ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=6;
Warnings:
Warning 1105 No file name. Table will use xt3.csv
INSERT INTO xt3 VALUES(60,'sixty'),(81,'eighty one'),(72,'seventy two');
@@ -92,7 +92,7 @@ id msg
EXPLAIN PARTITIONS
SELECT * FROM t1 WHERE id = 81;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 3 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 3 ALL NULL NULL NULL NULL 6 Using where
DELETE FROM t1;
Warnings:
Note 1105 xt1: 4 affected rows
diff --git a/storage/connect/mysql-test/connect/t/part_table.test b/storage/connect/mysql-test/connect/t/part_table.test
index 5edd5766bd6..0fb2a11f0f9 100644
--- a/storage/connect/mysql-test/connect/t/part_table.test
+++ b/storage/connect/mysql-test/connect/t/part_table.test
@@ -22,7 +22,7 @@ SELECT * FROM xt2;
CREATE TABLE xt3 (
id INT KEY NOT NULL,
msg VARCHAR(32))
-ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=10;
+ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=6;
INSERT INTO xt3 VALUES(60,'sixty'),(81,'eighty one'),(72,'seventy two');
SELECT * FROM xt3;
diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp
index 887527e38ab..048f00be75f 100644
--- a/storage/connect/plugutil.cpp
+++ b/storage/connect/plugutil.cpp
@@ -514,27 +514,31 @@ void FreeSarea(PGLOBAL g)
/* Here there should be some verification done such as validity of */
/* the address and size not larger than memory size. */
/***********************************************************************/
-BOOL PlugSubSet(PGLOBAL g __attribute__((unused)), void *memp, uint size)
+BOOL PlugSubSet(void *memp, uint size)
{
PPOOLHEADER pph = (PPOOLHEADER)memp;
pph->To_Free = (OFFSET)sizeof(POOLHEADER);
pph->FreeBlk = size - pph->To_Free;
-
return FALSE;
} /* end of PlugSubSet */
/***********************************************************************/
+/* Use it to export a function that do throwing. */
+/***********************************************************************/
+void *DoThrow(int n)
+{
+ throw n;
+} /* end of DoThrow */
+
+/***********************************************************************/
/* Program for sub-allocating one item in a storage area. */
-/* Note: SubAlloc routines of OS/2 are no more used to increase the */
-/* code portability and avoid problems when a grammar compiled under */
-/* one version of OS/2 is used under another version. */
-/* The simple way things are done here is also based on the fact */
-/* that no freeing of suballocated blocks is permitted in Plug. */
+/* The simple way things are done here is based on the fact */
+/* that no freeing of suballocated blocks is permitted in CONNECT. */
/***********************************************************************/
void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
- {
- PPOOLHEADER pph; /* Points on area header. */
+{
+ PPOOLHEADER pph; /* Points on area header. */
if (!memp)
/*******************************************************************/
@@ -559,8 +563,8 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
if (trace(1))
htrc("PlugSubAlloc: %s\n", g->Message);
- throw 1234;
- } /* endif size OS32 code */
+ DoThrow(1234);
+ } /* endif size OS32 code */
/*********************************************************************/
/* Do the suballocation the simplest way. */
@@ -574,7 +578,7 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
memp, pph->To_Free, pph->FreeBlk);
return (memp);
- } /* end of PlugSubAlloc */
+} /* end of PlugSubAlloc */
/***********************************************************************/
/* Program for sub-allocating and copying a string in a storage area. */
diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp
index e4f169575f8..30d8063d1a6 100644
--- a/storage/connect/reldef.cpp
+++ b/storage/connect/reldef.cpp
@@ -522,8 +522,15 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
// Get the function returning an instance of the external DEF class
if (!(getdef = (XGETDEF)GetProcAddress((HINSTANCE)Hdll, getname))) {
- sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), getname);
- FreeLibrary((HMODULE)Hdll);
+ char buf[256];
+ DWORD rc = GetLastError();
+
+ sprintf(g->Message, MSG(PROCADD_ERROR), rc, getname);
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
+ (LPTSTR)buf, sizeof(buf), NULL);
+ strcat(strcat(g->Message, ": "), buf);
+ FreeLibrary((HMODULE)Hdll);
return NULL;
} // endif getdef
#else // !__WIN__
diff --git a/storage/connect/tabfmt.h b/storage/connect/tabfmt.h
index 396bba568ff..10f0757c60b 100644
--- a/storage/connect/tabfmt.h
+++ b/storage/connect/tabfmt.h
@@ -13,7 +13,7 @@ typedef class TDBFMT *PTDBFMT;
/***********************************************************************/
/* Functions used externally. */
/***********************************************************************/
-PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info);
+DllExport PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info);
/***********************************************************************/
/* CSV table. */
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index 9e4f5ab987d..c0d36efcf42 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.5 */
-/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */
+/* PROGRAM NAME: tabjson Version 1.6 */
+/* (C) Copyright to the author Olivier BERTRAND 2014 - 2018 */
/* This program are the JSON class DB execution routines. */
/***********************************************************************/
@@ -173,6 +173,7 @@ JSONDISC::JSONDISC(PGLOBAL g, uint *lg)
int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
{
+ char filename[_MAX_PATH];
bool mgo = (GetTypeID(topt->type) == TAB_MONGO);
PCSZ level = GetStringTableOption(g, topt, "Level", NULL);
@@ -209,6 +210,12 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
return 0;
} // endif Fn
+ if (tdp->Fn) {
+ // We used the file name relative to recorded datapath
+ PlugSetPath(filename, tdp->Fn, tdp->GetPath());
+ tdp->Fn = PlugDup(g, filename);
+ } // endif Fn
+
if (trace(1))
htrc("File %s objname=%s pretty=%d lvl=%d\n",
tdp->Fn, tdp->Objname, tdp->Pretty, lvl);
@@ -299,7 +306,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
memset(G, 0, sizeof(GLOBAL));
G->Sarea_Size = tdp->Lrecl * 10;
G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size);
- PlugSubSet(G, G->Sarea, G->Sarea_Size);
+ PlugSubSet(G->Sarea, G->Sarea_Size);
G->jump_level = 0;
tjnp->SetG(G);
@@ -342,7 +349,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
strncpy(colname, jpp->GetKey(), 64);
fmt[bf] = 0;
- if (Find(g, jpp->GetVal(), MY_MIN(lvl, 0)))
+ if (Find(g, jpp->GetVal(), colname, MY_MIN(lvl, 0)))
goto err;
} // endfor jpp
@@ -385,7 +392,7 @@ err:
return 0;
} // end of GetColumns
-bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, int j)
+bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j)
{
char *p, *pc = colname + strlen(colname);
int ars;
@@ -413,12 +420,14 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, int j)
job = (PJOB)jsp;
for (PJPR jrp = job->GetFirst(); jrp; jrp = jrp->GetNext()) {
- if (*jrp->GetKey() != '$') {
- strncat(strncat(fmt, sep, 128), jrp->GetKey(), 128);
- strncat(strncat(colname, "_", 64), jrp->GetKey(), 64);
+ PCSZ k = jrp->GetKey();
+
+ if (*k != '$') {
+ strncat(strncat(fmt, sep, 128), k, 128);
+ strncat(strncat(colname, "_", 64), k, 64);
} // endif Key
- if (Find(g, jrp->GetVal(), j + 1))
+ if (Find(g, jrp->GetVal(), k, j + 1))
return true;
*p = *pc = 0;
@@ -428,13 +437,13 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, int j)
case TYPE_JAR:
jar = (PJAR)jsp;
- if (all || (tdp->Xcol && !stricmp(tdp->Xcol, colname)))
+ if (all || (tdp->Xcol && !stricmp(tdp->Xcol, key)))
ars = jar->GetSize(false);
else
ars = MY_MIN(jar->GetSize(false), 1);
for (int k = 0; k < ars; k++) {
- if (!tdp->Xcol || stricmp(tdp->Xcol, colname)) {
+ if (!tdp->Xcol || stricmp(tdp->Xcol, key)) {
sprintf(buf, "%d", k);
if (tdp->Uri)
@@ -448,7 +457,7 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, int j)
} else
strncat(fmt, (tdp->Uri ? sep : "[*]"), 128);
- if (Find(g, jar->GetValue(k), j))
+ if (Find(g, jar->GetValue(k), "", j))
return true;
*p = *pc = 0;
@@ -522,7 +531,9 @@ void JSONDISC::AddColumn(PGLOBAL g)
n++;
} // endif jcp
- pjcp = jcp;
+ if (jcp)
+ pjcp = jcp;
+
} // end of AddColumn
@@ -549,7 +560,7 @@ JSONDEF::JSONDEF(void)
/***********************************************************************/
/* DefineAM: define specific AM block values. */
/***********************************************************************/
-bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR, int poff)
+bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
Schema = GetStringCatInfo(g, "DBname", Schema);
Jmode = (JMODE)GetIntCatInfo("Jmode", MODE_OBJECT);
@@ -561,7 +572,8 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR, int poff)
Sep = *GetStringCatInfo(g, "Separator", ".");
Accept = GetBoolCatInfo("Accept", false);
- if (Uri = GetStringCatInfo(g, "Connect", NULL)) {
+ // Don't use url as uri when called from REST OEM module
+ if (stricmp(am, "REST") && (Uri = GetStringCatInfo(g, "Connect", NULL))) {
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
Collname = GetStringCatInfo(g, "Name",
(Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
@@ -670,7 +682,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
memset(G, 0, sizeof(GLOBAL));
G->Sarea_Size = Lrecl * 10;
G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size);
- PlugSubSet(G, G->Sarea, G->Sarea_Size);
+ PlugSubSet(G->Sarea, G->Sarea_Size);
G->jump_level = 0;
((TDBJSN*)tdbp)->G = G;
} else {
@@ -963,7 +975,7 @@ int TDBJSN::ReadDB(PGLOBAL g)
return rc;
// Recover the memory used for parsing
- PlugSubSet(G, G->Sarea, G->Sarea_Size);
+ PlugSubSet(G->Sarea, G->Sarea_Size);
if ((Row = ParseJson(G, To_Line, strlen(To_Line), &Pretty, &Comma))) {
Row = FindRow(g);
@@ -1079,13 +1091,13 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp)
} // end of PrepareWriting
/***********************************************************************/
-/* WriteDB: Data Base write routine for DOS access method. */
+/* WriteDB: Data Base write routine for JSON access method. */
/***********************************************************************/
int TDBJSN::WriteDB(PGLOBAL g)
{
int rc = TDBDOS::WriteDB(g);
- PlugSubSet(G, G->Sarea, G->Sarea_Size);
+ PlugSubSet(G->Sarea, G->Sarea_Size);
Row->Clear();
return rc;
} // end of WriteDB
@@ -2340,7 +2352,7 @@ void TDBJSON::CloseDB(PGLOBAL g)
TDBJCL::TDBJCL(PJDEF tdp) : TDBCAT(tdp)
{
Topt = tdp->GetTopt();
- Db = tdp->Schema;
+ Db = tdp->Schema;
Dsn = tdp->Uri;
} // end of TDBJCL constructor
diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h
index 2ff72905e86..8721a2a5ab7 100644
--- a/storage/connect/tabjson.h
+++ b/storage/connect/tabjson.h
@@ -1,11 +1,11 @@
/*************** tabjson H Declares Source Code File (.H) **************/
/* Name: tabjson.h Version 1.3 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2014 - 2018 */
/* */
/* This file contains the JSON classes declares. */
/***********************************************************************/
-#include "osutil.h"
+//#include "osutil.h" // Unuseful and bad for OEM
#include "block.h"
#include "colblk.h"
#include "json.h"
@@ -16,7 +16,7 @@ typedef class JSONDEF *PJDEF;
typedef class TDBJSON *PJTDB;
typedef class JSONCOL *PJCOL;
class TDBJSN;
-PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info);
+DllExport PQRYRES JSONColumns(PGLOBAL, PCSZ, PCSZ, PTOS, bool);
/***********************************************************************/
/* The JSON tree node. Can be an Object or an Array. */
@@ -52,7 +52,7 @@ public:
// Functions
int GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt);
- bool Find(PGLOBAL g, PJVAL jvp, int j);
+ bool Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j);
void AddColumn(PGLOBAL g);
// Members
diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp
index fddfb0c0420..0fa117c3d2f 100644
--- a/storage/connect/tabodbc.cpp
+++ b/storage/connect/tabodbc.cpp
@@ -5,7 +5,7 @@
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 2000-2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2000-2018 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -95,23 +95,23 @@ bool ExactInfo(void);
/* Constructor. */
/***********************************************************************/
ODBCDEF::ODBCDEF(void)
- {
+{
Connect = NULL;
Catver = 0;
UseCnc = false;
- } // end of ODBCDEF constructor
+} // end of ODBCDEF constructor
/***********************************************************************/
/* DefineAM: define specific AM block values from XDB file. */
/***********************************************************************/
bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
- {
+{
Desc = Connect = GetStringCatInfo(g, "Connect", NULL);
if (!Connect && !Catfunc) {
sprintf(g->Message, "Missing connection for ODBC table %s", Name);
return true;
- } // endif Connect
+ } // endif Connect
if (EXTDEF::DefineAM(g, am, poff))
return true;
@@ -123,13 +123,13 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT);
UseCnc = GetBoolCatInfo("UseDSN", false);
return false;
- } // end of DefineAM
+} // end of DefineAM
/***********************************************************************/
/* GetTable: makes a new Table Description Block. */
/***********************************************************************/
PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m)
- {
+{
PTDB tdbp = NULL;
/*********************************************************************/
@@ -158,10 +158,10 @@ PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m)
tdbp = new(g) TDBMUL(tdbp);
else if (Multiple == 2)
strcpy(g->Message, MSG(NO_ODBC_MUL));
- } // endswitch Catfunc
+ } // endswitch Catfunc
return tdbp;
- } // end of GetTable
+} // end of GetTable
/* -------------------------- Class TDBODBC -------------------------- */
@@ -169,7 +169,7 @@ PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m)
/* Implementation of the TDBODBC class. */
/***********************************************************************/
TDBODBC::TDBODBC(PODEF tdp) : TDBEXT(tdp)
- {
+{
Ocp = NULL;
Cnp = NULL;
@@ -191,19 +191,19 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBEXT(tdp)
Ops.UseCnc = false;
} // endif tdp
- } // end of TDBODBC standard constructor
+} // end of TDBODBC standard constructor
TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBEXT(tdbp)
- {
+{
Ocp = tdbp->Ocp; // is that right ?
Cnp = tdbp->Cnp;
Connect = tdbp->Connect;
Ops = tdbp->Ops;
- } // end of TDBODBC copy constructor
+} // end of TDBODBC copy constructor
// Method
PTDB TDBODBC::Clone(PTABS t)
- {
+{
PTDB tp;
PODBCCOL cp1, cp2;
PGLOBAL g = t->G; // Is this really useful ???
@@ -213,18 +213,18 @@ PTDB TDBODBC::Clone(PTABS t)
for (cp1 = (PODBCCOL)Columns; cp1; cp1 = (PODBCCOL)cp1->GetNext()) {
cp2 = new(g) ODBCCOL(cp1, tp); // Make a copy
NewPointer(t, cp1, cp2);
- } // endfor cp1
+ } // endfor cp1
return tp;
- } // end of CopyOne
+} // end of CopyOne
/***********************************************************************/
/* Allocate ODBC column description block. */
/***********************************************************************/
PCOL TDBODBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
- {
+{
return new(g) ODBCCOL(cdp, this, cprec, n);
- } // end of MakeCol
+} // end of MakeCol
/***********************************************************************/
/* Extract the filename from connect string and return it. */
@@ -232,7 +232,7 @@ PCOL TDBODBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
/* with a place holder to be used by SetFile. */
/***********************************************************************/
PCSZ TDBODBC::GetFile(PGLOBAL g)
- {
+{
if (Connect) {
char *p1, *p2;
int i;
@@ -263,18 +263,18 @@ PCSZ TDBODBC::GetFile(PGLOBAL g)
memcpy(MulConn, Connect, p1 - Connect);
MulConn[p1 - Connect] = '\0';
strcat(strcat(MulConn, "%s"), (p2) ? p2 : ";");
- } // endif p1
+ } // endif p1
- } // endif Connect
+ } // endif Connect
return (DBQ) ? DBQ : (PSZ)"???";
- } // end of GetFile
+} // end of GetFile
/***********************************************************************/
/* Set DBQ and get the new file name into the connect string. */
/***********************************************************************/
void TDBODBC::SetFile(PGLOBAL g, PCSZ fn)
- {
+{
if (MulConn) {
int n = strlen(MulConn) + strlen(fn) - 1;
@@ -283,20 +283,20 @@ void TDBODBC::SetFile(PGLOBAL g, PCSZ fn)
// of having to reallocate it is reduced.
BufSize = n + 6;
Connect = (char*)PlugSubAlloc(g, NULL, BufSize);
- } // endif n
+ } // endif n
// Make the complete connect string
sprintf(Connect, MulConn, fn);
- } // endif MultConn
+ } // endif MultConn
DBQ = PlugDup(g, fn);
- } // end of SetFile
+} // end of SetFile
/***********************************************************************/
/* MakeInsert: make the Insert statement used with ODBC connection. */
/***********************************************************************/
bool TDBODBC::MakeInsert(PGLOBAL g)
- {
+{
PCSZ schmp = NULL;
char *catp = NULL, buf[NAM_LEN * 3];
int len = 0;
@@ -377,7 +377,7 @@ bool TDBODBC::MakeInsert(PGLOBAL g)
} else
Query->Append(buf);
- } // endfor colp
+ } // endfor colp
Query->Append(") VALUES (");
@@ -390,32 +390,32 @@ bool TDBODBC::MakeInsert(PGLOBAL g)
Query->RepLast(')');
return oom;
- } // end of MakeInsert
+} // end of MakeInsert
/***********************************************************************/
/* ODBC Bind Parameter function. */
/***********************************************************************/
bool TDBODBC::BindParameters(PGLOBAL g)
- {
- PODBCCOL colp;
+{
+ PODBCCOL colp;
- for (colp = (PODBCCOL)Columns; colp; colp = (PODBCCOL)colp->Next) {
- colp->AllocateBuffers(g, 0);
+ for (colp = (PODBCCOL)Columns; colp; colp = (PODBCCOL)colp->Next) {
+ colp->AllocateBuffers(g, 0);
- if (Ocp->BindParam(colp))
- return true;
+ if (Ocp->BindParam(colp))
+ return true;
- } // endfor colp
+ } // endfor colp
- return false;
- } // end of BindParameters
+ return false;
+} // end of BindParameters
#if 0
/***********************************************************************/
/* MakeUpdate: make the SQL statement to send to ODBC connection. */
/***********************************************************************/
char *TDBODBC::MakeUpdate(PGLOBAL g)
- {
+{
char *qc, *stmt = NULL, cmd[8], tab[96], end[1024];
stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
@@ -440,60 +440,60 @@ char *TDBODBC::MakeUpdate(PGLOBAL g)
strcat(stmt, end);
return stmt;
- } // end of MakeUpdate
+} // end of MakeUpdate
/***********************************************************************/
/* MakeDelete: make the SQL statement to send to ODBC connection. */
/***********************************************************************/
char *TDBODBC::MakeDelete(PGLOBAL g)
- {
- char *qc, *stmt = NULL, cmd[8], from[8], tab[96], end[512];
-
- stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
- memset(end, 0, sizeof(end));
-
- if (sscanf(Qrystr, "%s %s `%[^`]`%511c", cmd, from, tab, end) > 2 ||
- sscanf(Qrystr, "%s %s \"%[^\"]\"%511c", cmd, from, tab, end) > 2)
- qc = Ocp->GetQuoteChar();
- else if (sscanf(Qrystr, "%s %s %s%511c", cmd, from, tab, end) > 2)
- qc = (Quoted) ? Quote : "";
- else {
- strcpy(g->Message, "Cannot use this DELETE command");
- return NULL;
- } // endif sscanf
-
- assert(!stricmp(cmd, "delete") && !stricmp(from, "from"));
- strcat(strcat(strcat(strcpy(stmt, "DELETE FROM "), qc), TableName), qc);
-
- if (*end) {
- for (int i = 0; end[i]; i++)
- if (end[i] == '`')
- end[i] = *qc;
-
- strcat(stmt, end);
- } // endif end
-
- return stmt;
- } // end of MakeDelete
+{
+ char *qc, *stmt = NULL, cmd[8], from[8], tab[96], end[512];
+
+ stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
+ memset(end, 0, sizeof(end));
+
+ if (sscanf(Qrystr, "%s %s `%[^`]`%511c", cmd, from, tab, end) > 2 ||
+ sscanf(Qrystr, "%s %s \"%[^\"]\"%511c", cmd, from, tab, end) > 2)
+ qc = Ocp->GetQuoteChar();
+ else if (sscanf(Qrystr, "%s %s %s%511c", cmd, from, tab, end) > 2)
+ qc = (Quoted) ? Quote : "";
+ else {
+ strcpy(g->Message, "Cannot use this DELETE command");
+ return NULL;
+ } // endif sscanf
+
+ assert(!stricmp(cmd, "delete") && !stricmp(from, "from"));
+ strcat(strcat(strcat(strcpy(stmt, "DELETE FROM "), qc), TableName), qc);
+
+ if (*end) {
+ for (int i = 0; end[i]; i++)
+ if (end[i] == '`')
+ end[i] = *qc;
+
+ strcat(stmt, end);
+ } // endif end
+
+ return stmt;
+} // end of MakeDelete
#endif // 0
/***********************************************************************/
/* ResetSize: call by TDBMUL when calculating size estimate. */
/***********************************************************************/
void TDBODBC::ResetSize(void)
- {
+{
MaxSize = -1;
if (Ocp && Ocp->IsOpen())
Ocp->Close();
- } // end of ResetSize
+} // end of ResetSize
/***********************************************************************/
/* ODBC Cardinality: returns table size in number of rows. */
/***********************************************************************/
int TDBODBC::Cardinality(PGLOBAL g)
- {
+{
if (!g)
return (Mode == MODE_ANY && !Srcdef) ? 1 : 0;
@@ -526,7 +526,7 @@ int TDBODBC::Cardinality(PGLOBAL g)
Cardinal = 10; // To make MySQL happy
return Cardinal;
- } // end of Cardinality
+} // end of Cardinality
/***********************************************************************/
/* ODBC Access Method opening routine. */
@@ -535,7 +535,7 @@ int TDBODBC::Cardinality(PGLOBAL g)
/* join block of next table if it exists or else are discarted. */
/***********************************************************************/
bool TDBODBC::OpenDB(PGLOBAL g)
- {
+{
bool rc = true;
if (trace(1))
@@ -571,7 +571,7 @@ bool TDBODBC::OpenDB(PGLOBAL g)
Fpos = 0;
Curpos = 1;
return false;
- } // endif use
+ } // endif use
/*********************************************************************/
/* Open an ODBC connection for this table. */
@@ -593,7 +593,7 @@ bool TDBODBC::OpenDB(PGLOBAL g)
Use = USE_OPEN; // Do it now in case we are recursively called
/*********************************************************************/
- /* Make the command and allocate whatever is used for getting results. */
+ /* Make the command and allocate whatever is used for getting results*/
/*********************************************************************/
if (Mode == MODE_READ || Mode == MODE_READX) {
if (Memory > 1 && !Srcdef) {
@@ -624,7 +624,7 @@ bool TDBODBC::OpenDB(PGLOBAL g)
} else
return true;
- } // endif Memory
+ } // endif Memory
if (!(rc = MakeSQL(g, false))) {
for (PODBCCOL colp = (PODBCCOL)Columns; colp;
@@ -635,7 +635,7 @@ bool TDBODBC::OpenDB(PGLOBAL g)
rc = (Mode == MODE_READ)
? ((Rows = Ocp->ExecDirectSQL(Query->GetStr(), (PODBCCOL)Columns)) < 0)
: false;
- } // endif rc
+ } // endif rc
} else if (Mode == MODE_INSERT) {
if (!(rc = MakeInsert(g))) {
@@ -645,7 +645,7 @@ bool TDBODBC::OpenDB(PGLOBAL g)
} else
rc = BindParameters(g);
- } // endif rc
+ } // endif rc
} else if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
rc = false; // wait for CheckCond before calling MakeCommand(g);
@@ -655,30 +655,30 @@ bool TDBODBC::OpenDB(PGLOBAL g)
if (rc) {
Ocp->Close();
return true;
- } // endif rc
+ } // endif rc
/*********************************************************************/
/* Reset statistics values. */
/*********************************************************************/
num_read = num_there = num_eq[0] = num_eq[1] = 0;
return false;
- } // end of OpenDB
+} // end of OpenDB
#if 0
/***********************************************************************/
/* GetRecpos: return the position of last read record. */
/***********************************************************************/
int TDBODBC::GetRecpos(void)
- {
+{
return Fpos;
- } // end of GetRecpos
+} // end of GetRecpos
#endif // 0
/***********************************************************************/
/* SetRecpos: set the position of next read record. */
/***********************************************************************/
bool TDBODBC::SetRecpos(PGLOBAL g, int recpos)
- {
+{
if (Ocp->m_Full) {
Fpos = 0;
CurNum = recpos - 1;
@@ -696,14 +696,15 @@ bool TDBODBC::SetRecpos(PGLOBAL g, int recpos)
} // endif recpos
} else {
- strcpy(g->Message, "This action requires a scrollable cursor");
+ strcpy(g->Message,
+ "This action requires Memory setting or a scrollable cursor");
return true;
} // endif's
// Indicate the table position was externally set
Placed = true;
return false;
- } // end of SetRecpos
+} // end of SetRecpos
/***********************************************************************/
/* Data Base indexed read routine for ODBC access method. */
@@ -721,7 +722,7 @@ bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
Rows = Ocp->ExecDirectSQL((char*)Query->GetStr(), (PODBCCOL)Columns);
Mode = MODE_READ;
return (Rows < 0);
- } // endif key
+ } // endif key
return false;
} else {
@@ -737,7 +738,7 @@ bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
if ((To_CondFil = hc->CheckCond(g, To_CondFil, Cond)))
PlugSubAlloc(g, NULL, strlen(To_CondFil->Body) + 1);
- } // endif active_index
+ } // endif active_index
if (To_CondFil)
if (Query->Append(" AND ") || Query->Append(To_CondFil->Body)) {
@@ -762,7 +763,7 @@ bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
/* VRDNDOS: Data Base read routine for odbc access method. */
/***********************************************************************/
int TDBODBC::ReadDB(PGLOBAL g)
- {
+{
int rc;
if (trace(2))
@@ -784,7 +785,7 @@ int TDBODBC::ReadDB(PGLOBAL g)
} else
return RC_FX; // Error
- } // endif Mode
+ } // endif Mode
/*********************************************************************/
/* Now start the reading process. */
@@ -813,7 +814,7 @@ int TDBODBC::ReadDB(PGLOBAL g)
Qrp->Nblin++;
Fpos++; // Used for memory and pos
- } // endif rc
+ } // endif rc
} // endif Placed
@@ -821,13 +822,13 @@ int TDBODBC::ReadDB(PGLOBAL g)
htrc(" Read: Rbuf=%d rc=%d\n", Rbuf, rc);
return rc;
- } // end of ReadDB
+} // end of ReadDB
/***********************************************************************/
/* Data Base Insert write routine for ODBC access method. */
/***********************************************************************/
int TDBODBC::WriteDB(PGLOBAL g)
- {
+{
int n = Ocp->ExecuteSQL();
if (n < 0) {
@@ -837,13 +838,13 @@ int TDBODBC::WriteDB(PGLOBAL g)
AftRows += n;
return RC_OK;
- } // end of WriteDB
+} // end of WriteDB
/***********************************************************************/
/* Data Base delete line routine for ODBC access method. */
/***********************************************************************/
int TDBODBC::DeleteDB(PGLOBAL g, int irc)
- {
+{
if (irc == RC_FX) {
if (!Query && MakeCommand(g))
return RC_FX;
@@ -863,13 +864,13 @@ int TDBODBC::DeleteDB(PGLOBAL g, int irc)
} else
return RC_OK; // Ignore
- } // end of DeleteDB
+} // end of DeleteDB
/***********************************************************************/
/* Data Base close routine for ODBC access method. */
/***********************************************************************/
void TDBODBC::CloseDB(PGLOBAL g)
- {
+{
if (Ocp)
Ocp->Close();
@@ -877,7 +878,7 @@ void TDBODBC::CloseDB(PGLOBAL g)
if (trace(1))
htrc("ODBC CloseDB: closing %s\n", Name);
- } // end of CloseDB
+} // end of CloseDB
/* --------------------------- ODBCCOL ------------------------------- */
@@ -886,33 +887,33 @@ void TDBODBC::CloseDB(PGLOBAL g)
/***********************************************************************/
ODBCCOL::ODBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
: EXTCOL(cdp, tdbp, cprec, i, am)
- {
+{
// Set additional ODBC access method information for column.
Slen = 0;
StrLen = &Slen;
Sqlbuf = NULL;
- } // end of ODBCCOL constructor
+} // end of ODBCCOL constructor
/***********************************************************************/
/* ODBCCOL private constructor. */
/***********************************************************************/
ODBCCOL::ODBCCOL(void) : EXTCOL()
- {
+{
Slen = 0;
StrLen = &Slen;
Sqlbuf = NULL;
- } // end of ODBCCOL constructor
+} // end of ODBCCOL constructor
/***********************************************************************/
/* ODBCCOL constructor used for copying columns. */
/* tdbp is the pointer to the new table descriptor. */
/***********************************************************************/
ODBCCOL::ODBCCOL(ODBCCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp)
- {
+{
Slen = col1->Slen;
StrLen = col1->StrLen;
Sqlbuf = col1->Sqlbuf;
- } // end of ODBCCOL copy constructor
+} // end of ODBCCOL copy constructor
/***********************************************************************/
/* ReadColumn: when SQLFetch is used there is nothing to do as the */
@@ -920,7 +921,7 @@ ODBCCOL::ODBCCOL(ODBCCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp)
/* when calculating MaxSize (Bufp is NULL even when Rows is not). */
/***********************************************************************/
void ODBCCOL::ReadColumn(PGLOBAL g)
- {
+{
PTDBODBC tdbp = (PTDBODBC)To_Tdb;
int i = tdbp->Fpos - 1, n = tdbp->CurNum;
@@ -953,7 +954,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g)
else
Value->SetValue_pvblk(Blkp, n);
- } // endif Bufp
+ } // endif Bufp
if (Buf_Type == TYPE_DATE) {
struct tm dbtime;
@@ -980,7 +981,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g)
htrc("ODBC Column %s: rows=%d buf=%p type=%d value=%s\n",
Name, tdbp->Rows, Bufp, Buf_Type, Value->GetCharString(buf));
- } // endif trace
+ } // endif trace
put:
if (tdbp->Memory != 2)
@@ -997,7 +998,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g)
} else
Crp->Kdata->SetValue(Value, i);
- } // end of ReadColumn
+} // end of ReadColumn
/***********************************************************************/
/* AllocateBuffers: allocate the extended buffer for SQLExtendedFetch */
@@ -1005,7 +1006,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g)
/* for the ending null character. */
/***********************************************************************/
void ODBCCOL::AllocateBuffers(PGLOBAL g, int rows)
- {
+{
if (Buf_Type == TYPE_DATE)
Sqlbuf = (TIMESTAMP_STRUCT*)PlugSubAlloc(g, NULL,
sizeof(TIMESTAMP_STRUCT));
@@ -1019,31 +1020,31 @@ void ODBCCOL::AllocateBuffers(PGLOBAL g, int rows)
Blkp = AllocValBlock(g, NULL, Buf_Type, rows, GetBuflen(),
GetScale(), true, false, false);
Bufp = Blkp->GetValPointer();
- } // endelse
+ } // endelse
if (rows > 1)
StrLen = (SQLLEN *)PlugSubAlloc(g, NULL, rows * sizeof(SQLLEN));
- } // end of AllocateBuffers
+} // end of AllocateBuffers
/***********************************************************************/
/* Returns the buffer to use for Fetch or Extended Fetch. */
/***********************************************************************/
void *ODBCCOL::GetBuffer(DWORD rows)
- {
+{
if (rows && To_Tdb) {
assert(rows == (DWORD)((TDBODBC*)To_Tdb)->Rows);
return Bufp;
} else
return (Buf_Type == TYPE_DATE) ? Sqlbuf : Value->GetTo_Val();
- } // end of GetBuffer
+} // end of GetBuffer
/***********************************************************************/
/* Returns the buffer length to use for Fetch or Extended Fetch. */
/***********************************************************************/
SWORD ODBCCOL::GetBuflen(void)
- {
+{
SWORD flen;
switch (Buf_Type) {
@@ -1059,13 +1060,13 @@ SWORD ODBCCOL::GetBuflen(void)
} // endswitch Buf_Type
return flen;
- } // end of GetBuflen
+} // end of GetBuflen
/***********************************************************************/
/* WriteColumn: make sure the bind buffer is updated. */
/***********************************************************************/
void ODBCCOL::WriteColumn(PGLOBAL g)
- {
+{
/*********************************************************************/
/* Do convert the column value if necessary. */
/*********************************************************************/
@@ -1095,7 +1096,7 @@ void ODBCCOL::WriteColumn(PGLOBAL g)
*StrLen = (Value->IsNull()) ? SQL_NULL_DATA :
(IsTypeChar(Buf_Type)) ? SQL_NTS : 0;
- } // end of WriteColumn
+} // end of WriteColumn
/* -------------------------- Class TDBXDBC -------------------------- */
@@ -1119,7 +1120,7 @@ TDBXDBC::TDBXDBC(PTDBXDBC tdbp) : TDBODBC(tdbp)
} // end of TDBXDBC copy constructor
PTDB TDBXDBC::Clone(PTABS t)
- {
+{
PTDB tp;
PXSRCCOL cp1, cp2;
PGLOBAL g = t->G; // Is this really useful ???
@@ -1129,29 +1130,29 @@ PTDB TDBXDBC::Clone(PTABS t)
for (cp1 = (PXSRCCOL)Columns; cp1; cp1 = (PXSRCCOL)cp1->GetNext()) {
cp2 = new(g) XSRCCOL(cp1, tp); // Make a copy
NewPointer(t, cp1, cp2);
- } // endfor cp1
+ } // endfor cp1
return tp;
- } // end of CopyOne
+} // end of CopyOne
/***********************************************************************/
/* Allocate XSRC column description block. */
/***********************************************************************/
PCOL TDBXDBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
- {
+{
PXSRCCOL colp = new(g) XSRCCOL(cdp, this, cprec, n);
if (!colp->Flag)
Cmdcol = colp->GetName();
return colp;
- } // end of MakeCol
+} // end of MakeCol
/***********************************************************************/
/* MakeCMD: make the SQL statement to send to ODBC connection. */
/***********************************************************************/
PCMD TDBXDBC::MakeCMD(PGLOBAL g)
- {
+{
PCMD xcmd = NULL;
if (To_CondFil) {
@@ -1171,14 +1172,14 @@ PCMD TDBXDBC::MakeCMD(PGLOBAL g)
xcmd = new(g) CMD(g, Srcdef);
return xcmd;
- } // end of MakeCMD
+} // end of MakeCMD
#if 0
/***********************************************************************/
/* ODBC Bind Parameter function. */
/***********************************************************************/
bool TDBXDBC::BindParameters(PGLOBAL g)
- {
+{
PODBCCOL colp;
for (colp = (PODBCCOL)Columns; colp; colp = (PODBCCOL)colp->Next) {
@@ -1190,19 +1191,19 @@ bool TDBXDBC::BindParameters(PGLOBAL g)
} // endfor colp
return false;
- } // end of BindParameters
+} // end of BindParameters
#endif // 0
/***********************************************************************/
/* XDBC GetMaxSize: returns table size (not always one row). */
/***********************************************************************/
int TDBXDBC::GetMaxSize(PGLOBAL g)
- {
+{
if (MaxSize < 0)
MaxSize = 10; // Just a guess
return MaxSize;
- } // end of GetMaxSize
+} // end of GetMaxSize
/***********************************************************************/
/* ODBC Access Method opening routine. */
@@ -1211,7 +1212,7 @@ int TDBXDBC::GetMaxSize(PGLOBAL g)
/* join block of next table if it exists or else are discarted. */
/***********************************************************************/
bool TDBXDBC::OpenDB(PGLOBAL g)
- {
+{
bool rc = false;
if (trace(1))
@@ -1221,7 +1222,7 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
if (Use == USE_OPEN) {
strcpy(g->Message, "Multiple execution is not allowed");
return true;
- } // endif use
+ } // endif use
/*********************************************************************/
/* Open an ODBC connection for this table. */
@@ -1243,7 +1244,7 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
if (Mode != MODE_READ && Mode != MODE_READX) {
strcpy(g->Message, "No INSERT/DELETE/UPDATE of XDBC tables");
return true;
- } // endif Mode
+ } // endif Mode
/*********************************************************************/
/* Get the command to execute. */
@@ -1256,13 +1257,13 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
Rows = 1;
return false;
- } // end of OpenDB
+} // end of OpenDB
/***********************************************************************/
/* ReadDB: Data Base read routine for xdbc access method. */
/***********************************************************************/
int TDBXDBC::ReadDB(PGLOBAL g)
- {
+{
if (Cmdlist) {
if (!Query)
Query = new(g)STRING(g, 0, Cmdlist->Cmd);
@@ -1280,25 +1281,25 @@ int TDBXDBC::ReadDB(PGLOBAL g)
return RC_EF;
} // endif Cmdlist
- } // end of ReadDB
+} // end of ReadDB
/***********************************************************************/
-/* Data Base delete line routine for ODBC access method. */
+/* Data Base write line routine for XDBC access method. */
/***********************************************************************/
int TDBXDBC::WriteDB(PGLOBAL g)
- {
+{
strcpy(g->Message, "Execsrc tables are read only");
return RC_FX;
- } // end of DeleteDB
+} // end of DeleteDB
/***********************************************************************/
-/* Data Base delete line routine for ODBC access method. */
+/* Data Base delete line routine for XDBC access method. */
/***********************************************************************/
int TDBXDBC::DeleteDB(PGLOBAL g, int irc)
- {
+{
strcpy(g->Message, MSG(NO_ODBC_DELETE));
return RC_FX;
- } // end of DeleteDB
+} // end of DeleteDB
/* --------------------------- XSRCCOL ------------------------------- */
@@ -1307,25 +1308,25 @@ int TDBXDBC::DeleteDB(PGLOBAL g, int irc)
/***********************************************************************/
XSRCCOL::XSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
: ODBCCOL(cdp, tdbp, cprec, i, am)
- {
+{
// Set additional ODBC access method information for column.
Flag = cdp->GetOffset();
- } // end of XSRCCOL constructor
+} // end of XSRCCOL constructor
/***********************************************************************/
/* XSRCCOL constructor used for copying columns. */
/* tdbp is the pointer to the new table descriptor. */
/***********************************************************************/
XSRCCOL::XSRCCOL(XSRCCOL *col1, PTDB tdbp) : ODBCCOL(col1, tdbp)
- {
+{
Flag = col1->Flag;
- } // end of XSRCCOL copy constructor
+} // end of XSRCCOL copy constructor
/***********************************************************************/
/* ReadColumn: set column value according to Flag. */
/***********************************************************************/
void XSRCCOL::ReadColumn(PGLOBAL g)
- {
+{
PTDBXDBC tdbp = (PTDBXDBC)To_Tdb;
switch (Flag) {
@@ -1335,15 +1336,15 @@ void XSRCCOL::ReadColumn(PGLOBAL g)
default: Value->SetValue_psz("Invalid Flag"); break;
} // endswitch Flag
- } // end of ReadColumn
+} // end of ReadColumn
/***********************************************************************/
/* WriteColumn: Should never be called. */
/***********************************************************************/
void XSRCCOL::WriteColumn(PGLOBAL g)
- {
+{
// Should never be called
- } // end of WriteColumn
+} // end of WriteColumn
/* ---------------------------TDBDRV class --------------------------- */
@@ -1351,9 +1352,9 @@ void XSRCCOL::WriteColumn(PGLOBAL g)
/* GetResult: Get the list of ODBC drivers. */
/***********************************************************************/
PQRYRES TDBDRV::GetResult(PGLOBAL g)
- {
+{
return ODBCDrivers(g, Maxres, false);
- } // end of GetResult
+} // end of GetResult
/* ---------------------------TDBSRC class --------------------------- */
@@ -1361,9 +1362,9 @@ PQRYRES TDBDRV::GetResult(PGLOBAL g)
/* GetResult: Get the list of ODBC data sources. */
/***********************************************************************/
PQRYRES TDBSRC::GetResult(PGLOBAL g)
- {
+{
return ODBCDataSources(g, Maxres, false);
- } // end of GetResult
+} // end of GetResult
/* ---------------------------TDBOTB class --------------------------- */
@@ -1371,7 +1372,7 @@ PQRYRES TDBSRC::GetResult(PGLOBAL g)
/* TDBOTB class constructor. */
/***********************************************************************/
TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp)
- {
+{
Dsn = tdp->GetConnect();
Schema = tdp->GetTabschema();
Tab = tdp->GetTabname();
@@ -1381,15 +1382,15 @@ TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp)
Ops.Cto = tdp->Cto;
Ops.Qto = tdp->Qto;
Ops.UseCnc = tdp->UseCnc;
- } // end of TDBOTB constructor
+} // end of TDBOTB constructor
/***********************************************************************/
/* GetResult: Get the list of ODBC tables. */
/***********************************************************************/
PQRYRES TDBOTB::GetResult(PGLOBAL g)
- {
+{
return ODBCTables(g, Dsn, Schema, Tab, Tabtyp, Maxres, false, &Ops);
- } // end of GetResult
+} // end of GetResult
/* ---------------------------TDBOCL class --------------------------- */
@@ -1405,8 +1406,8 @@ TDBOCL::TDBOCL(PODEF tdp) : TDBOTB(tdp)
/* GetResult: Get the list of ODBC table columns. */
/***********************************************************************/
PQRYRES TDBOCL::GetResult(PGLOBAL g)
- {
+{
return ODBCColumns(g, Dsn, Schema, Tab, Colpat, Maxres, false, &Ops);
- } // end of GetResult
+} // end of GetResult
/* ------------------------ End of Tabodbc --------------------------- */
diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp
index c96e0844497..d808bd5ecd4 100644
--- a/storage/connect/tabxml.cpp
+++ b/storage/connect/tabxml.cpp
@@ -163,8 +163,11 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
return NULL;
tdp->Tabname = tab;
+ tdp->Tabname = (char*)GetStringTableOption(g, topt, "Tabname", tab);
+ tdp->Rowname = (char*)GetStringTableOption(g, topt, "Rownode", NULL);
tdp->Zipped = GetBooleanTableOption(g, topt, "Zipped", false);
tdp->Entry = GetStringTableOption(g, topt, "Entry", NULL);
+ tdp->Skip = GetBooleanTableOption(g, topt, "Skipnull", false);
if (!(op = GetStringTableOption(g, topt, "Xmlsup", NULL)))
#if defined(__WIN__)
@@ -280,7 +283,9 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
if (!vp->atp)
node = vp->nl->GetItem(g, vp->k++, tdp->Usedom ? node : NULL);
- strncat(fmt, colname, XLEN(fmt));
+ if (!j)
+ strncat(fmt, colname, XLEN(fmt));
+
strncat(fmt, "/", XLEN(fmt));
strncat(xcol->Name, "_", XLEN(xcol->Name));
j++;
@@ -302,6 +307,7 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
case RC_INFO:
PushWarning(g, txmp);
case RC_OK:
+ xcol->Cbn = !strlen(buf);
break;
default:
goto err;
@@ -327,9 +333,9 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
xcp->Len = MY_MAX(xcp->Len, xcol->Len);
xcp->Scale = MY_MAX(xcp->Scale, xcol->Scale);
- xcp->Cbn |= xcol->Cbn;
+ xcp->Cbn |= (xcol->Cbn || !xcol->Len);
xcp->Found = true;
- } else {
+ } else if(xcol->Len || !tdp->Skip) {
// New column
xcp = new(g) XMCOL(g, xcol, fmt, i);
length[0] = MY_MAX(length[0], strlen(xcol->Name));
@@ -344,7 +350,8 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
n++;
} // endif xcp
- pxcp = xcp;
+ if (xcp)
+ pxcp = xcp;
if (vp->atp)
vp->atp = vp->atp->GetNext(g);
@@ -445,6 +452,7 @@ XMLDEF::XMLDEF(void)
Usedom = false;
Zipped = false;
Mulentries = false;
+ Skip = false;
} // end of XMLDEF constructor
/***********************************************************************/
@@ -682,6 +690,14 @@ PTDB TDBXML::Clone(PTABS t)
} // end of Clone
/***********************************************************************/
+/* Must not be in tabxml.h because of OEM tables */
+/***********************************************************************/
+const CHARSET_INFO *TDBXML::data_charset()
+{
+ return &my_charset_utf8_general_ci;
+} // end of data_charset
+
+/***********************************************************************/
/* Allocate XML column description block. */
/***********************************************************************/
PCOL TDBXML::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
@@ -806,127 +822,141 @@ bool TDBXML::Initialize(PGLOBAL g)
} // endif Bufdone
#if !defined(UNIX)
- if (!Root) try {
+ if (!Root) try {
#else
- if (!Root) {
+ if (!Root) {
#endif
- char tabpath[64], filename[_MAX_PATH];
-
- // We used the file name relative to recorded datapath
- PlugSetPath(filename, Xfile, GetPath());
-
- // Load or re-use the table file
- rc = LoadTableFile(g, filename);
-
- if (rc == RC_OK) {
- // Get root node
- if (!(Root = Docp->GetRoot(g))) {
- // This should never happen as load should have failed
- strcpy(g->Message, MSG(EMPTY_DOC));
- goto error;
- } // endif Root
-
- // If tabname is not an Xpath,
- // construct one that will find it anywhere
- if (!strchr(Tabname, '/'))
- strcat(strcpy(tabpath, "//"), Tabname);
- else
- strcpy(tabpath, Tabname);
-
- // Evaluate table xpath
- if ((TabNode = Root->SelectSingleNode(g, tabpath))) {
- if (TabNode->GetType() != XML_ELEMENT_NODE) {
- sprintf(g->Message, MSG(BAD_NODE_TYPE), TabNode->GetType());
- goto error;
- } // endif Type
-
- } else if (Mode == MODE_INSERT && XmlDB) {
- // We are adding a new table to a multi-table file
-
- // If XmlDB is not an Xpath,
- // construct one that will find it anywhere
- if (!strchr(XmlDB, '/'))
- strcat(strcpy(tabpath, "//"), XmlDB);
- else
- strcpy(tabpath, XmlDB);
-
- if (!(DBnode = Root->SelectSingleNode(g, tabpath))) {
- // DB node does not exist yet; we cannot create it
- // because we don't know where it should be placed
- sprintf(g->Message, MSG(MISSING_NODE), XmlDB, Xfile);
- goto error;
- } // endif DBnode
-
- if (!(TabNode = DBnode->AddChildNode(g, Tabname))) {
- sprintf(g->Message, MSG(FAIL_ADD_NODE), Tabname);
- goto error;
- } // endif TabNode
-
- DBnode->AddText(g, "\n");
- } else
- TabNode = Root; // Try this ?
-
- } else if (rc == RC_NF || rc == RC_EF) {
- // The XML file does not exist or is void
- if (Mode == MODE_INSERT) {
- // New Document
- char buf[64];
-
- // Create the XML node
- if (Docp->NewDoc(g, "1.0")) {
- strcpy(g->Message, MSG(NEW_DOC_FAILED));
- goto error;
- } // endif NewDoc
-
- // Now we can link the Xblock
- To_Xb = Docp->LinkXblock(g, Mode, rc, filename);
-
- // Add a CONNECT comment node
- strcpy(buf, " Created by the MariaDB CONNECT Storage Engine");
- Docp->AddComment(g, buf);
-
- if (XmlDB) {
- // This is a multi-table file
- DBnode = Root = Docp->NewRoot(g, XmlDB);
- DBnode->AddText(g, "\n");
- TabNode = DBnode->AddChildNode(g, Tabname);
- DBnode->AddText(g, "\n");
- } else
- TabNode = Root = Docp->NewRoot(g, Tabname);
-
- if (TabNode == NULL || Root == NULL) {
- strcpy(g->Message, MSG(XML_INIT_ERROR));
- goto error;
- } else if (SetTabNode(g))
- goto error;
-
- } else {
- sprintf(g->Message, MSG(FILE_UNFOUND), Xfile);
-
- if (Mode == MODE_READ) {
- PushWarning(g, this);
- Void = true;
- } // endif Mode
-
- goto error;
- } // endif Mode
-
- } else if (rc == RC_INFO) {
- // Loading failed
- sprintf(g->Message, MSG(LOADING_FAILED), Xfile);
- goto error;
- } else // (rc == RC_FX)
- goto error;
-
- // Get row node list
- if (Rowname)
- Nlist = TabNode->SelectNodes(g, Rowname);
- else
- Nlist = TabNode->GetChildElements(g);
-
- Docp->SetNofree(true); // For libxml2
+ char tabpath[64], filename[_MAX_PATH];
+
+ // We used the file name relative to recorded datapath
+ PlugSetPath(filename, Xfile, GetPath());
+
+ // Load or re-use the table file
+ rc = LoadTableFile(g, filename);
+
+ if (rc == RC_OK) {
+ // Get root node
+ if (!(Root = Docp->GetRoot(g))) {
+ // This should never happen as load should have failed
+ strcpy(g->Message, MSG(EMPTY_DOC));
+ goto error;
+ } // endif Root
+
+ // If tabname is not an Xpath,
+ // construct one that will find it anywhere
+ if (!strchr(Tabname, '/'))
+ strcat(strcpy(tabpath, "//"), Tabname);
+ else
+ strcpy(tabpath, Tabname);
+
+ // Evaluate table xpath
+ if ((TabNode = Root->SelectSingleNode(g, tabpath))) {
+ if (TabNode->GetType() != XML_ELEMENT_NODE) {
+ sprintf(g->Message, MSG(BAD_NODE_TYPE), TabNode->GetType());
+ goto error;
+ } // endif Type
+
+ } else if (Mode == MODE_INSERT && XmlDB) {
+ // We are adding a new table to a multi-table file
+
+ // If XmlDB is not an Xpath,
+ // construct one that will find it anywhere
+ if (!strchr(XmlDB, '/'))
+ strcat(strcpy(tabpath, "//"), XmlDB);
+ else
+ strcpy(tabpath, XmlDB);
+
+ if (!(DBnode = Root->SelectSingleNode(g, tabpath))) {
+ // DB node does not exist yet; we cannot create it
+ // because we don't know where it should be placed
+ sprintf(g->Message, MSG(MISSING_NODE), XmlDB, Xfile);
+ goto error;
+ } // endif DBnode
+
+ if (!(TabNode = DBnode->AddChildNode(g, Tabname))) {
+ sprintf(g->Message, MSG(FAIL_ADD_NODE), Tabname);
+ goto error;
+ } // endif TabNode
+
+ DBnode->AddText(g, "\n");
+ } else {
+ TabNode = Root; // Try this ?
+ Tabname = TabNode->GetName(g);
+ } // endif's
+
+ } else if (rc == RC_NF || rc == RC_EF) {
+ // The XML file does not exist or is void
+ if (Mode == MODE_INSERT) {
+ // New Document
+ char buf[64];
+
+ // Create the XML node
+ if (Docp->NewDoc(g, "1.0")) {
+ strcpy(g->Message, MSG(NEW_DOC_FAILED));
+ goto error;
+ } // endif NewDoc
+
+ // Now we can link the Xblock
+ To_Xb = Docp->LinkXblock(g, Mode, rc, filename);
+
+ // Add a CONNECT comment node
+ strcpy(buf, " Created by the MariaDB CONNECT Storage Engine");
+ Docp->AddComment(g, buf);
+
+ if (XmlDB) {
+ // This is a multi-table file
+ DBnode = Root = Docp->NewRoot(g, XmlDB);
+ DBnode->AddText(g, "\n");
+ TabNode = DBnode->AddChildNode(g, Tabname);
+ DBnode->AddText(g, "\n");
+ } else
+ TabNode = Root = Docp->NewRoot(g, Tabname);
+
+ if (TabNode == NULL || Root == NULL) {
+ strcpy(g->Message, MSG(XML_INIT_ERROR));
+ goto error;
+ } else if (SetTabNode(g))
+ goto error;
+
+ } else {
+ sprintf(g->Message, MSG(FILE_UNFOUND), Xfile);
+
+ if (Mode == MODE_READ) {
+ PushWarning(g, this);
+ Void = true;
+ } // endif Mode
+
+ goto error;
+ } // endif Mode
+
+ } else if (rc == RC_INFO) {
+ // Loading failed
+ sprintf(g->Message, MSG(LOADING_FAILED), Xfile);
+ goto error;
+ } else // (rc == RC_FX)
+ goto error;
+
+ if (!Rowname) {
+ for (PXNODE n = TabNode->GetChild(g); n; n = n->GetNext(g))
+ if (n->GetType() == XML_ELEMENT_NODE) {
+ Rowname = n->GetName(g);
+ break;
+ } // endif Type
+
+ if (!Rowname)
+ Rowname = TabNode->GetName(g);
+ } // endif Rowname
+
+ // Get row node list
+ if (strcmp(Rowname, Tabname))
+ Nlist = TabNode->SelectNodes(g, Rowname);
+ else
+ Nrow = 1;
+
+
+ Docp->SetNofree(true); // For libxml2
#if defined(__WIN__)
- } catch(_com_error e) {
+ } catch (_com_error e) {
// We come here if a DOM command threw an error
char buf[128];
@@ -1213,10 +1243,14 @@ int TDBXML::ReadDB(PGLOBAL g)
htrc("TDBXML ReadDB: Irow=%d RowNode=%p\n", Irow, RowNode);
// Get the new row node
- if ((RowNode = Nlist->GetItem(g, Irow, RowNode)) == NULL) {
- sprintf(g->Message, MSG(MISSING_ROWNODE), Irow);
- return RC_FX;
- } // endif RowNode
+ if (Nlist) {
+ if ((RowNode = Nlist->GetItem(g, Irow, RowNode)) == NULL) {
+ sprintf(g->Message, MSG(MISSING_ROWNODE), Irow);
+ return RC_FX;
+ } // endif RowNode
+
+ } else
+ RowNode = TabNode;
if (Colname && Coltype == 2)
Clist = RowNode->SelectNodes(g, Colname, Clist);
@@ -1271,6 +1305,7 @@ int TDBXML::WriteDB(PGLOBAL g)
/***********************************************************************/
int TDBXML::DeleteDB(PGLOBAL g, int irc)
{
+ // TODO: Handle null Nlist
if (irc == RC_FX) {
// Delete all rows
for (Irow = 0; Irow < Nrow; Irow++)
@@ -2209,8 +2244,9 @@ void XPOSCOL::WriteColumn(PGLOBAL g)
TDBXCT::TDBXCT(PXMLDEF tdp) : TDBCAT(tdp)
{
Topt = tdp->GetTopt();
- Db = (char*)tdp->GetDB();
- Tabn = tdp->Tabname;
+ //Db = (char*)tdp->GetDB();
+ Db = (char*)tdp->Schema;
+ Tabn = tdp->Tabname;
} // end of TDBXCT constructor
/***********************************************************************/
diff --git a/storage/connect/tabxml.h b/storage/connect/tabxml.h
index f55b7d98de7..fb3913f08ea 100644
--- a/storage/connect/tabxml.h
+++ b/storage/connect/tabxml.h
@@ -9,6 +9,8 @@ typedef class XMLDEF *PXMLDEF;
typedef class TDBXML *PTDBXML;
typedef class XMLCOL *PXMLCOL;
+DllExport PQRYRES XMLColumns(PGLOBAL, char *, char *, PTOS, bool);
+
/* --------------------------- XML classes --------------------------- */
/***********************************************************************/
@@ -50,6 +52,7 @@ class DllExport XMLDEF : public TABDEF { /* Logical table description */
bool Usedom; /* True: DOM, False: libxml2 */
bool Zipped; /* True: Zipped XML file(s) */
bool Mulentries; /* True: multiple entries in zip file*/
+ bool Skip; /* Skip null columns */
}; // end of XMLDEF
#if defined(INCLUDE_TDBXML)
@@ -100,8 +103,7 @@ class DllExport TDBXML : public TDBASE {
virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g);
virtual int CheckWrite(PGLOBAL g) {Checked = true; return 0;}
- virtual const CHARSET_INFO *data_charset()
- {return &my_charset_utf8_general_ci;}
+ virtual const CHARSET_INFO *data_charset();
protected:
// Members
diff --git a/storage/connect/user_connect.cc b/storage/connect/user_connect.cc
index e2d3b664aeb..a2a8faf9b38 100644
--- a/storage/connect/user_connect.cc
+++ b/storage/connect/user_connect.cc
@@ -107,7 +107,7 @@ bool user_connect::user_init()
g= PlugInit(NULL, worksize);
// Check whether the initialization is complete
- if (!g || !g->Sarea || PlugSubSet(g, g->Sarea, g->Sarea_Size)
+ if (!g || !g->Sarea || PlugSubSet(g->Sarea, g->Sarea_Size)
|| !(dup= PlgMakeUser(g))) {
if (g)
printf("%s\n", g->Message);
@@ -172,7 +172,7 @@ bool user_connect::CheckCleanup(bool force)
} // endif worksize
- PlugSubSet(g, g->Sarea, g->Sarea_Size);
+ PlugSubSet(g->Sarea, g->Sarea_Size);
g->Xchk = NULL;
g->Createas = 0;
g->Alchecked = 0;