mirror of
https://github.com/MariaDB/server.git
synced 2025-01-26 16:54:15 +01:00
Merge with 10.0-connect
This commit is contained in:
commit
18fc51f5a4
33 changed files with 1309 additions and 1110 deletions
storage/connect
colblk.cppcolblk.hconnect.ccconnect.hha_connect.ccha_connect.hmacutil.cppmycat.ccmyconn.cpp
mysql-test/connect
odbconn.cppplgdbsem.hreldef.cppreldef.htabfmt.cpptable.cpptabmysql.cpptabmysql.htabodbc.htabsys.cpptabtbl.cpptabutil.cpptabutil.htabwmi.cppvalblk.cppvalue.cppvalue.hxindex.cppxindex.hxtable.h
|
@ -350,8 +350,7 @@ TIDBLK::TIDBLK(PCOLUMN cp) : SPCBLK(cp)
|
|||
*Format.Type = 'C';
|
||||
Format.Length = Long;
|
||||
Format.Prec = 1; // Case insensitive
|
||||
Constant = (To_Tdb->GetAmType() != TYPE_AM_PLG &&
|
||||
To_Tdb->GetAmType() != TYPE_AM_PLM);
|
||||
Constant = (To_Tdb->GetAmType() != TYPE_AM_TBL);
|
||||
Tname = NULL;
|
||||
} // end of TIDBLK constructor
|
||||
|
||||
|
@ -367,3 +366,30 @@ void TIDBLK::ReadColumn(PGLOBAL g)
|
|||
|
||||
} // end of ReadColumn
|
||||
|
||||
/***********************************************************************/
|
||||
/* SIDBLK constructor for the SERVID special column. */
|
||||
/***********************************************************************/
|
||||
SIDBLK::SIDBLK(PCOLUMN cp) : SPCBLK(cp)
|
||||
{
|
||||
//Is_Key = 2; for when the MUL table indexed reading will be implemented.
|
||||
Long = 64;
|
||||
Buf_Type = TYPE_STRING;
|
||||
*Format.Type = 'C';
|
||||
Format.Length = Long;
|
||||
Format.Prec = 1; // Case insensitive
|
||||
Constant = (To_Tdb->GetAmType() != TYPE_AM_TBL);
|
||||
Sname = NULL;
|
||||
} // end of TIDBLK constructor
|
||||
|
||||
/***********************************************************************/
|
||||
/* ReadColumn: what this routine does is to return the server ID. */
|
||||
/***********************************************************************/
|
||||
void SIDBLK::ReadColumn(PGLOBAL g)
|
||||
{
|
||||
//if (Sname == NULL) {
|
||||
Sname = (char*)To_Tdb->GetServer();
|
||||
Value->SetValue_psz(Sname);
|
||||
// } // endif Sname
|
||||
|
||||
} // end of ReadColumn
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ class DllExport COLBLK : public XOBJECT {
|
|||
virtual bool SetFormat(PGLOBAL, FORMAT&);
|
||||
virtual int CheckColumn(PGLOBAL g, PSQL sqlp, PXOB &xp, int &ag);
|
||||
virtual bool IsSpecial(void) {return false;}
|
||||
virtual int CheckSpcCol(PTDB tdbp, int n) {return 2;}
|
||||
virtual int CheckSpcCol(PTDB tdbp, int n) {return 2;}
|
||||
virtual bool CheckSort(PTDB tdbp);
|
||||
virtual bool Eval(PGLOBAL g);
|
||||
virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
|
||||
|
@ -168,7 +168,7 @@ class TIDBLK : public SPCBLK {
|
|||
// Methods
|
||||
virtual void Reset(void) {} // This is a pseudo constant column
|
||||
virtual int CheckSpcCol(PTDB tdbp, int n)
|
||||
{return (n == 3 && tdbp == To_Tdb) ? 1 : 2;}
|
||||
{return (n == 3 && tdbp == To_Tdb) ? 1 : 2;}
|
||||
virtual void ReadColumn(PGLOBAL g);
|
||||
|
||||
protected:
|
||||
|
@ -179,4 +179,29 @@ class TIDBLK : public SPCBLK {
|
|||
PSZ Tname; // The current table name
|
||||
}; // end of class TIDBLK
|
||||
|
||||
/***********************************************************************/
|
||||
/* Class SIDBLK: SERVID special column descriptor. */
|
||||
/***********************************************************************/
|
||||
class SIDBLK : public SPCBLK {
|
||||
public:
|
||||
// Constructor
|
||||
SIDBLK(PCOLUMN cp);
|
||||
|
||||
// Implementation
|
||||
virtual int GetAmType(void) {return TYPE_AM_SRVID;}
|
||||
|
||||
// Methods
|
||||
virtual void Reset(void) {} // This is a pseudo constant column
|
||||
virtual int CheckSpcCol(PTDB tdbp, int n)
|
||||
{return (n == 3 && tdbp == To_Tdb) ? 1 : 2;}
|
||||
virtual void ReadColumn(PGLOBAL g);
|
||||
|
||||
protected:
|
||||
// Default constructor not to be used
|
||||
SIDBLK(void) {}
|
||||
|
||||
// Members
|
||||
PSZ Sname; // The current server name
|
||||
}; // end of class SIDBLK
|
||||
|
||||
#endif // __COLBLK__H
|
||||
|
|
|
@ -239,7 +239,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
|
|||
char *p;
|
||||
int i, n;
|
||||
PCOL colp;
|
||||
PCOLUMN cp;
|
||||
//PCOLUMN cp;
|
||||
PDBUSER dup= PlgGetUser(g);
|
||||
|
||||
if (xtrace)
|
||||
|
@ -251,6 +251,8 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
|
|||
return true;
|
||||
} // endif tdbp
|
||||
|
||||
tdbp->SetMode(mode);
|
||||
|
||||
if (!c1) {
|
||||
if (mode == MODE_INSERT)
|
||||
// Allocate all column blocks for that table
|
||||
|
@ -261,12 +263,12 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
|
|||
if (xtrace)
|
||||
printf("Allocating column %s\n", p);
|
||||
|
||||
if (*p == '*') {
|
||||
// This is a special column
|
||||
cp= new(g) COLUMN(p + 1);
|
||||
cp->SetTo_Table(tdbp->GetTable());
|
||||
colp= ((PTDBASE)tdbp)->InsertSpcBlk(g, cp);
|
||||
} else
|
||||
// if (*p == '*') {
|
||||
// // This is a special column
|
||||
// cp= new(g) COLUMN(p + 1);
|
||||
// cp->SetTo_Table(tdbp->GetTable());
|
||||
// colp= ((PTDBASE)tdbp)->InsertSpcBlk(g, cp);
|
||||
// } else
|
||||
colp= tdbp->ColDB(g, p, 0);
|
||||
|
||||
if (!colp) {
|
||||
|
@ -330,7 +332,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
|
|||
printf("Opening table %s in mode %d tdbp=%p\n",
|
||||
tdbp->GetName(), mode, tdbp);
|
||||
|
||||
tdbp->SetMode(mode);
|
||||
//tdbp->SetMode(mode);
|
||||
|
||||
if (del && ((PTDBASE)tdbp)->GetFtype() != RECFM_NAF) {
|
||||
// To avoid erasing the table when doing a partial delete
|
||||
|
|
|
@ -47,20 +47,9 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
|
|||
PGLOBAL CntExit(PGLOBAL g);
|
||||
|
||||
/***********************************************************************/
|
||||
/* Definition of classes XCOLCRT, XIXDEF, XKPDEF, DOXDEF, TDBDOX */
|
||||
/* Definition of classes XKPDEF, DOXDEF, TDBDOX */
|
||||
/* These classes purpose is chiefly to access protected items! */
|
||||
/***********************************************************************/
|
||||
class XCOLCRT: public COLCRT {
|
||||
friend class ha_connect;
|
||||
friend bool CntCreateTable(PGLOBAL, char *, PCXF);
|
||||
public:
|
||||
XCOLCRT(PSZ name) : COLCRT(name) {Nulls= -1;} // Constructor
|
||||
bool HasNulls(void) {return (Nulls != 0);}
|
||||
|
||||
private:
|
||||
int Nulls;
|
||||
}; // end of class XCOLCRT
|
||||
|
||||
class DOXDEF: public DOSDEF {
|
||||
//friend class TDBDOX;
|
||||
//friend int MakeIndex(PGLOBAL, PTDB, PIXDEF);
|
||||
|
@ -87,11 +76,7 @@ class XKPDEF: public KPARTDEF {
|
|||
//friend int CntMakeIndex(PGLOBAL, const char *, PIXDEF);
|
||||
friend int CntIndexInit(PGLOBAL, PTDB, int);
|
||||
public:
|
||||
XKPDEF(const char *name, int n) : KPARTDEF((PSZ)name, n) {HasNulls= false;}
|
||||
void SetNulls(bool b) {HasNulls= b;}
|
||||
|
||||
protected:
|
||||
bool HasNulls; /* Can have null values */
|
||||
XKPDEF(const char *name, int n) : KPARTDEF((PSZ)name, n) {}
|
||||
}; // end of class XKPDEF
|
||||
|
||||
//RCODE CheckRecord(PGLOBAL g, PTDB tdbp, char *oldbuf, char *newbuf);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -167,9 +167,9 @@ public:
|
|||
PIXDEF GetIndexInfo(void);
|
||||
const char *GetDBName(const char *name);
|
||||
const char *GetTableName(void);
|
||||
int GetColNameLen(Field *fp);
|
||||
char *GetColName(Field *fp);
|
||||
void AddColName(char *cp, Field *fp);
|
||||
//int GetColNameLen(Field *fp);
|
||||
//char *GetColName(Field *fp);
|
||||
//void AddColName(char *cp, Field *fp);
|
||||
TABLE *GetTable(void) {return table;}
|
||||
bool IsSameIndex(PIXDEF xp1, PIXDEF xp2);
|
||||
|
||||
|
@ -208,7 +208,7 @@ 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_NULL_IN_KEY |*/ HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE);
|
||||
}
|
||||
|
||||
/** @brief
|
||||
|
@ -319,6 +319,21 @@ const char *GetValStr(OPVAL vop, bool neg);
|
|||
*/
|
||||
virtual ha_rows records();
|
||||
|
||||
/**
|
||||
Type of table for caching query
|
||||
CONNECT should not use caching because its tables are external
|
||||
data prone to me modified out of MariaDB
|
||||
*/
|
||||
virtual uint8 table_cache_type(void)
|
||||
{
|
||||
#if defined(MEMORY_TRACE)
|
||||
// Temporary until bug MDEV-4771 is fixed
|
||||
return HA_CACHE_TBL_NONTRANSACT;
|
||||
#else
|
||||
return HA_CACHE_TBL_NOCACHE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @brief
|
||||
We implement this in ha_connect.cc; it's a required method.
|
||||
*/
|
||||
|
@ -400,6 +415,7 @@ const char *GetValStr(OPVAL vop, bool neg);
|
|||
void position(const uchar *record); ///< required
|
||||
int info(uint); ///< required
|
||||
int extra(enum ha_extra_function operation);
|
||||
int start_stmt(THD *thd, thr_lock_type lock_type);
|
||||
int external_lock(THD *thd, int lock_type); ///< required
|
||||
int delete_all_rows(void);
|
||||
ha_rows records_in_range(uint inx, key_range *min_key,
|
||||
|
@ -429,6 +445,7 @@ const char *GetValStr(OPVAL vop, bool neg);
|
|||
|
||||
protected:
|
||||
bool check_privileges(THD *thd, PTOS options);
|
||||
MODE CheckMode(PGLOBAL g, THD *thd, MODE newmode, bool *chk, bool *cras);
|
||||
|
||||
// Members
|
||||
static ulong num; // Tracable handler number
|
||||
|
@ -446,6 +463,7 @@ protected:
|
|||
bool valid_info; // True if xinfo is valid
|
||||
bool stop; // Used when creating index
|
||||
int indexing; // Type of indexing for CONNECT
|
||||
int locked; // Table lock
|
||||
THR_LOCK_DATA lock_data;
|
||||
|
||||
public:
|
||||
|
|
|
@ -315,4 +315,4 @@ bool MACINFO::GetOneInfo(PGLOBAL g, int flag, void *v, int lv)
|
|||
*((int*)v) = n;
|
||||
|
||||
return false;
|
||||
} // end of ReadColumn
|
||||
} // end of GetOneInfo
|
||||
|
|
|
@ -468,9 +468,9 @@ int MYCAT::GetColCatInfo(PGLOBAL g, PTABDEF defp)
|
|||
break;
|
||||
} // endswitch tc
|
||||
|
||||
do {
|
||||
// do {
|
||||
field= Hc->GetColumnOption(g, field, pcf);
|
||||
} while (field && (*pcf->Name =='*' /*|| pcf->Flags & U_VIRTUAL*/));
|
||||
// } while (field && (*pcf->Name =='*' /*|| pcf->Flags & U_VIRTUAL*/));
|
||||
|
||||
if (tc == TAB_DBF && pcf->Type == TYPE_DATE && !pcf->Datefmt) {
|
||||
// DBF date format defaults to 'YYYMMDD'
|
||||
|
|
|
@ -134,7 +134,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
|||
/* Allocate the structures used to refer to the result set. */
|
||||
/**********************************************************************/
|
||||
qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
|
||||
buftyp, fldtyp, length, true, true);
|
||||
buftyp, fldtyp, length, false, true);
|
||||
|
||||
// Some columns must be renamed
|
||||
for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next)
|
||||
|
|
|
@ -30,10 +30,12 @@ t2 CREATE TABLE `t2` (
|
|||
SELECT * FROM t2;
|
||||
ERROR HY000: Got error 174 '(1054) Unknown column 'x' in 'field list' [SELECT `x`, `y` FROM `t1`]' from CONNECT
|
||||
DROP TABLE t2;
|
||||
CREATE TABLE t2 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=PORT';
|
||||
ALTER TABLE t1 RENAME t1backup;
|
||||
SELECT * FROM t2;
|
||||
ERROR 42S02: Table 'test.t2' doesn't exist
|
||||
ERROR HY000: Got error 174 '(1146) Table 'test.t1' doesn't exist [SELECT `a`, `b` FROM `t1`]' from CONNECT
|
||||
ALTER TABLE t1backup RENAME t1;
|
||||
DROP TABLE t2;
|
||||
#
|
||||
# Testing SELECT, etc.
|
||||
#
|
||||
|
|
|
@ -78,6 +78,8 @@ Car DOUBLE(8,2) FLAG=1,
|
|||
Food DOUBLE(8,2) FLAG=1)
|
||||
ENGINE=CONNECT TABLE_TYPE=PIVOT
|
||||
SRCDEF='select who, week, what, sum(amount) as amount from expenses where week in (4,5) group by who, week, what';
|
||||
Warnings:
|
||||
Warning 1105 Cannot check looping reference
|
||||
ALTER TABLE pivex OPTION_LIST='PivotCol=what,FncCol=amount,port=PORT';
|
||||
Warnings:
|
||||
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
||||
|
@ -125,6 +127,8 @@ Middle DOUBLE(8,2) FLAG=1,
|
|||
Last DOUBLE(8,2) FLAG=1)
|
||||
ENGINE=CONNECT TABLE_TYPE=PIVOT
|
||||
SRCDEF='select who, what, case when week=3 then ''First'' when week=5 then ''Last'' else ''Middle'' end as wk, sum(amount) * 6.56 as amnt from expenses group by who, what, wk';
|
||||
Warnings:
|
||||
Warning 1105 Cannot check looping reference
|
||||
ALTER TABLE pivex OPTION_LIST='PivotCol=wk,FncCol=amnt,port=PORT';
|
||||
Warnings:
|
||||
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
||||
|
|
|
@ -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.0006 Mai 21, 2013 -->
|
||||
<!-- Created by CONNECT Version 1.01.0007 July 26, 2013 -->
|
||||
<t1>
|
||||
<line>
|
||||
<node>ÀÁÂÃ</node>
|
||||
|
|
|
@ -1,420 +1,422 @@
|
|||
-- source include/not_embedded.inc
|
||||
|
||||
#
|
||||
# TODO: consider a possibility to run this test
|
||||
# against some remote MySQL server
|
||||
#
|
||||
|
||||
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
|
||||
|
||||
# TODO: remote VARCHAR is displayed as CHAR
|
||||
|
||||
CREATE TABLE t1 (a int, b char(10));
|
||||
INSERT INTO t1 VALUES (NULL,NULL),(0,'test00'),(1,'test01'),(2,'test02'),(3,'test03');
|
||||
SELECT * FROM t1;
|
||||
|
||||
--echo #
|
||||
--echo # Testing errors
|
||||
--echo #
|
||||
|
||||
# Bad user name
|
||||
# Suppress "mysql_real_connect failed:" (printed in _DEBUG build)
|
||||
--replace_result $PORT PORT "mysql_real_connect failed: " ""
|
||||
--error ER_UNKNOWN_ERROR
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root1,port=$PORT'
|
||||
|
||||
# Bad database name
|
||||
--replace_result $PORT PORT "mysql_real_connect failed: " ""
|
||||
--error ER_UNKNOWN_ERROR
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL DBNAME='unknown' TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
|
||||
# Bad database name, with OPTION_LIST going first.
|
||||
--replace_result $PORT PORT "mysql_real_connect failed: " ""
|
||||
--error ER_UNKNOWN_ERROR
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL OPTION_LIST='host=localhost,user=root,port=$PORT' DBNAME='unknown' TABNAME='t1'
|
||||
|
||||
# Bad table name
|
||||
--replace_result $PORT PORT
|
||||
--error ER_UNKNOWN_ERROR
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='unknown' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--error ER_NO_SUCH_TABLE
|
||||
SHOW CREATE TABLE t2;
|
||||
|
||||
# Bad column name
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 (x int, y char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
--error ER_GET_ERRMSG
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2;
|
||||
|
||||
# The remote table disappeared
|
||||
ALTER TABLE t1 RENAME t1backup;
|
||||
--error ER_NO_SUCH_TABLE
|
||||
SELECT * FROM t2;
|
||||
ALTER TABLE t1backup RENAME t1;
|
||||
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Testing SELECT, etc.
|
||||
--echo #
|
||||
|
||||
# Automatic table structure
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2;
|
||||
|
||||
|
||||
# Explicit table structure
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2;
|
||||
|
||||
|
||||
# Explicit table structure: remote NULL, local NOT NULL
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 (a INT NOT NULL, b CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2;
|
||||
|
||||
|
||||
# Explicit table structure with wrong column types
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 (a char(10), b int) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Testing numeric data types
|
||||
--echo #
|
||||
|
||||
# TODO: tinyint is mapped to smallint
|
||||
#CREATE TABLE t1 (a tinyint);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: unsigned does not work
|
||||
#CREATE TABLE t1 (a tinyint unsigned);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
CREATE TABLE t1 (a smallint);
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t1;
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2, t1;
|
||||
|
||||
CREATE TABLE t1 (a mediumint);
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t1;
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2, t1;
|
||||
|
||||
CREATE TABLE t1 (a int);
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t1;
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2, t1;
|
||||
|
||||
|
||||
# TODO: bigint is mapped to double(20,0)
|
||||
CREATE TABLE t1 (a bigint);
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t1;
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2, t1;
|
||||
|
||||
|
||||
# TODO: ERROR 1439: Display width out of range for 'a' (max = 255)
|
||||
#CREATE TABLE t1 (a float);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1439: Display width out of range for 'a' (max = 255)
|
||||
#CREATE TABLE t1 (a double);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: decimal is converted to double
|
||||
#CREATE TABLE t1 (a decimal(20,5));
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: add test for BIT
|
||||
|
||||
--echo #
|
||||
--echo # Testing character data types
|
||||
--echo #
|
||||
|
||||
# TODO: char is mapped to varchar
|
||||
CREATE TABLE t1 (a char(10));
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t1;
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2, t1;
|
||||
|
||||
CREATE TABLE t1 (a varchar(10));
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t1;
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type tinytext
|
||||
#CREATE TABLE t1 (a tinytext);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type mediumtext
|
||||
#CREATE TABLE t1 (a mediumtext);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: text is converted to varchar(256)
|
||||
#CREATE TABLE t1 (a text);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type longtext
|
||||
#CREATE TABLE t1 (a longtext);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
#TODO: add tests for ENUM
|
||||
#TODO: add tests for SET
|
||||
|
||||
--echo #
|
||||
--echo # Testing binary data types
|
||||
--echo #
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type binary
|
||||
#CREATE TABLE t1 (a binary(10));
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type varbinary
|
||||
#CREATE TABLE t1 (a varbinary(10));
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type tinyblob
|
||||
#CREATE TABLE t1 (a tinyblob);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type mediumblob
|
||||
#CREATE TABLE t1 (a mediumblob);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: blob is converted to varchar(256)
|
||||
#CREATE TABLE t1 (a blob);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type longblob
|
||||
#CREATE TABLE t1 (a longblob);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type geometry
|
||||
#CREATE TABLE t1 (a geometry);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
--echo #
|
||||
--echo # Testing temporal data types
|
||||
--echo #
|
||||
|
||||
# TODO: time is converted to date
|
||||
#CREATE TABLE t1 (a time);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
CREATE TABLE t1 (a date);
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t1;
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2, t1;
|
||||
|
||||
# TODO: datetime is converted to date
|
||||
#CREATE TABLE t1 (a datetime);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: timestamp is converted to date
|
||||
#CREATE TABLE t1 (a timestamp);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: add test for YEAR
|
||||
# TODO: add tests for fractional seconds
|
||||
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
#
|
||||
# TODO: consider a possibility to run this test
|
||||
# against some remote MySQL server
|
||||
#
|
||||
|
||||
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
|
||||
|
||||
# TODO: remote VARCHAR is displayed as CHAR
|
||||
|
||||
CREATE TABLE t1 (a int, b char(10));
|
||||
INSERT INTO t1 VALUES (NULL,NULL),(0,'test00'),(1,'test01'),(2,'test02'),(3,'test03');
|
||||
SELECT * FROM t1;
|
||||
|
||||
--echo #
|
||||
--echo # Testing errors
|
||||
--echo #
|
||||
|
||||
# Bad user name
|
||||
# Suppress "mysql_real_connect failed:" (printed in _DEBUG build)
|
||||
--replace_result $PORT PORT "mysql_real_connect failed: " ""
|
||||
--error ER_UNKNOWN_ERROR
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root1,port=$PORT'
|
||||
|
||||
# Bad database name
|
||||
--replace_result $PORT PORT "mysql_real_connect failed: " ""
|
||||
--error ER_UNKNOWN_ERROR
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL DBNAME='unknown' TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
|
||||
# Bad database name, with OPTION_LIST going first.
|
||||
--replace_result $PORT PORT "mysql_real_connect failed: " ""
|
||||
--error ER_UNKNOWN_ERROR
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL OPTION_LIST='host=localhost,user=root,port=$PORT' DBNAME='unknown' TABNAME='t1'
|
||||
|
||||
# Bad table name
|
||||
--replace_result $PORT PORT
|
||||
--error ER_UNKNOWN_ERROR
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='unknown' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--error ER_NO_SUCH_TABLE
|
||||
SHOW CREATE TABLE t2;
|
||||
|
||||
# Bad column name
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 (x int, y char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
--error ER_GET_ERRMSG
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2;
|
||||
|
||||
# The remote table disappeared
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
ALTER TABLE t1 RENAME t1backup;
|
||||
--error ER_GET_ERRMSG
|
||||
SELECT * FROM t2;
|
||||
ALTER TABLE t1backup RENAME t1;
|
||||
DROP TABLE t2;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Testing SELECT, etc.
|
||||
--echo #
|
||||
|
||||
# Automatic table structure
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2;
|
||||
|
||||
|
||||
# Explicit table structure
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2;
|
||||
|
||||
|
||||
# Explicit table structure: remote NULL, local NOT NULL
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 (a INT NOT NULL, b CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2;
|
||||
|
||||
|
||||
# Explicit table structure with wrong column types
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 (a char(10), b int) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Testing numeric data types
|
||||
--echo #
|
||||
|
||||
# TODO: tinyint is mapped to smallint
|
||||
#CREATE TABLE t1 (a tinyint);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: unsigned does not work
|
||||
#CREATE TABLE t1 (a tinyint unsigned);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
CREATE TABLE t1 (a smallint);
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t1;
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2, t1;
|
||||
|
||||
CREATE TABLE t1 (a mediumint);
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t1;
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2, t1;
|
||||
|
||||
CREATE TABLE t1 (a int);
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t1;
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2, t1;
|
||||
|
||||
|
||||
# TODO: bigint is mapped to double(20,0)
|
||||
CREATE TABLE t1 (a bigint);
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t1;
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2, t1;
|
||||
|
||||
|
||||
# TODO: ERROR 1439: Display width out of range for 'a' (max = 255)
|
||||
#CREATE TABLE t1 (a float);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1439: Display width out of range for 'a' (max = 255)
|
||||
#CREATE TABLE t1 (a double);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: decimal is converted to double
|
||||
#CREATE TABLE t1 (a decimal(20,5));
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: add test for BIT
|
||||
|
||||
--echo #
|
||||
--echo # Testing character data types
|
||||
--echo #
|
||||
|
||||
# TODO: char is mapped to varchar
|
||||
CREATE TABLE t1 (a char(10));
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t1;
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2, t1;
|
||||
|
||||
CREATE TABLE t1 (a varchar(10));
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t1;
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type tinytext
|
||||
#CREATE TABLE t1 (a tinytext);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type mediumtext
|
||||
#CREATE TABLE t1 (a mediumtext);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: text is converted to varchar(256)
|
||||
#CREATE TABLE t1 (a text);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type longtext
|
||||
#CREATE TABLE t1 (a longtext);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
#TODO: add tests for ENUM
|
||||
#TODO: add tests for SET
|
||||
|
||||
--echo #
|
||||
--echo # Testing binary data types
|
||||
--echo #
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type binary
|
||||
#CREATE TABLE t1 (a binary(10));
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type varbinary
|
||||
#CREATE TABLE t1 (a varbinary(10));
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type tinyblob
|
||||
#CREATE TABLE t1 (a tinyblob);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type mediumblob
|
||||
#CREATE TABLE t1 (a mediumblob);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: blob is converted to varchar(256)
|
||||
#CREATE TABLE t1 (a blob);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type longblob
|
||||
#CREATE TABLE t1 (a longblob);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: ERROR 1105: Unsupported column type geometry
|
||||
#CREATE TABLE t1 (a geometry);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
--echo #
|
||||
--echo # Testing temporal data types
|
||||
--echo #
|
||||
|
||||
# TODO: time is converted to date
|
||||
#CREATE TABLE t1 (a time);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
CREATE TABLE t1 (a date);
|
||||
--replace_result $PORT PORT
|
||||
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t1;
|
||||
--replace_result $PORT PORT
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2, t1;
|
||||
|
||||
# TODO: datetime is converted to date
|
||||
#CREATE TABLE t1 (a datetime);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: timestamp is converted to date
|
||||
#CREATE TABLE t1 (a timestamp);
|
||||
#--replace_result $PORT PORT
|
||||
#--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t1;
|
||||
#--replace_result $PORT PORT
|
||||
#SHOW CREATE TABLE t2;
|
||||
#SELECT * FROM t2;
|
||||
#DROP TABLE t2, t1;
|
||||
|
||||
# TODO: add test for YEAR
|
||||
# TODO: add tests for fractional seconds
|
||||
|
||||
|
|
|
@ -281,7 +281,7 @@ PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *table,
|
|||
/* Allocate the structures used to refer to the result set. */
|
||||
/************************************************************************/
|
||||
qrp = PlgAllocResult(g, ncol, maxres, IDS_COLUMNS,
|
||||
buftyp, fldtyp, length, true, true);
|
||||
buftyp, fldtyp, length, false, true);
|
||||
|
||||
if (info) // Info table
|
||||
return qrp;
|
||||
|
@ -423,7 +423,7 @@ PQRYRES ODBCDataSources(PGLOBAL g, bool info)
|
|||
/* Allocate the structures used to refer to the result set. */
|
||||
/************************************************************************/
|
||||
qrp = PlgAllocResult(g, ncol, maxres, IDS_DSRC,
|
||||
buftyp, fldtyp, length, true, true);
|
||||
buftyp, fldtyp, length, false, true);
|
||||
|
||||
/************************************************************************/
|
||||
/* Now get the results into blocks. */
|
||||
|
@ -468,7 +468,7 @@ PQRYRES ODBCDrivers(PGLOBAL g, bool info)
|
|||
/* Allocate the structures used to refer to the result set. */
|
||||
/************************************************************************/
|
||||
qrp = PlgAllocResult(g, ncol, maxres, IDS_DRIVER,
|
||||
buftyp, fldtyp, length, true, true);
|
||||
buftyp, fldtyp, length, false, true);
|
||||
|
||||
/************************************************************************/
|
||||
/* Now get the results into blocks. */
|
||||
|
@ -533,7 +533,7 @@ PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *tabpat, bool info)
|
|||
/* Allocate the structures used to refer to the result set. */
|
||||
/************************************************************************/
|
||||
qrp = PlgAllocResult(g, ncol, maxres, IDS_TABLES, buftyp,
|
||||
fldtyp, length, true, true);
|
||||
fldtyp, length, false, true);
|
||||
|
||||
if (info)
|
||||
return qrp;
|
||||
|
@ -617,7 +617,7 @@ PQRYRES ODBCPrimaryKeys(PGLOBAL g, ODBConn *op, char *dsn, char *table)
|
|||
/* Allocate the structure used to refer to the result set. */
|
||||
/************************************************************************/
|
||||
qrp = PlgAllocResult(g, ncol, maxres, IDS_PKEY,
|
||||
buftyp, NULL, length, true, true);
|
||||
buftyp, NULL, length, false, true);
|
||||
|
||||
if (trace)
|
||||
htrc("Getting pkey results ncol=%d\n", qrp->Nbcol);
|
||||
|
@ -699,7 +699,7 @@ PQRYRES ODBCStatistics(PGLOBAL g, ODBConn *op, char *dsn, char *pat,
|
|||
/* Allocate the structure used to refer to the result set. */
|
||||
/************************************************************************/
|
||||
qrp = PlgAllocResult(g, ncol, maxres, IDS_STAT,
|
||||
buftyp, NULL, length, true, true);
|
||||
buftyp, NULL, length, false, true);
|
||||
|
||||
if (trace)
|
||||
htrc("Getting stat results ncol=%d\n", qrp->Nbcol);
|
||||
|
@ -1210,20 +1210,19 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols)
|
|||
RETCODE rc;
|
||||
HSTMT hstmt;
|
||||
|
||||
//m_Recset = new(m_G) RECSET(this);
|
||||
//ASSERT(m_Recset);
|
||||
|
||||
try {
|
||||
b = false;
|
||||
|
||||
if (m_hstmt) {
|
||||
/*RETCODE rc;*/
|
||||
|
||||
// All this did not seems to make sense and was been commented out
|
||||
// if (IsOpen())
|
||||
// Close(SQL_CLOSE);
|
||||
|
||||
/*rc =*/ SQLFreeStmt(m_hstmt, SQL_CLOSE);
|
||||
rc = SQLFreeStmt(m_hstmt, SQL_CLOSE);
|
||||
|
||||
if (trace && !Check(rc))
|
||||
htrc("Error: SQLFreeStmt rc=%d\n", rc);
|
||||
|
||||
hstmt = m_hstmt;
|
||||
m_hstmt = NULL;
|
||||
ThrowDBX(MSG(SEQUENCE_ERROR));
|
||||
|
@ -1340,7 +1339,6 @@ int ODBConn::GetResultSize(char *sql, ODBCCOL *colp)
|
|||
} // endfor n
|
||||
|
||||
} catch(DBX *x) {
|
||||
// strcpy(m_G->Message, x->m_ErrMsg[0]);
|
||||
strcpy(m_G->Message, x->GetErrorMessage(0));
|
||||
|
||||
if (trace)
|
||||
|
@ -1516,7 +1514,6 @@ bool ODBConn::BindParam(ODBCCOL *colp)
|
|||
#endif // 0
|
||||
|
||||
buf = colp->GetBuffer(0);
|
||||
// len = colp->GetBuflen();
|
||||
len = IsTypeNum(colp->GetResultType()) ? 0 : colp->GetBuflen();
|
||||
ct = GetSQLCType(colp->GetResultType());
|
||||
sqlt = GetSQLType(colp->GetResultType());
|
||||
|
@ -1580,7 +1577,6 @@ bool ODBConn::GetDataSources(PQRYRES qrp)
|
|||
rv = true;
|
||||
} // end try/catch
|
||||
|
||||
//SQLFreeEnv(m_henv);
|
||||
Close();
|
||||
return rv;
|
||||
} // end of GetDataSources
|
||||
|
@ -1632,7 +1628,6 @@ bool ODBConn::GetDrivers(PQRYRES qrp)
|
|||
rv = true;
|
||||
} // end try/catch
|
||||
|
||||
//SQLFreeEnv(m_henv);
|
||||
Close();
|
||||
return rv;
|
||||
} // end of GetDrivers
|
||||
|
@ -1801,7 +1796,6 @@ int ODBConn::GetCatInfo(CATPARM *cap)
|
|||
} else // ODBC Ver 3
|
||||
rc = SQLFetch(hstmt);
|
||||
|
||||
// if (!Check(rc))
|
||||
if (rc == SQL_NO_DATA_FOUND) {
|
||||
if (cap->Pat)
|
||||
sprintf(m_G->Message, MSG(NO_TABCOL_DATA), cap->Tab, cap->Pat);
|
||||
|
@ -1837,270 +1831,35 @@ int ODBConn::GetCatInfo(CATPARM *cap)
|
|||
/***********************************************************************/
|
||||
void ODBConn::Close()
|
||||
{
|
||||
/*RETCODE rc;*/
|
||||
|
||||
#if 0
|
||||
// Close any open recordsets
|
||||
AfxLockGlobals(CRIT_ODBC);
|
||||
TRY
|
||||
{
|
||||
while (!m_listRecordsets.IsEmpty())
|
||||
{
|
||||
CRecordset* pSet = (CRecordset*)m_listRecordsets.GetHead();
|
||||
pSet->Close(); // will implicitly remove from list
|
||||
pSet->m_pDatabase = NULL;
|
||||
}
|
||||
}
|
||||
CATCH_ALL(e)
|
||||
{
|
||||
AfxUnlockGlobals(CRIT_ODBC);
|
||||
THROW_LAST();
|
||||
}
|
||||
END_CATCH_ALL
|
||||
AfxUnlockGlobals(CRIT_ODBC);
|
||||
#endif // 0
|
||||
RETCODE rc;
|
||||
|
||||
if (m_hstmt) {
|
||||
// Is required for multiple tables
|
||||
/*rc =*/ SQLFreeStmt(m_hstmt, SQL_DROP);
|
||||
rc = SQLFreeStmt(m_hstmt, SQL_DROP);
|
||||
m_hstmt = NULL;
|
||||
} // endif m_hstmt
|
||||
|
||||
if (m_hdbc != SQL_NULL_HDBC) {
|
||||
/*rc =*/ SQLDisconnect(m_hdbc);
|
||||
/*rc =*/ SQLFreeConnect(m_hdbc);
|
||||
m_hdbc = SQL_NULL_HDBC;
|
||||
rc = SQLDisconnect(m_hdbc);
|
||||
|
||||
// AfxLockGlobals(CRIT_ODBC);
|
||||
// ASSERT(m_nAlloc != 0);
|
||||
// m_nAlloc--;
|
||||
// AfxUnlockGlobals(CRIT_ODBC);
|
||||
if (trace && rc != SQL_SUCCESS)
|
||||
htrc("Error: SQLDisconnect rc=%d\n", rc);
|
||||
|
||||
rc = SQLFreeConnect(m_hdbc);
|
||||
|
||||
if (trace && rc != SQL_SUCCESS)
|
||||
htrc("Error: SQLFreeConnect rc=%d\n", rc);
|
||||
|
||||
m_hdbc = SQL_NULL_HDBC;
|
||||
} // endif m_hdbc
|
||||
|
||||
if (m_henv != SQL_NULL_HENV) {
|
||||
if (trace) {
|
||||
RETCODE rc = SQLFreeEnv(m_henv);
|
||||
|
||||
if (rc != SQL_SUCCESS) // Nothing we can do
|
||||
htrc("Error: SQLFreeEnv failure ignored in Close\n");
|
||||
|
||||
} else
|
||||
SQLFreeEnv(m_henv);
|
||||
rc = SQLFreeEnv(m_henv);
|
||||
|
||||
m_henv = SQL_NULL_HENV;
|
||||
if (trace && rc != SQL_SUCCESS) // Nothing we can do
|
||||
htrc("Error: SQLFreeEnv failure ignored in Close\n");
|
||||
|
||||
m_henv = SQL_NULL_HENV;
|
||||
} // endif m_henv
|
||||
|
||||
} // end of Close
|
||||
|
||||
#if 0
|
||||
// Silently disconnect and free all ODBC resources.
|
||||
// Don't throw any exceptions
|
||||
void ODBConn::Free()
|
||||
{
|
||||
// Trap failures upon close
|
||||
try {
|
||||
Close();
|
||||
} catch(DBX*) {
|
||||
// Nothing we can do
|
||||
if (trace)
|
||||
htrc("Error: exception by Close ignored in Free\n");
|
||||
|
||||
// DELETE_EXCEPTION(x);
|
||||
} // endcatch
|
||||
|
||||
// free henv if refcount goes to 0
|
||||
//AfxLockGlobals(CRIT_ODBC);
|
||||
if (m_henv != SQL_NULL_HENV) {
|
||||
ASSERT(m_nAlloc >= 0);
|
||||
|
||||
if (m_nAlloc == 0) {
|
||||
// free last connection - release HENV
|
||||
if (trace) {
|
||||
RETCODE rc = SQLFreeEnv(m_henv);
|
||||
|
||||
if (rc != SQL_SUCCESS) // Nothing we can do
|
||||
htrc("Error: SQLFreeEnv failure ignored in Free\n");
|
||||
|
||||
} else
|
||||
SQLFreeEnv(m_henv);
|
||||
|
||||
m_henv = SQL_NULL_HENV;
|
||||
} // endif m_nAlloc
|
||||
} // endif m_henv
|
||||
//AfxUnlockGlobals(CRIT_ODBC);
|
||||
} // end of Free
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// CRecordset helpers
|
||||
|
||||
//id AFXAPI AfxSetCurrentRecord(int* plCurrentRecord, int nRows, RETCODE nRetCode);
|
||||
//id AFXAPI AfxSetRecordCount(int* plRecordCount, int lCurrentRecord,
|
||||
//bool bEOFSeen, RETCODE nRetCode);
|
||||
|
||||
/***********************************************************************/
|
||||
/* RECSET class implementation */
|
||||
/***********************************************************************/
|
||||
RECSET::RECSET(ODBConn *dbcp)
|
||||
{
|
||||
m_pDB = dbcp;
|
||||
m_hstmt = SQL_NULL_HSTMT;
|
||||
m_OpenType = snapshot;
|
||||
m_Options = none;
|
||||
|
||||
#if 0
|
||||
m_lOpen = AFX_RECORDSET_STATUS_UNKNOWN;
|
||||
m_nEditMode = noMode;
|
||||
m_nDefaultType = snapshot;
|
||||
|
||||
m_bAppendable = false;
|
||||
m_bUpdatable = false;
|
||||
m_bScrollable = false;
|
||||
m_bRecordsetDb = false;
|
||||
m_bRebindParams = false;
|
||||
m_bLongBinaryColumns = false;
|
||||
m_nLockMode = optimistic;
|
||||
m_dwInitialGetDataLen = 0;
|
||||
m_rgODBCFieldInfos = NULL;
|
||||
m_rgFieldInfos = NULL;
|
||||
m_rgRowStatus = NULL;
|
||||
m_dwRowsetSize = 25;
|
||||
m_dwAllocatedRowsetSize = 0;
|
||||
|
||||
m_nFields = 0;
|
||||
m_nParams = 0;
|
||||
m_nFieldsBound = 0;
|
||||
m_lCurrentRecord = AFX_CURRENT_RECORD_UNDEFINED;
|
||||
m_lRecordCount = 0;
|
||||
m_bUseUpdateSQL = false;
|
||||
m_bUseODBCCursorLib = false;
|
||||
m_nResultCols = -1;
|
||||
m_bCheckCacheForDirtyFields = true;
|
||||
|
||||
m_pbFieldFlags = NULL;
|
||||
m_pbParamFlags = NULL;
|
||||
m_plParamLength = NULL;
|
||||
m_pvFieldProxy = NULL;
|
||||
m_pvParamProxy = NULL;
|
||||
m_nProxyFields = 0;
|
||||
m_nProxyParams = 0;
|
||||
|
||||
m_hstmtUpdate = SQL_NULL_HSTMT;
|
||||
#endif // 0
|
||||
} // end of RECSET constructor
|
||||
|
||||
RECSET::~RECSET()
|
||||
{
|
||||
try {
|
||||
if (m_hstmt) {
|
||||
if (trace && (m_dwOptions & useMultiRowFetch)) {
|
||||
htrc("WARNING: Close called implicitly from destructor\n");
|
||||
htrc("Use of multi row fetch requires explicit call\n");
|
||||
htrc("to Close or memory leaks will result\n");
|
||||
} // endif trace
|
||||
|
||||
Close();
|
||||
} // endif m_hstmt
|
||||
|
||||
// if (m_bRecordsetDb)
|
||||
// delete m_pDB; ??????
|
||||
|
||||
m_pDB = NULL;
|
||||
} catch(DBX*) {
|
||||
// Nothing we can do
|
||||
if (trace)
|
||||
htrc("Error: Exception ignored in ~RECSET\n");
|
||||
|
||||
} // endtry/catch
|
||||
|
||||
} // end of ~RECSET
|
||||
|
||||
/***********************************************************************/
|
||||
/* Open: this function does the following: */
|
||||
/* Allocates the hstmt, */
|
||||
/* Bind columns, */
|
||||
/* Execute the SQL statement */
|
||||
/***********************************************************************/
|
||||
bool RECSET::Open(PSZ sql, uint Type, DWORD options)
|
||||
{
|
||||
ASSERT(m_pDB && m_pDB->IsOpen());
|
||||
ASSERT(Type == DB_USE_DEFAULT_TYPE || Type == dynaset ||
|
||||
Type == snapshot || Type == forwardOnly || Type == dynamic);
|
||||
//ASSERT(!(options & readOnly && options & appendOnly));
|
||||
|
||||
// Cache state info and allocate hstmt
|
||||
SetState(Type, sql, options);
|
||||
|
||||
try {
|
||||
if (m_hstmt) {
|
||||
if (IsOpen())
|
||||
Close(SQL_CLOSE);
|
||||
|
||||
} else {
|
||||
RETCODE rc = SQLAllocStmt(m_pDB->m_hdbc, &m_hstmt);
|
||||
|
||||
if (!Check(rc))
|
||||
ThrowDBException(SQL_INVALID_HANDLE);
|
||||
|
||||
} // endif m_hstmt
|
||||
|
||||
m_pDB->OnSetOptions(m_hstmt);
|
||||
|
||||
// Allocate the field/param status arrays, if necessary
|
||||
// bool bUnbound = false;
|
||||
|
||||
// if (m_nFields > 0 || m_nParams > 0)
|
||||
// AllocStatusArrays();
|
||||
// else
|
||||
// bUnbound = true;
|
||||
|
||||
// Build SQL and prep/execute or just execute direct
|
||||
// BuildSQL(sql);
|
||||
PrepareAndExecute(sql);
|
||||
|
||||
// Cache some field info and prepare the rowset
|
||||
AllocAndCacheFieldInfo();
|
||||
AllocRowset();
|
||||
|
||||
// If late binding, still need to allocate status arrays
|
||||
// if (bUnbound && (m_nFields > 0 || m_nParams > 0))
|
||||
// AllocStatusArrays();
|
||||
|
||||
} catch(DBX *x) {
|
||||
Close(SQL_DROP);
|
||||
// strcpy(m_pDB->m_G->Message, x->GetErrorMessage[0]);
|
||||
strcpy(m_pDB->m_G->Message, x->GetErrorMessage(0));
|
||||
return true;
|
||||
} // endtry/catch
|
||||
|
||||
return false;
|
||||
} // end of Open
|
||||
|
||||
/***********************************************************************/
|
||||
/* Close a hstmt. */
|
||||
/***********************************************************************/
|
||||
void RECSET::Close(SWORD option)
|
||||
{
|
||||
if (m_hstmt != SQL_NULL_HSTMT) {
|
||||
RETCODE rc = SQLFreeStmt(m_hstmt, option);
|
||||
|
||||
if (option == SQL_DROP)
|
||||
m_hstmt = SQL_NULL_HSTMT;
|
||||
|
||||
} // endif m_hstmt
|
||||
|
||||
#if 0
|
||||
m_lOpen = RECORDSET_STATUS_CLOSED;
|
||||
m_bBOF = true;
|
||||
m_bEOF = true;
|
||||
m_bDeleted = false;
|
||||
m_bAppendable = false;
|
||||
m_bUpdatable = false;
|
||||
m_bScrollable = false;
|
||||
m_bRebindParams = false;
|
||||
m_bLongBinaryColumns = false;
|
||||
m_nLockMode = optimistic;
|
||||
m_nFieldsBound = 0;
|
||||
m_nResultCols = -1;
|
||||
#endif // 0
|
||||
} // end of Close
|
||||
#endif // 0
|
||||
|
|
|
@ -151,7 +151,8 @@ enum ALGMOD {AMOD_AUTO = 0, /* PLG chooses best algorithm */
|
|||
#define NAM_LEN 128
|
||||
#endif // !0
|
||||
|
||||
enum MODE {MODE_ANY = 0, /* Unspecified mode */
|
||||
enum MODE {MODE_ERROR = -1, /* Invalid mode */
|
||||
MODE_ANY = 0, /* Unspecified mode */
|
||||
MODE_READ = 10, /* Input/Output mode */
|
||||
MODE_WRITE = 20, /* Input/Output mode */
|
||||
MODE_UPDATE = 30, /* Input/Output mode */
|
||||
|
@ -319,7 +320,8 @@ enum COLUSE {U_P = 0x01, /* the projection list. */
|
|||
U_VAR = 0x10, /* a VARCHAR column */
|
||||
U_VIRTUAL = 0x20, /* a VIRTUAL column */
|
||||
U_NULLS = 0x40, /* The column may have nulls */
|
||||
U_IS_NULL = 0x80}; /* The column has a null value */
|
||||
U_IS_NULL = 0x80, /* The column has a null value */
|
||||
U_SPECIAL = 0x100}; /* The column is special */
|
||||
|
||||
/***********************************************************************/
|
||||
/* DB description class and block pointer definitions. */
|
||||
|
|
|
@ -383,32 +383,35 @@ int COLDEF::Define(PGLOBAL g, void *memp, PCOLINFO cfp, int poff)
|
|||
Name = (PSZ)PlugSubAlloc(g, memp, strlen(cfp->Name) + 1);
|
||||
strcpy(Name, cfp->Name);
|
||||
|
||||
Poff = poff;
|
||||
Buf_Type = cfp->Type;
|
||||
if (!(cfp->Flags & U_SPECIAL)) {
|
||||
Poff = poff;
|
||||
Buf_Type = cfp->Type;
|
||||
|
||||
if ((Clen = GetTypeSize(Buf_Type, cfp->Length)) <= 0) {
|
||||
sprintf(g->Message, MSG(BAD_COL_TYPE), GetTypeName(Buf_Type), Name);
|
||||
return -1;
|
||||
} // endswitch
|
||||
if ((Clen = GetTypeSize(Buf_Type, cfp->Length)) <= 0) {
|
||||
sprintf(g->Message, MSG(BAD_COL_TYPE), GetTypeName(Buf_Type), Name);
|
||||
return -1;
|
||||
} // endswitch
|
||||
|
||||
strcpy(F.Type, GetFormatType(Buf_Type));
|
||||
F.Length = cfp->Length;
|
||||
F.Prec = cfp->Prec;
|
||||
Offset = (cfp->Offset < 0) ? poff : cfp->Offset;
|
||||
Long = cfp->Length;
|
||||
Opt = cfp->Opt;
|
||||
Key = cfp->Key;
|
||||
//Freq = cfp->Freq;
|
||||
strcpy(F.Type, GetFormatType(Buf_Type));
|
||||
F.Length = cfp->Length;
|
||||
F.Prec = cfp->Prec;
|
||||
Offset = (cfp->Offset < 0) ? poff : cfp->Offset;
|
||||
Long = cfp->Length;
|
||||
Opt = cfp->Opt;
|
||||
Key = cfp->Key;
|
||||
// Freq = cfp->Freq;
|
||||
|
||||
if (cfp->Remark && *cfp->Remark) {
|
||||
Desc = (PSZ)PlugSubAlloc(g, memp, strlen(cfp->Remark) + 1);
|
||||
strcpy(Desc, cfp->Remark);
|
||||
} // endif Remark
|
||||
if (cfp->Remark && *cfp->Remark) {
|
||||
Desc = (PSZ)PlugSubAlloc(g, memp, strlen(cfp->Remark) + 1);
|
||||
strcpy(Desc, cfp->Remark);
|
||||
} // endif Remark
|
||||
|
||||
if (cfp->Datefmt) {
|
||||
Decode = (PSZ)PlugSubAlloc(g, memp, strlen(cfp->Datefmt) + 1);
|
||||
strcpy(Decode, cfp->Datefmt);
|
||||
} // endif Datefmt
|
||||
if (cfp->Datefmt) {
|
||||
Decode = (PSZ)PlugSubAlloc(g, memp, strlen(cfp->Datefmt) + 1);
|
||||
strcpy(Decode, cfp->Datefmt);
|
||||
} // endif Datefmt
|
||||
|
||||
} // endif special
|
||||
|
||||
if (cfp->Fieldfmt) {
|
||||
Fmt = (PSZ)PlugSubAlloc(g, memp, strlen(cfp->Fieldfmt) + 1);
|
||||
|
@ -416,7 +419,7 @@ int COLDEF::Define(PGLOBAL g, void *memp, PCOLINFO cfp, int poff)
|
|||
} // endif Fieldfmt
|
||||
|
||||
Flags = cfp->Flags;
|
||||
return (Flags & U_VIRTUAL) ? 0 : Long;
|
||||
return (Flags & (U_VIRTUAL|U_SPECIAL)) ? 0 : Long;
|
||||
} // end of Define
|
||||
|
||||
/* ------------------------- End of RelDef --------------------------- */
|
||||
|
|
|
@ -175,6 +175,7 @@ class DllExport COLDEF : public COLCRT { /* Column description block
|
|||
friend class MYCAT;
|
||||
friend class COLBLK;
|
||||
friend class DBFFAM;
|
||||
friend class TDBASE;
|
||||
public:
|
||||
COLDEF(void); // Constructor
|
||||
|
||||
|
|
|
@ -339,7 +339,7 @@ PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q,
|
|||
/* Allocate the structures used to refer to the result set. */
|
||||
/*********************************************************************/
|
||||
qrp = PlgAllocResult(g, ncol, imax, IDS_COLUMNS + 3,
|
||||
buftyp, fldtyp, length, true, false);
|
||||
buftyp, fldtyp, length, false, false);
|
||||
qrp->Nblin = imax;
|
||||
|
||||
if (info)
|
||||
|
|
|
@ -307,15 +307,17 @@ PCOL TDBASE::ColDB(PGLOBAL g, PSZ name, int num)
|
|||
/*****************************************************************/
|
||||
if (cp)
|
||||
colp = cp;
|
||||
else
|
||||
else if (!(cdp->Flags & U_SPECIAL))
|
||||
colp = MakeCol(g, cdp, cprec, i);
|
||||
else if (Mode == MODE_READ)
|
||||
colp = InsertSpcBlk(g, cdp);
|
||||
|
||||
if (trace)
|
||||
htrc("colp=%p\n", colp);
|
||||
|
||||
if (name || num)
|
||||
break;
|
||||
else if (colp)
|
||||
else if (colp && !colp->IsSpecial())
|
||||
cprec = colp;
|
||||
|
||||
} // endif Name
|
||||
|
@ -339,30 +341,35 @@ PCOL TDBASE::InsertSpecialColumn(PGLOBAL g, PCOL colp)
|
|||
/***********************************************************************/
|
||||
/* Make a special COLBLK to insert in a table. */
|
||||
/***********************************************************************/
|
||||
PCOL TDBASE::InsertSpcBlk(PGLOBAL g, PCOLUMN cp)
|
||||
PCOL TDBASE::InsertSpcBlk(PGLOBAL g, PCOLDEF cdp)
|
||||
{
|
||||
char *name = (char*)cp->GetName();
|
||||
PCOL colp;
|
||||
//char *name = cdp->GetName();
|
||||
char *name = cdp->GetFmt();
|
||||
PCOLUMN cp;
|
||||
PCOL colp;
|
||||
|
||||
if (!strcmp(name, "FILEID")) {
|
||||
// !strcmp(name, "SERVID")) {
|
||||
cp= new(g) COLUMN(cdp->GetName());
|
||||
cp->SetTo_Table(To_Table);
|
||||
|
||||
if (!stricmp(name, "FILEID") ||
|
||||
!stricmp(name, "SERVID")) {
|
||||
if (!To_Def || !(To_Def->GetPseudo() & 2)) {
|
||||
sprintf(g->Message, MSG(BAD_SPEC_COLUMN));
|
||||
return NULL;
|
||||
} // endif Pseudo
|
||||
|
||||
// if (!strcmp(name, "FILEID"))
|
||||
if (!stricmp(name, "FILEID"))
|
||||
colp = new(g) FIDBLK(cp);
|
||||
// else
|
||||
// colp = new(g) SIDBLK(cp);
|
||||
else
|
||||
colp = new(g) SIDBLK(cp);
|
||||
|
||||
} else if (!strcmp(name, "TABID")) {
|
||||
} else if (!stricmp(name, "TABID")) {
|
||||
colp = new(g) TIDBLK(cp);
|
||||
//} else if (!strcmp(name, "CONID")) {
|
||||
//} else if (!stricmp(name, "CONID")) {
|
||||
// colp = new(g) CIDBLK(cp);
|
||||
} else if (!strcmp(name, "ROWID")) {
|
||||
} else if (!stricmp(name, "ROWID")) {
|
||||
colp = new(g) RIDBLK(cp, false);
|
||||
} else if (!strcmp(name, "ROWNUM")) {
|
||||
} else if (!stricmp(name, "ROWNUM")) {
|
||||
colp = new(g) RIDBLK(cp, true);
|
||||
} else {
|
||||
sprintf(g->Message, MSG(BAD_SPECIAL_COL), name);
|
||||
|
|
|
@ -194,6 +194,7 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
|
|||
if (trace)
|
||||
htrc("server: %s Tabname: %s", url, Tabname);
|
||||
|
||||
Server = url;
|
||||
return GetServerInfo(g, url);
|
||||
} else {
|
||||
// URL, parse it
|
||||
|
@ -216,8 +217,10 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
|
|||
if (!(Hostname = strchr(Username, '@'))) {
|
||||
strcpy(g->Message, "No host specified in URL");
|
||||
return true;
|
||||
} else
|
||||
} else {
|
||||
*Hostname++ = 0; // End Username
|
||||
Server = Hostname;
|
||||
} // endif Hostname
|
||||
|
||||
if ((Password = strchr(Username, ':'))) {
|
||||
*Password++ = 0; // End username
|
||||
|
@ -308,6 +311,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||
Username = Cat->GetStringCatInfo(g, "User", "*");
|
||||
Password = Cat->GetStringCatInfo(g, "Password", NULL);
|
||||
Portnumber = Cat->GetIntCatInfo("Port", GetDefaultPort());
|
||||
Server = Hostname;
|
||||
} else if (ParseURL(g, url))
|
||||
return TRUE;
|
||||
|
||||
|
@ -327,6 +331,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||
Username = Cat->GetStringCatInfo(g, "User", "*");
|
||||
Password = Cat->GetStringCatInfo(g, "Password", NULL);
|
||||
Portnumber = Cat->GetIntCatInfo("Port", GetDefaultPort());
|
||||
Server = Hostname;
|
||||
} else {
|
||||
char *locdb = Database;
|
||||
|
||||
|
@ -365,13 +370,14 @@ PTDB MYSQLDEF::GetTable(PGLOBAL g, MODE m)
|
|||
TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp)
|
||||
{
|
||||
if (tdp) {
|
||||
Host = tdp->GetHostname();
|
||||
Database = tdp->GetDatabase();
|
||||
Tabname = tdp->GetTabname();
|
||||
Srcdef = tdp->GetSrcdef();
|
||||
User = tdp->GetUsername();
|
||||
Pwd = tdp->GetPassword();
|
||||
Port = tdp->GetPortnumber();
|
||||
Host = tdp->Hostname;
|
||||
Database = tdp->Database;
|
||||
Tabname = tdp->Tabname;
|
||||
Srcdef = tdp->Srcdef;
|
||||
User = tdp->Username;
|
||||
Pwd = tdp->Password;
|
||||
Server = tdp->Server;
|
||||
Port = tdp->Portnumber;
|
||||
Isview = tdp->Isview;
|
||||
Prep = tdp->Bind;
|
||||
Delayed = tdp->Delayed;
|
||||
|
@ -382,6 +388,7 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp)
|
|||
Srcdef = NULL;
|
||||
User = NULL;
|
||||
Pwd = NULL;
|
||||
Server = NULL;
|
||||
Port = 0;
|
||||
Isview = FALSE;
|
||||
Prep = FALSE;
|
||||
|
@ -473,10 +480,11 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g)
|
|||
|
||||
if (Columns) {
|
||||
for (colp = Columns; colp; colp = colp->GetNext())
|
||||
if (colp->IsSpecial()) {
|
||||
strcpy(g->Message, MSG(NO_SPEC_COL));
|
||||
return TRUE;
|
||||
} else {
|
||||
if (!colp->IsSpecial()) {
|
||||
// if (colp->IsSpecial()) {
|
||||
// strcpy(g->Message, MSG(NO_SPEC_COL));
|
||||
// return TRUE;
|
||||
// } else {
|
||||
if (b)
|
||||
strcat(Query, ", ");
|
||||
else
|
||||
|
@ -519,10 +527,11 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
|
|||
return FALSE; // already done
|
||||
|
||||
for (colp = Columns; colp; colp = colp->GetNext())
|
||||
if (colp->IsSpecial()) {
|
||||
strcpy(g->Message, MSG(NO_SPEC_COL));
|
||||
return TRUE;
|
||||
} else {
|
||||
if (!colp->IsSpecial()) {
|
||||
// if (colp->IsSpecial()) {
|
||||
// strcpy(g->Message, MSG(NO_SPEC_COL));
|
||||
// return TRUE;
|
||||
// } else {
|
||||
len += (strlen(colp->GetName()) + 4);
|
||||
((PMYCOL)colp)->Rank = Nparm++;
|
||||
} // endif colp
|
||||
|
@ -1232,7 +1241,7 @@ void MYSQLCOL::ReadColumn(PGLOBAL g)
|
|||
if (trace)
|
||||
htrc("MySQL ReadColumn: name=%s buf=%s\n", Name, buf);
|
||||
|
||||
Value->SetValue_char(buf, Long);
|
||||
Value->SetValue_char(buf, min((unsigned)Long, strlen(buf)));
|
||||
} else {
|
||||
if (Nullable)
|
||||
Value->SetNull(true);
|
||||
|
|
|
@ -49,6 +49,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
|
|||
PSZ Srcdef; /* The source table SQL definition */
|
||||
PSZ Username; /* User logon name */
|
||||
PSZ Password; /* Password logon info */
|
||||
PSZ Server; /* PServerID */
|
||||
int Portnumber; /* MySQL port number (0 = default) */
|
||||
bool Isview; /* TRUE if this table is a MySQL view */
|
||||
bool Bind; /* Use prepared statement on insert */
|
||||
|
@ -77,6 +78,7 @@ class TDBMYSQL : public TDBASE {
|
|||
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
|
||||
|
@ -110,6 +112,7 @@ class TDBMYSQL : public TDBASE {
|
|||
char *Database; // Database to be used by server
|
||||
char *Tabname; // External table name
|
||||
char *Srcdef; // The source table SQL definition
|
||||
char *Server; // The server ID
|
||||
char *Query; // Points to SQL query
|
||||
char *Qbuf; // Used for not prepared insert
|
||||
bool Fetched; // True when fetch was done
|
||||
|
|
|
@ -71,10 +71,11 @@ class TDBODBC : public TDBASE {
|
|||
// Methods
|
||||
virtual PTDB CopyOne(PTABS t);
|
||||
virtual int GetRecpos(void);
|
||||
virtual PSZ GetFile(PGLOBAL g);
|
||||
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);
|
||||
|
|
|
@ -36,7 +36,9 @@
|
|||
#include "global.h"
|
||||
#include "plgdbsem.h"
|
||||
#include "reldef.h"
|
||||
//#include "xobject.h"
|
||||
#if !defined(WIN32)
|
||||
#include "osutil.h"
|
||||
#endif // !WIN32
|
||||
#include "filamtxt.h"
|
||||
#include "tabdos.h"
|
||||
#include "tabsys.h"
|
||||
|
@ -320,7 +322,11 @@ int TDBINI::DeleteDB(PGLOBAL g, int irc)
|
|||
break;
|
||||
case RC_FX:
|
||||
while (ReadDB(g) == RC_OK)
|
||||
WritePrivateProfileString(Section, NULL, NULL, Ifile);
|
||||
if (!WritePrivateProfileString(Section, NULL, NULL, Ifile)) {
|
||||
sprintf(g->Message, "Error %d accessing %s",
|
||||
GetLastError(), Ifile);
|
||||
return RC_FX;
|
||||
} // endif
|
||||
|
||||
break;
|
||||
default:
|
||||
|
@ -328,7 +334,11 @@ int TDBINI::DeleteDB(PGLOBAL g, int irc)
|
|||
strcpy(g->Message, MSG(NO_SECTION_NAME));
|
||||
return RC_FX;
|
||||
} else
|
||||
WritePrivateProfileString(Section, NULL, NULL, Ifile);
|
||||
if (!WritePrivateProfileString(Section, NULL, NULL, Ifile)) {
|
||||
sprintf(g->Message, "Error %d accessing %s",
|
||||
GetLastError(), Ifile);
|
||||
return RC_FX;
|
||||
} // endif rc
|
||||
|
||||
} // endswitch irc
|
||||
|
||||
|
@ -461,13 +471,13 @@ void INICOL::ReadColumn(PGLOBAL g)
|
|||
Valbuf[Long] = '\0';
|
||||
break;
|
||||
default:
|
||||
GetPrivateProfileString(tdbp->Section, Name, "µ",
|
||||
GetPrivateProfileString(tdbp->Section, Name, "\b",
|
||||
Valbuf, Long + 1, tdbp->Ifile);
|
||||
break;
|
||||
} // endswitch Flag
|
||||
|
||||
// Missing keys are interpreted as null values
|
||||
if (!strcmp(Valbuf, "µ")) {
|
||||
if (!strcmp(Valbuf, "\b")) {
|
||||
if (Nullable)
|
||||
Value->SetNull(true);
|
||||
|
||||
|
@ -485,6 +495,7 @@ void INICOL::ReadColumn(PGLOBAL g)
|
|||
void INICOL::WriteColumn(PGLOBAL g)
|
||||
{
|
||||
char *p;
|
||||
bool rc;
|
||||
PTDBINI tdbp = (PTDBINI)To_Tdb;
|
||||
|
||||
if (trace > 1)
|
||||
|
@ -510,11 +521,12 @@ void INICOL::WriteColumn(PGLOBAL g)
|
|||
if (tdbp->Mode == MODE_UPDATE) {
|
||||
strcpy(g->Message, MSG(NO_SEC_UPDATE));
|
||||
longjmp(g->jumper[g->jump_level], 31);
|
||||
} else {
|
||||
} else if (*p) {
|
||||
tdbp->Section = p;
|
||||
return;
|
||||
} // endif Mode
|
||||
} else
|
||||
tdbp->Section = NULL;
|
||||
|
||||
return;
|
||||
} else if (!tdbp->Section) {
|
||||
strcpy(g->Message, MSG(SEC_NAME_FIRST));
|
||||
longjmp(g->jumper[g->jump_level], 31);
|
||||
|
@ -523,8 +535,16 @@ void INICOL::WriteColumn(PGLOBAL g)
|
|||
/*********************************************************************/
|
||||
/* Updating must be done only when not in checking pass. */
|
||||
/*********************************************************************/
|
||||
if (Status)
|
||||
WritePrivateProfileString(tdbp->Section, Name, p, tdbp->Ifile);
|
||||
if (Status) {
|
||||
rc = WritePrivateProfileString(tdbp->Section, Name, p, tdbp->Ifile);
|
||||
|
||||
if (!rc) {
|
||||
sprintf(g->Message, "Error %d writing to %s",
|
||||
GetLastError(), tdbp->Ifile);
|
||||
longjmp(g->jumper[g->jump_level], 31);
|
||||
} // endif rc
|
||||
|
||||
} // endif Status
|
||||
|
||||
} // end of WriteColumn
|
||||
|
||||
|
@ -724,14 +744,21 @@ int TDBXIN::DeleteDB(PGLOBAL g, int irc)
|
|||
if (irc == RC_EF) {
|
||||
} else if (irc == RC_FX) {
|
||||
for (Section = Seclist; *Section; Section += (strlen(Section) + 1))
|
||||
WritePrivateProfileString(Section, NULL, NULL, Ifile);
|
||||
if (!WritePrivateProfileString(Section, NULL, NULL, Ifile)) {
|
||||
sprintf(g->Message, "Error %d accessing %s",
|
||||
GetLastError(), Ifile);
|
||||
return RC_FX;
|
||||
} // endif
|
||||
|
||||
} else if (Section) {
|
||||
WritePrivateProfileString(Section, Keycur, NULL, Ifile);
|
||||
} else {
|
||||
} else if (!Section) {
|
||||
strcpy(g->Message, MSG(NO_SECTION_NAME));
|
||||
return RC_FX;
|
||||
} // endif's
|
||||
} else
|
||||
if (!WritePrivateProfileString(Section, Keycur, NULL, Ifile)) {
|
||||
sprintf(g->Message, "Error %d accessing %s",
|
||||
GetLastError(), Ifile);
|
||||
return RC_FX;
|
||||
} // endif
|
||||
|
||||
return RC_OK;
|
||||
} // end of DeleteDB
|
||||
|
@ -792,6 +819,7 @@ void XINCOL::ReadColumn(PGLOBAL g)
|
|||
void XINCOL::WriteColumn(PGLOBAL g)
|
||||
{
|
||||
char *p;
|
||||
bool rc;
|
||||
PTDBXIN tdbp = (PTDBXIN)To_Tdb;
|
||||
|
||||
if (trace > 1)
|
||||
|
@ -813,20 +841,22 @@ void XINCOL::WriteColumn(PGLOBAL g)
|
|||
if (tdbp->Mode == MODE_UPDATE) {
|
||||
strcpy(g->Message, MSG(NO_SEC_UPDATE));
|
||||
longjmp(g->jumper[g->jump_level], 31);
|
||||
} else {
|
||||
} else if (*p) {
|
||||
tdbp->Section = p;
|
||||
return;
|
||||
} // endif Mode
|
||||
} else
|
||||
tdbp->Section = NULL;
|
||||
|
||||
return;
|
||||
} else if (Flag == 2) {
|
||||
if (tdbp->Mode == MODE_UPDATE) {
|
||||
strcpy(g->Message, MSG(NO_KEY_UPDATE));
|
||||
longjmp(g->jumper[g->jump_level], 31);
|
||||
} else {
|
||||
} else if (*p) {
|
||||
tdbp->Keycur = p;
|
||||
return;
|
||||
} // endif Mode
|
||||
} else
|
||||
tdbp->Keycur = NULL;
|
||||
|
||||
return;
|
||||
} else if (!tdbp->Section || !tdbp->Keycur) {
|
||||
strcpy(g->Message, MSG(SEC_KEY_FIRST));
|
||||
longjmp(g->jumper[g->jump_level], 31);
|
||||
|
@ -835,8 +865,16 @@ void XINCOL::WriteColumn(PGLOBAL g)
|
|||
/*********************************************************************/
|
||||
/* Updating must be done only when not in checking pass. */
|
||||
/*********************************************************************/
|
||||
if (Status)
|
||||
WritePrivateProfileString(tdbp->Section, tdbp->Keycur, p, tdbp->Ifile);
|
||||
if (Status) {
|
||||
rc = WritePrivateProfileString(tdbp->Section, tdbp->Keycur, p, tdbp->Ifile);
|
||||
|
||||
if (!rc) {
|
||||
sprintf(g->Message, "Error %d writing to %s",
|
||||
GetLastError(), tdbp->Ifile);
|
||||
longjmp(g->jumper[g->jump_level], 31);
|
||||
} // endif rc
|
||||
|
||||
} // endif Status
|
||||
|
||||
} // end of WriteColumn
|
||||
|
||||
|
|
|
@ -380,7 +380,8 @@ int TDBTBL::GetMaxSize(PGLOBAL g)
|
|||
void TDBTBL::ResetDB(void)
|
||||
{
|
||||
for (PCOL colp = Columns; colp; colp = colp->GetNext())
|
||||
if (colp->GetAmType() == TYPE_AM_TABID)
|
||||
if (colp->GetAmType() == TYPE_AM_TABID ||
|
||||
colp->GetAmType() == TYPE_AM_SRVID)
|
||||
colp->COLBLK::Reset();
|
||||
|
||||
for (PTABLE tabp = Tablist; tabp; tabp = tabp->GetNext())
|
||||
|
@ -492,7 +493,8 @@ int TDBTBL::ReadDB(PGLOBAL g)
|
|||
|
||||
// Check and initialize the subtable columns
|
||||
for (PCOL cp = Columns; cp; cp = cp->GetNext())
|
||||
if (cp->GetAmType() == TYPE_AM_TABID)
|
||||
if (cp->GetAmType() == TYPE_AM_TABID ||
|
||||
cp->GetAmType() == TYPE_AM_SRVID)
|
||||
cp->COLBLK::Reset();
|
||||
else if (((PPRXCOL)cp)->Init(g) && !Accept)
|
||||
return RC_FX;
|
||||
|
|
|
@ -159,7 +159,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
|
|||
/* Allocate the structures used to refer to the result set. */
|
||||
/**********************************************************************/
|
||||
qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
|
||||
buftyp, fldtyp, length, true, true);
|
||||
buftyp, fldtyp, length, false, true);
|
||||
|
||||
// Some columns must be renamed
|
||||
for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next)
|
||||
|
@ -226,8 +226,12 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
|
|||
crp->Kdata->SetValue((fp->null_ptr != 0) ? 1 : 0, i);
|
||||
|
||||
crp = crp->Next; // Remark
|
||||
fld = fp->comment.str;
|
||||
crp->Kdata->SetValue(fld, fp->comment.length, i);
|
||||
|
||||
// For Valgrind
|
||||
if (fp->comment.length > 0 && (fld = fp->comment.str))
|
||||
crp->Kdata->SetValue(fld, fp->comment.length, i);
|
||||
else
|
||||
crp->Kdata->Reset(i);
|
||||
|
||||
crp = crp->Next; // New
|
||||
crp->Kdata->SetValue((fmt) ? fmt : (char*) "", i);
|
||||
|
@ -364,7 +368,11 @@ PTDBASE TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b)
|
|||
#if defined(MYSQL_SUPPORT)
|
||||
// Access sub-table via MySQL API
|
||||
if (!(tdbp= cat->GetTable(g, tabp, MODE_READ, "MYPRX"))) {
|
||||
sprintf(g->Message, "Cannot access %s.%s", db, name);
|
||||
char buf[MAX_STR];
|
||||
|
||||
strcpy(buf, g->Message);
|
||||
sprintf(g->Message, "Error accessing %s.%s: %s", db, name, buf);
|
||||
hc->tshp = NULL;
|
||||
goto err;
|
||||
} // endif Define
|
||||
|
||||
|
|
|
@ -70,6 +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() : "?";}
|
||||
|
||||
// Database routines
|
||||
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
|
||||
|
|
|
@ -211,7 +211,7 @@ PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *cls, bool info)
|
|||
/* Allocate the structures used to refer to the result set. */
|
||||
/*********************************************************************/
|
||||
qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
|
||||
buftyp, fldtyp, length, true, true);
|
||||
buftyp, fldtyp, length, false, true);
|
||||
|
||||
if (info)
|
||||
return qrp;
|
||||
|
|
|
@ -592,7 +592,7 @@ void CHRBLK::SetValue(char *sp, uint len, int n)
|
|||
#endif
|
||||
|
||||
if (sp)
|
||||
memcpy(p, sp, Long);
|
||||
memcpy(p, sp, min((unsigned)Long, len));
|
||||
|
||||
if (Blanks) {
|
||||
// Suppress eventual ending zero and right fill with blanks
|
||||
|
@ -712,7 +712,7 @@ void *CHRBLK::GetValPtrEx(int n)
|
|||
// For VCT blocks we must remove rightmost blanks.
|
||||
char *p = Valp + Long;
|
||||
|
||||
for (p--; *p == ' ' && p >= Valp; p--) ;
|
||||
for (p--; p >= Valp && *p == ' '; p--) ;
|
||||
|
||||
*(++p) = '\0';
|
||||
} // endif Blanks
|
||||
|
|
|
@ -583,12 +583,12 @@ template <>
|
|||
void TYPVAL<double>::SetValue_char(char *p, int n)
|
||||
{
|
||||
if (p) {
|
||||
char *p2, buf[32];
|
||||
char buf[32];
|
||||
|
||||
for (p2 = p + n; p < p2 && *p == ' '; p++) ;
|
||||
for (; n > 0 && *p == ' '; p++)
|
||||
n--;
|
||||
|
||||
n = min(p2 - p, 31);
|
||||
memcpy(buf, p, n);
|
||||
memcpy(buf, p, min(n, 31));
|
||||
buf[n] = '\0';
|
||||
Tval = atof(buf);
|
||||
|
||||
|
@ -875,12 +875,16 @@ TYPVAL<PSZ>::TYPVAL(PSZ s) : VALUE(TYPE_STRING)
|
|||
TYPVAL<PSZ>::TYPVAL(PGLOBAL g, PSZ s, int n, int c)
|
||||
: VALUE(TYPE_STRING)
|
||||
{
|
||||
assert(Type == TYPE_STRING && (g || s));
|
||||
assert(Type == TYPE_STRING);
|
||||
Len = (g) ? n : strlen(s);
|
||||
|
||||
if (g && !s) {
|
||||
Strp = (char *)PlugSubAlloc(g, NULL, Len + 1);
|
||||
Strp[Len] = '\0';
|
||||
if (!s) {
|
||||
if (g) {
|
||||
Strp = (char *)PlugSubAlloc(g, NULL, Len + 1);
|
||||
Strp[Len] = '\0';
|
||||
} else
|
||||
assert(false);
|
||||
|
||||
} else
|
||||
Strp = s;
|
||||
|
||||
|
@ -912,15 +916,21 @@ bool TYPVAL<PSZ>::SetValue_pval(PVAL valp, bool chktype)
|
|||
void TYPVAL<PSZ>::SetValue_char(char *p, int n)
|
||||
{
|
||||
if (p) {
|
||||
n = min(n, Len);
|
||||
strncpy(Strp, p, n);
|
||||
if ((n = min(n, Len))) {
|
||||
strncpy(Strp, p, n);
|
||||
|
||||
for (p = Strp + n - 1; (*p == ' ' || *p == '\0') && p >= Strp; p--) ;
|
||||
// for (p = Strp + n - 1; p >= Strp && (*p == ' ' || *p == '\0'); p--) ;
|
||||
for (p = Strp + n - 1; p >= Strp; p--)
|
||||
if (*p && *p != ' ')
|
||||
break;
|
||||
|
||||
*(++p) = '\0';
|
||||
*(++p) = '\0';
|
||||
|
||||
if (trace > 1)
|
||||
htrc(" Setting string to: '%s'\n", Strp);
|
||||
if (trace > 1)
|
||||
htrc(" Setting string to: '%s'\n", Strp);
|
||||
|
||||
} else
|
||||
Reset();
|
||||
|
||||
Null = false;
|
||||
} else {
|
||||
|
|
|
@ -83,6 +83,7 @@ class DllExport VALUE : public BLOCK {
|
|||
virtual void SetPrec(int prec) {Prec = prec;}
|
||||
bool IsNull(void) {return Null;}
|
||||
void SetNull(bool b) {Null = b;}
|
||||
bool GetNullable(void) {return Nullable;}
|
||||
void SetNullable(bool b) {Nullable = b;}
|
||||
int GetType(void) {return Type;}
|
||||
int GetClen(void) {return Clen;}
|
||||
|
|
|
@ -1832,8 +1832,9 @@ int XINDXS::Range(PGLOBAL g, int limit, bool incl)
|
|||
/*********************************************************************/
|
||||
if (xp->GetType() == TYPE_CONST) {
|
||||
kp->Valp->SetValue_pval(xp->GetValue(), !kp->Prefix);
|
||||
k = FastFind(Nval);
|
||||
|
||||
if ((k = FastFind(Nval)) < Num_K)
|
||||
if (k < Num_K || Op != OP_EQ)
|
||||
if (limit)
|
||||
n = (Mul) ? k : kp->Val_K;
|
||||
else
|
||||
|
@ -2797,7 +2798,7 @@ bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln)
|
|||
if (Asc)
|
||||
IsSorted = colp->GetOpt() < 0;
|
||||
|
||||
//MayHaveNulls = colp->HasNulls();
|
||||
//SetNulls(colp->IsNullable()); for when null columns will be indexable
|
||||
return false;
|
||||
} // end of Init
|
||||
|
||||
|
@ -2956,6 +2957,11 @@ void KXYCOL::InitBinFind(void *vp)
|
|||
void KXYCOL::FillValue(PVAL valp)
|
||||
{
|
||||
valp->SetValue_pvblk(Kblp, Val_K);
|
||||
|
||||
// Set null when applicable (NIY)
|
||||
//if (valp->GetNullable())
|
||||
// valp->SetNull(valp->IsZero());
|
||||
|
||||
} // end of FillValue
|
||||
|
||||
/***********************************************************************/
|
||||
|
|
|
@ -473,10 +473,10 @@ class KXYCOL: public BLOCK {
|
|||
|
||||
protected:
|
||||
// Members
|
||||
PXCOL Next; // To next in the key part list
|
||||
PXCOL Next; // To next in the key part list
|
||||
PXCOL Previous; // To previous in the key part list
|
||||
PKXBASE Kxp; // To the INDEX class block
|
||||
PCOL Colp; // To matching object if a column
|
||||
PCOL Colp; // To matching object if a column
|
||||
bool IsSorted; // true if column is already sorted
|
||||
bool Asc; // true for ascending sort, false for Desc
|
||||
MBLOCK Keys; // Data array allocation block
|
||||
|
|
|
@ -113,6 +113,7 @@ class DllExport TDB: public TBX { // Table Descriptor Block.
|
|||
{fprintf(f, "%s AM(%d)\n", m, GetAmType());}
|
||||
virtual void Print(PGLOBAL g, FILE *f, uint n);
|
||||
virtual void Print(PGLOBAL g, char *ps, uint z);
|
||||
virtual PSZ GetServer(void) = 0;
|
||||
|
||||
// Database pure virtual routines
|
||||
virtual PCOL ColDB(PGLOBAL g, PSZ name, int num) = 0;
|
||||
|
@ -192,13 +193,14 @@ class DllExport TDBASE : public TDB {
|
|||
virtual void ResetSize(void) {MaxSize = -1;}
|
||||
virtual void RestoreNrec(void) {}
|
||||
virtual int ResetTableOpt(PGLOBAL g, bool dox);
|
||||
virtual PSZ GetServer(void) {return "Current";}
|
||||
|
||||
// Database routines
|
||||
virtual PCOL ColDB(PGLOBAL g, PSZ name, int num);
|
||||
virtual PCOL MakeCol(PGLOBAL, PCOLDEF, PCOL, int)
|
||||
{assert(false); return NULL;}
|
||||
virtual PCOL InsertSpecialColumn(PGLOBAL g, PCOL colp);
|
||||
virtual PCOL InsertSpcBlk(PGLOBAL g, PCOLUMN cp);
|
||||
virtual PCOL InsertSpcBlk(PGLOBAL g, PCOLDEF cdp);
|
||||
virtual void MarkDB(PGLOBAL g, PTDB tdb2);
|
||||
|
||||
protected:
|
||||
|
|
Loading…
Add table
Reference in a new issue