Commit 7a30ec72 authored by Olivier Bertrand's avatar Olivier Bertrand

- 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
parent c7b95cb9
...@@ -24,21 +24,21 @@ tel CHAR(16) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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' ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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, "",
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, "")) {
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) ...@@ -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) ...@@ -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++) {
ValNode = Nl->GetItem(g, i, Vxnp);
if (ValNode->GetType() != XML_ELEMENT_NODE && for (i = Tdbp->Nsub; i < n; i++) {
ValNode->GetType() != XML_ATTRIBUTE_NODE) { ValNode = Nl->GetItem(g, i, Vxnp);
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 if (ValNode->GetType() != XML_ELEMENT_NODE &&
switch (ValNode->GetContent(g, p, len + 1)) { ValNode->GetType() != XML_ATTRIBUTE_NODE) {
case RC_OK: sprintf(g->Message, MSG(BAD_VALNODE), ValNode->GetType(), Name);
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;
} // endfor i
Value->SetValue_psz(Valbuf);
} else {
if (Nullable)
Value->SetNull(true);
// } // endif Nx 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) ...@@ -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) ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment