summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2015-05-07 18:02:31 +0200
committerOlivier Bertrand <bertrandop@gmail.com>2015-05-07 18:02:31 +0200
commit5fa2a6ce819221a7480b6f658ec8960ed8797b1b (patch)
tree2cfadeb64a8267ec3bffbe8b6ba8d35d557ed150
parent7704fde0c6fcb4d337d315c00ae366a7776a2f41 (diff)
parentc387e7d8e2b5d69aa05514ec9b08a8ea7fdf470c (diff)
downloadmariadb-git-5fa2a6ce819221a7480b6f658ec8960ed8797b1b.tar.gz
Merge branch 'ob-10.0' into 10.0
-rw-r--r--storage/connect/RelWithDebInfo/ha_connect.expbin0 -> 390776 bytes
-rw-r--r--storage/connect/connect.dir/RelWithDebInfo/ha_connect.dll.intermediate.manifest10
-rw-r--r--storage/connect/connect.dir/RelWithDebInfo/mt.dep1
-rw-r--r--storage/connect/connect.dir/RelWithDebInfo/vc90.idbbin0 -> 1002496 bytes
-rw-r--r--storage/connect/connect.dir/RelWithDebInfo/versioninfo_dll.resbin0 -> 392 bytes
-rw-r--r--storage/connect/filamdbf.cpp25
-rw-r--r--storage/connect/global.h2
-rw-r--r--storage/connect/ha_connect.cc73
-rw-r--r--storage/connect/jsonudf.cpp94
-rw-r--r--storage/connect/mysql-test/connect/r/json.result12
-rw-r--r--storage/connect/mysql-test/connect/r/xml_html.result32
-rw-r--r--storage/connect/mysql-test/connect/std_data/beers.xml16
-rw-r--r--storage/connect/mysql-test/connect/std_data/coffee.htm24
-rw-r--r--storage/connect/mysql-test/connect/t/xml_html.test39
-rw-r--r--storage/connect/tabjson.cpp21
-rw-r--r--storage/connect/tabjson.h3
-rw-r--r--storage/connect/tabmul.cpp6
-rw-r--r--storage/connect/tabmysql.cpp11
-rw-r--r--storage/connect/tabtbl.cpp2
-rw-r--r--storage/connect/tabutil.cpp7
-rw-r--r--storage/connect/tabxml.cpp5
-rw-r--r--storage/connect/value.cpp2
22 files changed, 295 insertions, 90 deletions
diff --git a/storage/connect/RelWithDebInfo/ha_connect.exp b/storage/connect/RelWithDebInfo/ha_connect.exp
new file mode 100644
index 00000000000..270a1ae0b18
--- /dev/null
+++ b/storage/connect/RelWithDebInfo/ha_connect.exp
Binary files differ
diff --git a/storage/connect/connect.dir/RelWithDebInfo/ha_connect.dll.intermediate.manifest b/storage/connect/connect.dir/RelWithDebInfo/ha_connect.dll.intermediate.manifest
new file mode 100644
index 00000000000..ecea6f7f567
--- /dev/null
+++ b/storage/connect/connect.dir/RelWithDebInfo/ha_connect.dll.intermediate.manifest
@@ -0,0 +1,10 @@
+<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
+<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level='asInvoker' uiAccess='false' />
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>
diff --git a/storage/connect/connect.dir/RelWithDebInfo/mt.dep b/storage/connect/connect.dir/RelWithDebInfo/mt.dep
new file mode 100644
index 00000000000..07d724edfa8
--- /dev/null
+++ b/storage/connect/connect.dir/RelWithDebInfo/mt.dep
@@ -0,0 +1 @@
+La ressource de manifeste a ‚t‚ mise … jour pour la derniŠre fois … 15:30:20,49 le 24/04/2015
diff --git a/storage/connect/connect.dir/RelWithDebInfo/vc90.idb b/storage/connect/connect.dir/RelWithDebInfo/vc90.idb
new file mode 100644
index 00000000000..40b22184aad
--- /dev/null
+++ b/storage/connect/connect.dir/RelWithDebInfo/vc90.idb
Binary files differ
diff --git a/storage/connect/connect.dir/RelWithDebInfo/versioninfo_dll.res b/storage/connect/connect.dir/RelWithDebInfo/versioninfo_dll.res
new file mode 100644
index 00000000000..1482ce4193a
--- /dev/null
+++ b/storage/connect/connect.dir/RelWithDebInfo/versioninfo_dll.res
Binary files differ
diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp
index 98b8bb6fd95..7acbba309b2 100644
--- a/storage/connect/filamdbf.cpp
+++ b/storage/connect/filamdbf.cpp
@@ -115,6 +115,7 @@ typedef struct _descriptor {
/* Side effects: */
/* Moves file pointer to byte 32; fills buffer at buf with */
/* first 32 bytes of file. */
+/* Converts numeric values to platform byte ordering (LE in file) */
/****************************************************************************/
static int dbfhead(PGLOBAL g, FILE *file, PSZ fn, DBFHEADER *buf)
{
@@ -142,6 +143,11 @@ static int dbfhead(PGLOBAL g, FILE *file, PSZ fn, DBFHEADER *buf)
} else
strcpy(g->Message, MSG(DBASE_FILE));
+ // Convert numeric fields to have them in platform byte ordering
+ buf->Records = uint4korr(&buf->Records);
+ buf->Headlen = uint2korr(&buf->Headlen);
+ buf->Reclen = uint2korr(&buf->Reclen);
+
// Check last byte(s) of header
if (fseek(file, buf->Headlen - dbc, SEEK_SET) != 0) {
sprintf(g->Message, MSG(BAD_HEADER), fn);
@@ -565,8 +571,8 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
header->Filedate[0] = datm->tm_year - 100;
header->Filedate[1] = datm->tm_mon + 1;
header->Filedate[2] = datm->tm_mday;
- header->Headlen = (ushort)hlen;
- header->Reclen = (ushort)reclen;
+ int2store(&header->Headlen, hlen);
+ int2store(&header->Reclen, reclen);
descp = (DESCRIPTOR*)header;
// Currently only standard Xbase types are supported
@@ -729,7 +735,7 @@ bool DBFFAM::CopyHeader(PGLOBAL g)
if (Headlen) {
void *hdr = PlugSubAlloc(g, NULL, Headlen);
size_t n, hlen = (size_t)Headlen;
- int pos = ftell(Stream);
+ int pos = ftell(Stream);
if (fseek(Stream, 0, SEEK_SET))
strcpy(g->Message, "Seek error in CopyHeader");
@@ -863,13 +869,14 @@ void DBFFAM::CloseTableFile(PGLOBAL g, bool abort)
if (n > Records) {
// Update the number of rows in the file header
- char filename[_MAX_PATH];
+ char filename[_MAX_PATH], nRecords[4];
+ int4store(&nRecords, n);
PlugSetPath(filename, To_File, Tdbp->GetPath());
if ((Stream= global_fopen(g, MSGID_OPEN_MODE_STRERROR, filename, "r+b")))
{
fseek(Stream, 4, SEEK_SET); // Get header.Records position
- fwrite(&n, sizeof(int), 1, Stream);
+ fwrite(nRecords, sizeof(nRecords), 1, Stream);
fclose(Stream);
Stream= NULL;
Records= n; // Update Records value
@@ -944,13 +951,13 @@ bool DBMFAM::AllocateBuffer(PGLOBAL g)
/************************************************************************/
DBFHEADER *hp = (DBFHEADER*)Memory;
- if (Lrecl != (int)hp->Reclen) {
- sprintf(g->Message, MSG(BAD_LRECL), Lrecl, hp->Reclen);
+ if (Lrecl != (int)uint2korr(&hp->Reclen)) {
+ sprintf(g->Message, MSG(BAD_LRECL), Lrecl, uint2korr(&hp->Reclen));
return true;
} // endif Lrecl
- Records = (int)hp->Records;
- Headlen = (int)hp->Headlen;
+ Records = (int)uint4korr(&hp->Records);
+ Headlen = (int)uint2korr(&hp->Headlen);
} // endif Headlen
/**************************************************************************/
diff --git a/storage/connect/global.h b/storage/connect/global.h
index a67bb605755..10564d09815 100644
--- a/storage/connect/global.h
+++ b/storage/connect/global.h
@@ -118,7 +118,7 @@ extern "C" {
/* Static variables */
/***********************************************************************/
#if defined(STORAGE)
- char sys_stamp[4] = SYS_STAMP;
+ char sys_stamp[5] = SYS_STAMP;
#else
extern char sys_stamp[];
#endif
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index a3f88bfe7eb..f2827f56cd8 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -168,35 +168,21 @@
#define JSONMAX 10 // JSON Default max grp size
extern "C" {
- char version[]= "Version 1.03.0006 April 12, 2015";
-
+ char version[]= "Version 1.03.0007 April 30, 2015";
#if defined(WIN32)
- char compver[]= "Version 1.03.0006 " __DATE__ " " __TIME__;
+ char compver[]= "Version 1.03.0007 " __DATE__ " " __TIME__;
char slash= '\\';
#else // !WIN32
char slash= '/';
#endif // !WIN32
-
-// int trace= 0; // The general trace value
-// ulong xconv= 0; // The type conversion option
-// int zconv= 0; // The text conversion size
} // extern "C"
#if defined(XMAP)
my_bool xmap= false;
#endif // XMAP
-// uint worksize= 0;
ulong ha_connect::num= 0;
-//int DTVAL::Shift= 0;
-/* CONNECT system variables */
-//atic int conv_size= 0;
-//atic uint work_size= 0;
-//atic ulong type_conv= 0;
-#if defined(XMAP)
-//atic my_bool indx_map= 0;
-#endif // XMAP
#if defined(XMSG)
extern "C" {
char *msg_path;
@@ -613,9 +599,9 @@ DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR name, LPCSTR dir)
delete_table method in handler.cc
*/
static const char *ha_connect_exts[]= {
- ".dos", ".fix", ".csv", ".bin", ".fmt", ".dbf", ".xml", ".ini", ".vec",
- ".dnx", ".fnx", ".bnx", ".vnx", ".dbx", ".dop", ".fop", ".bop", ".vop",
- NULL};
+ ".dos", ".fix", ".csv", ".bin", ".fmt", ".dbf", ".xml", ".json", ".ini",
+ ".vec", ".dnx", ".fnx", ".bnx", ".vnx", ".dbx", ".dop", ".fop", ".bop",
+ ".vop", NULL};
/**
@brief
@@ -4646,8 +4632,13 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to)
} // endif pos
- } else // Avoid infamous DBUG_ASSERT
- thd->get_stmt_da()->reset_diagnostics_area();
+ } // endif open_table_def
+
+// This below was done to avoid DBUG_ASSERT in some case that
+// we don't know anymore what they were. It was suppressed because
+// it did cause assertion in other cases (see MDEV-7935)
+// } else // Avoid infamous DBUG_ASSERT
+// thd->get_stmt_da()->reset_diagnostics_area();
free_table_share(share);
} else // Temporary file
@@ -4730,6 +4721,25 @@ ha_rows ha_connect::records_in_range(uint inx, key_range *min_key,
DBUG_RETURN(rows);
} // end of records_in_range
+// Used to check whether a MYSQL table is created on itself
+bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host,
+ const char *db, char *tab, const char *src, int port)
+{
+ if (src)
+ return false;
+ else if (host && stricmp(host, "localhost") && strcmp(host, "127.0.0.1"))
+ return false;
+ else if (db && stricmp(db, s->db.str))
+ return false;
+ else if (tab && stricmp(tab, s->table_name.str))
+ return false;
+ else if (port && port != (signed)GetDefaultPort())
+ return false;
+
+ strcpy(g->Message, "This MySQL table is defined on itself");
+ return true;
+} // end of CheckSelf
+
/**
Convert an ISO-8859-1 column name to UTF-8
*/
@@ -4891,7 +4901,7 @@ static int init_table_share(THD* thd,
oom|= sql->append(' ');
oom|= sql->append(opt->name);
oom|= sql->append('=');
- oom|= sql->append(vull ? "ON" : "OFF");
+ oom|= sql->append(vull ? "YES" : "NO");
} // endif vull
break;
@@ -4933,25 +4943,6 @@ static int init_table_share(THD* thd,
sql->ptr(), sql->length());
} // end of init_table_share
-// Used to check whether a MYSQL table is created on itself
-bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host,
- const char *db, char *tab, const char *src, int port)
-{
- if (src)
- return false;
- else if (host && stricmp(host, "localhost") && strcmp(host, "127.0.0.1"))
- return false;
- else if (db && stricmp(db, s->db.str))
- return false;
- else if (tab && stricmp(tab, s->table_name.str))
- return false;
- else if (port && port != (signed)GetDefaultPort())
- return false;
-
- strcpy(g->Message, "This MySQL table is defined on itself");
- return true;
-} // end of CheckSelf
-
/**
@brief
connect_assisted_discovery() is called when creating a table with no columns.
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index 194cb6defd6..1afd79bec05 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -17,40 +17,45 @@
#include "json.h"
#define MEMFIX 512
+#define UDF_EXEC_ARGS \
+ UDF_INIT*, UDF_ARGS*, char*, unsigned long*, char*, char*
uint GetJsonGrpSize(void);
extern "C" {
DllExport my_bool Json_Value_init(UDF_INIT*, UDF_ARGS*, char*);
-DllExport char *Json_Value(UDF_INIT*, UDF_ARGS*, char*,
- unsigned long*, char *, char *);
+DllExport char *Json_Value(UDF_EXEC_ARGS);
DllExport void Json_Value_deinit(UDF_INIT*);
+
DllExport my_bool Json_Array_init(UDF_INIT*, UDF_ARGS*, char*);
-DllExport char *Json_Array(UDF_INIT*, UDF_ARGS*, char*,
- unsigned long*, char *, char *);
+DllExport char *Json_Array(UDF_EXEC_ARGS);
DllExport void Json_Array_deinit(UDF_INIT*);
+
DllExport my_bool Json_Array_Add_init(UDF_INIT*, UDF_ARGS*, char*);
-DllExport char *Json_Array_Add(UDF_INIT*, UDF_ARGS*, char*,
- unsigned long*, char *, char *);
+DllExport char *Json_Array_Add(UDF_EXEC_ARGS);
DllExport void Json_Array_Add_deinit(UDF_INIT*);
+
+DllExport my_bool Json_Array_Delete_init(UDF_INIT*, UDF_ARGS*, char*);
+DllExport char *Json_Array_Delete(UDF_EXEC_ARGS);
+DllExport void Json_Array_Delete_deinit(UDF_INIT*);
+
DllExport my_bool Json_Object_init(UDF_INIT*, UDF_ARGS*, char*);
-DllExport char *Json_Object(UDF_INIT*, UDF_ARGS*, char*,
- unsigned long*, char *, char *);
+DllExport char *Json_Object(UDF_EXEC_ARGS);
DllExport void Json_Object_deinit(UDF_INIT*);
+
DllExport my_bool Json_Object_Nonull_init(UDF_INIT*, UDF_ARGS*, char*);
-DllExport char *Json_Object_Nonull(UDF_INIT*, UDF_ARGS*, char*,
- unsigned long*, char *, char *);
+DllExport char *Json_Object_Nonull(UDF_EXEC_ARGS);
DllExport void Json_Object_Nonull_deinit(UDF_INIT*);
+
DllExport my_bool Json_Array_Grp_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport void Json_Array_Grp_add(UDF_INIT *, UDF_ARGS *, char *, char *);
-DllExport char *Json_Array_Grp(UDF_INIT*, UDF_ARGS*, char*,
- unsigned long*, char *, char *);
+DllExport char *Json_Array_Grp(UDF_EXEC_ARGS);
DllExport void Json_Array_Grp_clear(UDF_INIT *, char *, char *);
DllExport void Json_Array_Grp_deinit(UDF_INIT*);
+
DllExport my_bool Json_Object_Grp_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport void Json_Object_Grp_add(UDF_INIT *, UDF_ARGS *, char *, char *);
-DllExport char *Json_Object_Grp(UDF_INIT*, UDF_ARGS*, char*,
- unsigned long*, char *, char *);
+DllExport char *Json_Object_Grp(UDF_EXEC_ARGS);
DllExport void Json_Object_Grp_clear(UDF_INIT *, char *, char *);
DllExport void Json_Object_Grp_deinit(UDF_INIT*);
} // extern "C"
@@ -405,6 +410,67 @@ void Json_Array_Add_deinit(UDF_INIT* initid)
} // end of Json_Array_Add_deinit
/***********************************************************************/
+/* Add values to a Json array. */
+/***********************************************************************/
+my_bool Json_Array_Delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+ unsigned long reslen, memlen;
+
+ if (args->arg_count != 2) {
+ strcpy(message, "Json_Value_Delete must have 2 arguments");
+ return true;
+ } else if (!IsJson(args, 0)) {
+ strcpy(message, "Json_Value_Delete first argument must be a json item");
+ return true;
+ } else
+ CalcLen(args, false, reslen, memlen);
+
+ return JsonInit(initid, message, reslen, memlen);
+} // end of Json_Array_Delete_init
+
+char *Json_Array_Delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
+ unsigned long *res_length, char *is_null, char *error)
+{
+ char *str;
+ int n;
+ PJVAL jvp;
+ PJAR arp;
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ PlugSubSet(g, g->Sarea, g->Sarea_Size);
+ jvp = MakeValue(g, args, 0);
+
+ if (jvp->GetValType() != TYPE_JAR) {
+ push_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, 0,
+ "First argument is not an array");
+ str = args->args[0];
+ } else if (args->arg_type[1] != INT_RESULT) {
+ push_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, 0,
+ "Second argument is not an integer");
+ str = args->args[0];
+ } else {
+ n = *(int*)args->args[1];
+ arp = jvp->GetArray();
+ arp->DeleteValue(n - 1);
+ arp->InitArray(g);
+
+ if (!(str = Serialize(g, arp, NULL, 0))) {
+ str = strcpy(result, g->Message);
+ push_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, 0, str);
+ } // endif str
+
+ } // endif's
+
+ *res_length = strlen(str);
+ return str;
+} // end of Json_Array_Delete
+
+void Json_Array_Delete_deinit(UDF_INIT* initid)
+{
+ PlugExit((PGLOBAL)initid->ptr);
+} // end of Json_Array_Delete_deinit
+
+/***********************************************************************/
/* Make a Json Oject containing all the parameters. */
/***********************************************************************/
my_bool Json_Object_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
diff --git a/storage/connect/mysql-test/connect/r/json.result b/storage/connect/mysql-test/connect/r/json.result
index fa6497e5bba..80b0a2cbc18 100644
--- a/storage/connect/mysql-test/connect/r/json.result
+++ b/storage/connect/mysql-test/connect/r/json.result
@@ -89,8 +89,8 @@ ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher L
UPDATE t1 SET AuthorFN = 'Philippe' WHERE AuthorLN = 'Knab';
SELECT * FROM t1 WHERE ISBN = '9782212090819';
ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher Location Year
-9782212090819 fr applications Philippe Bernadac Construire une application XML NULL NULL Eyrolles Paris 1999
-9782212090819 fr applications François Knab Construire une application XML NULL NULL Eyrolles Paris 1999
+9782212090819 fr applications Jean-Christophe Bernadac Construire une application XML NULL NULL Eyrolles Paris 1999
+9782212090819 fr applications Philippe Knab Construire une application XML NULL NULL Eyrolles Paris 1999
#
# To add an author a new table must be created
#
@@ -104,8 +104,8 @@ William J. Pardi
INSERT INTO t2 VALUES('Charles','Dickens');
SELECT * FROM t1;
ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher Location Year
-9782212090819 fr applications Philippe Bernadac Construire une application XML NULL NULL Eyrolles Paris 1999
-9782212090819 fr applications François Knab Construire une application XML NULL NULL Eyrolles Paris 1999
+9782212090819 fr applications Jean-Christophe Bernadac Construire une application XML NULL NULL Eyrolles Paris 1999
+9782212090819 fr applications Philippe Knab Construire une application XML NULL NULL Eyrolles Paris 1999
9782840825685 fr applications William J. Pardi XML en Action adapté de l'anglais par James Guerin Microsoft Press Paris 1999
9782840825685 fr applications Charles Dickens XML en Action adapté de l'anglais par James Guerin Microsoft Press Paris 1999
DROP TABLE t1;
@@ -127,11 +127,11 @@ line
"SUBJECT": "applications",
"AUTHOR": [
{
- "FIRSTNAME": "Philippe",
+ "FIRSTNAME": "Jean-Christophe",
"LASTNAME": "Bernadac"
},
{
- "FIRSTNAME": "François",
+ "FIRSTNAME": "Philippe",
"LASTNAME": "Knab"
}
],
diff --git a/storage/connect/mysql-test/connect/r/xml_html.result b/storage/connect/mysql-test/connect/r/xml_html.result
new file mode 100644
index 00000000000..7b5e0febe6e
--- /dev/null
+++ b/storage/connect/mysql-test/connect/r/xml_html.result
@@ -0,0 +1,32 @@
+Warnings:
+Warning 1105 No file name. Table will use t1.xml
+SET NAMES utf8;
+#
+# Testing HTML like XML file
+#
+CREATE TABLE beers (
+`Name` CHAR(16) FIELD_FORMAT='brandName',
+`Origin` CHAR(16) FIELD_FORMAT='origin',
+`Description` CHAR(32) FIELD_FORMAT='details')
+ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='beers.xml'
+TABNAME='table' OPTION_LIST='xmlsup=libxml2,rownode=tr,colnode=td';
+SELECT * FROM beers;
+Name Origin Description
+Huntsman Bath, UK Wonderful hop, light alcohol
+Tuborg Danmark In small bottles
+DROP TABLE beers;
+#
+# Testing HTML file
+#
+CREATE TABLE coffee (
+`Name` CHAR(16),
+`Cups` INT(8),
+`Type` CHAR(16),
+`Sugar` CHAR(4))
+ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='coffee.htm'
+TABNAME='TABLE' HEADER=1 OPTION_LIST='xmlsup=libxml2,Coltype=HTML';
+SELECT * FROM coffee;
+Name Cups Type Sugar
+T. Sexton 10 Espresso No
+J. Dinnen 5 Decaf Yes
+DROP TABLE coffee;
diff --git a/storage/connect/mysql-test/connect/std_data/beers.xml b/storage/connect/mysql-test/connect/std_data/beers.xml
new file mode 100644
index 00000000000..1abc77fe0f9
--- /dev/null
+++ b/storage/connect/mysql-test/connect/std_data/beers.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<Beers>
+ <table>
+ <th><td>Name</td><td>Origin</td><td>Description</td></th>
+ <tr>
+ <td><brandName>Huntsman</brandName></td>
+ <td><origin>Bath, UK</origin></td>
+ <td><details>Wonderful hop, light alcohol</details></td>
+ </tr>
+ <tr>
+ <td><brandName>Tuborg</brandName></td>
+ <td><origin>Danmark</origin></td>
+ <td><details>In small bottles</details></td>
+ </tr>
+ </table>
+</Beers>
diff --git a/storage/connect/mysql-test/connect/std_data/coffee.htm b/storage/connect/mysql-test/connect/std_data/coffee.htm
new file mode 100644
index 00000000000..95a23d5c0ad
--- /dev/null
+++ b/storage/connect/mysql-test/connect/std_data/coffee.htm
@@ -0,0 +1,24 @@
+<TABLE summary="This table charts the number of cups of coffe
+ consumed by each senator, the type of coffee (decaf
+ or regular), and whether taken with sugar.">
+ <CAPTION>Cups of coffee consumed by each senator</CAPTION>
+ <TR>
+ <TH>Name</TH>
+ <TH>Cups</TH>
+ <TH>Type of Coffee</TH>
+ <TH>Sugar?</TH>
+ </TR>
+ <TR>
+ <TD>T. Sexton</TD>
+ <TD>10</TD>
+ <TD>Espresso</TD>
+ <TD>No</TD>
+ </TR>
+ <TR>
+ <TD>J. Dinnen</TD>
+ <TD>5</TD>
+ <TD>Decaf</TD>
+ <TD>Yes</TD>
+ </TR>
+</TABLE>
+
diff --git a/storage/connect/mysql-test/connect/t/xml_html.test b/storage/connect/mysql-test/connect/t/xml_html.test
new file mode 100644
index 00000000000..1c84b46ec38
--- /dev/null
+++ b/storage/connect/mysql-test/connect/t/xml_html.test
@@ -0,0 +1,39 @@
+--source have_libxml2.inc
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+
+SET NAMES utf8;
+
+--copy_file $MTR_SUITE_DIR/std_data/beers.xml $MYSQLD_DATADIR/test/beers.xml
+--copy_file $MTR_SUITE_DIR/std_data/coffee.htm $MYSQLD_DATADIR/test/coffee.htm
+
+--echo #
+--echo # Testing HTML like XML file
+--echo #
+CREATE TABLE beers (
+`Name` CHAR(16) FIELD_FORMAT='brandName',
+`Origin` CHAR(16) FIELD_FORMAT='origin',
+`Description` CHAR(32) FIELD_FORMAT='details')
+ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='beers.xml'
+TABNAME='table' OPTION_LIST='xmlsup=libxml2,rownode=tr,colnode=td';
+SELECT * FROM beers;
+DROP TABLE beers;
+
+--echo #
+--echo # Testing HTML file
+--echo #
+CREATE TABLE coffee (
+`Name` CHAR(16),
+`Cups` INT(8),
+`Type` CHAR(16),
+`Sugar` CHAR(4))
+ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='coffee.htm'
+TABNAME='TABLE' HEADER=1 OPTION_LIST='xmlsup=libxml2,Coltype=HTML';
+SELECT * FROM coffee;
+DROP TABLE coffee;
+
+#
+# Clean up
+#
+--remove_file $MYSQLD_DATADIR/test/beers.xml
+--remove_file $MYSQLD_DATADIR/test/coffee.htm
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index 4432f164cf8..0231b369fc1 100644
--- a/storage/connect/tabjson.cpp
+++ b/storage/connect/tabjson.cpp
@@ -968,6 +968,20 @@ bool JSONCOL::ParseJpath(PGLOBAL g)
else if (!Jpath)
Jpath = Name;
+ if (To_Tdb->GetOrig()) {
+ // This is an updated column, get nodes from origin
+ for (PJCOL colp = (PJCOL)Tjp->GetColumns(); colp;
+ colp = (PJCOL)colp->GetNext())
+ if (!stricmp(Name, colp->GetName())) {
+ Nod = colp->Nod;
+ Nodes = colp->Nodes;
+ goto fin;
+ } // endif Name
+
+ sprintf(g->Message, "Cannot parse updated column %s", Name);
+ return true;
+ } // endif To_Orig
+
pbuf = PlugDup(g, Jpath);
// The Jpath must be analyzed
@@ -998,6 +1012,7 @@ bool JSONCOL::ParseJpath(PGLOBAL g)
} // endfor i, p
+ fin:
MulVal = AllocateValue(g, Value);
Parsed = true;
return false;
@@ -1147,7 +1162,7 @@ PVAL JSONCOL::ExpandArray(PGLOBAL g, PJAR arp, int n)
ars = MY_MIN(Tjp->Limit, arp->size());
- if (!(jvp = arp->GetValue(Nodes[n].Nx))) {
+ if (!(jvp = arp->GetValue((Nodes[n].Rx = Nodes[n].Nx)))) {
strcpy(g->Message, "Logical error expanding array");
longjmp(g->jumper[g->jump_level], 666);
} // endif jvp
@@ -1278,7 +1293,7 @@ PJSON JSONCOL::GetRow(PGLOBAL g)
if (Nodes[i].Rank)
val = arp->GetValue(Nodes[i].Rank - 1);
else
- val = arp->GetValue(Nodes[i].Nx);
+ val = arp->GetValue(Nodes[i].Rx);
} else
val = NULL;
@@ -1726,7 +1741,7 @@ bool TDBJSON::OpenDB(PGLOBAL g)
/***********************************************************************/
int TDBJSON::ReadDB(PGLOBAL g)
{
- int rc;
+ int rc;
N++;
diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h
index 7e9896c3b75..10b9a9a9cc3 100644
--- a/storage/connect/tabjson.h
+++ b/storage/connect/tabjson.h
@@ -25,7 +25,8 @@ typedef struct _jnode {
PVAL CncVal; // To cont value used for OP_CNC
PVAL Valp; // The internal array VALUE
int Rank; // The rank in array
- int Nx; // Same row number
+ int Rx; // Read row number
+ int Nx; // Next to read row number
} JNODE, *PJNODE;
/***********************************************************************/
diff --git a/storage/connect/tabmul.cpp b/storage/connect/tabmul.cpp
index 36f3fc73210..94950584c9b 100644
--- a/storage/connect/tabmul.cpp
+++ b/storage/connect/tabmul.cpp
@@ -171,8 +171,10 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
} // endif hSearch
while (n < PFNZ) {
- strcat(strcat(strcpy(filename, drive), direc), FileData.cFileName);
- pfn[n++] = PlugDup(g, filename);
+ if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+ strcat(strcat(strcpy(filename, drive), direc), FileData.cFileName);
+ pfn[n++] = PlugDup(g, filename);
+ } // endif dwFileAttributes
if (!FindNextFile(hSearch, &FileData)) {
rc = GetLastError();
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index 66f275796b5..b18e4da2ec4 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -1060,9 +1060,16 @@ bool TDBMYSQL::ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
int oldlen = Query->GetLength();
if (!key || op == OP_NEXT ||
- Mode == MODE_UPDATE || Mode == MODE_DELETE)
+ Mode == MODE_UPDATE || Mode == MODE_DELETE) {
+ if (!key && Mode == MODE_READX) {
+ // This is a false indexed read
+ m_Rc = Myc.ExecSQL(g, Query->GetStr());
+ Mode = MODE_READ;
+ return (m_Rc == RC_FX) ? true : false;
+ } // endif key
+
return false;
- else if (op == OP_FIRST) {
+ } else if (op == OP_FIRST) {
if (To_CondFil) {
oom = Query->Append(" WHERE ");
diff --git a/storage/connect/tabtbl.cpp b/storage/connect/tabtbl.cpp
index 1ef70549751..2bf26a5f183 100644
--- a/storage/connect/tabtbl.cpp
+++ b/storage/connect/tabtbl.cpp
@@ -5,7 +5,7 @@
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to PlugDB Software Development 2008-2014 */
+/* (C) Copyright to PlugDB Software Development 2008-2015 */
/* Author: Olivier BERTRAND */
/* */
/* WHAT THIS PROGRAM DOES: */
diff --git a/storage/connect/tabutil.cpp b/storage/connect/tabutil.cpp
index 1c238bcf6f2..c26d766af01 100644
--- a/storage/connect/tabutil.cpp
+++ b/storage/connect/tabutil.cpp
@@ -52,7 +52,6 @@
#include "tabutil.h"
#include "ha_connect.h"
-//extern "C" int zconv;
int GetConvSize(void);
/************************************************************************/
@@ -72,11 +71,8 @@ TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db,
{
char key[256];
uint k;
-//TABLE_LIST table_list;
TABLE_SHARE *s;
-//table_list.init_one_table(db, strlen(db), name, strlen(name),
-// NULL, TL_IGNORE);
k = sprintf(key, "%s", db) + 1;
k += sprintf(key + k, "%s", name);
key[++k] = 0;
@@ -86,9 +82,6 @@ TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db,
return NULL;
} // endif s
-// 1 2 4 8
-//flags = GTS_TABLE | GTS_VIEW | GTS_NOLOCK | GTS_FORCE_DISCOVERY;
-
if (!open_table_def(thd, s, GTS_TABLE | GTS_VIEW)) {
if (!s->is_view) {
if (stricmp(plugin_name(s->db_plugin)->str, "connect"))
diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp
index 8ea44fed2be..1c1ff8a2ffe 100644
--- a/storage/connect/tabxml.cpp
+++ b/storage/connect/tabxml.cpp
@@ -1505,8 +1505,9 @@ bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
} else if (Type == 2) {
// HTML like table, columns are retrieved by position
new(this) XPOSCOL(Value); // Change the class of this column
- Tdbp->Hasnod = true;
- return false;
+ Inod = -1;
+// Tdbp->Hasnod = true;
+// return false;
} else if (Type == 0 && !mode) {
strcat(strcat(pbuf, "@"), Name);
} else { // Type == 1
diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp
index 7d3d5463129..d14fc367cc7 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.5 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2001-2014 */
+/* (C) Copyright to the author Olivier BERTRAND 2001-2015 */
/* */
/* This file contains the VALUE and derived classes family functions. */
/* These classes contain values of different types. They are used so */