summaryrefslogtreecommitdiff
path: root/storage/connect/tabxml.cpp
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2019-01-03 18:19:36 +0100
committerOlivier Bertrand <bertrandop@gmail.com>2019-01-03 18:19:36 +0100
commit261e9a8a5362c463c1b927e103acce28461fff68 (patch)
tree97034cad7676396f3a7d33f4a1dc170369836057 /storage/connect/tabxml.cpp
parentf25aab0ecf8b46ffdc30e4b7ff98d5842317664b (diff)
downloadmariadb-git-261e9a8a5362c463c1b927e103acce28461fff68.tar.gz
- 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
Diffstat (limited to 'storage/connect/tabxml.cpp')
-rw-r--r--storage/connect/tabxml.cpp279
1 files changed, 153 insertions, 126 deletions
diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp
index fa4854bb618..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
/***********************************************************************/
@@ -814,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];
@@ -1221,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);
@@ -1279,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++)