summaryrefslogtreecommitdiff
path: root/storage/connect/tabxml.cpp
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2014-04-22 19:15:08 +0200
committerOlivier Bertrand <bertrandop@gmail.com>2014-04-22 19:15:08 +0200
commit39750cd4dbe9b79a100d45aae010f39f71ec7ddf (patch)
treec30843abc0d7cb2a42626698d8a3513b06320a25 /storage/connect/tabxml.cpp
parent046ae9f5c668056288f4c314310a87fbcb3221d5 (diff)
downloadmariadb-git-39750cd4dbe9b79a100d45aae010f39f71ec7ddf.tar.gz
- FIX a bug causing libxml2 not retrieving expanded multiple column values.
This was working but the cause probably comes from freeing Xop object to handle memory leaks reported by Valgrind. Also add a test case on XML multiple tables. added: storage/connect/mysql-test/connect/r/xml_mult.result storage/connect/mysql-test/connect/std_data/bookstore.xml storage/connect/mysql-test/connect/t/xml_mult.test modified: storage/connect/domdoc.cpp storage/connect/tabxml.cpp storage/connect/tabxml.h - Enhance the index types and flages returning functions. modified: storage/connect/ha_connect.cc storage/connect/ha_connect.h - Suppress irrelevant warning message (MDEV-6117) modified: storage/connect/ha_connect.cc
Diffstat (limited to 'storage/connect/tabxml.cpp')
-rw-r--r--storage/connect/tabxml.cpp125
1 files changed, 74 insertions, 51 deletions
diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp
index c7c61f0dcbb..1e9c172cdb3 100644
--- a/storage/connect/tabxml.cpp
+++ b/storage/connect/tabxml.cpp
@@ -145,7 +145,7 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
XmlDB = GetStringCatInfo(g, "XmlDB", "");
Nslist = GetStringCatInfo(g, "Nslist", "");
DefNs = GetStringCatInfo(g, "DefNs", "");
- Limit = GetIntCatInfo("Limit", 2);
+ Limit = GetIntCatInfo("Limit", 10);
Xpand = (GetIntCatInfo("Expand", 0) != 0);
Header = GetIntCatInfo("Header", 0);
GetCharCatInfo("Xmlsup", "*", buf, sizeof(buf));
@@ -1038,12 +1038,13 @@ XMLCOL::XMLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
Type = Tdbp->Coltype;
Nx = -1;
Sx = -1;
+ N = 0;
Valbuf = NULL;
To_Val = NULL;
} // end of XMLCOL constructor
/***********************************************************************/
-/* XMLCOL constructor used for copying columns. */
+/* XMLCOL constructor used for copying columns. */
/* tdbp is the pointer to the new table descriptor. */
/***********************************************************************/
XMLCOL::XMLCOL(XMLCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
@@ -1068,6 +1069,7 @@ XMLCOL::XMLCOL(XMLCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
Rank = col1->Rank;
Nx = col1->Nx;
Sx = col1->Sx;
+ N = col1->N;
Type = col1->Type;
To_Val = col1->To_Val;
} // end of XMLCOL copy constructor
@@ -1080,8 +1082,8 @@ bool XMLCOL::AllocBuf(PGLOBAL g, bool mode)
if (Valbuf)
return false; // Already done
- Valbuf = (char*)PlugSubAlloc(g, NULL, Long + 1);
- Valbuf[Long] = '\0';
+//Valbuf = (char*)PlugSubAlloc(g, NULL, Long + 1);
+//Valbuf[Long] = '\0';
return ParseXpath(g, mode);
} // end of AllocBuf
@@ -1095,7 +1097,7 @@ bool XMLCOL::AllocBuf(PGLOBAL g, bool mode)
bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
{
char *p, *p2, *pbuf = NULL;
- int i, len = strlen(Name);
+ int i, n = 1, len = strlen(Name);
len += ((Tdbp->Colname) ? strlen(Tdbp->Colname) : 0);
len += ((Xname) ? strlen(Xname) : 0);
@@ -1122,7 +1124,7 @@ bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
// For Update or Insert the Xpath must be analyzed
if (mode) {
for (i = 0, p = pbuf; (p = strchr(p, '/')); i++, p++)
- Nod++; // One path node found
+ Nod++; // One path node found
if (Nod)
Nodes = (char**)PlugSubAlloc(g, NULL, Nod * sizeof(char*));
@@ -1136,7 +1138,7 @@ bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
strcpy(g->Message, MSG(CONCAT_SUBNODE));
return true;
} else
- Inod = i; // Index of multiple node
+ Inod = i; // Index of multiple node
if (mode) {
// For Update or Insert the Xpath must be explicit
@@ -1171,7 +1173,7 @@ 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
+ new(this) XPOSCOL(Value); // Change the class of this column
Tdbp->Hasnod = true;
return false;
} else if (Type == 0 && !mode) {
@@ -1185,9 +1187,18 @@ bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
if (Inod >= 0) {
Tdbp->Colp = this; // To force expand
- new(this) XMULCOL(Value); // Change the class of this column
+
+ if (Tdbp->Xpand)
+ n = Tdbp->Limit;
+
+ new(this) XMULCOL(Value); // Change the class of this column
} // endif Inod
+ Valbuf = (char*)PlugSubAlloc(g, NULL, n * (Long + 1));
+
+ for (i = 0; i < n; i++)
+ Valbuf[Long + (i * (Long + 1))] = '\0';
+
if (Type || Nod)
Tdbp->Hasnod = true;
@@ -1470,60 +1481,72 @@ void XMLCOL::WriteColumn(PGLOBAL g)
void XMULCOL::ReadColumn(PGLOBAL g)
{
char *p;
- int i, n, len;
+ int i, len;
+ bool b = Tdbp->Xpand;
- if (Nx != Tdbp->Irow) // New row
+ if (Nx != Tdbp->Irow) { // New row
Nl = Tdbp->RowNode->SelectNodes(g, Xname, Nl);
- else if (Sx == Tdbp->Nsub)
- return; // Same row
- if ((n = Nl->GetLength())) {
- *(p = Valbuf) = '\0';
- len = Long;
+ if ((N = Nl->GetLength())) {
+ *(p = Valbuf) = '\0';
+ len = Long;
- for (i = Tdbp->Nsub; i < n; i++) {
- ValNode = Nl->GetItem(g, i, Vxnp);
+ if (N > Tdbp->Limit) {
+ N = Tdbp->Limit;
+ sprintf(g->Message, "Mutiple values limited to %d", Tdbp->Limit);
+ PushWarning(g, Tdbp);
+ } // endif N
- if (ValNode->GetType() != XML_ELEMENT_NODE &&
- ValNode->GetType() != XML_ATTRIBUTE_NODE) {
- sprintf(g->Message, MSG(BAD_VALNODE), ValNode->GetType(), Name);
- longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
- } // endif type
+ for (i = 0; i < N; i++) {
+ ValNode = Nl->GetItem(g, i, Vxnp);
- // Get the Xname value from the XML file
- switch (ValNode->GetContent(g, p, len + 1)) {
- case RC_OK:
- break;
- case RC_INFO:
- PushWarning(g, Tdbp);
- break;
- default:
+ if (ValNode->GetType() != XML_ELEMENT_NODE &&
+ ValNode->GetType() != XML_ATTRIBUTE_NODE) {
+ sprintf(g->Message, MSG(BAD_VALNODE), ValNode->GetType(), Name);
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
- } // endswitch
-
- if (!Tdbp->Xpand) {
- // Concatenate all values
- if (n - i > 1)
- strncat(Valbuf, ", ", Long + 1);
-
- len -= strlen(p);
- p += strlen(p);
- } else
- break;
-
- } // endfor i
+ } // endif type
+
+ // Get the Xname value from the XML file
+ switch (ValNode->GetContent(g, p, (b ? Long : len))) {
+ case RC_OK:
+ break;
+ case RC_INFO:
+ PushWarning(g, Tdbp);
+ break;
+ default:
+ longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
+ } // endswitch
+
+ if (!b) {
+ // Concatenate all values
+ if (N - i > 1)
+ strncat(Valbuf, ", ", len - strlen(p));
+
+ if ((len -= strlen(p)) <= 0)
+ break;
+
+ p += strlen(p);
+ } else // Xpand
+ p += (Long + 1);
+
+ } // endfor i
+
+ Value->SetValue_psz(Valbuf);
+ } else {
+ if (Nullable)
+ Value->SetNull(true);
- Value->SetValue_psz(Valbuf);
- } else {
- if (Nullable)
- Value->SetNull(true);
+ Value->Reset(); // Null value
+ } // endif ValNode
- Value->Reset(); // Null value
- } // endif ValNode
+ } else if (Sx == Tdbp->Nsub)
+ return; // Same row
+ else // Expanded value
+ Value->SetValue_psz(Valbuf + (Tdbp->Nsub * (Long + 1)));
Nx = Tdbp->Irow;
Sx = Tdbp->Nsub;
- Tdbp->NextSame = (Tdbp->Xpand && Nl->GetLength() - Sx > 1);
+ Tdbp->NextSame = (Tdbp->Xpand && N - Sx > 1);
} // end of ReadColumn
/***********************************************************************/