diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2014-04-22 19:15:08 +0200 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2014-04-22 19:15:08 +0200 |
commit | 39750cd4dbe9b79a100d45aae010f39f71ec7ddf (patch) | |
tree | c30843abc0d7cb2a42626698d8a3513b06320a25 /storage/connect/tabxml.cpp | |
parent | 046ae9f5c668056288f4c314310a87fbcb3221d5 (diff) | |
download | mariadb-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.cpp | 125 |
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 /***********************************************************************/ |