mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
- XML and INI tables now return NULL when a node does not exist in a row (XML)
or if the key is missing in a section (INI) modified: mysql-test/suite/connect/r/ini.result mysql-test/suite/connect/r/xml.result storage/connect/tabsys.cpp storage/connect/tabxml.cpp - Do a sub-storage cleanup on info commands and fix a limit of column number in ODBCColumns. This was doing a crash for unexpected longjmp when many info commands were executed in a row. modified: storage/connect/ha_connect.cc storage/connect/odbconn.cpp
This commit is contained in:
@@ -24,21 +24,21 @@ tel CHAR(16)
|
|||||||
) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='contact.ini';
|
) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='contact.ini';
|
||||||
SELECT contact, name, hired, city, tel FROM t1;
|
SELECT contact, name, hired, city, tel FROM t1;
|
||||||
contact name hired city tel
|
contact name hired city tel
|
||||||
BER Bertrand 1970-01-01 Issy-les-Mlx 09.54.36.29.60
|
BER Bertrand NULL Issy-les-Mlx 09.54.36.29.60
|
||||||
WEL Schmitt 1985-02-19 Berlin 03.43.377.360
|
WEL Schmitt 1985-02-19 Berlin 03.43.377.360
|
||||||
UK1 Smith 2003-11-08 London
|
UK1 Smith 2003-11-08 London NULL
|
||||||
UPDATE t1 SET forename= 'Harry' where contact='UK1';
|
UPDATE t1 SET forename= 'Harry' where contact='UK1';
|
||||||
SELECT * FROM t1 WHERE contact='UK1';
|
SELECT * FROM t1 WHERE contact='UK1';
|
||||||
contact name forename hired address city zipcode tel
|
contact name forename hired address city zipcode tel
|
||||||
UK1 Smith Harry 2003-11-08 143 Blum Rd. London NW1 2BP
|
UK1 Smith Harry 2003-11-08 143 Blum Rd. London NW1 2BP NULL
|
||||||
INSERT INTO t1 (contact,forename) VALUES ('UK1','Harrison');
|
INSERT INTO t1 (contact,forename) VALUES ('UK1','Harrison');
|
||||||
SELECT * FROM t1 WHERE contact='UK1';
|
SELECT * FROM t1 WHERE contact='UK1';
|
||||||
contact name forename hired address city zipcode tel
|
contact name forename hired address city zipcode tel
|
||||||
UK1 Smith Harrison 2003-11-08 143 Blum Rd. London NW1 2BP
|
UK1 Smith Harrison 2003-11-08 143 Blum Rd. London NW1 2BP NULL
|
||||||
INSERT INTO t1 (contact,forename) VALUES ('UK2','John');
|
INSERT INTO t1 (contact,forename) VALUES ('UK2','John');
|
||||||
SELECT * FROM t1 WHERE contact='UK2';
|
SELECT * FROM t1 WHERE contact='UK2';
|
||||||
contact name forename hired address city zipcode tel
|
contact name forename hired address city zipcode tel
|
||||||
UK2 John 1970-01-01
|
UK2 NULL John NULL NULL NULL NULL NULL
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
SELECT REPLACE(REPLACE(LOAD_FILE('DATADIR/test/contact.ini'),'\r\n','\n'),'\n\n','\n');;
|
SELECT REPLACE(REPLACE(LOAD_FILE('DATADIR/test/contact.ini'),'\r\n','\n'),'\n\n','\n');;
|
||||||
REPLACE(REPLACE(LOAD_FILE('DATADIR/test/contact.ini'),'\r\n','\n'),'\n\n','\n')
|
REPLACE(REPLACE(LOAD_FILE('DATADIR/test/contact.ini'),'\r\n','\n'),'\n\n','\n')
|
||||||
|
@@ -16,7 +16,7 @@ DATEPUB INT(4)
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
AUTHOR Jean-Christophe Bernadac
|
AUTHOR Jean-Christophe Bernadac
|
||||||
TITLE Construire une application XML
|
TITLE Construire une application XML
|
||||||
TRANSLATOR
|
TRANSLATOR NULL
|
||||||
PUBLISHER Eyrolles Paris
|
PUBLISHER Eyrolles Paris
|
||||||
DATEPUB 1999
|
DATEPUB 1999
|
||||||
AUTHOR William J. Pardi
|
AUTHOR William J. Pardi
|
||||||
@@ -38,12 +38,12 @@ DATEPUB INT(4)
|
|||||||
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
|
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
|
||||||
OPTION_LIST='xmlsup=libxml2';
|
OPTION_LIST='xmlsup=libxml2';
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
author
|
author NULL
|
||||||
TITLE Construire une application XML
|
TITLE Construire une application XML
|
||||||
TRANSLATOR
|
TRANSLATOR NULL
|
||||||
PUBLISHER Eyrolles Paris
|
PUBLISHER Eyrolles Paris
|
||||||
DATEPUB 1999
|
DATEPUB 1999
|
||||||
author
|
author NULL
|
||||||
TITLE XML en Action
|
TITLE XML en Action
|
||||||
TRANSLATOR James Guerin
|
TRANSLATOR James Guerin
|
||||||
PUBLISHER Microsoft Press Paris
|
PUBLISHER Microsoft Press Paris
|
||||||
@@ -76,10 +76,10 @@ SUBJECT CHAR(32)
|
|||||||
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
|
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
|
||||||
OPTION_LIST='Coltype=@,xmlsup=libxml2';
|
OPTION_LIST='Coltype=@,xmlsup=libxml2';
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
isbn
|
isbn NULL
|
||||||
LANG fr
|
LANG fr
|
||||||
SUBJECT applications
|
SUBJECT applications
|
||||||
isbn
|
isbn NULL
|
||||||
LANG fr
|
LANG fr
|
||||||
SUBJECT applications
|
SUBJECT applications
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
@@ -104,7 +104,7 @@ LANG fr
|
|||||||
SUBJECT applications
|
SUBJECT applications
|
||||||
AUTHOR Jean-Christophe Bernadac
|
AUTHOR Jean-Christophe Bernadac
|
||||||
TITLE Construire une application XML
|
TITLE Construire une application XML
|
||||||
TRANSLATOR
|
TRANSLATOR NULL
|
||||||
PUBLISHER Eyrolles Paris
|
PUBLISHER Eyrolles Paris
|
||||||
DATEPUB 1999
|
DATEPUB 1999
|
||||||
ISBN 9782840825685
|
ISBN 9782840825685
|
||||||
@@ -140,7 +140,7 @@ LANG fr
|
|||||||
SUBJECT applications
|
SUBJECT applications
|
||||||
AUTHOR Jean-Christophe Bernadac
|
AUTHOR Jean-Christophe Bernadac
|
||||||
TITLE Construire une application XML
|
TITLE Construire une application XML
|
||||||
TRANSLATOR
|
TRANSLATOR NULL
|
||||||
PUBLISHER Eyrolles Paris
|
PUBLISHER Eyrolles Paris
|
||||||
DATEPUB 1999
|
DATEPUB 1999
|
||||||
ISBN 9782840825685
|
ISBN 9782840825685
|
||||||
@@ -156,7 +156,7 @@ LANG fr
|
|||||||
SUBJECT général
|
SUBJECT général
|
||||||
AUTHOR Alain Michard
|
AUTHOR Alain Michard
|
||||||
TITLE XML, Langage et Applications
|
TITLE XML, Langage et Applications
|
||||||
TRANSLATOR
|
TRANSLATOR NULL
|
||||||
PUBLISHER Eyrolles Paris
|
PUBLISHER Eyrolles Paris
|
||||||
DATEPUB 1998
|
DATEPUB 1998
|
||||||
SELECT LOAD_FILE('test/xsample2.xml');
|
SELECT LOAD_FILE('test/xsample2.xml');
|
||||||
@@ -228,9 +228,9 @@ subject applications
|
|||||||
authorfn Jean-Christophe
|
authorfn Jean-Christophe
|
||||||
authorln Bernadac
|
authorln Bernadac
|
||||||
title Construire une application XML
|
title Construire une application XML
|
||||||
translated
|
translated NULL
|
||||||
tranfn
|
tranfn NULL
|
||||||
tranln
|
tranln NULL
|
||||||
publisher Eyrolles
|
publisher Eyrolles
|
||||||
location Paris
|
location Paris
|
||||||
year 1999
|
year 1999
|
||||||
@@ -264,8 +264,8 @@ isbn CHAR(15) FIELD_FORMAT='@isbn'
|
|||||||
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
|
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
|
||||||
TABNAME='BIBLIO' OPTION_LIST='rownode=BOOK,skipnull=1,xmlsup=libxml2';
|
TABNAME='BIBLIO' OPTION_LIST='rownode=BOOK,skipnull=1,xmlsup=libxml2';
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
isbn
|
isbn NULL
|
||||||
isbn
|
isbn NULL
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
# Testing character sets
|
# Testing character sets
|
||||||
|
@@ -2761,10 +2761,10 @@ int ha_connect::info(uint flag)
|
|||||||
|
|
||||||
if (!valid_info) {
|
if (!valid_info) {
|
||||||
// tdbp must be available to get updated info
|
// tdbp must be available to get updated info
|
||||||
if (!tdbp || xp->CheckQuery(valid_query_id)) {
|
if (xp->CheckQuery(valid_query_id) || !tdbp) {
|
||||||
if (xmod == MODE_ANY) { // Pure info, not a query
|
if (xmod == MODE_ANY) { // Pure info, not a query
|
||||||
pure= true;
|
pure= true;
|
||||||
// xmod= MODE_READ;
|
xp->CheckCleanup();
|
||||||
} // endif xmod
|
} // endif xmod
|
||||||
|
|
||||||
// tdbp= OpenTable(g, xmod == MODE_DELETE);
|
// tdbp= OpenTable(g, xmod == MODE_DELETE);
|
||||||
|
@@ -258,8 +258,9 @@ PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *table,
|
|||||||
if (ocp->Open(dsn, 2) < 1) // 2 is openReadOnly
|
if (ocp->Open(dsn, 2) < 1) // 2 is openReadOnly
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
// We fix a MySQL limit because some data sources return 32767
|
||||||
n = ocp->GetMaxValue(SQL_MAX_COLUMNS_IN_TABLE);
|
n = ocp->GetMaxValue(SQL_MAX_COLUMNS_IN_TABLE);
|
||||||
maxres = (n) ? (int)n : 250;
|
maxres = (n) ? min(n, 4096) : 4096;
|
||||||
n = ocp->GetMaxValue(SQL_MAX_QUALIFIER_NAME_LEN);
|
n = ocp->GetMaxValue(SQL_MAX_QUALIFIER_NAME_LEN);
|
||||||
length[0] = (n) ? (n + 1) : 128;
|
length[0] = (n) ? (n + 1) : 128;
|
||||||
n = ocp->GetMaxValue(SQL_MAX_USER_NAME_LEN);
|
n = ocp->GetMaxValue(SQL_MAX_USER_NAME_LEN);
|
||||||
|
@@ -507,12 +507,20 @@ void INICOL::ReadColumn(PGLOBAL g)
|
|||||||
Valbuf[Long] = '\0';
|
Valbuf[Long] = '\0';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
GetPrivateProfileString(tdbp->Section, Name, "",
|
GetPrivateProfileString(tdbp->Section, Name, "<EFBFBD>",
|
||||||
Valbuf, Long + 1, tdbp->Ifile);
|
Valbuf, Long + 1, tdbp->Ifile);
|
||||||
break;
|
break;
|
||||||
} // endswitch Flag
|
} // endswitch Flag
|
||||||
|
|
||||||
Value->SetValue_psz(Valbuf);
|
// Missing keys are interpreted as null values
|
||||||
|
if (!strcmp(Valbuf, "<EFBFBD>")) {
|
||||||
|
if (Nullable)
|
||||||
|
Value->SetNull(true);
|
||||||
|
|
||||||
|
Value->Reset(); // Null value
|
||||||
|
} else
|
||||||
|
Value->SetValue_psz(Valbuf);
|
||||||
|
|
||||||
} // end of ReadColumn
|
} // end of ReadColumn
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -1222,10 +1222,14 @@ void XMLCOL::ReadColumn(PGLOBAL g)
|
|||||||
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
||||||
} // endswitch
|
} // endswitch
|
||||||
|
|
||||||
} else
|
Value->SetValue_psz(Valbuf);
|
||||||
*Valbuf = '\0';
|
} else {
|
||||||
|
if (Nullable)
|
||||||
|
Value->SetNull(true);
|
||||||
|
|
||||||
|
Value->Reset(); // Null value
|
||||||
|
} // endif ValNode
|
||||||
|
|
||||||
Value->SetValue_psz(Valbuf);
|
|
||||||
Nx = Tdbp->Irow;
|
Nx = Tdbp->Irow;
|
||||||
} // end of ReadColumn
|
} // end of ReadColumn
|
||||||
|
|
||||||
@@ -1400,45 +1404,50 @@ void XMULCOL::ReadColumn(PGLOBAL g)
|
|||||||
else if (Sx == Tdbp->Nsub)
|
else if (Sx == Tdbp->Nsub)
|
||||||
return; // Same row
|
return; // Same row
|
||||||
|
|
||||||
n = Nl->GetLength();
|
if ((n = Nl->GetLength())) {
|
||||||
*(p = Valbuf) = '\0';
|
*(p = Valbuf) = '\0';
|
||||||
len = Long;
|
len = Long;
|
||||||
|
|
||||||
for (i = Tdbp->Nsub; i < n; i++) {
|
for (i = Tdbp->Nsub; i < n; i++) {
|
||||||
ValNode = Nl->GetItem(g, i, Vxnp);
|
ValNode = Nl->GetItem(g, i, Vxnp);
|
||||||
|
|
||||||
if (ValNode->GetType() != XML_ELEMENT_NODE &&
|
if (ValNode->GetType() != XML_ELEMENT_NODE &&
|
||||||
ValNode->GetType() != XML_ATTRIBUTE_NODE) {
|
ValNode->GetType() != XML_ATTRIBUTE_NODE) {
|
||||||
sprintf(g->Message, MSG(BAD_VALNODE), ValNode->GetType(), Name);
|
sprintf(g->Message, MSG(BAD_VALNODE), ValNode->GetType(), Name);
|
||||||
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
|
||||||
} // endif type
|
|
||||||
|
|
||||||
// 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:
|
|
||||||
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
||||||
} // endswitch
|
} // endif type
|
||||||
|
|
||||||
if (!Tdbp->Xpand) {
|
// Get the Xname value from the XML file
|
||||||
// Concatenate all values
|
switch (ValNode->GetContent(g, p, len + 1)) {
|
||||||
if (n - i > 1)
|
case RC_OK:
|
||||||
strncat(Valbuf, ", ", Long + 1);
|
break;
|
||||||
|
case RC_INFO:
|
||||||
|
PushWarning(g, Tdbp);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
||||||
|
} // endswitch
|
||||||
|
|
||||||
len -= strlen(p);
|
if (!Tdbp->Xpand) {
|
||||||
p += strlen(p);
|
// Concatenate all values
|
||||||
} else
|
if (n - i > 1)
|
||||||
break;
|
strncat(Valbuf, ", ", Long + 1);
|
||||||
|
|
||||||
} // endfor i
|
len -= strlen(p);
|
||||||
|
p += strlen(p);
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
|
||||||
// } // endif Nx
|
} // endfor i
|
||||||
|
|
||||||
|
Value->SetValue_psz(Valbuf);
|
||||||
|
} else {
|
||||||
|
if (Nullable)
|
||||||
|
Value->SetNull(true);
|
||||||
|
|
||||||
|
Value->Reset(); // Null value
|
||||||
|
} // endif ValNode
|
||||||
|
|
||||||
Value->SetValue_psz(Valbuf);
|
|
||||||
Nx = Tdbp->Irow;
|
Nx = Tdbp->Irow;
|
||||||
Sx = Tdbp->Nsub;
|
Sx = Tdbp->Nsub;
|
||||||
Tdbp->NextSame = (Tdbp->Xpand && Nl->GetLength() - Sx > 1);
|
Tdbp->NextSame = (Tdbp->Xpand && Nl->GetLength() - Sx > 1);
|
||||||
@@ -1640,9 +1649,7 @@ void XPOSCOL::ReadColumn(PGLOBAL g)
|
|||||||
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
||||||
} // endif Clist
|
} // endif Clist
|
||||||
|
|
||||||
*Valbuf = '\0';
|
if ((ValNode = Tdbp->Clist->GetItem(g, Rank, Vxnp))) {
|
||||||
|
|
||||||
if ((ValNode = Tdbp->Clist->GetItem(g, Rank, Vxnp)))
|
|
||||||
// Get the column value from the XML file
|
// Get the column value from the XML file
|
||||||
switch (ValNode->GetContent(g, Valbuf, Long + 1)) {
|
switch (ValNode->GetContent(g, Valbuf, Long + 1)) {
|
||||||
case RC_OK:
|
case RC_OK:
|
||||||
@@ -1654,7 +1661,14 @@ void XPOSCOL::ReadColumn(PGLOBAL g)
|
|||||||
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
||||||
} // endswitch
|
} // endswitch
|
||||||
|
|
||||||
Value->SetValue_psz(Valbuf);
|
Value->SetValue_psz(Valbuf);
|
||||||
|
} else {
|
||||||
|
if (Nullable)
|
||||||
|
Value->SetNull(true);
|
||||||
|
|
||||||
|
Value->Reset(); // Null value
|
||||||
|
} // endif ValNode
|
||||||
|
|
||||||
Nx = Tdbp->Irow;
|
Nx = Tdbp->Irow;
|
||||||
} // end of ReadColumn
|
} // end of ReadColumn
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user