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:
@@ -416,6 +416,7 @@ PXLIST DOMNODE::SelectNodes(PGLOBAL g, char *xp, PXLIST lp)
|
||||
/******************************************************************/
|
||||
PXNODE DOMNODE::SelectSingleNode(PGLOBAL g, char *xp, PXNODE np)
|
||||
{
|
||||
try {
|
||||
MSXML2::IXMLDOMNodePtr dnp = Nodep->selectSingleNode(xp);
|
||||
|
||||
if (dnp) {
|
||||
@@ -425,9 +426,14 @@ PXNODE DOMNODE::SelectSingleNode(PGLOBAL g, char *xp, PXNODE np)
|
||||
} else
|
||||
return new(g) DOMNODE(Doc, dnp);
|
||||
|
||||
} else
|
||||
return NULL;
|
||||
} // endif dnp
|
||||
|
||||
} catch(_com_error e) {
|
||||
sprintf(g->Message, "%s: %s", MSG(COM_ERROR),
|
||||
_com_util::ConvertBSTRToString(e.Description()));
|
||||
} catch(...) {}
|
||||
|
||||
return NULL;
|
||||
} // end of SelectSingleNode
|
||||
|
||||
/******************************************************************/
|
||||
|
@@ -621,7 +621,7 @@ TABTYPE ha_connect::GetRealType(PTOS pos)
|
||||
{
|
||||
TABTYPE type;
|
||||
|
||||
if (pos || (pos= GetTableOptionStruct(table))) {
|
||||
if (pos || (pos= GetTableOptionStruct())) {
|
||||
type= GetTypeID(pos->type);
|
||||
|
||||
if (type == TAB_UNDEF)
|
||||
@@ -633,6 +633,50 @@ TABTYPE ha_connect::GetRealType(PTOS pos)
|
||||
return type;
|
||||
} // end of GetRealType
|
||||
|
||||
/** @brief
|
||||
The name of the index type that will be used for display.
|
||||
Don't implement this method unless you really have indexes.
|
||||
*/
|
||||
const char *ha_connect::index_type(uint inx)
|
||||
{
|
||||
switch (GetIndexType(GetRealType())) {
|
||||
case 1: return "XPLUG";
|
||||
case 2: return "REMOTE";
|
||||
} // endswitch
|
||||
|
||||
return "Unknown";
|
||||
} // end of index_type
|
||||
|
||||
/** @brief
|
||||
This is a bitmap of flags that indicates how the storage engine
|
||||
implements indexes. The current index flags are documented in
|
||||
handler.h. If you do not implement indexes, just return zero here.
|
||||
|
||||
@details
|
||||
part is the key part to check. First key part is 0.
|
||||
If all_parts is set, MySQL wants to know the flags for the combined
|
||||
index, up to and including 'part'.
|
||||
*/
|
||||
ulong ha_connect::index_flags(uint inx, uint part, bool all_parts) const
|
||||
{
|
||||
ulong flags= HA_READ_NEXT | HA_READ_RANGE |
|
||||
HA_KEYREAD_ONLY | HA_KEY_SCAN_NOT_ROR;
|
||||
ha_connect *hp= (ha_connect*)this;
|
||||
PTOS pos= hp->GetTableOptionStruct();
|
||||
|
||||
if (pos) {
|
||||
TABTYPE type= hp->GetRealType(pos);
|
||||
|
||||
switch (GetIndexType(type)) {
|
||||
case 1: flags|= (HA_READ_ORDER | HA_READ_PREV); break;
|
||||
case 2: flags|= HA_READ_AFTER_KEY; break;
|
||||
} // endswitch
|
||||
|
||||
} // endif pos
|
||||
|
||||
return flags;
|
||||
} // end of index_flags
|
||||
|
||||
/** @brief
|
||||
This is a list of flags that indicate what functionality the storage
|
||||
engine implements. The current table flags are documented in handler.h
|
||||
@@ -641,14 +685,14 @@ ulonglong ha_connect::table_flags() const
|
||||
{
|
||||
ulonglong flags= HA_CAN_VIRTUAL_COLUMNS | HA_REC_NOT_IN_SEQ |
|
||||
HA_NO_AUTO_INCREMENT | HA_NO_PREFIX_CHAR_KEYS |
|
||||
// HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
|
||||
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
|
||||
HA_PARTIAL_COLUMN_READ | HA_FILE_BASED |
|
||||
// HA_NULL_IN_KEY | not implemented yet
|
||||
// HA_FAST_KEY_READ | causes error when sorting (???)
|
||||
HA_NO_TRANSACTIONS | HA_DUPLICATE_KEY_NOT_IN_ORDER |
|
||||
HA_NO_BLOBS | HA_MUST_USE_TABLE_CONDITION_PUSHDOWN;
|
||||
ha_connect *hp= (ha_connect*)this;
|
||||
PTOS pos= hp->GetTableOptionStruct(table);
|
||||
PTOS pos= hp->GetTableOptionStruct();
|
||||
|
||||
if (pos) {
|
||||
TABTYPE type= hp->GetRealType(pos);
|
||||
@@ -719,10 +763,11 @@ char *GetListOption(PGLOBAL g, const char *opname,
|
||||
/****************************************************************************/
|
||||
/* Return the table option structure. */
|
||||
/****************************************************************************/
|
||||
PTOS ha_connect::GetTableOptionStruct(TABLE *tab)
|
||||
PTOS ha_connect::GetTableOptionStruct(TABLE_SHARE *s)
|
||||
{
|
||||
return (tshp) ? tshp->option_struct :
|
||||
(tab) ? tab->s->option_struct : NULL;
|
||||
TABLE_SHARE *tsp= (tshp) ? tshp : (s) ? s : table_share;
|
||||
|
||||
return (tsp) ? tsp->option_struct : NULL;
|
||||
} // end of GetTableOptionStruct
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -731,7 +776,7 @@ PTOS ha_connect::GetTableOptionStruct(TABLE *tab)
|
||||
char *ha_connect::GetStringOption(char *opname, char *sdef)
|
||||
{
|
||||
char *opval= NULL;
|
||||
PTOS options= GetTableOptionStruct(table);
|
||||
PTOS options= GetTableOptionStruct();
|
||||
|
||||
if (!options)
|
||||
;
|
||||
@@ -803,10 +848,10 @@ bool ha_connect::GetBooleanOption(char *opname, bool bdef)
|
||||
{
|
||||
bool opval= bdef;
|
||||
char *pv;
|
||||
PTOS options= GetTableOptionStruct(table);
|
||||
PTOS options= GetTableOptionStruct();
|
||||
|
||||
if (!stricmp(opname, "View"))
|
||||
opval= (tshp) ? tshp->is_view : table->s->is_view;
|
||||
opval= (tshp) ? tshp->is_view : table_share->is_view;
|
||||
else if (!options)
|
||||
;
|
||||
else if (!stricmp(opname, "Mapped"))
|
||||
@@ -834,7 +879,7 @@ bool ha_connect::GetBooleanOption(char *opname, bool bdef)
|
||||
/****************************************************************************/
|
||||
bool ha_connect::SetBooleanOption(char *opname, bool b)
|
||||
{
|
||||
PTOS options= GetTableOptionStruct(table);
|
||||
PTOS options= GetTableOptionStruct();
|
||||
|
||||
if (!options)
|
||||
return true;
|
||||
@@ -854,7 +899,7 @@ int ha_connect::GetIntegerOption(char *opname)
|
||||
{
|
||||
ulonglong opval= NO_IVAL;
|
||||
char *pv;
|
||||
PTOS options= GetTableOptionStruct(table);
|
||||
PTOS options= GetTableOptionStruct();
|
||||
|
||||
if (!options)
|
||||
;
|
||||
@@ -891,7 +936,7 @@ int ha_connect::GetIntegerOption(char *opname)
|
||||
/****************************************************************************/
|
||||
bool ha_connect::SetIntegerOption(char *opname, int n)
|
||||
{
|
||||
PTOS options= GetTableOptionStruct(table);
|
||||
PTOS options= GetTableOptionStruct();
|
||||
|
||||
if (!options)
|
||||
return true;
|
||||
@@ -1153,7 +1198,7 @@ const char *ha_connect::GetDBName(const char* name)
|
||||
|
||||
const char *ha_connect::GetTableName(void)
|
||||
{
|
||||
return (tshp) ? tshp->table_name.str : table->s->table_name.str;
|
||||
return (tshp) ? tshp->table_name.str : table_share->table_name.str;
|
||||
} // end of GetTableName
|
||||
|
||||
#if 0
|
||||
@@ -3310,7 +3355,7 @@ int ha_connect::external_lock(THD *thd, int lock_type)
|
||||
int rc= 0;
|
||||
bool xcheck=false, cras= false;
|
||||
MODE newmode;
|
||||
PTOS options= GetTableOptionStruct(table);
|
||||
PTOS options= GetTableOptionStruct();
|
||||
PGLOBAL g= GetPlug(thd, xp);
|
||||
DBUG_ENTER("ha_connect::external_lock");
|
||||
|
||||
@@ -4550,7 +4595,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
|
||||
|
||||
DBUG_ENTER("ha_connect::create");
|
||||
int sqlcom= thd_sql_command(table_arg->in_use);
|
||||
PTOS options= GetTableOptionStruct(table_arg);
|
||||
PTOS options= GetTableOptionStruct(table_arg->s);
|
||||
|
||||
table= table_arg; // Used by called functions
|
||||
|
||||
@@ -4885,7 +4930,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
|
||||
} else
|
||||
::close(h);
|
||||
|
||||
if (type == TAB_FMT || options->readonly)
|
||||
if ((type == TAB_FMT || options->readonly) && sqlcom == SQLCOM_CREATE_TABLE)
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0,
|
||||
"Congratulation, you just created a read-only void table!");
|
||||
|
||||
@@ -5123,7 +5168,6 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table,
|
||||
int sqlcom= thd_sql_command(thd);
|
||||
TABTYPE newtyp, type= TAB_UNDEF;
|
||||
HA_CREATE_INFO *create_info= ha_alter_info->create_info;
|
||||
//PTOS pos= GetTableOptionStruct(table);
|
||||
PTOS newopt, oldopt;
|
||||
xp= GetUser(thd, xp);
|
||||
PGLOBAL g= xp->g;
|
||||
|
@@ -167,7 +167,7 @@ public:
|
||||
static bool connect_end(void);
|
||||
TABTYPE GetRealType(PTOS pos= NULL);
|
||||
char *GetStringOption(char *opname, char *sdef= NULL);
|
||||
PTOS GetTableOptionStruct(TABLE *table_arg);
|
||||
PTOS GetTableOptionStruct(TABLE_SHARE *s= NULL);
|
||||
bool GetBooleanOption(char *opname, bool bdef);
|
||||
bool SetBooleanOption(char *opname, bool b);
|
||||
int GetIntegerOption(char *opname);
|
||||
@@ -210,7 +210,7 @@ public:
|
||||
The name of the index type that will be used for display.
|
||||
Don't implement this method unless you really have indexes.
|
||||
*/
|
||||
const char *index_type(uint inx) { return "XPLUG"; }
|
||||
const char *index_type(uint inx);
|
||||
|
||||
/** @brief
|
||||
The file extensions.
|
||||
@@ -241,11 +241,7 @@ public:
|
||||
If all_parts is set, MySQL wants to know the flags for the combined
|
||||
index, up to and including 'part'.
|
||||
*/
|
||||
ulong index_flags(uint inx, uint part, bool all_parts) const
|
||||
{
|
||||
return HA_READ_NEXT | HA_READ_RANGE | HA_READ_ORDER |
|
||||
HA_READ_PREV | HA_KEYREAD_ONLY | HA_KEY_SCAN_NOT_ROR;
|
||||
} // end of index_flags
|
||||
ulong index_flags(uint inx, uint part, bool all_parts) const;
|
||||
|
||||
/** @brief
|
||||
unireg.cc will call max_supported_record_length(), max_supported_keys(),
|
||||
|
102
storage/connect/mysql-test/connect/r/xml_mult.result
Normal file
102
storage/connect/mysql-test/connect/r/xml_mult.result
Normal file
@@ -0,0 +1,102 @@
|
||||
Warnings:
|
||||
Warning 1105 No file name. Table will use t1.xml
|
||||
SET NAMES utf8;
|
||||
#
|
||||
# Testing expanded values
|
||||
#
|
||||
CREATE TABLE `bookstore` (
|
||||
`category` CHAR(16) NOT NULL FIELD_FORMAT='@',
|
||||
`title` VARCHAR(50) NOT NULL,
|
||||
`lang` char(2) NOT NULL FIELD_FORMAT='title/@',
|
||||
`author` VARCHAR(24) NOT NULL,
|
||||
`year` INT(4) NOT NULL,
|
||||
`price` DOUBLE(8,2) NOT NULL)
|
||||
ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='bookstore.xml' OPTION_LIST='expand=1,mulnode=author,limit=6,xmlsup=libxml2';
|
||||
SELECT * FROM bookstore;
|
||||
category title lang author year price
|
||||
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00
|
||||
CHILDREN Harry Potter en J K. Rowling 2005 29.99
|
||||
WEB XQuery Kick Start en James McGovern 2003 49.99
|
||||
WEB XQuery Kick Start en Per Bothner 2003 49.99
|
||||
WEB XQuery Kick Start en Kurt Cagle 2003 49.99
|
||||
WEB XQuery Kick Start en James Linn 2003 49.99
|
||||
WEB XQuery Kick Start en Vaidyanathan Nagarajan 2003 49.99
|
||||
WEB Learning XML en Erik T. Ray 2003 39.95
|
||||
SELECT category, title, price FROM bookstore;
|
||||
category title price
|
||||
COOKING Everyday Italian 30.00
|
||||
CHILDREN Harry Potter 29.99
|
||||
WEB XQuery Kick Start 49.99
|
||||
WEB Learning XML 39.95
|
||||
SELECT category, title, author, price FROM bookstore WHERE author LIKE '%K%';
|
||||
category title author price
|
||||
CHILDREN Harry Potter J K. Rowling 29.99
|
||||
WEB XQuery Kick Start Kurt Cagle 49.99
|
||||
WEB Learning XML Erik T. Ray 39.95
|
||||
SELECT category, title, price FROM bookstore WHERE author LIKE 'J%';
|
||||
category title price
|
||||
CHILDREN Harry Potter 29.99
|
||||
WEB XQuery Kick Start 49.99
|
||||
WEB XQuery Kick Start 49.99
|
||||
#
|
||||
# Limiting expanded values
|
||||
#
|
||||
ALTER TABLE bookstore OPTION_LIST='expand=1,mulnode=author,limit=3,xmlsup=libxml2';
|
||||
SELECT * FROM bookstore;
|
||||
category title lang author year price
|
||||
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00
|
||||
CHILDREN Harry Potter en J K. Rowling 2005 29.99
|
||||
WEB XQuery Kick Start en James McGovern 2003 49.99
|
||||
WEB XQuery Kick Start en Per Bothner 2003 49.99
|
||||
WEB XQuery Kick Start en Kurt Cagle 2003 49.99
|
||||
WEB Learning XML en Erik T. Ray 2003 39.95
|
||||
Warnings:
|
||||
Warning 1105 Mutiple values limited to 3
|
||||
# One line lost because the where clause is applied only on the first 3 rows
|
||||
SELECT category, title, author, price FROM bookstore WHERE author LIKE 'J%';
|
||||
category title author price
|
||||
CHILDREN Harry Potter J K. Rowling 29.99
|
||||
WEB XQuery Kick Start James McGovern 49.99
|
||||
Warnings:
|
||||
Warning 1105 Mutiple values limited to 3
|
||||
#
|
||||
# Testing concatenated values
|
||||
#
|
||||
ALTER TABLE bookstore OPTION_LIST='mulnode=author,limit=6,xmlsup=libxml2';
|
||||
# truncated
|
||||
SELECT * FROM bookstore;
|
||||
category title lang author year price
|
||||
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00
|
||||
CHILDREN Harry Potter en J K. Rowling 2005 29.99
|
||||
WEB XQuery Kick Start en James McGovern, Per Both 2003 49.99
|
||||
WEB Learning XML en Erik T. Ray 2003 39.95
|
||||
Warnings:
|
||||
Warning 1105 Truncated author content
|
||||
# increase author size
|
||||
ALTER TABLE bookstore MODIFY `author` VARCHAR(128) NOT NULL;
|
||||
SELECT * FROM bookstore;
|
||||
category title lang author year price
|
||||
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00
|
||||
CHILDREN Harry Potter en J K. Rowling 2005 29.99
|
||||
WEB XQuery Kick Start en James McGovern, Per Bothner, Kurt Cagle, James Linn, Vaidyanathan Nagarajan 2003 49.99
|
||||
WEB Learning XML en Erik T. Ray 2003 39.95
|
||||
#
|
||||
# Limiting concatenated values
|
||||
#
|
||||
ALTER TABLE bookstore OPTION_LIST='mulnode=author,limit=4,xmlsup=libxml2';
|
||||
SELECT * FROM bookstore;
|
||||
category title lang author year price
|
||||
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00
|
||||
CHILDREN Harry Potter en J K. Rowling 2005 29.99
|
||||
WEB XQuery Kick Start en James McGovern, Per Bothner, Kurt Cagle, James Linn 2003 49.99
|
||||
WEB Learning XML en Erik T. Ray 2003 39.95
|
||||
Warnings:
|
||||
Warning 1105 Mutiple values limited to 4
|
||||
# The where clause is applied on the concatenated column result
|
||||
SELECT category, title, author, price FROM bookstore WHERE author LIKE 'J%';
|
||||
category title author price
|
||||
CHILDREN Harry Potter J K. Rowling 29.99
|
||||
WEB XQuery Kick Start James McGovern, Per Bothner, Kurt Cagle, James Linn 49.99
|
||||
Warnings:
|
||||
Warning 1105 Mutiple values limited to 4
|
||||
DROP TABLE bookstore;
|
31
storage/connect/mysql-test/connect/std_data/bookstore.xml
Normal file
31
storage/connect/mysql-test/connect/std_data/bookstore.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bookstore>
|
||||
<book category="COOKING">
|
||||
<title lang="en">Everyday Italian</title>
|
||||
<author>Giada De Laurentiis</author>
|
||||
<year>2005</year>
|
||||
<price>30.00</price>
|
||||
</book>
|
||||
<book category="CHILDREN">
|
||||
<title lang="en">Harry Potter</title>
|
||||
<author>J K. Rowling</author>
|
||||
<year>2005</year>
|
||||
<price>29.99</price>
|
||||
</book>
|
||||
<book category="WEB">
|
||||
<title lang="en">XQuery Kick Start</title>
|
||||
<author>James McGovern</author>
|
||||
<author>Per Bothner</author>
|
||||
<author>Kurt Cagle</author>
|
||||
<author>James Linn</author>
|
||||
<author>Vaidyanathan Nagarajan</author>
|
||||
<year>2003</year>
|
||||
<price>49.99</price>
|
||||
</book>
|
||||
<book category="WEB">
|
||||
<title lang="en">Learning XML</title>
|
||||
<author>Erik T. Ray</author>
|
||||
<year>2003</year>
|
||||
<price>39.95</price>
|
||||
</book>
|
||||
</bookstore>
|
64
storage/connect/mysql-test/connect/t/xml_mult.test
Normal file
64
storage/connect/mysql-test/connect/t/xml_mult.test
Normal file
@@ -0,0 +1,64 @@
|
||||
--source have_libxml2.inc
|
||||
|
||||
let $MYSQLD_DATADIR= `select @@datadir`;
|
||||
|
||||
SET NAMES utf8;
|
||||
|
||||
--copy_file $MTR_SUITE_DIR/std_data/bookstore.xml $MYSQLD_DATADIR/test/bookstore.xml
|
||||
|
||||
#--echo $MYSQL_TEST_DIR
|
||||
#--exec pwd
|
||||
#SELECT LOAD_FILE('test/bookstore.xml');
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Testing expanded values
|
||||
--echo #
|
||||
CREATE TABLE `bookstore` (
|
||||
`category` CHAR(16) NOT NULL FIELD_FORMAT='@',
|
||||
`title` VARCHAR(50) NOT NULL,
|
||||
`lang` char(2) NOT NULL FIELD_FORMAT='title/@',
|
||||
`author` VARCHAR(24) NOT NULL,
|
||||
`year` INT(4) NOT NULL,
|
||||
`price` DOUBLE(8,2) NOT NULL)
|
||||
ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='bookstore.xml' OPTION_LIST='expand=1,mulnode=author,limit=6,xmlsup=libxml2';
|
||||
SELECT * FROM bookstore;
|
||||
SELECT category, title, price FROM bookstore;
|
||||
SELECT category, title, author, price FROM bookstore WHERE author LIKE '%K%';
|
||||
SELECT category, title, price FROM bookstore WHERE author LIKE 'J%';
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Limiting expanded values
|
||||
--echo #
|
||||
ALTER TABLE bookstore OPTION_LIST='expand=1,mulnode=author,limit=3,xmlsup=libxml2';
|
||||
SELECT * FROM bookstore;
|
||||
--echo # One line lost because the where clause is applied only on the first 3 rows
|
||||
SELECT category, title, author, price FROM bookstore WHERE author LIKE 'J%';
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Testing concatenated values
|
||||
--echo #
|
||||
ALTER TABLE bookstore OPTION_LIST='mulnode=author,limit=6,xmlsup=libxml2';
|
||||
--echo # truncated
|
||||
SELECT * FROM bookstore;
|
||||
--echo # increase author size
|
||||
ALTER TABLE bookstore MODIFY `author` VARCHAR(128) NOT NULL;
|
||||
SELECT * FROM bookstore;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Limiting concatenated values
|
||||
--echo #
|
||||
ALTER TABLE bookstore OPTION_LIST='mulnode=author,limit=4,xmlsup=libxml2';
|
||||
SELECT * FROM bookstore;
|
||||
--echo # The where clause is applied on the concatenated column result
|
||||
SELECT category, title, author, price FROM bookstore WHERE author LIKE 'J%';
|
||||
DROP TABLE bookstore;
|
||||
|
||||
|
||||
#
|
||||
# Clean up
|
||||
#
|
||||
--remove_file $MYSQLD_DATADIR/test/bookstore.xml
|
@@ -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,6 +1038,7 @@ 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
|
||||
@@ -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);
|
||||
@@ -1185,9 +1187,18 @@ bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
|
||||
|
||||
if (Inod >= 0) {
|
||||
Tdbp->Colp = this; // To force expand
|
||||
|
||||
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,18 +1481,23 @@ 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())) {
|
||||
if ((N = Nl->GetLength())) {
|
||||
*(p = Valbuf) = '\0';
|
||||
len = Long;
|
||||
|
||||
for (i = Tdbp->Nsub; i < n; i++) {
|
||||
if (N > Tdbp->Limit) {
|
||||
N = Tdbp->Limit;
|
||||
sprintf(g->Message, "Mutiple values limited to %d", Tdbp->Limit);
|
||||
PushWarning(g, Tdbp);
|
||||
} // endif N
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
ValNode = Nl->GetItem(g, i, Vxnp);
|
||||
|
||||
if (ValNode->GetType() != XML_ELEMENT_NODE &&
|
||||
@@ -1491,7 +1507,7 @@ void XMULCOL::ReadColumn(PGLOBAL g)
|
||||
} // endif type
|
||||
|
||||
// Get the Xname value from the XML file
|
||||
switch (ValNode->GetContent(g, p, len + 1)) {
|
||||
switch (ValNode->GetContent(g, p, (b ? Long : len))) {
|
||||
case RC_OK:
|
||||
break;
|
||||
case RC_INFO:
|
||||
@@ -1501,16 +1517,18 @@ void XMULCOL::ReadColumn(PGLOBAL g)
|
||||
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
||||
} // endswitch
|
||||
|
||||
if (!Tdbp->Xpand) {
|
||||
if (!b) {
|
||||
// Concatenate all values
|
||||
if (n - i > 1)
|
||||
strncat(Valbuf, ", ", Long + 1);
|
||||
if (N - i > 1)
|
||||
strncat(Valbuf, ", ", len - strlen(p));
|
||||
|
||||
len -= strlen(p);
|
||||
p += strlen(p);
|
||||
} else
|
||||
if ((len -= strlen(p)) <= 0)
|
||||
break;
|
||||
|
||||
p += strlen(p);
|
||||
} else // Xpand
|
||||
p += (Long + 1);
|
||||
|
||||
} // endfor i
|
||||
|
||||
Value->SetValue_psz(Valbuf);
|
||||
@@ -1521,9 +1539,14 @@ void XMULCOL::ReadColumn(PGLOBAL g)
|
||||
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
|
||||
|
||||
/***********************************************************************/
|
||||
|
@@ -190,6 +190,7 @@ class XMLCOL : public COLBLK {
|
||||
int Long; // Buffer length
|
||||
int Nx; // The last read row
|
||||
int Sx; // The last read sub-row
|
||||
int N; // The number of (multiple) values
|
||||
PVAL To_Val; // To value used for Update/Insert
|
||||
}; // end of class XMLCOL
|
||||
|
||||
|
Reference in New Issue
Block a user