Commit 7dc48ae3 authored by Alexander Barkov's avatar Alexander Barkov

Merge 10.0-connect -> 10.0

parents 9290a580 727c1f62
......@@ -5147,6 +5147,7 @@ char check_if_ignore_table(const char *table_name, char *table_type)
if (!opt_no_data &&
(!my_strcasecmp(&my_charset_latin1, table_type, "MRG_MyISAM") ||
!strcmp(table_type,"MRG_ISAM") ||
!strcmp(table_type,"CONNECT") ||
!strcmp(table_type,"FEDERATED")))
result= IGNORE_DATA;
}
......
......@@ -379,6 +379,7 @@ sub main {
mtr_report("Logging: $0 ", join(" ", @ARGV));
$DEFAULT_SUITES.= ',' . join(',', qw(
connect
query_response_time
sequence
spider
......
......@@ -1117,3 +1117,95 @@
fun:_nss_dns_gethostbyaddr_r
fun:gethostbyaddr_r
}
{
ConnectSE: unixODBC SQLAllocEnv leaves some "still reachable" pointers
Memcheck:Leak
fun:malloc
fun:strdup
...
obj:*/libodbc.so*
fun:_ZN7ODBConn10GetDriversEP7_qryres
}
{
ConnectSE: unixODBC SQLAllocEnv leaves some "still reachable" pointers
Memcheck:Leak
fun:calloc
...
obj:*/libodbc.so*
fun:_ZN7ODBConn10GetDriversEP7_qryres
}
{
ConnectSE: unixODBC SQLAllocEnv leavs some "still reachable" pointers
Memcheck:Leak
fun:malloc
fun:strdup
...
obj:*/libodbc.so*
fun:_ZN7ODBConn14GetDataSourcesEP7_qryres
}
{
ConnectSE: unixODBC SQLAllocEnv leavs some "still reachable" pointers
Memcheck:Leak
fun:calloc
...
obj:*/libodbc.so*
fun:_ZN7ODBConn14GetDataSourcesEP7_qryres
}
{
ConnectSE: unixODBC SQLDriverConnect leaves some "still reachable" pointers
Memcheck:Leak
fun:malloc
fun:strdup
...
obj:*/libodbc.so*
fun:SQLDriverConnect
fun:_ZN7ODBConn7ConnectEj
fun:_ZN7ODBConn4OpenEPcj
fun:_Z11ODBCColumnsP7_globalPcS1_S1_b
fun:_ZL26connect_assisted_discoveryP10handlertonP3THDP11TABLE_SHAREP14HA_CREATE_INFO
}
{
ConnectSE: unixODBC SQLDriverConnect leaves some "still reachable" pointers
Memcheck:Leak
fun:calloc
...
obj:*/libodbc.so*
fun:SQLDriverConnect
fun:_ZN7ODBConn7ConnectEj
fun:_ZN7ODBConn4OpenEPcj
fun:_Z11ODBCColumnsP7_globalPcS1_S1_b
fun:_ZL26connect_assisted_discoveryP10handlertonP3THDP11TABLE_SHAREP14HA_CREATE_INFO
}
{
ConnectSE: unixODBC SQLDriverConnect leaves some "still reachable" pointers
Memcheck:Leak
fun:malloc
...
obj:*/libodbc.so*
fun:SQLDriverConnect
fun:_ZN7ODBConn7ConnectEj
fun:_ZN7ODBConn4OpenEPcj
fun:_Z11ODBCColumnsP7_globalPcS1_S1_b
fun:_ZL26connect_assisted_discoveryP10handlertonP3THDP11TABLE_SHAREP14HA_CREATE_INFO
}
{
ConnectSE: unixODBC dlopen leaves some "still reachable"
Memcheck:Leak
fun:malloc
fun:expand_dynamic_string_token
...
obj:*/libltdl.so*
...
obj:*/libodbc.so*
}
......@@ -178,7 +178,7 @@ bool COLBLK::InitValue(PGLOBAL g)
(To_Tdb) ? To_Tdb->GetCat() : NULL)))
return true;
Status = BUF_READY;
AddStatus(BUF_READY);
Value->SetNullable(Nullable);
#ifdef DEBTRACE
......
......@@ -592,6 +592,18 @@ PXNODE DOMNODELIST::GetItem(PGLOBAL g, int n, PXNODE np)
} // end of GetItem
/******************************************************************/
/* Reset the pointer on the deleted item. */
/******************************************************************/
bool DOMNODELIST::DropItem(PGLOBAL g, int n)
{
if (Listp == NULL || Listp->length <= n)
return true;
//Listp->item[n] = NULL; La proprit n'a pas de mthode 'set'
return false;
} // end of DeleteItem
/* ----------------------- class DOMATTR ------------------------ */
/******************************************************************/
......@@ -618,8 +630,8 @@ bool DOMATTR::SetText(PGLOBAL g, char *txtp, int len)
Len = len;
} // endif len
if (!MultiByteToWideChar(CP_ACP, 0, txtp, strlen(txtp) + 1,
Ws, Len + 1)) {
if (!MultiByteToWideChar(CP_UTF8, 0, txtp, strlen(txtp) + 1,
Ws, Len + 1)) {
sprintf(g->Message, MSG(WS_CONV_ERR), txtp);
return true;
} // endif
......
......@@ -104,8 +104,9 @@ class DOMNODELIST : public XMLNODELIST {
friend class DOMNODE;
public:
// Methods
virtual int GetLength(void) {return Listp->length;}
virtual int GetLength(void) {return Listp->length;}
virtual PXNODE GetItem(PGLOBAL g, int n, PXNODE np);
virtual bool DropItem(PGLOBAL g, int n);
protected:
// Constructor
......
This diff is collapsed.
......@@ -208,7 +208,8 @@ public:
return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_HAS_RECORDS |
HA_NO_AUTO_INCREMENT | HA_NO_PREFIX_CHAR_KEYS |
HA_NO_COPY_ON_ALTER | HA_CAN_VIRTUAL_COLUMNS |
/*HA_NULL_IN_KEY |*/ HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE);
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
/*HA_NULL_IN_KEY |*/ HA_MUST_USE_TABLE_CONDITION_PUSHDOWN);
}
/** @brief
......
......@@ -14,6 +14,10 @@
#include "my_global.h"
//#endif // !WIN32
#if !defined(LIBXML_TREE_ENABLED) || !defined(LIBXML_OUTPUT_ENABLED)
#error "tree support not compiled in"
#endif
#if !defined(LIBXML_XPATH_ENABLED) || !defined(LIBXML_SAX1_ENABLED)
#error "XPath not supported"
#endif
......@@ -47,8 +51,6 @@ typedef struct _x2block { /* Loaded XML file block */
short Type; /* TYPE_FB_XML */
int Retcode; /* Return code from Load */
xmlDocPtr Docp; /* Document interface pointer */
// xmlXPathContextPtr Ctxp;
// xmlXPathObjectPtr Xop;
} X2BLOCK, *PX2BLOCK;
/******************************************************************/
......@@ -91,6 +93,8 @@ class LIBXMLDOC : public XMLDOCUMENT {
xmlNodeSetPtr Nlist;
xmlXPathContextPtr Ctxp;
xmlXPathObjectPtr Xop;
xmlXPathObjectPtr NlXop;
xmlErrorPtr Xerr;
char *Buf; // Temporary
bool Nofreelist;
}; // end of class LIBXMLDOC
......@@ -141,6 +145,7 @@ class XML2NODELIST : public XMLNODELIST {
// Methods
virtual int GetLength(void);
virtual PXNODE GetItem(PGLOBAL g, int n, PXNODE np);
virtual bool DropItem(PGLOBAL g, int n);
protected:
// Constructor
......@@ -180,6 +185,23 @@ extern int trace;
} // "C"
#if defined(MEMORY_TRACE)
static int m = 0;
static char s[500];
/**************************************************************************/
/* Tracing output function. */
/**************************************************************************/
void xtrc(char const *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
//vfprintf(stderr, fmt, ap);
vsprintf(s, fmt, ap);
if (s[strlen(s)-1] == '\n')
s[strlen(s)-1] = 0;
va_end (ap);
} // end of htrc
static xmlFreeFunc Free;
static xmlMallocFunc Malloc;
static xmlMallocFunc MallocA;
......@@ -188,42 +210,53 @@ static xmlStrdupFunc Strdup;
void xmlMyFree(void *mem)
{
if (trace)
htrc("Freeing at %p\n", mem);
if (trace) {
htrc("%.4d Freeing at %p %s\n", ++m, mem, s);
*s = 0;
} // endif trace
Free(mem);
} // end of xmlMyFree
void *xmlMyMalloc(size_t size)
{
void *p = Malloc(size);
if (trace)
htrc("Allocating %.5d at %p\n", size, p);
if (trace) {
htrc("%.4d Allocating %.5d at %p %s\n", ++m, size, p, s);
*s = 0;
} // endif trace
return p;
} // end of xmlMyMalloc
void *xmlMyMallocAtomic(size_t size)
{
void *p = MallocA(size);
if (trace)
htrc("Atom alloc %.5d at %p\n", size, p);
if (trace) {
htrc("%.4d Atom alloc %.5d at %p %s\n", ++m, size, p, s);
*s = 0;
} // endif trace
return p;
} // end of xmlMyMallocAtomic
void *xmlMyRealloc(void *mem, size_t size)
{
void *p = Realloc(mem, size);
if (trace)
htrc("ReAlloc %.5d to %p from %p\n", size, p, mem);
if (trace) {
htrc("%.4d ReAlloc %.5d to %p from %p %s\n", ++m, size, p, mem, s);
*s = 0;
} // endif trace
return p;
} // end of xmlMyRealloc
char *xmlMyStrdup(const char *str)
{
char *p = Strdup(str);
if (trace)
htrc("Duplicating to %p from %p %s\n", p, str, str);
if (trace) {
htrc("%.4d Duplicating to %p from %p %s %s\n", ++m, p, str, str, s);
*s = 0;
} // endif trace
return p;
} // end of xmlMyStrdup
#define htrc xtrc
#endif // MEMORY_TRACE
/******************************************************************/
......@@ -295,6 +328,8 @@ LIBXMLDOC::LIBXMLDOC(char *nsl, char *nsdf, char *enc, PFBLOCK fp)
Nlist = NULL;
Ctxp = NULL;
Xop = NULL;
NlXop = NULL;
Xerr = NULL;
Buf = NULL;
Nofreelist = false;
} // end of LIBXMLDOC constructor
......@@ -321,9 +356,10 @@ bool LIBXMLDOC::ParseFile(char *fn)
Encoding = (char*)Docp->encoding;
return false;
} else
return true;
} else if ((Xerr = xmlGetLastError()))
xmlResetError(Xerr);
return true;
} // end of ParseFile
/******************************************************************/
......@@ -344,8 +380,6 @@ PFBLOCK LIBXMLDOC::LinkXblock(PGLOBAL g, MODE m, int rc, char *fn)
xp->Length = (m == MODE_READ) ? 1 : 0;
xp->Retcode = rc;
xp->Docp = Docp;
// xp->Ctxp = Ctxp;
// xp->Xop = Xop;
// Return xp as a fp
return (PFBLOCK)xp;
......@@ -356,6 +390,9 @@ PFBLOCK LIBXMLDOC::LinkXblock(PGLOBAL g, MODE m, int rc, char *fn)
/******************************************************************/
bool LIBXMLDOC::NewDoc(PGLOBAL g, char *ver)
{
if (trace)
htrc("NewDoc\n");
return ((Docp = xmlNewDoc(BAD_CAST ver)) == NULL);
} // end of NewDoc
......@@ -462,8 +499,7 @@ int LIBXMLDOC::DumpDoc(PGLOBAL g, char *ofn)
if (xmlSaveFormatFileEnc((const char *)ofn, Docp, Encoding, 0) < 0) {
xmlErrorPtr err = xmlGetLastError();
strcpy(g->Message, (err) ? err->message : "Error saving XML doc"
);
strcpy(g->Message, (err) ? err->message : "Error saving XML doc");
rc = -1;
} // endif Save
// rc = xmlDocDump(of, Docp);
......@@ -497,17 +533,44 @@ void LIBXMLDOC::CloseDoc(PGLOBAL g, PFBLOCK xp)
if (trace)
htrc("CloseDoc: xp=%p count=%d\n", xp, (xp) ? xp->Count : 0);
if (xp && xp->Count == 1) {
if (Nlist)
//if (xp && xp->Count == 1) {
if (Nlist) {
xmlXPathFreeNodeSet(Nlist);
if (Xop)
if ((Xerr = xmlGetLastError()))
xmlResetError(Xerr);
Nlist = NULL;
} // endif Nlist
if (Xop) {
xmlXPathFreeObject(Xop);
if (Ctxp)
if ((Xerr = xmlGetLastError()))
xmlResetError(Xerr);
Xop = NULL;
} // endif Xop
if (NlXop) {
xmlXPathFreeObject(NlXop);
if ((Xerr = xmlGetLastError()))
xmlResetError(Xerr);
NlXop = NULL;
} // endif NlXop
if (Ctxp) {
xmlXPathFreeContext(Ctxp);
} // endif Count
if ((Xerr = xmlGetLastError()))
xmlResetError(Xerr);
Ctxp = NULL;
} // endif Ctxp
// } // endif Count
CloseXML2File(g, xp, false);
} // end of Close
......@@ -560,18 +623,29 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp)
} // endfor nsp
} else {
} // endif Ctxp
if (Xop) {
if (trace)
htrc("Calling xmlXPathFreeNodeSetList Xop=%p\n", Xop);
htrc("Calling xmlXPathFreeNodeSetList Xop=%p NOFREE=%d\n",
Xop, Nofreelist);
if (Nofreelist) {
// Making Nlist that must not be freed yet
xmlXPathFreeNodeSetList(Xop); // Caused memory leak
// xmlXPathFreeNodeSetList(Xop); // Caused memory leak
assert(!NlXop);
NlXop = Xop; // Freed on closing
Nofreelist = false;
} else
xmlXPathFreeObject(Xop); // Caused node not found
} // endif Ctxp
if ((Xerr = xmlGetLastError())) {
strcpy(g->Message, Xerr->message);
xmlResetError(Xerr);
return NULL;
} // endif Xerr
} // endif Xop
// Set the context to the calling node
Ctxp->node = np;
......@@ -990,6 +1064,8 @@ void XML2NODE::AddText(PGLOBAL g, char *txtp)
/******************************************************************/
void XML2NODE::DeleteChild(PGLOBAL g, PXNODE dnp)
{
xmlErrorPtr xerr;
if (trace)
htrc("DeleteChild: node=%p\n", dnp);
......@@ -999,12 +1075,39 @@ void XML2NODE::DeleteChild(PGLOBAL g, PXNODE dnp)
// This is specific to row nodes
if (text && text->type == XML_TEXT_NODE) {
xmlUnlinkNode(text);
if ((xerr = xmlGetLastError()))
goto err;
xmlFreeNode(text);
if ((xerr = xmlGetLastError()))
goto err;
} // endif type
xmlUnlinkNode(np);
if ((xerr = xmlGetLastError()))
goto err;
xmlFreeNode(np);
if ((xerr = xmlGetLastError()))
goto err;
Delete(dnp);
if ((xerr = xmlGetLastError()))
goto err;
return;
err:
if (trace)
htrc("DeleteChild: errmsg=%s\n", xerr->message);
xmlResetError(xerr);
} // end of DeleteChild
/* -------------------- class XML2NODELIST ---------------------- */
......@@ -1045,6 +1148,22 @@ PXNODE XML2NODELIST::GetItem(PGLOBAL g, int n, PXNODE np)
} // end of GetItem
/******************************************************************/
/* Reset the pointer on the deleted item. */
/******************************************************************/
bool XML2NODELIST::DropItem(PGLOBAL g, int n)
{
if (trace)
htrc("DropItem: n=%d\n", n);
// We should do something here
if (!Listp || Listp->nodeNr <= n)
return true;
Listp->nodeTab[n] = NULL; // This was causing Valgrind warning
return false;
} // end of DropItem
/* ---------------------- class XML2ATTR ------------------------ */
/******************************************************************/
......
......@@ -89,7 +89,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
static unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 256, 32, 32};
char *fld, *fmt, cmd[128];
int i, n, nf, ncol = sizeof(buftyp) / sizeof(int);
int len, type, prec, rc, k = 0;
int len, type, prec, rc, k = 0;
PQRYRES qrp;
PCOLRES crp;
MYSQLC myc;
......@@ -166,7 +166,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
// Get type, type name, and precision
fld = myc.GetCharField(1);
prec = 0;
len = 256; // Default for text or blob
len = 255; // Default for text or blob
if ((nf = sscanf(fld, "%[^(](%d,%d", cmd, &len, &prec)) < 1) {
sprintf(g->Message, MSG(BAD_FIELD_TYPE), fld);
......
......@@ -54,6 +54,7 @@ uint GetDefaultPort(void);
class DllItem MYSQLC {
friend class TDBMYSQL;
friend class MYSQLCOL;
friend class TDBMYEXC;
// Construction
public:
MYSQLC(void);
......
......@@ -217,3 +217,24 @@ t2 CREATE TABLE `t2` (
SELECT * FROM t2;
a
DROP TABLE t2, t1;
#
# MDEV-4877 mysqldump dumps all data from a connect table
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (10),(20),(30);
CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL CONNECTION='mysql://root@localhost:PORT/test/t1';
SELECT * FROM t2;
a
10
20
30
# Start of mysqldump ------
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@localhost:PORT/test/t1' `TABLE_TYPE`='MYSQL';
/*!40101 SET character_set_client = @saved_cs_client */;
# End of mysqldump ------
DROP TABLE t2;
DROP TABLE t1;
......@@ -413,7 +413,7 @@ DROP TABLE t1;
SET @a=LOAD_FILE('MYSQLD_DATADIR/test/t1.xml');
SELECT CAST(@a AS CHAR CHARACTER SET latin1);
CAST(@a AS CHAR CHARACTER SET latin1) <?xml version="1.0" encoding="iso-8859-1"?>
<!-- Created by CONNECT Version 1.01.0007 July 26, 2013 -->
<!-- Created by CONNECT Version 1.01.0008 August 18, 2013 -->
<t1>
<line>
<node>ÀÁÂÃ</node>
......
......@@ -10,7 +10,7 @@ let $PORT= `select @@port`;
--disable_query_log
--replace_result $PORT PORT
--error 0,ER_UNKNOWN_ERROR
--eval CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
--eval CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='tx1' OPTION_LIST='host=localhost,user=root,port=$PORT'
if (!`SELECT count(*) FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'
AND ENGINE='CONNECT'
......@@ -420,3 +420,17 @@ DROP TABLE t2, t1;
# TODO: add test for YEAR
# TODO: add tests for fractional seconds
--echo #
--echo # MDEV-4877 mysqldump dumps all data from a connect table
--echo #
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (10),(20),(30);
--replace_result $PORT PORT
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL CONNECTION='mysql://root@localhost:$PORT/test/t1'
SELECT * FROM t2;
--echo # Start of mysqldump ------
--replace_result $PORT PORT
--exec $MYSQL_DUMP --compact test t2
--echo # End of mysqldump ------
DROP TABLE t2;
DROP TABLE t1;
-- source include/not_embedded.inc
let $PORT= `select @@port`;
--disable_query_log
--replace_result $PORT PORT
--error 0,ER_UNKNOWN_ERROR
--eval CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
if (!`SELECT count(*) FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'
AND ENGINE='CONNECT'
AND CREATE_OPTIONS LIKE '%`table_type`=MySQL%'`)
{
Skip Need MySQL support;
}
DROP TABLE t1;
--enable_query_log
--echo #
--echo # Testing FILE privilege
--echo #
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
--connect(user,localhost,user,,)
--connection user
SELECT user();
--replace_result $PORT PORT
--error ER_ACCESS_DENIED_ERROR
--eval CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=MySQL OPTION_LIST='host=localhost,user=root1,port=$PORT'
--connection default
SELECT user();
CREATE TABLE t1remote (a INT NOT NULL);
INSERT INTO t1remote VALUES (10),(20),(30);
--replace_result $PORT PORT
--eval CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=MySQL TABNAME=t1remote OPTION_LIST='host=localhost,user=root,port=$PORT'
SELECT * FROM t1;
--connection user
SELECT user();
--error ER_ACCESS_DENIED_ERROR
SELECT * FROM t1;
--error ER_ACCESS_DENIED_ERROR
INSERT INTO t1 VALUES ('xxx');
--error ER_ACCESS_DENIED_ERROR
DELETE FROM t1 WHERE a='xxx';
--error ER_ACCESS_DENIED_ERROR
UPDATE t1 SET a='yyy' WHERE a='xxx';
--error ER_ACCESS_DENIED_ERROR
TRUNCATE TABLE t1;
--error ER_ACCESS_DENIED_ERROR
ALTER TABLE t1 READONLY=1;
--error ER_ACCESS_DENIED_ERROR
CREATE VIEW v1 AS SELECT * FROM t1;
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE
--connection default
SELECT user();
CREATE VIEW v1 AS SELECT * FROM t1;
--connection user
SELECT user();
--error ER_ACCESS_DENIED_ERROR
SELECT * FROM v1;
--error ER_ACCESS_DENIED_ERROR
INSERT INTO v1 VALUES (2);
--error ER_ACCESS_DENIED_ERROR
UPDATE v1 SET a=123;
--error ER_ACCESS_DENIED_ERROR
DELETE FROM v1;
--disconnect user
--connection default
SELECT user();
DROP VIEW v1;
DROP TABLE t1, t1remote;
DROP USER user@localhost;
--echo #
--echo # Testing FILE privileges done
--echo #
-- source include/not_embedded.inc
let $PORT= `select @@port`;
--disable_query_log
--replace_result $PORT PORT
--error 0,ER_UNKNOWN_ERROR
--eval CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='tx1' OPTION_LIST='host=localhost,user=root,port=$PORT'
if (!`SELECT count(*) FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'
AND ENGINE='CONNECT'
AND CREATE_OPTIONS LIKE '%`table_type`=MySQL%'`)
{
Skip Need MySQL support;
}
DROP TABLE t1;
--enable_query_log
--echo #
--echo # Testing FILE privilege
--echo #
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
--connect(user,localhost,user,,)
--connection user
SELECT user();
--replace_result $PORT PORT
--error ER_ACCESS_DENIED_ERROR
--eval CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=MySQL OPTION_LIST='host=localhost,user=root1,port=$PORT'
--connection default
SELECT user();
CREATE TABLE t1remote (a INT NOT NULL);
INSERT INTO t1remote VALUES (10),(20),(30);
--replace_result $PORT PORT
--eval CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=MySQL TABNAME=t1remote OPTION_LIST='host=localhost,user=root,port=$PORT'
SELECT * FROM t1;
--connection user
SELECT user();
--error ER_ACCESS_DENIED_ERROR
SELECT * FROM t1;
--error ER_ACCESS_DENIED_ERROR
INSERT INTO t1 VALUES ('xxx');
--error ER_ACCESS_DENIED_ERROR
DELETE FROM t1 WHERE a='xxx';
--error ER_ACCESS_DENIED_ERROR
UPDATE t1 SET a='yyy' WHERE a='xxx';
--error ER_ACCESS_DENIED_ERROR
TRUNCATE TABLE t1;
--error ER_ACCESS_DENIED_ERROR
ALTER TABLE t1 READONLY=1;
--error ER_ACCESS_DENIED_ERROR
CREATE VIEW v1 AS SELECT * FROM t1;
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE
--connection default
SELECT user();
CREATE VIEW v1 AS SELECT * FROM t1;
--connection user
SELECT user();
--error ER_ACCESS_DENIED_ERROR
SELECT * FROM v1;
--error ER_ACCESS_DENIED_ERROR
INSERT INTO v1 VALUES (2);
--error ER_ACCESS_DENIED_ERROR
UPDATE v1 SET a=123;
--error ER_ACCESS_DENIED_ERROR
DELETE FROM v1;
--disconnect user
--connection default
SELECT user();
DROP VIEW v1;
DROP TABLE t1, t1remote;
DROP USER user@localhost;
--echo #
--echo # Testing FILE privileges done
--echo #
/***********************************************************************/
/* ODBC catalog function prototypes. */
/***********************************************************************/
char *ODBCCheckConnection(PGLOBAL g, char *dsn, int cop);
PQRYRES ODBCDataSources(PGLOBAL g, bool info);
PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *table,
char *colpat, bool info);
PQRYRES ODBCSrcCols(PGLOBAL g, char *dsn, char *src);
PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *tabpat, bool info);
PQRYRES ODBCDrivers(PGLOBAL g, bool info);
This diff is collapsed.
......@@ -91,8 +91,7 @@ class DBX : public BLOCK {
// Implementation (use ThrowDBX to create)
RETCODE GetRC(void) {return m_RC;}
PSZ GetMsg(void) {return m_Msg;}
const char *GetErrorMessage(int i)
{return (i >=0 && i < MAX_NUM_OF_MSG) ? m_ErrMsg[i] : "No ODBC error";}
const char *GetErrorMessage(int i);
protected:
void BuildErrorMessage(ODBConn* pdb, HSTMT hstmt = SQL_NULL_HSTMT);
......@@ -107,6 +106,7 @@ class DBX : public BLOCK {
/* ODBConn class. */
/***********************************************************************/
class ODBConn : public BLOCK {
friend class TDBODBC;
friend class DBX;
friend PQRYRES GetColumnInfo(PGLOBAL, char*&, char *, int, PVBLK&);
private:
......@@ -142,11 +142,12 @@ class ODBConn : public BLOCK {
int ExecDirectSQL(char *sql, ODBCCOL *tocols);
int Fetch(void);
int PrepareSQL(char *sql);
bool ExecuteSQL(void);
int ExecuteSQL(bool x);
bool BindParam(ODBCCOL *colp);
int GetCatInfo(CATPARM *cap);
bool GetDataSources(PQRYRES qrp);
bool GetDrivers(PQRYRES qrp);
PQRYRES GetMetaData(PGLOBAL g, char *dsn, char *src);
public:
// Set special options
......@@ -185,5 +186,6 @@ class ODBConn : public BLOCK {
int m_Catver;
PSZ m_Connect;
bool m_Updatable;
bool m_Transact;
char m_IDQuoteChar;
}; // end of ODBConn class definition
#ifndef _OS_H_INCLUDED
#define _OS_H_INCLUDED
#if defined(__FreeBSD__) || defined(__APPLE__)
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__APPLE__)
typedef off_t off64_t;
#define lseek64(fd, offset, whence) lseek((fd), (offset), (whence))
#define open64(path, flags, mode) open((path), (flags), (mode))
......
......@@ -111,6 +111,7 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_PIVOT = 120, /* PIVOT access method type no */
TYPE_AM_SRC = 121, /* PIVOT multiple column type no */
TYPE_AM_FNC = 122, /* PIVOT source column type no */
TYPE_AM_XML = 127, /* XML access method type no */
TYPE_AM_XTB = 130, /* SYS table access method type */
TYPE_AM_MAC = 137, /* MAC table access method type */
TYPE_AM_WMI = 139, /* WMI table access method type */
......@@ -582,5 +583,6 @@ FILE *global_fopen(GLOBAL *g, int msgid, const char *path, const char *mode);
int global_open(GLOBAL *g, int msgid, const char *filename, int flags);
int global_open(GLOBAL *g, int msgid, const char *filename, int flags, int mode);
DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR name, LPCSTR dir);
char *MakeEscape(PGLOBAL g, char* str, char q);
bool PushWarning(PGLOBAL, PTDBASE);
......@@ -731,6 +731,34 @@ bool EvalLikePattern(LPCSTR sp, LPCSTR tp)
return (b);
} /* end of EvalLikePattern */
/***********************************************************************/
/* MakeEscape: Escape some characters in a string. */
/***********************************************************************/
char *MakeEscape(PGLOBAL g, char* str, char q)
{
char *bufp;
int i, k, n = 0, len = (int)strlen(str);
for (i = 0; i < len; i++)
if (str[i] == q || str[i] == '\\')
n++;
if (!n)
return str;
else
bufp = (char*)PlugSubAlloc(g, NULL, len + n + 1);
for (i = k = 0; i < len; i++) {
if (str[i] == q || str[i] == '\\')
bufp[k++] = '\\';
bufp[k++] = str[i];
} // endfor i
bufp[k] = 0;
return bufp;
} /* end of MakeEscape */
/***********************************************************************/
/* PlugConvertConstant: convert a Plug constant to an Xobject. */
/***********************************************************************/
......
......@@ -147,6 +147,7 @@ class XMLNODELIST : public BLOCK {
// Properties
virtual int GetLength(void) = 0;
virtual PXNODE GetItem(PGLOBAL, int, PXNODE = NULL) = 0;
virtual bool DropItem(PGLOBAL, int) = 0;
protected:
// Constructor
......
......@@ -93,7 +93,7 @@ PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q,
PCOLRES crp;
if (info) {
imax = 0;
imax = hmax = 0;
length[0] = 128;
goto skipit;
} // endif info
......
......@@ -884,9 +884,11 @@ void TDBDIR::CloseDB(PGLOBAL g)
_findclose(Hsearch);
Hsearch = -1;
#else // !WIN32
// Close the DIR handle.
closedir(Dir);
Dir = NULL;
// Close the DIR handle
if (Dir) {
closedir(Dir);
Dir = NULL;
} // endif dir
#endif // !WIN32
iFile = 0;
} // end of CloseDB
......
This diff is collapsed.
......@@ -3,8 +3,10 @@
typedef class MYSQLDEF *PMYDEF;
typedef class TDBMYSQL *PTDBMY;
typedef class MYSQLC *PMYC;
typedef class MYSQLCOL *PMYCOL;
typedef class TDBMYEXC *PTDBMYX;
typedef class MYXCOL *PMYXCOL;
typedef class MYSQLC *PMYC;
/* ------------------------- MYSQL classes --------------------------- */
......@@ -38,7 +40,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
// Methods
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE m);
bool ParseURL(PGLOBAL g, char *url);
bool ParseURL(PGLOBAL g, char *url, bool b = true);
bool GetServerInfo(PGLOBAL g, const char *server_name);
protected:
......@@ -54,6 +56,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
bool Isview; /* TRUE if this table is a MySQL view */
bool Bind; /* Use prepared statement on insert */
bool Delayed; /* Delayed insert */
bool Xsrc; /* Execution type */
}; // end of MYSQLDEF
/***********************************************************************/
......@@ -158,6 +161,87 @@ class MYSQLCOL : public COLBLK {
int Rank; // Rank (position) number in the query
}; // end of class MYSQLCOL
/***********************************************************************/
/* This is the class declaration for the exec command MYSQL table. */
/***********************************************************************/
class TDBMYEXC : public TDBMYSQL {
friend class MYXCOL;
public:
// Constructor
TDBMYEXC(PMYDEF tdp) : TDBMYSQL(tdp) {Cmdcol = NULL;}
TDBMYEXC(PGLOBAL g, PTDBMYX tdbp) : TDBMYSQL(g, tdbp)
{Cmdcol = tdbp->Cmdcol;}
// Implementation
//virtual AMT GetAmType(void) {return TYPE_AM_MYSQL;}
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMYEXC(g, this);}
// Methods
virtual PTDB CopyOne(PTABS t);
//virtual int GetAffectedRows(void) {return AftRows;}
//virtual int GetRecpos(void) {return N;}
//virtual int GetProgMax(PGLOBAL g);
//virtual void ResetDB(void) {N = 0;}
//virtual int RowNumber(PGLOBAL g, bool b = FALSE);
virtual bool IsView(void) {return Isview;}
//virtual PSZ GetServer(void) {return Server;}
// void SetDatabase(LPCSTR db) {Database = (char*)db;}
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual int GetMaxSize(PGLOBAL g);
virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g);
//virtual int DeleteDB(PGLOBAL g, int irc);
//virtual void CloseDB(PGLOBAL g);
// Specific routines
// bool SetColumnRanks(PGLOBAL g);
// PCOL MakeFieldColumn(PGLOBAL g, char *name);
// PSZ FindFieldColumn(char *name);
protected:
// Internal functions
char *MakeCMD(PGLOBAL g);
//bool MakeSelect(PGLOBAL g);
//bool MakeInsert(PGLOBAL g);
//int BindColumns(PGLOBAL g);
// Members
char *Cmdcol; // The name of the Xsrc command column
}; // end of class TDBMYEXC
/***********************************************************************/
/* Class MYXCOL: MySQL exec command table column. */
/***********************************************************************/
class MYXCOL : public MYSQLCOL {
friend class TDBMYEXC;
public:
// Constructors
MYXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "MYSQL");
MYXCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am = "MYSQL");
MYXCOL(MYXCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
//virtual int GetAmType(void) {return TYPE_AM_MYSQL;}
// void InitBind(PGLOBAL g);
// Methods
//virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
virtual void ReadColumn(PGLOBAL g);
virtual void WriteColumn(PGLOBAL g);
// bool FindRank(PGLOBAL g);
protected:
// Default constructor not to be used
MYXCOL(void) {}
// Members
char *Buffer; // To get returned message
int Flag; // Column content desc
}; // end of class MYXCOL
/***********************************************************************/
/* This is the class declaration for the MYSQL column catalog table. */
/***********************************************************************/
......
This diff is collapsed.
/*************** Tabodbc H Declares Source Code File (.H) **************/
/* Name: TABODBC.H Version 1.5 */
/* Name: TABODBC.H Version 1.6 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2000-2013 */
/* */
......@@ -11,6 +11,8 @@
typedef class ODBCDEF *PODEF;
typedef class TDBODBC *PTDBODBC;
typedef class ODBCCOL *PODBCCOL;
typedef class TDBXDBC *PTDBXDBC;
typedef class XSRCCOL *PXSRCCOL;
typedef class TDBOIF *PTDBOIF;
typedef class OIFCOL *POIFCOL;
typedef class TDBSRC *PTDBSRC;
......@@ -19,6 +21,8 @@ typedef class TDBSRC *PTDBSRC;
/* ODBC table. */
/***********************************************************************/
class DllExport ODBCDEF : public TABDEF { /* Logical table description */
friend class TDBODBC;
friend class TDBXDBC;
public:
// Constructor
ODBCDEF(void);
......@@ -29,6 +33,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
PSZ GetTabname(void) {return Tabname;}
PSZ GetTabowner(void) {return Tabowner;}
PSZ GetTabqual(void) {return Tabqual;}
PSZ GetSrcdef(void) {return Srcdef;}
PSZ GetQchar(void) {return (Qchar && *Qchar) ? Qchar : NULL;}
int GetCatver(void) {return Catver;}
int GetOptions(void) {return Options;}
......@@ -43,9 +48,11 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
PSZ Tabname; /* External table name */
PSZ Tabowner; /* External table owner */
PSZ Tabqual; /* External table qualifier */
PSZ Srcdef; /* The source table SQL definition */
PSZ Qchar; /* Identifier quoting character */
int Catver; /* ODBC version for catalog functions */
int Options; /* Open connection options */
bool Xsrc; /* Execution type */
}; // end of ODBCDEF
#if !defined(NODBC)
......@@ -92,10 +99,10 @@ class TDBODBC : public TDBASE {
int Decode(char *utf, char *buf, size_t n);
char *MakeSQL(PGLOBAL g, bool cnt);
//bool MakeUpdate(PGLOBAL g, PSELECT selist);
//bool MakeInsert(PGLOBAL g);
bool MakeInsert(PGLOBAL g);
//bool MakeDelete(PGLOBAL g);
//bool MakeFilter(PGLOBAL g, bool c);
//bool BindParameters(PGLOBAL g);
bool BindParameters(PGLOBAL g);
// Members
ODBConn *Ocp; // Points to an ODBC connection class
......@@ -104,6 +111,7 @@ class TDBODBC : public TDBASE {
char *TableName; // Points to ODBC table name
char *Owner; // Points to ODBC table Owner
char *Qualifier; // Points to ODBC table Qualifier
char *Srcdef; // The source table SQL definition
char *Query; // Points to SQL statement
char *Count; // Points to count(*) SQL statement
//char *Where; // Points to local where clause
......@@ -122,7 +130,7 @@ class TDBODBC : public TDBASE {
}; // end of class TDBODBC
/***********************************************************************/
/* Class ODBCCOL: DOS access method column descriptor. */
/* Class ODBCCOL: ODBC access method column descriptor. */
/* This A.M. is used for ODBC tables. */
/***********************************************************************/
class ODBCCOL : public COLBLK {
......@@ -153,16 +161,85 @@ class ODBCCOL : public COLBLK {
ODBCCOL(void);
// Members
TIMESTAMP_STRUCT *Sqlbuf; // To get SQL_TIMESTAMP's
void *Bufp; // To extended buffer
TIMESTAMP_STRUCT *Sqlbuf; // To get SQL_TIMESTAMP's
void *Bufp; // To extended buffer
PVBLK Blkp; // To Value Block
//char F_Date[12]; // Internal Date format
PVAL To_Val; // To value used for Insert
SQLLEN *StrLen; // As returned by ODBC
SQLLEN Slen; // Used with Fetch
int Rank; // Rank (position) number in the query
SQLLEN Slen; // Used with Fetch
int Rank; // Rank (position) number in the query
}; // end of class ODBCCOL
/***********************************************************************/
/* This is the ODBC Access Method class declaration that send */
/* commands to be executed by other DB ODBC drivers. */
/***********************************************************************/
class TDBXDBC : public TDBODBC {
friend class XSRCCOL;
friend class ODBConn;
public:
// Constructor
TDBXDBC(PODEF tdp = NULL) : TDBODBC(tdp) {Cmdcol = NULL;}
TDBXDBC(PTDBXDBC tdbp) : TDBODBC(tdbp) {Cmdcol = tdbp->Cmdcol;}
// Implementation
//virtual AMT GetAmType(void) {return TYPE_AM_ODBC;}
virtual PTDB Duplicate(PGLOBAL g)
{return (PTDB)new(g) TDBXDBC(this);}
// Methods
virtual PTDB CopyOne(PTABS t);
//virtual int GetRecpos(void);
//virtual PSZ GetFile(PGLOBAL g);
//virtual void SetFile(PGLOBAL g, PSZ fn);
//virtual void ResetSize(void);
//virtual int GetAffectedRows(void) {return AftRows;}
//virtual PSZ GetServer(void) {return "ODBC";}
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
//virtual int GetProgMax(PGLOBAL g);
virtual int GetMaxSize(PGLOBAL g);
virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g);
//virtual int DeleteDB(PGLOBAL g, int irc);
//virtual void CloseDB(PGLOBAL g);
protected:
// Internal functions
char *MakeCMD(PGLOBAL g);
//bool BindParameters(PGLOBAL g);
// Members
char *Cmdcol; // The name of the Xsrc command column
}; // end of class TDBXDBC
/***********************************************************************/
/* Used by table in source execute mode. */
/***********************************************************************/
class XSRCCOL : public ODBCCOL {
friend class TDBXDBC;
public:
// Constructors
XSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "ODBC");
XSRCCOL(XSRCCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
//virtual int GetAmType(void) {return TYPE_AM_ODBC;}
// Methods
virtual void ReadColumn(PGLOBAL g);
virtual void WriteColumn(PGLOBAL g);
// void Print(PGLOBAL g, FILE *, uint);
protected:
// Members
char *Buffer; // To get returned message
int Flag; // Column content desc
}; // end of class XSRCCOL
/***********************************************************************/
/* This is the class declaration for the Data Sources catalog table. */
/***********************************************************************/
......
......@@ -591,6 +591,17 @@ bool PRXCOL::Init(PGLOBAL g)
return FALSE;
} // end of Init
/***********************************************************************/
/* Reset the column descriptor to non evaluated yet. */
/***********************************************************************/
void PRXCOL::Reset(void)
{
if (Colp)
Colp->Reset();
Status &= ~BUF_READ;
} // end of Reset
/***********************************************************************/
/* ReadColumn: */
/***********************************************************************/
......@@ -600,7 +611,7 @@ void PRXCOL::ReadColumn(PGLOBAL g)
htrc("PRX ReadColumn: name=%s\n", Name);
if (Colp) {
Colp->ReadColumn(g);
Colp->Eval(g);
Value->SetValue_pval(To_Val);
// Set null when applicable
......
......@@ -70,7 +70,7 @@ class DllExport TDBPRX : public TDBASE {
virtual int GetRecpos(void) {return Tdbp->GetRecpos();}
virtual void ResetDB(void) {Tdbp->ResetDB();}
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
virtual PSZ GetServer(void) {return (Tdbp) ? Tdbp->GetServer() : (char*) "?";}
virtual PSZ GetServer(void) {return (Tdbp) ? Tdbp->GetServer() : (PSZ)"?";}
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
......@@ -105,6 +105,7 @@ class DllExport PRXCOL : public COLBLK {
virtual int GetAmType(void) {return TYPE_AM_PRX;}
// Methods
virtual void Reset(void);
virtual bool IsSpecial(void) {return Pseudo;}
virtual void ReadColumn(PGLOBAL g);
bool Init(PGLOBAL g);
......
......@@ -253,7 +253,7 @@ XCLCOL::XCLCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
void XCLCOL::ReadColumn(PGLOBAL g)
{
if (((PTDBXCL)To_Tdb)->New) {
Colp->ReadColumn(g);
Colp->Eval(g);
strcpy(Cbuf, To_Val->GetCharValue());
Cp = Cbuf;
} // endif New
......@@ -272,9 +272,11 @@ void XCLCOL::ReadColumn(PGLOBAL g)
} else if (Nullable) {
Value->Reset();
Value->SetNull(true);
} else
} else {
// Skip that row
((PTDBXCL)To_Tdb)->RowFlag = 2;
Colp->Reset();
} // endif Cp
if (Cp && *Cp)
// More to come from the same row
......
......@@ -90,7 +90,7 @@ class XCLCOL : public PRXCOL {
XCLCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i);
// Methods
virtual void Reset(void) {} // Evaluated only by TDBXCL
virtual void Reset(void) {Colp->Reset();} // Evaluated only by TDBXCL
virtual void ReadColumn(PGLOBAL g);
protected:
......
......@@ -78,7 +78,9 @@ XMLDEF::XMLDEF(void)
DefNs = NULL;
Attrib = NULL;
Hdattr = NULL;
Coltype = 1;
Limit = 0;
Header = 0;
Xpand = false;
Usedom = false;
} // end of XMLDEF constructor
......@@ -338,17 +340,14 @@ PCOL TDBXML::InsertSpecialColumn(PGLOBAL g, PCOL colp)
/***********************************************************************/
/* LoadTableFile: Load and parse an XML file. */
/***********************************************************************/
int TDBXML::LoadTableFile(PGLOBAL g)
int TDBXML::LoadTableFile(PGLOBAL g, char *filename)
{
char filename[_MAX_PATH];
int rc = RC_OK, type = (Usedom) ? TYPE_FB_XML : TYPE_FB_XML2;
PFBLOCK fp = NULL;
PDBUSER dup = (PDBUSER)g->Activityp->Aptr;
/*********************************************************************/
/* We used the file name relative to recorded datapath. */
/*********************************************************************/
PlugSetPath(filename, Xfile, GetPath());
if (Docp)
return rc; // Already done
if (trace)
htrc("TDBXML: loading %s\n", filename);
......@@ -397,6 +396,7 @@ int TDBXML::LoadTableFile(PGLOBAL g)
} else
rc = (errno == ENOENT) ? RC_NF : RC_INFO;
// Cannot make a Xblock until document is made
return rc;
} // endif Docp
......@@ -418,9 +418,8 @@ int TDBXML::LoadTableFile(PGLOBAL g)
/***********************************************************************/
bool TDBXML::Initialize(PGLOBAL g)
{
char tabpath[64];
int rc;
PXMLCOL colp;
int rc;
PXMLCOL colp;
if (Void)
return false;
......@@ -440,8 +439,13 @@ bool TDBXML::Initialize(PGLOBAL g)
#else
if (!Root) {
#endif
char tabpath[64], filename[_MAX_PATH];
// We used the file name relative to recorded datapath
PlugSetPath(filename, Xfile, GetPath());
// Load or re-use the table file
rc = LoadTableFile(g);
rc = LoadTableFile(g, filename);
if (rc == RC_OK) {
// Get root node
......@@ -503,6 +507,9 @@ bool TDBXML::Initialize(PGLOBAL g)
goto error;
} // endif NewDoc
// Now we can link the Xblock
To_Xb = Docp->LinkXblock(g, Mode, rc, filename);
// Add a CONNECT comment node
// sprintf(buf, MSG(CREATED_PLUGDB), version);
sprintf(buf, " Created by CONNECT %s ", version);
......@@ -893,12 +900,21 @@ int TDBXML::DeleteDB(PGLOBAL g, int irc)
if ((RowNode = Nlist->GetItem(g, Irow, RowNode)) == NULL) {
sprintf(g->Message, MSG(MISSING_ROWNODE), Irow);
return RC_FX;
} else
} else {
TabNode->DeleteChild(g, RowNode);
if (Nlist->DropItem(g, Irow))
return RC_FX;
} // endif RowNode
Changed = true;
} else if (irc != RC_EF) {
TabNode->DeleteChild(g, RowNode);
if (Nlist->DropItem(g, Irow))
return RC_FX;
Changed = true;
} // endif's irc
......
......@@ -6,8 +6,6 @@
/* */
/* This file contains the XML table classes declares. */
/***********************************************************************/
#define TYPE_AM_XML (AMT)127
typedef class XMLDEF *PXMLDEF;
typedef class TDBXML *PTDBXML;
typedef class XMLCOL *PXMLCOL;
......@@ -81,7 +79,7 @@ class DllExport TDBXML : public TDBASE {
virtual void ResetDB(void) {N = 0;}
virtual void ResetSize(void) {MaxSize = -1;}
virtual int RowNumber(PGLOBAL g, bool b = false);
int LoadTableFile(PGLOBAL g);
int LoadTableFile(PGLOBAL g, char *filename);
bool Initialize(PGLOBAL g);
bool SetTabNode(PGLOBAL g);
void SetNodeAttr(PGLOBAL g, char *attr, PXNODE node);
......
......@@ -447,13 +447,12 @@ int TYPBLK<TYPE>::Find(PVAL vp)
template <class TYPE>
int TYPBLK<TYPE>::GetMaxLength(void)
{
char buf[12];
int i, n;
char buf[32];
int i, n, m;
for (i = n = 0; i < Nval; i++) {
sprintf(buf, Fmt, Typp[i]);
n = max(n, (signed)strlen(buf));
m = sprintf(buf, Fmt, Typp[i]);
n = max(n, m);
} // endfor i
return n;
......
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