1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

- 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
This commit is contained in:
Olivier Bertrand
2014-04-22 19:15:08 +02:00
parent 046ae9f5c6
commit 39750cd4db
8 changed files with 348 additions and 81 deletions

View File

@@ -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
} // endif type
if (!Tdbp->Xpand) {
// Concatenate all values
if (n - i > 1)
strncat(Valbuf, ", ", Long + 1);
// 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
len -= strlen(p);
p += strlen(p);
} else
break;
if (!b) {
// Concatenate all values
if (N - i > 1)
strncat(Valbuf, ", ", len - strlen(p));
} // endfor i
if ((len -= strlen(p)) <= 0)
break;
Value->SetValue_psz(Valbuf);
} else {
if (Nullable)
Value->SetNull(true);
p += strlen(p);
} else // Xpand
p += (Long + 1);
Value->Reset(); // Null value
} // endif ValNode
} // endfor i
Value->SetValue_psz(Valbuf);
} else {
if (Nullable)
Value->SetNull(true);
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
/***********************************************************************/