Commit d240a041 authored by Alexander Barkov's avatar Alexander Barkov

Merge 10.0-connect -> 10.0

parents 5bb01fa1 0d37409f
......@@ -166,6 +166,7 @@ my $DEFAULT_SUITES= join(',', map { "$_-" } qw(
main
archive
binlog
connect
csv
federated
funcs_1
......@@ -380,7 +381,6 @@ sub main {
mtr_report("Logging: $0 ", join(" ", @ARGV));
$DEFAULT_SUITES.= ',' . join(',', qw(
connect
query_response_time
sequence
spider
......
......@@ -264,6 +264,19 @@ int main() {
ENDIF(UNIX)
ENDIF(CONNECT_WITH_ODBC)
#
# Installing tests
#
IF(INSTALL_MYSQLTESTDIR)
INSTALL(
DIRECTORY mysql-test/connect
DESTINATION ${INSTALL_MYSQLTESTDIR}/suite
USE_SOURCE_PERMISSIONS
COMPONENT Test
PATTERN "*~" EXCLUDE
)
ENDIF()
#
# Plugin definition
......
......@@ -164,8 +164,7 @@ bool COLBLK::CheckSort(PTDB tdbp)
/* Now we use Format.Length for the len parameter to avoid strings */
/* to be truncated when converting from string to coded string. */
/* Added in version 1.5 is the arguments GetPrecision() and Domain */
/* in calling AllocateValue. Domain is used for TYPE_TOKEN only, */
/* but why was GetPrecision() not specified ? To be checked. */
/* in calling AllocateValue. Domain is used for TYPE_DATE only. */
/***********************************************************************/
bool COLBLK::InitValue(PGLOBAL g)
{
......@@ -174,8 +173,7 @@ bool COLBLK::InitValue(PGLOBAL g)
// Allocate a Value object
if (!(Value = AllocateValue(g, Buf_Type, Format.Length,
GetPrecision(), GetDomain(),
(To_Tdb) ? To_Tdb->GetCat() : NULL)))
GetPrecision(), GetDomain())))
return true;
AddStatus(BUF_READY);
......
......@@ -251,7 +251,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
return true;
} // endif tdbp
tdbp->SetMode(mode);
//tdbp->SetMode(mode); done in ha_connect::GetTDB
if (!c1) {
if (mode == MODE_INSERT)
......@@ -498,8 +498,8 @@ RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all)
if (!tdbp || tdbp->GetMode() != MODE_DELETE)
return RC_FX;
// else
// ((PTDBDOX)tdbp)->SetModified(true);
else if (tdbp->IsReadOnly())
return RC_NF;
if (((PTDBASE)tdbp)->GetDef()->Indexable() && all)
((PTDBDOS)tdbp)->Cardinal= 0;
......@@ -518,17 +518,13 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
int rc= RC_OK;
TDBDOX *tbxp= NULL;
if (!tdbp)
return rc; // Already done
if (!tdbp || tdbp->GetUse() != USE_OPEN)
return rc; // Nothing to do
if (xtrace)
printf("CntCloseTable: tdbp=%p mode=%d\n", tdbp, tdbp->GetMode());
/*********************************************************************/
/* This will close the table file(s) and also finalize write */
/* operations such as Insert, Update, or Delete. */
/*********************************************************************/
if (tdbp->GetMode() == MODE_DELETE)
if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN)
rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine
// Prepare error return
......@@ -543,6 +539,8 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
goto err;
} // endif
// This will close the table file(s) and also finalize write
// operations such as Insert, Update, or Delete.
tdbp->CloseDB(g);
g->jump_level--;
......
......@@ -17,8 +17,6 @@ typedef class BLKFAM *PBLKFAM;
typedef class DOSDEF *PDOSDEF;
typedef class TDBDOS *PTDBDOS;
#define TYPE_AM_BLK (AMT)160
/***********************************************************************/
/* This is the base class for all file access method classes. */
/***********************************************************************/
......
......@@ -91,7 +91,7 @@ typedef struct _vecheader {
/* Conversion of block values allowed conditionally for insert only. */
/***********************************************************************/
PVBLK AllocValBlock(PGLOBAL, void *, int, int, int, int,
bool check = true, bool blank = true);
bool check = true, bool blank = true, bool un = false);
/* -------------------------- Class VCTFAM --------------------------- */
......
......@@ -10,9 +10,6 @@
#include "zlib.h"
#define TYPE_AM_ZIP (AMT)150
#define TYPE_AM_ZLIB (AMT)155
typedef class ZIPFAM *PZIPFAM;
typedef class ZBKFAM *PZBKFAM;
typedef class ZIXFAM *PZIXFAM;
......
This diff is collapsed.
......@@ -174,7 +174,7 @@ class ha_connect: public handler
bool IsSameIndex(PIXDEF xp1, PIXDEF xp2);
PTDB GetTDB(PGLOBAL g);
bool OpenTable(PGLOBAL g, bool del= false);
int OpenTable(PGLOBAL g, bool del= false);
bool IsOpened(void);
int CloseTable(PGLOBAL g);
int MakeRecord(char *buf);
......
......@@ -8,6 +8,9 @@
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include <libxml/catalog.h>
#include <libxml/xmlschemastypes.h>
#include <libxml/relaxng.h>
//#if defined(WIN32)
//#include <windows.h>
//#else // !WIN32
......@@ -290,10 +293,46 @@ if (!rc)
/******************************************************************/
/* XML library cleanup function. */
/******************************************************************/
/*
This is a copy of xmlCleanupParser() from the libxml2 sources
with xmlResetLastError() commented.
xmlResetLastError() called from the original xmlCleanupParser() causes
valgrind to report memory leaks. This happens because
ha_initialize_handlerton() is called from the main thread in mysqld.cc,
while ha_finalize_handlerton() is called from a non-main thread.
libxml2 gets confused because of xmlInitParser() and xmlCleanupParser()
being called from the different threads.
Perhaps the code in mysqld.cc should eventually be modified
to shutdown plugins from the main thread.
*/
static void
xmlCleanupParser_replacement(void)
{
xmlCleanupCharEncodingHandlers();
#ifdef LIBXML_CATALOG_ENABLED
xmlCatalogCleanup();
#endif
xmlDictCleanup();
xmlCleanupInputCallbacks();
#ifdef LIBXML_OUTPUT_ENABLED
xmlCleanupOutputCallbacks();
#endif
#ifdef LIBXML_SCHEMAS_ENABLED
xmlSchemaCleanupTypes();
xmlRelaxNGCleanupTypes();
#endif
//xmlResetLastError();
xmlCleanupGlobals();
xmlCleanupThreads(); /* must be last if called not from the main thread */
xmlCleanupMemory();
}
void XmlCleanupParserLib(void)
{
xmlCleanupParser();
xmlMemoryDump();
xmlCleanupParser_replacement();
} // end of XmlCleanupParserLib
/******************************************************************/
......
......@@ -87,7 +87,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
FLD_KEY, FLD_SCALE, FLD_RADIX, FLD_NULL,
FLD_REM, FLD_NO, FLD_CHARSET};
static unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 256, 32, 32};
char *fld, *fmt, cmd[128];
char *fld, *fmt, v, cmd[128];
int i, n, nf, ncol = sizeof(buftyp) / sizeof(int);
int len, type, prec, rc, k = 0;
PQRYRES qrp;
......@@ -139,6 +139,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
// Some columns must be renamed
for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next)
switch (++i) {
case 2: crp->Nulls = (char*)PlugSubAlloc(g, NULL, n); break;
case 4: crp->Name = "Length"; break;
case 5: crp->Name = "Key"; break;
case 10: crp->Name = "Date_fmt"; break;
......@@ -166,7 +167,8 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
// Get type, type name, and precision
fld = myc.GetCharField(1);
prec = 0;
len = 255; // Default for text or blob
len = 0;
v = 0;
if ((nf = sscanf(fld, "%[^(](%d,%d", cmd, &len, &prec)) < 1) {
sprintf(g->Message, MSG(BAD_FIELD_TYPE), fld);
......@@ -175,14 +177,16 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
} else
qrp->Nblin++;
if ((type = MYSQLtoPLG(cmd)) == TYPE_ERROR) {
if ((type = MYSQLtoPLG(cmd, &v)) == TYPE_ERROR) {
sprintf(g->Message, "Unsupported column type %s", cmd);
myc.Close();
return NULL;
} // endif type
} else if (type == TYPE_STRING)
len = min(len, 4096);
crp = crp->Next; // Data_Type
crp->Kdata->SetValue(type, i);
crp->Nulls[i] = v;
crp = crp->Next; // Type_Name
crp->Kdata->SetValue(cmd, i);
......@@ -253,6 +257,7 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db,
const char *user, const char *pwd,
const char *srcdef, int port)
{
char *query;
int w;
MYSQLC myc;
PQRYRES qrp = NULL;
......@@ -260,12 +265,15 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db,
if (!port)
port = mysqld_port;
query = (char *)PlugSubAlloc(g, NULL, strlen(srcdef) + 9);
strcat(strcpy(query, srcdef), " LIMIT 0");
// Open a MySQL connection for this table
if (myc.Open(g, host, db, user, pwd, port))
return NULL;
// Send the source command to MySQL
if (myc.ExecSQL(g, srcdef, &w) == RC_OK)
if (myc.ExecSQL(g, query, &w) == RC_OK)
qrp = myc.GetResult(g);
myc.Close();
......@@ -701,7 +709,7 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb)
crp->Clen = GetTypeSize(crp->Type, crp->Length);
if (!(crp->Kdata = AllocValBlock(g, NULL, crp->Type, m_Rows,
crp->Clen, 0, FALSE, TRUE))) {
crp->Clen, 0, FALSE, TRUE, FALSE))) {
sprintf(g->Message, MSG(INV_RESULT_TYPE),
GetFormatType(crp->Type));
return NULL;
......@@ -778,6 +786,42 @@ void MYSQLC::Rewind(void)
} // end of Rewind
/***********************************************************************/
/* Exec the Select SQL command and return ncol or afrws (TDBMYEXC). */
/***********************************************************************/
int MYSQLC::ExecSQLcmd(PGLOBAL g, const char *query, int *w)
{
int rc = RC_OK;
if (!m_DB) {
strcpy(g->Message, "MySQL not connected");
return RC_FX;
} else
*w = 0;
if (!stricmp(query, "Warning") || !stricmp(query, "Note")
|| !stricmp(query, "Error"))
return RC_INFO;
else
m_Afrw = 0;
//if (mysql_query(m_DB, query) != 0) {
if (mysql_real_query(m_DB, query, strlen(query))) {
m_Afrw = (int)mysql_errno(m_DB);
sprintf(g->Message, "Remote: %s", mysql_error(m_DB));
rc = RC_FX;
//} else if (!(m_Fields = mysql_field_count(m_DB))) {
} else if (!(m_Fields = (int)m_DB->field_count)) {
// m_Afrw = (int)mysql_affected_rows(m_DB);
m_Afrw = (int)m_DB->affected_rows;
rc = RC_NF;
} // endif's
//*w = mysql_warning_count(m_DB);
*w = m_DB->warning_count;
return rc;
} // end of ExecSQLcmd
/***********************************************************************/
/* Close the connection. */
/***********************************************************************/
......
......@@ -26,7 +26,6 @@
#define DllItem
#endif // !WIN32
//#define TYPE_AM_MYSQL (AMT)192
#define MYSQL_ENABLED 0x00000001
#define MYSQL_LOGON 0x00000002
......@@ -75,9 +74,12 @@ class DllItem MYSQLC {
//const char *ServerInfo(void);
int KillQuery(ulong id);
int ExecSQL(PGLOBAL g, const char *query, int *w = NULL);
int ExecSQLcmd(PGLOBAL g, const char *query, int *w);
#if defined(MYSQL_PREPARED_STATEMENTS)
int PrepareSQL(PGLOBAL g, const char *query);
int ExecStmt(PGLOBAL g);
int BindParams(PGLOBAL g, MYSQL_BIND *bind);
#endif // MYSQL_PREPARED_STATEMENTS
PQRYRES GetResult(PGLOBAL g, bool pdb = FALSE);
int Fetch(PGLOBAL g, int pos);
char *GetCharField(int i);
......@@ -99,5 +101,6 @@ class DllItem MYSQLC {
int m_Rows; // The number of rows of the result
int N;
int m_Fields; // The number of result fields
int m_Afrw; // The number of affected rows
}; // end of class MYSQLC
# Use default setting for mysqld processes
!include include/default_mysqld.cnf
!include include/default_client.cnf
[mysqld.1]
#log-bin= master-bin
[mysqld.2]
[ENV]
MASTER_MYPORT= @mysqld.1.port
MASTER_MYSOCK= @mysqld.1.socket
SLAVE_MYPORT= @mysqld.2.port
SLAVE_MYSOCK= @mysqld.2.socket
......@@ -48,7 +48,7 @@ salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F',
dept INT(4) NOT NULL FIELD_FORMAT='S'
) ENGINE=CONNECT TABLE_TYPE=BIN READONLY=Yes FILE_NAME='Testbal.dat';
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
ALTER TABLE t1 READONLY=NO;
Warnings:
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
......@@ -84,7 +84,7 @@ t1 CREATE TABLE `t1` (
`dept` int(4) NOT NULL `FIELD_FORMAT`='S'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=BIN `FILE_NAME`='Testbal.dat' `READONLY`=YES
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
DROP TABLE t1;
#
# Testing that the underlying file is created
......
......@@ -50,13 +50,13 @@ children SMALLINT(2) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
HEADER=1 SEP_CHAR=';' QUOTED=1 READONLY=yes;
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
UPDATE t1 SET children=6 WHERE name='BILL';
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
DELETE FROM t1 WHERE name='BILL';
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
TRUNCATE TABLE t1;
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
SELECT * FROM t1;
name birth children
Archibald 2001-05-17 3
......@@ -90,7 +90,7 @@ t1 CREATE TABLE `t1` (
`children` smallint(2) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=CSV `FILE_NAME`='people.csv' `HEADER`=1 `SEP_CHAR`=';' `QUOTED`=1 `READONLY`=1
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
SELECT * FROM t1;
name birth children
Archibald 2001-05-17 3
......
......@@ -77,13 +77,13 @@ t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=DBF `FILE_NAME`='t1.dbf' `READONLY`=Yes
INSERT INTO t1 VALUES (30);
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
UPDATE t1 SET a=30 WHERE a=10;
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
DELETE FROM t1 WHERE a=10;
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
TRUNCATE TABLE t1;
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
ALTER TABLE t1 READONLY=NO;
Warnings:
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
......
......@@ -30,13 +30,13 @@ t1 CREATE TABLE `t1` (
`id` int(11) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=FIX `FILE_NAME`='t1.txt' `READONLY`=1
INSERT INTO t1 VALUES (20);
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
UPDATE t1 SET id=20 WHERE id=10;
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
DELETE FROM t1 WHERE id=10;
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
TRUNCATE TABLE t1;
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
ALTER TABLE t1 READONLY=0;
Warnings:
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
......
......@@ -194,13 +194,13 @@ t1 CREATE TABLE `t1` (
`c2` char(60) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=INI `FILE_NAME`='t1.ini' `READONLY`=1
INSERT INTO t1 VALUES ('US',40);
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
UPDATE t1 SET c2=20 WHERE c2=10;
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
DELETE FROM t1 WHERE c2=10;
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
TRUNCATE TABLE t1;
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
ALTER TABLE t1 READONLY=0;
Warnings:
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
......
......@@ -44,7 +44,7 @@ SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL,
`b` varchar(10) DEFAULT NULL
`b` char(10) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MYSQL' `TABNAME`='t1' `OPTION_LIST`='host=localhost,user=root,port=PORT'
SELECT * FROM t2;
a b
......@@ -176,7 +176,7 @@ t1 CREATE TABLE `t1` (
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` varchar(10) DEFAULT NULL
`a` char(10) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MYSQL' `TABNAME`='t1' `OPTION_LIST`='host=localhost,user=root,port=PORT'
SELECT * FROM t2;
a
......
CREATE DATABASE connect;
CREATE DATABASE connect;
CREATE TABLE t1 (
`id` int(20) primary key,
`group` int NOT NULL default 1,
`a\\b` int NOT NULL default 2,
`a\\` int unsigned,
`name` varchar(32) default 'name')
DEFAULT CHARSET=latin1;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(20) NOT NULL,
`group` int(11) NOT NULL,
`a\\b` int(11) NOT NULL,
`a\\` int(10) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1' `TABLE_TYPE`='MYSQL'
INSERT INTO t1 (id, name) VALUES (1, 'foo');
Warnings:
Warning 1364 Field 'group' doesn't have a default value
Warning 1364 Field 'a\\b' doesn't have a default value
INSERT INTO t1 (id, name) VALUES (2, 'fee');
Warnings:
Warning 1364 Field 'group' doesn't have a default value
Warning 1364 Field 'a\\b' doesn't have a default value
SELECT * FROM t1;
id group a\\b a\\ name
1 1 2 NULL foo
2 1 2 NULL fee
DROP TABLE t1;
SELECT * FROM t1;
id group a\\b a\\ name
1 1 2 NULL foo
2 1 2 NULL fee
DROP TABLE t1;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
CREATE DATABASE connect;
CREATE DATABASE connect;
#
# Checking Sending Commands
#
CREATE TABLE t1 (
command VARCHAR(128) NOT NULL,
warnings INT(4) NOT NULL FLAG=3,
number INT(5) NOT NULL FLAG=1,
message VARCHAR(255) FLAG=2)
ENGINE=CONNECT TABLE_TYPE=MYSQL CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test' OPTION_LIST='Execsrc=1,maxerr=2';
SELECT * FROM t1 WHERE command IN ('Warning','Note',
'drop table if exists t1',
'create table t1 (id int key auto_increment, msg varchar(32) not null)',
"insert into t1(msg) values('One'),(NULL),('Three')",
"insert into t1 values(2,'Deux') on duplicate key update msg = 'Two'",
"insert into t1(message) values('Four'),('Five'),('Six')",
'insert into t1(id) values(NULL)',
"update t1 set msg = 'Four' where id = 4",
'select * from t1');
command warnings number message
drop table if exists t1 1 0 Affected rows
Note 0 1051 Unknown table 'test.t1'
create table t1 (id int key auto_increment, msg varchar(32) not null) 0 0 Affected rows
insert into t1(msg) values('One'),(NULL),('Three') 1 3 Affected rows
Warning 0 1048 Column 'msg' cannot be null
insert into t1 values(2,'Deux') on duplicate key update msg = 'Two' 0 2 Affected rows
insert into t1(message) values('Four'),('Five'),('Six') 0 1054 Remote: Unknown column 'message' in 'field list'
insert into t1(id) values(NULL) 1 1 Affected rows
Warning 0 1364 Field 'msg' doesn't have a default value
update t1 set msg = 'Four' where id = 4 0 1 Affected rows
select * from t1 0 2 Result set columns
#
# Checking Using Procedure
#
DROP PROCEDURE IF EXISTS p1;
Warnings:
Note 1305 PROCEDURE test.p1 does not exist
CREATE PROCEDURE p1(cmd varchar(512))
READS SQL DATA
SELECT * FROM t1 WHERE command IN ('Warning','Note',cmd);
CALL p1('insert into t1(id) values(NULL)');
command warnings number message
insert into t1(id) values(NULL) 1 1 Affected rows
Warning 0 1364 Field 'msg' doesn't have a default value
CALL p1('update t1 set msg = "Five" where id = 5');
command warnings number message
update t1 set msg = "Five" where id = 5 0 1 Affected rows
DROP PROCEDURE p1;
DROP TABLE t1;
SELECT * FROM t1;
id msg
1 One
2 Two
3 Three
4 Four
5 Five
DROP TABLE t1;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
CREATE DATABASE connect;
CREATE DATABASE connect;
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;
a b
NULL NULL
0 test00
1 test01
2 test02
3 test03
#
# Testing errors
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://unknown@127.0.0.1:SLAVE_PORT/test/t1';
ERROR HY000: (1045) Access denied for user 'unknown'@'localhost' (using password: NO)
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/unknown/t1';
ERROR HY000: (1049) Unknown database 'unknown'
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
OPTION_LIST='host=127.0.0.1,user=root,port=SLAVE_PORT' DBNAME='unknown' TABNAME='t1';
ERROR HY000: (1049) Unknown database 'unknown'
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/unknown';
ERROR HY000: (1146) Table 'test.unknown' doesn't exist [SHOW FULL COLUMNS FROM unknown FROM test]
SHOW CREATE TABLE t1;
ERROR 42S02: Table 'test.t1' doesn't exist
CREATE TABLE t1 (x int, y char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`x` int(11) DEFAULT NULL,
`y` char(10) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1' `TABLE_TYPE`=MYSQL
SELECT * FROM t1;
ERROR HY000: Got error 174 '(1054) Unknown column 'x' in 'field list' [SELECT `x`, `y` FROM `t1`]' from CONNECT
DROP TABLE t1;
CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1';
ALTER TABLE t1 RENAME t1backup;
SELECT * FROM t1;
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 t1;
#
# Testing SELECT, etc.
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` char(10) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1' `TABLE_TYPE`='MYSQL'
SELECT * FROM t1;
a b
NULL NULL
0 test00
1 test01
2 test02
3 test03
DROP TABLE t1;
CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1'
OPTION_LIST='host=127.0.0.1,user=root,port=SLAVE_PORT';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` char(10) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=MYSQL `TABNAME`='t1' `OPTION_LIST`='host=127.0.0.1,user=root,port=SLAVE_PORT'
SELECT * FROM t1;
a b
NULL NULL
0 test00
1 test01
2 test02
3 test03
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL, b CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=MYSQL
OPTION_LIST='host=127.0.0.1,user=root,port=SLAVE_PORT';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` char(10) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=MYSQL `OPTION_LIST`='host=127.0.0.1,user=root,port=SLAVE_PORT'
SELECT * FROM t1;
a b
0
0 test00
1 test01
2 test02
3 test03
DROP TABLE t1;
CREATE TABLE t1 (a char(10), b int) ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` char(10) DEFAULT NULL,
`b` int(11) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1' `TABLE_TYPE`=MYSQL
SELECT * FROM t1;
a b
NULL NULL
0 0
1 0
2 0
3 0
DROP TABLE t1;
DROP TABLE t1;
#
# Testing numeric data types
#
CREATE TABLE t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float, g double, h decimal(20,5));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` tinyint(4) DEFAULT NULL,
`b` smallint(6) DEFAULT NULL,
`c` mediumint(9) DEFAULT NULL,
`d` int(11) DEFAULT NULL,
`e` bigint(20) DEFAULT NULL,
`f` float DEFAULT NULL,
`g` double DEFAULT NULL,
`h` decimal(20,5) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES(100,3333,41235,1234567890,235000000000,3.14159265,3.14159265,3141.59265);
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
OPTION_LIST='host=127.0.0.1,user=root,port=SLAVE_PORT';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` tinyint(4) DEFAULT NULL,
`b` smallint(6) DEFAULT NULL,
`c` int(9) DEFAULT NULL,
`d` int(11) DEFAULT NULL,
`e` bigint(20) DEFAULT NULL,
`f` double DEFAULT NULL,
`g` double DEFAULT NULL,
`h` double(20,5) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MYSQL' `OPTION_LIST`='host=127.0.0.1,user=root,port=SLAVE_PORT'
SELECT * FROM t1;
a b c d e f g h
100 3333 41235 1234567890 235000000000 3.14159 3.14159265 3141.59265
DROP TABLE t1;
DROP TABLE t1;
#
# Testing character data types
#
CREATE TABLE t1 (a char(12), b varchar(12));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` char(12) DEFAULT NULL,
`b` varchar(12) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES('Welcome','Hello, World');
SELECT * FROM t1;
a b
Welcome Hello, World
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` char(12) DEFAULT NULL,
`b` varchar(12) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT' `TABLE_TYPE`='MYSQL'
SELECT * FROM t1;
a b
Welcome Hello, World
DROP TABLE t1;
DROP TABLE t1;
#
# Testing temporal data types
#
CREATE TABLE t1 (a date, b datetime, c time, d timestamp, e year);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` date DEFAULT NULL,
`b` datetime DEFAULT NULL,
`c` time DEFAULT NULL,
`d` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`e` year(4) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23');
Warnings:
Note 1265 Data truncated for column 'a' at row 1
Note 1265 Data truncated for column 'c' at row 1
Warning 1265 Data truncated for column 'e' at row 1
SELECT * FROM t1;
a b c d e
2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 2003
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` date DEFAULT NULL,
`b` datetime DEFAULT NULL,
`c` time DEFAULT NULL,
`d` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`e` year(4) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT' `TABLE_TYPE`='MYSQL'
SELECT * FROM t1;
a b c d e
2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 2003
DROP TABLE t1;
DROP TABLE t1;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
Table Create Table
t1 CREATE TABLE `t1` (
`Description` varchar(128) NOT NULL,
`Description` char(128) NOT NULL,
`Attributes` varchar(256) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='ODBC' `CATFUNC`='Drivers'
SET NAMES utf8;
......@@ -41,3 +41,13 @@ test2
ÆÇÈÉË
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 ENGINE=CONNECT CATFUNC=Columns TABNAME='t1' TABLE_TYPE=ODBC CONNECTION='Driver=SQLite3 ODBC Driver;Database=MTR_SUITE_DIR/std_data/test.sqlite3;NoWCHAR=yes' CHARSET=utf8 DATA_CHARSET=utf8;
SELECT * FROM t1;
Table_Qualif Table_Owner Table_Name Column_Name Data_Type Type_Name Precision Length Scale Radix Nullable Remarks
t1 a 12 varchar(64) 64 64 10 0 1
DROP TABLE t1;
CREATE TABLE t1 ENGINE=CONNECT CATFUNC=Tables TABNAME='t1' TABLE_TYPE=ODBC CONNECTION='Driver=SQLite3 ODBC Driver;Database=MTR_SUITE_DIR/std_data/test.sqlite3;NoWCHAR=yes' CHARSET=utf8 DATA_CHARSET=utf8;
SELECT * FROM t1;
Table_Qualifier Table_Owner Table_Name Table_Type Remark
t1 TABLE
DROP TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`Description` varchar(128) NOT NULL,
`Description` char(128) NOT NULL,
`Attributes` varchar(256) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='ODBC' `CATFUNC`='Drivers'
SET NAMES utf8;
......
......@@ -13,3 +13,14 @@ Thomas Dominique NULL
Lemonnier Nathalie Directeur Marketing Client
Menseau Eric NULL
DROP TABLE contact;
CREATE TABLE t1 ENGINE=CONNECT CATFUNC=Tables TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineXLS;DBQ=DATADIR/test/contacts.xls' CHARSET=utf8 DATA_CHARSET=latin1;;
SELECT * FROM t1 WHERE Table_name='CONTACT';
Table_Qualifier Table_Owner Table_Name Table_Type Remark
DATADIR/test/contacts CONTACT TABLE
DROP TABLE t1;
CREATE TABLE t1 ENGINE=CONNECT CATFUNC=Columns TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineXLS;DBQ=DATADIR/test/contacts.xls' CHARSET=utf8 DATA_CHARSET=latin1;;
SELECT * FROM t1 WHERE Table_name='CONTACT' AND Column_name IN ('Nom','Fonction');
Table_Qualif Table_Owner Table_Name Column_Name Data_Type Type_Name Precision Length Scale Radix Nullable Remarks
DATADIR/test/contacts CONTACT Nom 12 VARCHAR 255 510 0 0 1
DATADIR/test/contacts CONTACT Fonction 12 VARCHAR 255 510 0 0 1
DROP TABLE t1;
......@@ -103,13 +103,13 @@ t1 CREATE TABLE `t1` (
`b` char(10) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 MAX_ROWS=10 `TABLE_TYPE`=VEC `FILE_NAME`='t1vec' `READONLY`=yes
INSERT INTO t1 VALUES (4,'test04');
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
UPDATE t1 SET b='test04' WHERE a=3;
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
DELETE FROM t1 WHERE a=3;
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
TRUNCATE TABLE t1;
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
ERROR HY000: Table 't1' is read only
ALTER TABLE t1 READONLY=no;
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.0008 August 18, 2013 -->
<!-- Created by CONNECT Version 1.01.0009 October 29, 2013 -->
<t1>
<line>
<node>ÀÁÂÃ</node>
......
let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/Testbal.dat $MYSQLD_DATADIR/test/Testbal.dat
--echo #
--echo # Testing errors
--echo #
CREATE TABLE t1
(
ID INT NOT NULL
) Engine=CONNECT TABLE_TYPE=BIN FILE_NAME='nonexistent.txt';
--replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/
# TODO: check why this is needed for Windows
--replace_result Open(rt) Open(rb)
SELECT * FROM t1;
DROP TABLE t1;
SET time_zone='+00:00';
CREATE TABLE t1
(
fig INT(4) NOT NULL FIELD_FORMAT='C',
name CHAR(10) not null,
birth DATE NOT NULL,
id CHAR(5) NOT NULL FIELD_FORMAT='S',
salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F',
dept INT(4) NOT NULL FIELD_FORMAT='S'
) ENGINE=CONNECT TABLE_TYPE=BIN BLOCK_SIZE=5 FILE_NAME='Testbal.dat';
SELECT * FROM t1;
--error ER_GET_ERRMSG
INSERT INTO t1 VALUES (55555,'RONALD','1980-02-26','3333',4444.44,555);
INSERT INTO t1 VALUES (5555,'RONALD','1980-02-26','3333',4444.44,555);
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Testing READONLY tables
--echo #
CREATE TABLE t1
(
fig INT(4) NOT NULL FIELD_FORMAT='C',
name CHAR(10) not null,
birth DATE NOT NULL,
id CHAR(5) NOT NULL FIELD_FORMAT='S',
salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F',
dept INT(4) NOT NULL FIELD_FORMAT='S'
) ENGINE=CONNECT TABLE_TYPE=BIN READONLY=Yes FILE_NAME='Testbal.dat';
--error ER_GET_ERRMSG
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
ALTER TABLE t1 READONLY=NO;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
SELECT * FROM t1;
ALTER TABLE t1 READONLY=YES;
SHOW CREATE TABLE t1;
--error ER_GET_ERRMSG
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
DROP TABLE t1;
--echo #
--echo # Testing that the underlying file is created
--echo #
CREATE TABLE t1
(
c CHAR(4) NOT NULL FIELD_FORMAT='C'
) ENGINE=CONNECT TABLE_TYPE=BIN FILE_NAME='bin2.dat';
INSERT INTO t1 VALUES (10),(20),(300),(4000);
SELECT * FROM t1;
DROP TABLE t1;
#
# Clean up
#
--remove_file $MYSQLD_DATADIR/test/Testbal.dat
--remove_file $MYSQLD_DATADIR/test/bin2.dat
let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/Testbal.dat $MYSQLD_DATADIR/test/Testbal.dat
--echo #
--echo # Testing errors
--echo #
CREATE TABLE t1
(
ID INT NOT NULL
) Engine=CONNECT TABLE_TYPE=BIN FILE_NAME='nonexistent.txt';
--replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/
# TODO: check why this is needed for Windows
--replace_result Open(rt) Open(rb)
SELECT * FROM t1;
DROP TABLE t1;
SET time_zone='+00:00';
CREATE TABLE t1
(
fig INT(4) NOT NULL FIELD_FORMAT='C',
name CHAR(10) not null,
birth DATE NOT NULL,
id CHAR(5) NOT NULL FIELD_FORMAT='S',
salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F',
dept INT(4) NOT NULL FIELD_FORMAT='S'
) ENGINE=CONNECT TABLE_TYPE=BIN BLOCK_SIZE=5 FILE_NAME='Testbal.dat';
SELECT * FROM t1;
--error ER_GET_ERRMSG
INSERT INTO t1 VALUES (55555,'RONALD','1980-02-26','3333',4444.44,555);
INSERT INTO t1 VALUES (5555,'RONALD','1980-02-26','3333',4444.44,555);
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Testing READONLY tables
--echo #
CREATE TABLE t1
(
fig INT(4) NOT NULL FIELD_FORMAT='C',
name CHAR(10) not null,
birth DATE NOT NULL,
id CHAR(5) NOT NULL FIELD_FORMAT='S',
salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F',
dept INT(4) NOT NULL FIELD_FORMAT='S'
) ENGINE=CONNECT TABLE_TYPE=BIN READONLY=Yes FILE_NAME='Testbal.dat';
--error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
ALTER TABLE t1 READONLY=NO;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
SELECT * FROM t1;
ALTER TABLE t1 READONLY=YES;
SHOW CREATE TABLE t1;
--error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
DROP TABLE t1;
--echo #
--echo # Testing that the underlying file is created
--echo #
CREATE TABLE t1
(
c CHAR(4) NOT NULL FIELD_FORMAT='C'
) ENGINE=CONNECT TABLE_TYPE=BIN FILE_NAME='bin2.dat';
INSERT INTO t1 VALUES (10),(20),(300),(4000);
SELECT * FROM t1;
DROP TABLE t1;
#
# Clean up
#
--remove_file $MYSQLD_DATADIR/test/Testbal.dat
--remove_file $MYSQLD_DATADIR/test/bin2.dat
let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/dept.dat $MYSQLD_DATADIR/test/dept.dat
--copy_file $MTR_SUITE_DIR/std_data/boys.txt $MYSQLD_DATADIR/test/boys.txt
--copy_file $MTR_SUITE_DIR/std_data/boyswin.txt $MYSQLD_DATADIR/test/boyswin.txt
--echo #
--echo # Testing errors
--echo #
CREATE TABLE t1
(
ID INT NOT NULL
) Engine=CONNECT TABLE_TYPE=DOS FILE_NAME='nonexistent.txt';
--replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/
# TODO: check why this is needed for Windows
--replace_result Open(rt) Open(rb)
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Testing READONLY tables
--echo #
CREATE TABLE t1
(
id INT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='t1.txt';
INSERT INTO t1 VALUES (10);
SELECT * FROM t1;
ALTER TABLE t1 READONLY=1;
SHOW CREATE TABLE t1;
--error ER_GET_ERRMSG
INSERT INTO t1 VALUES (20);
--error ER_GET_ERRMSG
UPDATE t1 SET id=20 WHERE id=10;
--error ER_GET_ERRMSG
DELETE FROM t1 WHERE id=10;
--error ER_GET_ERRMSG
TRUNCATE TABLE t1;
ALTER TABLE t1 READONLY=0;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (20);
SELECT * FROM t1;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.txt
--echo #
--echo # Testing manual examples
--echo #
CREATE TABLE t1
(
number CHAR(4) not null,
location CHAR(15) NOT NULL flag=5,
director CHAR(5) NOT NULL flag=20,
function CHAR(12) NOT NULL flag=26,
name CHAR(22) NOT NULL flag=38
) ENGINE=CONNECT TABLE_TYPE=DOS FILE_NAME='dept.dat';
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1
(
name char(12) not null,
city char(12) not null,
birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' ENDING=1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1
(
name char(12) not null,
city char(12) not null,
birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' LRECL=47 ENDING=1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1
(
name char(12) not null,
city char(12) not null,
birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boyswin.txt' ENDING=2;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1
(
name char(12) not null,
city char(12) not null,
birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boyswin.txt' LRECL=47 ENDING=2;
SELECT * FROM t1;
DROP TABLE t1;
#
# Clean up
#
--remove_file $MYSQLD_DATADIR/test/dept.dat
--remove_file $MYSQLD_DATADIR/test/boys.txt
--remove_file $MYSQLD_DATADIR/test/boyswin.txt
let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/dept.dat $MYSQLD_DATADIR/test/dept.dat
--copy_file $MTR_SUITE_DIR/std_data/boys.txt $MYSQLD_DATADIR/test/boys.txt
--copy_file $MTR_SUITE_DIR/std_data/boyswin.txt $MYSQLD_DATADIR/test/boyswin.txt
--echo #
--echo # Testing errors
--echo #
CREATE TABLE t1
(
ID INT NOT NULL
) Engine=CONNECT TABLE_TYPE=DOS FILE_NAME='nonexistent.txt';
--replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/
# TODO: check why this is needed for Windows
--replace_result Open(rt) Open(rb)
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Testing READONLY tables
--echo #
CREATE TABLE t1
(
id INT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='t1.txt';
INSERT INTO t1 VALUES (10);
SELECT * FROM t1;
ALTER TABLE t1 READONLY=1;
SHOW CREATE TABLE t1;
--error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES (20);
--error ER_OPEN_AS_READONLY
UPDATE t1 SET id=20 WHERE id=10;
--error ER_OPEN_AS_READONLY
DELETE FROM t1 WHERE id=10;
--error ER_OPEN_AS_READONLY
TRUNCATE TABLE t1;
ALTER TABLE t1 READONLY=0;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (20);
SELECT * FROM t1;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.txt
--echo #
--echo # Testing manual examples
--echo #
CREATE TABLE t1
(
number CHAR(4) not null,
location CHAR(15) NOT NULL flag=5,
director CHAR(5) NOT NULL flag=20,
function CHAR(12) NOT NULL flag=26,
name CHAR(22) NOT NULL flag=38
) ENGINE=CONNECT TABLE_TYPE=DOS FILE_NAME='dept.dat';
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1
(
name char(12) not null,
city char(12) not null,
birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' ENDING=1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1
(
name char(12) not null,
city char(12) not null,
birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' LRECL=47 ENDING=1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1
(
name char(12) not null,
city char(12) not null,
birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boyswin.txt' ENDING=2;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1
(
name char(12) not null,
city char(12) not null,
birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boyswin.txt' LRECL=47 ENDING=2;
SELECT * FROM t1;
DROP TABLE t1;
#
# Clean up
#
--remove_file $MYSQLD_DATADIR/test/dept.dat
--remove_file $MYSQLD_DATADIR/test/boys.txt
--remove_file $MYSQLD_DATADIR/test/boyswin.txt
let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/contact.ini $MYSQLD_DATADIR/test/contact.ini
--echo #
--echo # Testing errors
--echo #
CREATE TABLE t1
(
ID INT
) Engine=CONNECT TABLE_TYPE=INI FILE_NAME='nonexistent.txt';
--replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/
# TODO: check why this is needed for Windows
--replace_result Open(rt) Open(rb)
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Testing examples from the manual
--echo #
CREATE TABLE t1
(
contact CHAR(16) flag=1,
name CHAR(20),
forename CHAR(32),
hired date date_format='DD/MM/YYYY',
address CHAR(64),
city CHAR(20),
zipcode CHAR(8),
tel CHAR(16)
) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='contact.ini';
SELECT contact, name, hired, city, tel FROM t1;
UPDATE t1 SET forename= 'Harry' where contact='UK1';
SELECT * FROM t1 WHERE contact='UK1';
INSERT INTO t1 (contact,forename) VALUES ('UK1','Harrison');
SELECT * FROM t1 WHERE contact='UK1';
INSERT INTO t1 (contact,forename) VALUES ('UK2','John');
SELECT * FROM t1 WHERE contact='UK2';
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/contact.ini
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/contact.ini'),'\r\n','\n'),'\n\n','\n');
CREATE TABLE t1
(
section CHAR(16) flag=1,
keyname CHAR(16) flag=2,
value CHAR(32)
) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='contact.ini'
OPTION_LIST='Layout=Row';
UPDATE t1 SET value='Paul' WHERE section='UK2' AND keyname='forename';
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/contact.ini
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/contact.ini'),'\r\n','\n'),'\n\n','\n');
--echo #
--echo # Testing that the underlying file is created
--echo #
CREATE TABLE t1
(
contact CHAR(12) NOT NULL flag=1,
c2 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='tmp.ini';
INSERT INTO t1 VALUES (10,10),(20,20),(300,300),(4000,4000), ('a b','c d');
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/tmp.ini
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/tmp.ini'),'\r\n','\n'),'\n\n','\n');
--echo #
--echo # Testing bad table
--echo #
CREATE TABLE t1
(
id INT
) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.ini';
--error ER_GET_ERRMSG
INSERT INTO t1 VALUES (10);
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Testing READONLY tables
--echo #
CREATE TABLE t1
(
contact CHAR(10) flag=1,
c2 CHAR(60)
) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.ini';
INSERT INTO t1 VALUES ('UK',10),('FR',20),('RU',30);
SELECT * FROM t1;
ALTER TABLE t1 READONLY=1;
SHOW CREATE TABLE t1;
--error ER_GET_ERRMSG
INSERT INTO t1 VALUES ('US',40);
--error ER_GET_ERRMSG
UPDATE t1 SET c2=20 WHERE c2=10;
--error ER_GET_ERRMSG
DELETE FROM t1 WHERE c2=10;
--error ER_GET_ERRMSG
TRUNCATE TABLE t1;
ALTER TABLE t1 READONLY=0;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ('US',40);
SELECT * FROM t1;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.ini
#
# Clean up
#
--remove_file $MYSQLD_DATADIR/test/contact.ini
--remove_file $MYSQLD_DATADIR/test/tmp.ini
--echo #
--echo # Bug: TABLE_TYPE=ini does not clear memory between CREATE TABLEs
--echo #
CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=INI;
INSERT INTO t1 VALUES ('sec1','val1'),('sec2','val2');
SELECT sec AS s, val AS v FROM t1;
DROP TABLE t1;
CREATE TABLE t1 (sec2 CHAR(10) NOT NULL FLAG=1, val2 CHAR(10) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=INI;
INSERT INTO t1 VALUES ('sec1','val11'),('sec2','val22');
SELECT sec2 AS s, val2 AS v FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.ini
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.ini'),'\r\n','\n'),'\n\n','\n');
DROP TABLE t1;
CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=INI;
CREATE TABLE t2 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=INI;
INSERT INTO t1 VALUES('1sec1','1val1'),('1sec2','1val2');
INSERT INTO t2 VALUES('2sec1','2val1'),('2sec2','2val2');
SELECT sec AS s, val AS v FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.ini
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.ini'),'\r\n','\n'),'\n\n','\n');
SELECT sec AS s, val AS v FROM t2;
--chmod 0777 $MYSQLD_DATADIR/test/t2.ini
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t2.ini'),'\r\n','\n'),'\n\n','\n');
DROP TABLE t1, t2;
let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/contact.ini $MYSQLD_DATADIR/test/contact.ini
--echo #
--echo # Testing errors
--echo #
CREATE TABLE t1
(
ID INT
) Engine=CONNECT TABLE_TYPE=INI FILE_NAME='nonexistent.txt';
--replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/
# TODO: check why this is needed for Windows
--replace_result Open(rt) Open(rb)
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Testing examples from the manual
--echo #
CREATE TABLE t1
(
contact CHAR(16) flag=1,
name CHAR(20),
forename CHAR(32),
hired date date_format='DD/MM/YYYY',
address CHAR(64),
city CHAR(20),
zipcode CHAR(8),
tel CHAR(16)
) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='contact.ini';
SELECT contact, name, hired, city, tel FROM t1;
UPDATE t1 SET forename= 'Harry' where contact='UK1';
SELECT * FROM t1 WHERE contact='UK1';
INSERT INTO t1 (contact,forename) VALUES ('UK1','Harrison');
SELECT * FROM t1 WHERE contact='UK1';
INSERT INTO t1 (contact,forename) VALUES ('UK2','John');
SELECT * FROM t1 WHERE contact='UK2';
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/contact.ini
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/contact.ini'),'\r\n','\n'),'\n\n','\n');
CREATE TABLE t1
(
section CHAR(16) flag=1,
keyname CHAR(16) flag=2,
value CHAR(32)
) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='contact.ini'
OPTION_LIST='Layout=Row';
UPDATE t1 SET value='Paul' WHERE section='UK2' AND keyname='forename';
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/contact.ini
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/contact.ini'),'\r\n','\n'),'\n\n','\n');
--echo #
--echo # Testing that the underlying file is created
--echo #
CREATE TABLE t1
(
contact CHAR(12) NOT NULL flag=1,
c2 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='tmp.ini';
INSERT INTO t1 VALUES (10,10),(20,20),(300,300),(4000,4000), ('a b','c d');
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/tmp.ini
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/tmp.ini'),'\r\n','\n'),'\n\n','\n');
--echo #
--echo # Testing bad table
--echo #
CREATE TABLE t1
(
id INT
) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.ini';
--error ER_GET_ERRMSG
INSERT INTO t1 VALUES (10);
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Testing READONLY tables
--echo #
CREATE TABLE t1
(
contact CHAR(10) flag=1,
c2 CHAR(60)
) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.ini';
INSERT INTO t1 VALUES ('UK',10),('FR',20),('RU',30);
SELECT * FROM t1;
ALTER TABLE t1 READONLY=1;
SHOW CREATE TABLE t1;
--error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES ('US',40);
--error ER_OPEN_AS_READONLY
UPDATE t1 SET c2=20 WHERE c2=10;
--error ER_OPEN_AS_READONLY
DELETE FROM t1 WHERE c2=10;
--error ER_OPEN_AS_READONLY
TRUNCATE TABLE t1;
ALTER TABLE t1 READONLY=0;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ('US',40);
SELECT * FROM t1;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.ini
#
# Clean up
#
--remove_file $MYSQLD_DATADIR/test/contact.ini
--remove_file $MYSQLD_DATADIR/test/tmp.ini
--echo #
--echo # Bug: TABLE_TYPE=ini does not clear memory between CREATE TABLEs
--echo #
CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=INI;
INSERT INTO t1 VALUES ('sec1','val1'),('sec2','val2');
SELECT sec AS s, val AS v FROM t1;
DROP TABLE t1;
CREATE TABLE t1 (sec2 CHAR(10) NOT NULL FLAG=1, val2 CHAR(10) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=INI;
INSERT INTO t1 VALUES ('sec1','val11'),('sec2','val22');
SELECT sec2 AS s, val2 AS v FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.ini
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.ini'),'\r\n','\n'),'\n\n','\n');
DROP TABLE t1;
CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=INI;
CREATE TABLE t2 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=INI;
INSERT INTO t1 VALUES('1sec1','1val1'),('1sec2','1val2');
INSERT INTO t2 VALUES('2sec1','2val1'),('2sec2','2val2');
SELECT sec AS s, val AS v FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.ini
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.ini'),'\r\n','\n'),'\n\n','\n');
SELECT sec AS s, val AS v FROM t2;
--chmod 0777 $MYSQLD_DATADIR/test/t2.ini
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t2.ini'),'\r\n','\n'),'\n\n','\n');
DROP TABLE t1, t2;
--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
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/tx1';
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
connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,);
connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT,);
connection master;
CREATE DATABASE connect;
connection slave;
CREATE DATABASE connect;
connection master;
--disable_warnings
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
connection slave;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
--enable_warnings
-- source myconn.inc
connection slave;
CREATE TABLE t1 (
`id` int(20) primary key,
`group` int NOT NULL default 1,
`a\\b` int NOT NULL default 2,
`a\\` int unsigned,
`name` varchar(32) default 'name')
DEFAULT CHARSET=latin1;
connection master;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1';
--replace_result $SLAVE_MYPORT SLAVE_PORT
SHOW CREATE TABLE t1;
INSERT INTO t1 (id, name) VALUES (1, 'foo');
INSERT INTO t1 (id, name) VALUES (2, 'fee');
--sorted_result
SELECT * FROM t1;
DROP TABLE t1;
connection slave;
--sorted_result
SELECT * FROM t1;
DROP TABLE t1;
-- source myconn_cleanup.inc
-- source myconn.inc
--echo #
--echo # Checking Sending Commands
--echo #
connection master;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE t1 (
command VARCHAR(128) NOT NULL,
warnings INT(4) NOT NULL FLAG=3,
number INT(5) NOT NULL FLAG=1,
message VARCHAR(255) FLAG=2)
ENGINE=CONNECT TABLE_TYPE=MYSQL CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test' OPTION_LIST='Execsrc=1,maxerr=2';
SELECT * FROM t1 WHERE command IN ('Warning','Note',
'drop table if exists t1',
'create table t1 (id int key auto_increment, msg varchar(32) not null)',
"insert into t1(msg) values('One'),(NULL),('Three')",
"insert into t1 values(2,'Deux') on duplicate key update msg = 'Two'",
"insert into t1(message) values('Four'),('Five'),('Six')",
'insert into t1(id) values(NULL)',
"update t1 set msg = 'Four' where id = 4",
'select * from t1');
--echo #
--echo # Checking Using Procedure
--echo #
DROP PROCEDURE IF EXISTS p1;
CREATE PROCEDURE p1(cmd varchar(512))
READS SQL DATA
SELECT * FROM t1 WHERE command IN ('Warning','Note',cmd);
CALL p1('insert into t1(id) values(NULL)');
CALL p1('update t1 set msg = "Five" where id = 5');
DROP PROCEDURE p1;
DROP TABLE t1;
connection slave;
--sorted_result
SELECT * FROM t1;
DROP TABLE t1;
-- source myconn_cleanup.inc
This diff is collapsed.
......@@ -67,3 +67,13 @@ SELECT * FROM v1;
DROP VIEW v1;
DROP TABLE t1;
--replace_result $MTR_SUITE_DIR MTR_SUITE_DIR
--eval CREATE TABLE t1 ENGINE=CONNECT CATFUNC=Columns TABNAME='t1' TABLE_TYPE=ODBC CONNECTION='Driver=SQLite3 ODBC Driver;Database=$Database;NoWCHAR=yes' CHARSET=utf8 DATA_CHARSET=utf8
SELECT * FROM t1;
DROP TABLE t1;
--replace_result $MTR_SUITE_DIR MTR_SUITE_DIR
--eval CREATE TABLE t1 ENGINE=CONNECT CATFUNC=Tables TABNAME='t1' TABLE_TYPE=ODBC CONNECTION='Driver=SQLite3 ODBC Driver;Database=$Database;NoWCHAR=yes' CHARSET=utf8 DATA_CHARSET=utf8
SELECT * FROM t1;
DROP TABLE t1;
......@@ -23,4 +23,17 @@ let $MYSQLD_DATADIR= `select @@datadir`;
SELECT Nom, Fonction FROM contact WHERE Repertoire='ascii';
DROP TABLE contact;
--replace_result $MYSQLD_DATADIR DATADIR
--eval CREATE TABLE t1 ENGINE=CONNECT CATFUNC=Tables TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineXLS;DBQ=$MYSQLD_DATADIR/test/contacts.xls' CHARSET=utf8 DATA_CHARSET=latin1;
--replace_result $MYSQLD_DATADIR DATADIR
SELECT * FROM t1 WHERE Table_name='CONTACT';
DROP TABLE t1;
--replace_result $MYSQLD_DATADIR DATADIR
--eval CREATE TABLE t1 ENGINE=CONNECT CATFUNC=Columns TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineXLS;DBQ=$MYSQLD_DATADIR/test/contacts.xls' CHARSET=utf8 DATA_CHARSET=latin1;
--replace_result $MYSQLD_DATADIR DATADIR
SELECT * FROM t1 WHERE Table_name='CONTACT' AND Column_name IN ('Nom','Fonction');
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/contacts.xls
let $MYSQLD_DATADIR= `select @@datadir`;
CREATE TABLE dir1 (
spath VARCHAR(256) NOT NULL flag=1,
fname VARCHAR(256) NOT NULL,
ftype CHAR(4) NOT NULL,
size DOUBLE(12,0) NOT NULL flag=5
) ENGINE=CONNECT TABLE_TYPE=DIR FILE_NAME='*vec*';
CREATE TABLE t1
(
a INT NOT NULL,
b CHAR(10) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=VEC FILE_NAME='t1vec';
SHOW CREATE TABLE t1;
# Testing SELECT on empty file
--replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
SELECT * FROM t1;
INSERT INTO t1 VALUES (0,'test01'), (1,'test01'), (2,'test02'), (3,'test03');
SELECT * FROM t1;
SELECT a FROM t1;
SELECT b FROM t1;
--replace_result $MYSQLD_DATADIR DATADIR/
SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1vec1
--remove_file $MYSQLD_DATADIR/test/t1vec2
CREATE TABLE t1
(
a INT NOT NULL,
b CHAR(10) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=VEC FILE_NAME='t1vec' MAX_ROWS=10;
SHOW CREATE TABLE t1;
# Testing SELECTs on empty file
--replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
SELECT * FROM t1;
--replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
SELECT a FROM t1;
--replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
SELECT b FROM t1;
INSERT INTO t1 VALUES (0,'test01'), (1,'test01'), (2,'test02'), (3,'test03');
SELECT * FROM t1;
SELECT a FROM t1;
SELECT b FROM t1;
--replace_result $MYSQLD_DATADIR DATADIR/
SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype;
--echo #
--echo # Testing READONLY
--echo #
ALTER TABLE t1 READONLY=yes;
SHOW CREATE TABLE t1;
--error ER_GET_ERRMSG
INSERT INTO t1 VALUES (4,'test04');
--error ER_GET_ERRMSG
UPDATE t1 SET b='test04' WHERE a=3;
--error ER_GET_ERRMSG
DELETE FROM t1 WHERE a=3;
--error ER_GET_ERRMSG
TRUNCATE TABLE t1;
ALTER TABLE t1 READONLY=no;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (4,'test04');
UPDATE t1 SET b='test04a' WHERE a=4;
DELETE FROM t1 WHERE a=0;
SELECT * FROM t1;
TRUNCATE TABLE t1;
SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype;
SELECT * FROM t1;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1vec
--remove_file $MYSQLD_DATADIR/test/t1vec.blk
--echo #
--echo # Clean up
--echo #
DROP TABLE dir1;
let $MYSQLD_DATADIR= `select @@datadir`;
CREATE TABLE dir1 (
spath VARCHAR(256) NOT NULL flag=1,
fname VARCHAR(256) NOT NULL,
ftype CHAR(4) NOT NULL,
size DOUBLE(12,0) NOT NULL flag=5
) ENGINE=CONNECT TABLE_TYPE=DIR FILE_NAME='*vec*';
CREATE TABLE t1
(
a INT NOT NULL,
b CHAR(10) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=VEC FILE_NAME='t1vec';
SHOW CREATE TABLE t1;
# Testing SELECT on empty file
--replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
SELECT * FROM t1;
INSERT INTO t1 VALUES (0,'test01'), (1,'test01'), (2,'test02'), (3,'test03');
SELECT * FROM t1;
SELECT a FROM t1;
SELECT b FROM t1;
--replace_result $MYSQLD_DATADIR DATADIR/
SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1vec1
--remove_file $MYSQLD_DATADIR/test/t1vec2
CREATE TABLE t1
(
a INT NOT NULL,
b CHAR(10) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=VEC FILE_NAME='t1vec' MAX_ROWS=10;
SHOW CREATE TABLE t1;
# Testing SELECTs on empty file
--replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
SELECT * FROM t1;
--replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
SELECT a FROM t1;
--replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
SELECT b FROM t1;
INSERT INTO t1 VALUES (0,'test01'), (1,'test01'), (2,'test02'), (3,'test03');
SELECT * FROM t1;
SELECT a FROM t1;
SELECT b FROM t1;
--replace_result $MYSQLD_DATADIR DATADIR/
SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype;
--echo #
--echo # Testing READONLY
--echo #
ALTER TABLE t1 READONLY=yes;
SHOW CREATE TABLE t1;
--error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES (4,'test04');
--error ER_OPEN_AS_READONLY
UPDATE t1 SET b='test04' WHERE a=3;
--error ER_OPEN_AS_READONLY
DELETE FROM t1 WHERE a=3;
--error ER_OPEN_AS_READONLY
TRUNCATE TABLE t1;
ALTER TABLE t1 READONLY=no;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (4,'test04');
UPDATE t1 SET b='test04a' WHERE a=4;
DELETE FROM t1 WHERE a=0;
SELECT * FROM t1;
TRUNCATE TABLE t1;
SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype;
SELECT * FROM t1;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1vec
--remove_file $MYSQLD_DATADIR/test/t1vec.blk
--echo #
--echo # Clean up
--echo #
DROP TABLE dir1;
......@@ -29,7 +29,7 @@
/************************************************************************/
/* Convert from MySQL type name to PlugDB type number */
/************************************************************************/
int MYSQLtoPLG(char *typname)
int MYSQLtoPLG(char *typname, char *var)
{
int type;
......@@ -56,6 +56,28 @@ int MYSQLtoPLG(char *typname)
else
type = TYPE_ERROR;
if (var) {
// This is to make the difference between CHAR and VARCHAR
if (type == TYPE_STRING && stricmp(typname, "char"))
*var = 'V';
// This is to make the difference between temporal values
if (type == TYPE_DATE) {
if (!stricmp(typname, "date"))
*var = 'D';
else if (!stricmp(typname, "datetime"))
*var = 'A';
else if (!stricmp(typname, "timestamp"))
*var = 'S';
else if (!stricmp(typname, "time"))
*var = 'T';
else if (!stricmp(typname, "year"))
*var = 'Y';
} // endif type
} // endif var
return type;
} // end of MYSQLtoPLG
......@@ -98,14 +120,18 @@ enum enum_field_types PLGtoMYSQL(int type, bool dbf)
/************************************************************************/
/* Convert from PlugDB type to MySQL type name */
/************************************************************************/
const char *PLGtoMYSQLtype(int type, bool dbf)
const char *PLGtoMYSQLtype(int type, bool dbf, char v)
{
switch (type) {
case TYPE_INT: return "INT";
case TYPE_SHORT: return "SMALLINT";
case TYPE_FLOAT: return "DOUBLE";
case TYPE_DATE: return dbf ? "DATE" : "DATETIME";
case TYPE_STRING: return "VARCHAR";
case TYPE_DATE: return dbf ? "DATE" :
(v == 'S') ? "TIMESTAMP" :
(v == 'D') ? "DATE" :
(v == 'T') ? "TIME" :
(v == 'Y') ? "YEAR" : "DATETIME";
case TYPE_STRING: return v ? "VARCHAR" : "CHAR";
case TYPE_BIGINT: return "BIGINT";
case TYPE_TINY: return "TINYINT";
default: return "CHAR(0)";
......
/***********************************************************************/
/* Prototypes of Functions used externally. */
/***********************************************************************/
#ifndef __MYUTIL__H
#define __MYUTIL__H
enum enum_field_types PLGtoMYSQL(int type, bool dbf);
const char *PLGtoMYSQLtype(int type, bool dbf);
int MYSQLtoPLG(char *typname);
const char *PLGtoMYSQLtype(int type, bool dbf, char var = NULL);
int MYSQLtoPLG(char *typname, char *var = NULL);
int MYSQLtoPLG(int mytype);
char *MyDateFmt(int mytype);
char *MyDateFmt(char *typname);
#endif // __MYUTIL__H
/***********************************************************************/
/* ODBC catalog function prototypes. */
/***********************************************************************/
#if defined(PROMPT_OK)
char *ODBCCheckConnection(PGLOBAL g, char *dsn, int cop);
#endif // PROMPT_OK
PQRYRES ODBCDataSources(PGLOBAL g, bool info);
PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *table,
char *colpat, bool info);
......
......@@ -108,16 +108,18 @@ static int GetSQLCType(int type)
/***********************************************************************/
/* TranslateSQLType: translate a SQL Type to a PLG type. */
/***********************************************************************/
int TranslateSQLType(int stp, int prec, int& len)
int TranslateSQLType(int stp, int prec, int& len, char& v)
{
int type;
switch (stp) {
case SQL_CHAR: // 1
case SQL_VARCHAR: // 12
v = 'V';
case SQL_CHAR: // 1
type = TYPE_STRING;
break;
case SQL_LONGVARCHAR: // (-1)
v = 'V';
type = TYPE_STRING;
len = min(abs(len), 255);
break;
......@@ -172,6 +174,7 @@ int TranslateSQLType(int stp, int prec, int& len)
return type;
} // end of TranslateSQLType
#if defined(PROMPT_OK)
/***********************************************************************/
/* ODBCCheckConnection: Check completeness of connection string. */
/***********************************************************************/
......@@ -203,6 +206,7 @@ char *ODBCCheckConnection(PGLOBAL g, char *dsn, int cop)
ocp->Close();
return newdsn; // Return complete connection string
} // end of ODBCCheckConnection
#endif // PROMPT_OK
/***********************************************************************/
/* Allocate the structure used to refer to the result set. */
......@@ -871,7 +875,8 @@ ODBConn::ODBConn(PGLOBAL g, TDBODBC *tdbp)
m_Connect = NULL;
m_Updatable = true;
m_Transact = false;
m_IDQuoteChar = '\'';
m_IDQuoteChar[0] = '"';
m_IDQuoteChar[1] = 0;
//*m_ErrMsg = '\0';
} // end of ODBConn
......@@ -889,7 +894,7 @@ bool ODBConn::Check(RETCODE rc)
{
switch (rc) {
case SQL_SUCCESS_WITH_INFO:
if (trace > 1) {
if (trace) {
DBX x(rc);
x.BuildErrorMessage(this, m_hstmt);
......@@ -1113,7 +1118,7 @@ bool ODBConn::Connect(DWORD Options)
if (hWnd == NULL)
hWnd = GetDesktopWindow();
#else // !WIN32
HWND hWnd = 1;
HWND hWnd = (HWND)1;
#endif // !WIN32
PGLOBAL& g = m_G;
PDBUSER dup = PlgGetUser(g);
......@@ -1230,20 +1235,13 @@ void ODBConn::GetConnectInfo()
SQL_MODE_READ_ONLY);
#endif // 0
// Cache the quote char to use when constructing SQL
char QuoteChar[2];
// Get the quote char to use when constructing SQL
rc = SQLGetInfo(m_hdbc, SQL_IDENTIFIER_QUOTE_CHAR,
QuoteChar, sizeof(QuoteChar), &nResult);
if (Check(rc) && nResult == 1)
m_IDQuoteChar = QuoteChar[0];
else
m_IDQuoteChar = ' ';
m_IDQuoteChar, sizeof(m_IDQuoteChar), &nResult);
if (trace)
htrc("DBMS: %s, Version: %s",
GetStringInfo(SQL_DBMS_NAME), GetStringInfo(SQL_DBMS_VER));
htrc("DBMS: %s, Version: %s, rc=%d\n",
GetStringInfo(SQL_DBMS_NAME), GetStringInfo(SQL_DBMS_VER), rc);
} // end of GetConnectInfo
......@@ -1511,14 +1509,16 @@ int ODBConn::PrepareSQL(char *sql)
hstmt = m_hstmt;
m_hstmt = NULL;
ThrowDBX(MSG(SEQUENCE_ERROR));
} else {
rc = SQLAllocStmt(m_hdbc, &hstmt);
if (!Check(rc))
ThrowDBX(SQL_INVALID_HANDLE, "SQLAllocStmt");
if (m_Tdb->GetAmType() != TYPE_AM_XDBC)
ThrowDBX(MSG(SEQUENCE_ERROR));
} // endif hstmt
} // endif m_hstmt
rc = SQLAllocStmt(m_hdbc, &hstmt);
if (!Check(rc))
ThrowDBX(SQL_INVALID_HANDLE, "SQLAllocStmt");
OnSetOptions(hstmt);
b = true;
......@@ -1565,7 +1565,7 @@ int ODBConn::PrepareSQL(char *sql)
/***********************************************************************/
/* Execute a prepared statement. */
/***********************************************************************/
int ODBConn::ExecuteSQL(bool x)
int ODBConn::ExecuteSQL(void)
{
PGLOBAL& g = m_G;
SWORD ncol = 0;
......@@ -1580,26 +1580,17 @@ int ODBConn::ExecuteSQL(bool x)
if (!Check(rc))
ThrowDBX(rc, "SQLExecute", m_hstmt);
if (!Check(SQLNumResultCols(m_hstmt, &ncol)))
if (!Check(rc = SQLNumResultCols(m_hstmt, &ncol)))
ThrowDBX(rc, "SQLNumResultCols", m_hstmt);
if (ncol) {
if (x) {
afrw = ncol;
strcpy(g->Message, "Result set column number");
} else {
// This should never happen while inserting
strcpy(g->Message, "Logical error while inserting");
} // endif ncol
// This should never happen while inserting
strcpy(g->Message, "Logical error while inserting");
} else {
// Insert, Update or Delete statement
if (!Check(SQLRowCount(m_hstmt, &afrw)))
if (!Check(rc = SQLRowCount(m_hstmt, &afrw)))
ThrowDBX(rc, "SQLRowCount", m_hstmt);
if (x)
strcpy(g->Message, "Affected rows");
} // endif ncol
} catch(DBX *x) {
......@@ -1613,6 +1604,7 @@ int ODBConn::ExecuteSQL(bool x)
m_Transact = false;
} // endif m_Transact
afrw = -1;
} // end try/catch
return (int)afrw;
......@@ -1667,6 +1659,112 @@ bool ODBConn::BindParam(ODBCCOL *colp)
return false;
} // end of BindParam
/***********************************************************************/
/* Execute an SQL command. */
/***********************************************************************/
bool ODBConn::ExecSQLcommand(char *sql)
{
char cmd[16];
bool b, rcd = false;
UINT txn = 0;
PGLOBAL& g = m_G;
SWORD ncol = 0;
SQLLEN afrw;
RETCODE rc;
HSTMT hstmt;
try {
b = FALSE;
// Check whether we should use transaction
if (sscanf(sql, " %15s ", cmd) == 1) {
if (!stricmp(cmd, "INSERT") || !stricmp(cmd, "UPDATE") ||
!stricmp(cmd, "DELETE") || !stricmp(cmd, "REPLACE")) {
// Does the data source support transactions
rc = SQLGetInfo(m_hdbc, SQL_TXN_CAPABLE, &txn, 0, NULL);
if (Check(rc) && txn != SQL_TC_NONE) {
rc = SQLSetConnectAttr(m_hdbc, SQL_ATTR_AUTOCOMMIT,
SQL_AUTOCOMMIT_OFF, SQL_IS_UINTEGER);
if (!Check(rc))
ThrowDBX(SQL_INVALID_HANDLE, "SQLSetConnectAttr");
m_Transact = TRUE;
} // endif txn
} // endif cmd
} // endif sql
// Allocate the statement handle
rc = SQLAllocStmt(m_hdbc, &hstmt);
if (!Check(rc))
ThrowDBX(SQL_INVALID_HANDLE, "SQLAllocStmt");
OnSetOptions(hstmt);
b = true;
if (trace)
htrc("ExecSQLcommand hstmt=%p %.64s\n", hstmt, sql);
// Proceed with command execution
do {
rc = SQLExecDirect(hstmt, (PUCHAR)sql, SQL_NTS);
} while (rc == SQL_STILL_EXECUTING);
if (!Check(rc))
ThrowDBX(rc, "SQLExecDirect", hstmt);
// Check whether this is a query returning a result set
if (!Check(rc = SQLNumResultCols(hstmt, &ncol)))
ThrowDBX(rc, "SQLNumResultCols", hstmt);
if (!ncol) {
if (!Check(SQLRowCount(hstmt, &afrw)))
ThrowDBX(rc, "SQLRowCount", hstmt);
m_Tdb->AftRows = (int)afrw;
strcpy(g->Message, "Affected rows");
} else {
m_Tdb->AftRows = (int)ncol;
strcpy(g->Message, "Result set column number");
} // endif ncol
} catch(DBX *x) {
if (trace)
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
htrc(x->m_ErrMsg[i]);
sprintf(g->Message, "Remote: %s", x->GetErrorMessage(0));
if (b)
SQLCancel(hstmt);
m_Tdb->AftRows = -1;
rcd = true;
} // end try/catch
if (!Check(rc = SQLFreeStmt(hstmt, SQL_CLOSE)))
sprintf(g->Message, "SQLFreeStmt: rc=%d", rc);
if (m_Transact) {
// Terminate the transaction
if (!Check(rc = SQLEndTran(SQL_HANDLE_DBC, m_hdbc,
(rcd) ? SQL_ROLLBACK : SQL_COMMIT)))
sprintf(g->Message, "SQLEndTran: rc=%d", rc);
if (!Check(rc = SQLSetConnectAttr(m_hdbc, SQL_ATTR_AUTOCOMMIT,
(SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_IS_UINTEGER)))
sprintf(g->Message, "SQLSetConnectAttr: rc=%d", rc);
m_Transact = false;
} // endif m_Transact
return rcd;
} // end of ExecSQLcommand
/**************************************************************************/
/* GetMetaData: constructs the result blocks containing the */
/* description of all the columns of an SQL command. */
......
......@@ -127,7 +127,7 @@ class ODBConn : public BLOCK {
// Attributes
public:
char GetQuoteChar(void) {return m_IDQuoteChar;}
char *GetQuoteChar(void) {return m_IDQuoteChar;}
// Database successfully opened?
bool IsOpen(void) {return m_hdbc != SQL_NULL_HDBC;}
PSZ GetStringInfo(ushort infotype);
......@@ -142,8 +142,9 @@ class ODBConn : public BLOCK {
int ExecDirectSQL(char *sql, ODBCCOL *tocols);
int Fetch(void);
int PrepareSQL(char *sql);
int ExecuteSQL(bool x);
int ExecuteSQL(void);
bool BindParam(ODBCCOL *colp);
bool ExecSQLcommand(char *sql);
int GetCatInfo(CATPARM *cap);
bool GetDataSources(PQRYRES qrp);
bool GetDrivers(PQRYRES qrp);
......@@ -183,9 +184,9 @@ class ODBConn : public BLOCK {
DWORD m_QueryTimeout;
DWORD m_UpdateOptions;
DWORD m_RowsetSize;
char m_IDQuoteChar[2];
int m_Catver;
PSZ m_Connect;
bool m_Updatable;
bool m_Transact;
char m_IDQuoteChar;
}; // end of ODBConn class definition
......@@ -106,13 +106,20 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_DOM = 80, /* DOM access method type no */
TYPE_AM_DIR = 90, /* DIR access method type no */
TYPE_AM_ODBC = 100, /* ODBC access method type no */
TYPE_AM_XDBC = 101, /* XDBC access method type no */
TYPE_AM_OEM = 110, /* OEM access method type no */
TYPE_AM_TBL = 115, /* TBL access method type no */
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_XCOL = 124, /* XCOL access method type no */
TYPE_AM_XML = 127, /* XML access method type no */
TYPE_AM_OCCUR = 128, /* OCCUR access method type no */
TYPE_AM_PRX = 129, /* PROXY access method type no */
TYPE_AM_XTB = 130, /* SYS table access method type */
TYPE_AM_BLK = 131, /* BLK access method type no */
TYPE_AM_ZIP = 132, /* ZIP access method type no */
TYPE_AM_ZLIB = 133, /* ZLIB access method type no */
TYPE_AM_MAC = 137, /* MAC table access method type */
TYPE_AM_WMI = 139, /* WMI table access method type */
TYPE_AM_XCL = 140, /* SYS column access method type */
......@@ -123,7 +130,8 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_DMY = 172, /* DMY Dummy tables am type no */
TYPE_AM_SET = 180, /* SET Set tables am type no */
TYPE_AM_MYSQL = 192, /* MYSQL access method type no */
TYPE_AM_CAT = 193, /* Catalog access method type no */
TYPE_AM_MYX = 193, /* MYSQL EXEC access method type */
TYPE_AM_CAT = 195, /* Catalog access method type no */
TYPE_AM_OUT = 200}; /* Output relations (storage) */
enum RECFM {RECFM_NAF = -2, /* Not a file */
......@@ -585,4 +593,4 @@ 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);
bool PushWarning(PGLOBAL, PTDBASE, int level = 1);
......@@ -330,7 +330,7 @@ PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
// Allocate the Value Block that will contain data
if (crp->Length || nonull)
crp->Kdata = AllocValBlock(g, NULL, crp->Type, maxres,
crp->Length, 0, true, blank);
crp->Length, 0, true, blank, false);
else
crp->Kdata = NULL;
......
......@@ -77,7 +77,7 @@ extern "C" int trace;
/* No conversion of block values (check = true). */
/***********************************************************************/
PVBLK AllocValBlock(PGLOBAL, void *, int, int, int len = 0, int prec = 0,
bool check = true, bool blank = false);
bool check = true, bool blank = false, bool un = false);
/* --------------------------- Class DOSDEF -------------------------- */
......
......@@ -524,6 +524,7 @@ bool TDBCAT::OpenDB(PGLOBAL g)
if (Initialize(g))
return true;
Use = USE_OPEN;
return InitCol(g);
} // end of OpenDB
......
This diff is collapsed.
......@@ -20,6 +20,7 @@ typedef class MYSQLC *PMYC;
/***********************************************************************/
class MYSQLDEF : public TABDEF {/* Logical table description */
friend class TDBMYSQL;
friend class TDBMYEXC;
friend class TDBMCL;
friend class ha_connect;
public:
......@@ -52,7 +53,10 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
PSZ Username; /* User logon name */
PSZ Password; /* Password logon info */
PSZ Server; /* PServerID */
PSZ Qrystr; /* The original query */
int Portnumber; /* MySQL port number (0 = default) */
int Mxr; /* Maxerr for an Exec table */
int Quoted; /* Identifier quoting level */
bool Isview; /* TRUE if this table is a MySQL view */
bool Bind; /* Use prepared statement on insert */
bool Delayed; /* Delayed insert */
......@@ -102,9 +106,11 @@ class TDBMYSQL : public TDBASE {
// Internal functions
bool MakeSelect(PGLOBAL g);
bool MakeInsert(PGLOBAL g);
//bool MakeUpdate(PGLOBAL g);
//bool MakeDelete(PGLOBAL g);
int BindColumns(PGLOBAL g);
int MakeCommand(PGLOBAL g);
//int MakeUpdate(PGLOBAL g);
//int MakeDelete(PGLOBAL g);
int SendCommand(PGLOBAL g);
// Members
MYSQLC Myc; // MySQL connection class
......@@ -118,6 +124,7 @@ class TDBMYSQL : public TDBASE {
char *Server; // The server ID
char *Query; // Points to SQL query
char *Qbuf; // Used for not prepared insert
char *Qrystr; // The original query
bool Fetched; // True when fetch was done
bool Isview; // True if this table is a MySQL view
bool Prep; // Use prepared statement on insert
......@@ -127,6 +134,7 @@ class TDBMYSQL : public TDBASE {
int N; // The current table index
int Port; // MySQL port number (0 = default)
int Nparm; // The number of statement parameters
int Quoted; // The identifier quoting level
}; // end of class TDBMYSQL
/***********************************************************************/
......@@ -167,13 +175,12 @@ class MYSQLCOL : public COLBLK {
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;}
// Constructors
TDBMYEXC(PMYDEF tdp);
TDBMYEXC(PGLOBAL g, PTDBMYX tdbp);
// Implementation
//virtual AMT GetAmType(void) {return TYPE_AM_MYSQL;}
virtual AMT GetAmType(void) {return TYPE_AM_MYX;}
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMYEXC(g, this);}
// Methods
......@@ -203,13 +210,20 @@ class TDBMYEXC : public TDBMYSQL {
protected:
// Internal functions
char *MakeCMD(PGLOBAL g);
PCMD MakeCMD(PGLOBAL g);
//bool MakeSelect(PGLOBAL g);
//bool MakeInsert(PGLOBAL g);
//int BindColumns(PGLOBAL g);
// Members
PCMD Cmdlist; // The commands to execute
char *Cmdcol; // The name of the Xsrc command column
bool Shw; // Show warnings
bool Havew; // True when processing warnings
bool Isw; // True for warning lines
int Warnings; // Warnings number
int Mxr; // Maximum errors before closing
int Nerr; // Number of errors so far
}; // end of class TDBMYEXC
/***********************************************************************/
......
......@@ -495,6 +495,7 @@ bool TDBOCCUR::OpenDB(PGLOBAL g)
if (Tdbp->OpenDB(g))
return TRUE;
Use = USE_OPEN;
return ViewColumnList(g);
} // end of OpenDB
......
......@@ -3,8 +3,6 @@
#include "tabutil.h"
#define TYPE_AM_OCCUR (AMT)128
typedef class OCCURDEF *POCCURDEF;
typedef class TDBOCCUR *PTDBOCCUR;
typedef class OCCURCOL *POCCURCOL;
......
This diff is collapsed.
......@@ -34,7 +34,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
PSZ GetTabowner(void) {return Tabowner;}
PSZ GetTabqual(void) {return Tabqual;}
PSZ GetSrcdef(void) {return Srcdef;}
PSZ GetQchar(void) {return (Qchar && *Qchar) ? Qchar : NULL;}
int GetQuoted(void) {return Quoted;}
int GetCatver(void) {return Catver;}
int GetOptions(void) {return Options;}
......@@ -50,8 +50,11 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
PSZ Tabqual; /* External table qualifier */
PSZ Srcdef; /* The source table SQL definition */
PSZ Qchar; /* Identifier quoting character */
PSZ Qrystr; /* The original query */
int Catver; /* ODBC version for catalog functions */
int Options; /* Open connection options */
int Quoted; /* Identifier quoting level */
int Mxr; /* Maxerr for an Exec table */
bool Xsrc; /* Execution type */
}; // end of ODBCDEF
......@@ -96,13 +99,14 @@ class TDBODBC : public TDBASE {
protected:
// Internal functions
int Decode(char *utf, char *buf, size_t n);
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 MakeDelete(PGLOBAL g);
char *MakeInsert(PGLOBAL g);
char *MakeCommand(PGLOBAL g);
//bool MakeFilter(PGLOBAL g, bool c);
bool BindParameters(PGLOBAL g);
//char *MakeUpdate(PGLOBAL g);
//char *MakeDelete(PGLOBAL g);
// Members
ODBConn *Ocp; // Points to an ODBC connection class
......@@ -118,7 +122,9 @@ class TDBODBC : public TDBASE {
char *Quote; // The identifier quoting character
char *MulConn; // Used for multiple ODBC tables
char *DBQ; // The address part of Connect string
char *Qrystr; // The original query
int Options; // Connect options
int Quoted; // The identifier quoting level
int Fpos; // Position of last read record
int AftRows; // The number of affected rows
int Rows; // Rowset size
......@@ -179,12 +185,12 @@ 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;}
// Constructors
TDBXDBC(PODEF tdp = NULL);
TDBXDBC(PTDBXDBC tdbp);
// Implementation
//virtual AMT GetAmType(void) {return TYPE_AM_ODBC;}
virtual AMT GetAmType(void) {return TYPE_AM_XDBC;}
virtual PTDB Duplicate(PGLOBAL g)
{return (PTDB)new(g) TDBXDBC(this);}
......@@ -204,16 +210,19 @@ class TDBXDBC : public TDBODBC {
virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g);
//virtual int DeleteDB(PGLOBAL g, int irc);
virtual int DeleteDB(PGLOBAL g, int irc);
//virtual void CloseDB(PGLOBAL g);
protected:
// Internal functions
char *MakeCMD(PGLOBAL g);
PCMD MakeCMD(PGLOBAL g);
//bool BindParameters(PGLOBAL g);
// Members
PCMD Cmdlist; // The commands to execute
char *Cmdcol; // The name of the Xsrc command column
int Mxr; // Maximum errors before closing
int Nerr; // Number of errors so far
}; // end of class TDBXDBC
/***********************************************************************/
......
......@@ -607,6 +607,8 @@ bool TDBPIVOT::OpenDB(PGLOBAL g)
if (Tdbp->OpenDB(g))
return TRUE;
Use = USE_OPEN; // Do it now in case we are recursively called
/*********************************************************************/
/* Make all required pivot columns for object views. */
/*********************************************************************/
......
......@@ -295,15 +295,18 @@ bool TDBTBL::InitTableList(PGLOBAL g)
/***********************************************************************/
bool TDBTBL::TestFil(PGLOBAL g, PFIL filp, PTABLE tabp)
{
char *fil, op[8], tn[NAME_LEN];
char *body, *fil, op[8], tn[NAME_LEN];
bool neg;
if (!filp)
return TRUE;
else if (strstr(filp, " OR ") || strstr(filp, " AND "))
else
body = filp->Body;
if (strstr(body, " OR ") || strstr(body, " AND "))
return TRUE; // Not handled yet
else
fil = filp + (*filp == '(' ? 1 : 0);
fil = body + (*body == '(' ? 1 : 0);
if (sscanf(fil, "TABID %s", op) != 1)
return TRUE; // ignore invalid filter
......
......@@ -495,6 +495,7 @@ bool TDBPRX::OpenDB(PGLOBAL g)
if (Tdbp->OpenDB(g))
return TRUE;
Use = USE_OPEN;
return FALSE;
} // end of OpenDB
......
......@@ -6,8 +6,6 @@
//#include "tabtbl.h"
#define TYPE_AM_PRX (AMT)129
typedef class PRXDEF *PPRXDEF;
typedef class TDBPRX *PTDBPRX;
typedef class XXLCOL *PXXLCOL;
......
......@@ -81,7 +81,7 @@ char *strerror(int num);
/* Conversion of block values allowed conditionally for insert only. */
/***********************************************************************/
PVBLK AllocValBlock(PGLOBAL, void *, int, int, int, int,
bool check = true, bool blank = true);
bool check = true, bool blank = true, bool un = false);
/* --------------------------- Class VCTDEF -------------------------- */
......
......@@ -480,18 +480,19 @@ bool TDBWMI::Initialize(PGLOBAL g)
/***********************************************************************/
void TDBWMI::DoubleSlash(PGLOBAL g)
{
if (To_Filter && strchr(To_Filter, '\\')) {
char *buf = (char*)PlugSubAlloc(g, NULL, strlen(To_Filter) * 2);
if (To_Filter && strchr(To_Filter->Body, '\\')) {
char *body = To_Filter->Body;
char *buf = (char*)PlugSubAlloc(g, NULL, strlen(body) * 2);
int i = 0, k = 0;
do {
if (To_Filter[i] == '\\')
if (body[i] == '\\')
buf[k++] = '\\';
buf[k++] = To_Filter[i];
} while (To_Filter[i++]);
buf[k++] = body[i];
} while (body[i++]);
To_Filter = buf;
To_Filter->Body = buf;
} // endif To_Filter
} // end of DoubleSlash
......@@ -539,13 +540,13 @@ char *TDBWMI::MakeWQL(PGLOBAL g)
// Below 14 is length of 'select ' + length of ' from ' + 1
len = (strlen(colist) + strlen(Wclass) + 14);
len += (To_Filter ? strlen(To_Filter) + 7 : 0);
len += (To_Filter ? strlen(To_Filter->Body) + 7 : 0);
wql = (char*)PlugSubAlloc(g, NULL, len);
strcat(strcat(strcpy(wql, "SELECT "), colist), " FROM ");
strcat(wql, Wclass);
if (To_Filter)
strcat(strcat(wql, " WHERE "), To_Filter);
strcat(strcat(wql, " WHERE "), To_Filter->Body);
return wql;
} // end of MakeWQL
......@@ -666,6 +667,8 @@ bool TDBWMI::OpenDB(PGLOBAL g)
} else
DoubleSlash(g);
Use = USE_OPEN; // Do it now in case we are recursively called
/*********************************************************************/
/* Initialize the WMI processing. */
/*********************************************************************/
......
......@@ -193,6 +193,7 @@ bool TDBXCL::OpenDB(PGLOBAL g)
if (Tdbp->OpenDB(g))
return TRUE;
Use = USE_OPEN;
return FALSE;
} // end of OpenDB
......
......@@ -3,8 +3,6 @@
#include "tabutil.h"
#define TYPE_AM_XCOL (AMT)124
typedef class XCLDEF *PXCLDEF;
typedef class TDBXCL *PTDBXCL;
typedef class XCLCOL *PXCLCOL;
......
This diff is collapsed.
/*************** Valblk H Declares Source Code File (.H) ***************/
/* Name: VALBLK.H Version 1.9 */
/* Name: VALBLK.H Version 2.0 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2005-2013 */
/* */
......@@ -18,8 +18,9 @@
/***********************************************************************/
/* Utility used to allocate value blocks. */
/***********************************************************************/
DllExport PVBLK AllocValBlock(PGLOBAL, void*, int, int, int, int, bool, bool);
const char *GetFmt(int type);
DllExport PVBLK AllocValBlock(PGLOBAL, void*, int, int, int, int,
bool, bool, bool);
const char *GetFmt(int type, bool un = false);
/***********************************************************************/
/* Class VALBLK represent a base class for variable blocks. */
......@@ -28,7 +29,7 @@ class VALBLK : public BLOCK {
//friend void SemColData(PGLOBAL g, PSEM semp);
public:
// Constructors
VALBLK(void *mp, int type, int nval);
VALBLK(void *mp, int type, int nval, bool un = false);
// Implementation
int GetNval(void) {return Nval;}
......@@ -48,10 +49,14 @@ class VALBLK : public BLOCK {
virtual int GetVlen(void) = 0;
virtual PSZ GetCharValue(int n);
virtual short GetShortValue(int n) = 0;
virtual ushort GetUShortValue(int n) = 0;
virtual int GetIntValue(int n) = 0;
virtual uint GetUIntValue(int n) = 0;
virtual longlong GetBigintValue(int n) = 0;
virtual ulonglong GetUBigintValue(int n) = 0;
virtual double GetFloatValue(int n) = 0;
virtual char GetTinyValue(int n) = 0;
virtual uchar GetUTinyValue(int n) = 0;
virtual void ReAlloc(void *mp, int n) {Blkp = mp; Nval = n;}
virtual void Reset(int n) = 0;
virtual bool SetFormat(PGLOBAL g, PSZ fmt, int len, int year = 0);
......@@ -60,10 +65,14 @@ class VALBLK : public BLOCK {
// Methods
virtual void SetValue(short sval, int n) {assert(false);}
virtual void SetValue(ushort sval, int n) {assert(false);}
virtual void SetValue(int lval, int n) {assert(false);}
virtual void SetValue(uint lval, int n) {assert(false);}
virtual void SetValue(longlong lval, int n) {assert(false);}
virtual void SetValue(ulonglong lval, int n) {assert(false);}
virtual void SetValue(double fval, int n) {assert(false);}
virtual void SetValue(char cval, int n) {assert(false);}
virtual void SetValue(uchar cval, int n) {assert(false);}
virtual void SetValue(PSZ sp, int n) {assert(false);}
virtual void SetValue(char *sp, uint len, int n) {assert(false);}
virtual void SetValue(PVAL valp, int n) = 0;
......@@ -94,6 +103,7 @@ class VALBLK : public BLOCK {
void *Blkp; // To value block
bool Check; // If true SetValue types must match
bool Nullable; // True if values can be null
bool Unsigned; // True if values are unsigned
int Type; // Type of individual values
int Nval; // Max number of values in block
int Prec; // Precision of float values
......@@ -106,18 +116,22 @@ template <class TYPE>
class TYPBLK : public VALBLK {
public:
// Constructors
TYPBLK(void *mp, int size, int type);
TYPBLK(void *mp, int size, int prec, int type);
TYPBLK(void *mp, int size, int type, int prec = 0, bool un = false);
//TYPBLK(void *mp, int size, int prec, int type);
// Implementation
virtual void Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return sizeof(TYPE);}
//virtual PSZ GetCharValue(int n);
virtual short GetShortValue(int n) {return (short)Typp[n];}
virtual ushort GetUShortValue(int n) {return (ushort)Typp[n];}
virtual int GetIntValue(int n) {return (int)Typp[n];}
virtual uint GetUIntValue(int n) {return (uint)Typp[n];}
virtual longlong GetBigintValue(int n) {return (longlong)Typp[n];}
virtual ulonglong GetUBigintValue(int n) {return (ulonglong)Typp[n];}
virtual double GetFloatValue(int n) {return (double)Typp[n];}
virtual char GetTinyValue(int n) {return (char)Typp[n];}
virtual uchar GetUTinyValue(int n) {return (uchar)Typp[n];}
virtual void Reset(int n) {Typp[n] = 0;}
// Methods
......@@ -125,14 +139,22 @@ class TYPBLK : public VALBLK {
virtual void SetValue(char *sp, uint len, int n);
virtual void SetValue(short sval, int n)
{Typp[n] = (TYPE)sval; SetNull(n, false);}
virtual void SetValue(ushort sval, int n)
{Typp[n] = (TYPE)sval; SetNull(n, false);}
virtual void SetValue(int lval, int n)
{Typp[n] = (TYPE)lval; SetNull(n, false);}
virtual void SetValue(uint lval, int n)
{Typp[n] = (TYPE)lval; SetNull(n, false);}
virtual void SetValue(longlong lval, int n)
{Typp[n] = (TYPE)lval; SetNull(n, false);}
virtual void SetValue(ulonglong lval, int n)
{Typp[n] = (TYPE)lval; SetNull(n, false);}
virtual void SetValue(double fval, int n)
{Typp[n] = (TYPE)fval; SetNull(n, false);}
virtual void SetValue(char cval, int n)
{Typp[n] = (TYPE)cval; SetNull(n, false);}
virtual void SetValue(uchar cval, int n)
{Typp[n] = (TYPE)cval; SetNull(n, false);}
virtual void SetValue(PVAL valp, int n);
virtual void SetValue(PVBLK pv, int n1, int n2);
//virtual void SetValues(PVBLK pv, int k, int n);
......@@ -168,10 +190,14 @@ class CHRBLK : public VALBLK {
virtual int GetVlen(void) {return Long;}
virtual PSZ GetCharValue(int n);
virtual short GetShortValue(int n);
virtual ushort GetUShortValue(int n);
virtual int GetIntValue(int n);
virtual uint GetUIntValue(int n);
virtual longlong GetBigintValue(int n);
virtual ulonglong GetUBigintValue(int n);
virtual double GetFloatValue(int n);
virtual char GetTinyValue(int n);
virtual uchar GetUTinyValue(int n);
virtual void Reset(int n);
virtual void SetPrec(int p) {Ci = (p != 0);}
virtual bool IsCi(void) {return Ci;}
......@@ -217,10 +243,14 @@ class STRBLK : public VALBLK {
virtual int GetVlen(void) {return sizeof(PSZ);}
virtual PSZ GetCharValue(int n) {return Strp[n];}
virtual short GetShortValue(int n) {return (short)atoi(Strp[n]);}
virtual ushort GetUShortValue(int n) {return (ushort)atoi(Strp[n]);}
virtual int GetIntValue(int n) {return atol(Strp[n]);}
virtual uint GetUIntValue(int n) {return (unsigned)atol(Strp[n]);}
virtual longlong GetBigintValue(int n) {return atoll(Strp[n]);}
virtual ulonglong GetUBigintValue(int n) {return (unsigned)atoll(Strp[n]);}
virtual double GetFloatValue(int n) {return atof(Strp[n]);}
virtual char GetTinyValue(int n) {return (char)atoi(Strp[n]);}
virtual uchar GetUTinyValue(int n) {return (uchar)atoi(Strp[n]);}
virtual void Reset(int n) {Strp[n] = NULL;}
// Methods
......
This diff is collapsed.
This diff is collapsed.
......@@ -66,7 +66,7 @@ extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */
/* to have rows filled by blanks to be compatible with QRY blocks. */
/***********************************************************************/
PVBLK AllocValBlock(PGLOBAL, void *, int, int, int, int,
bool check = true, bool blank = true);
bool check = true, bool blank = true, bool un = false);
/***********************************************************************/
/* Check whether we have to create/update permanent indexes. */
......@@ -2919,7 +2919,7 @@ void KXYCOL::SetValue(PCOL colp, int i)
assert (Kblp != NULL);
#endif
Kblp->SetValue(colp->GetValue(), (int)i);
Kblp->SetValue(colp->GetValue(), i);
} // end of SetValue
/***********************************************************************/
......@@ -2970,7 +2970,7 @@ void KXYCOL::FillValue(PVAL valp)
int KXYCOL::Compare(int i1, int i2)
{
// Do the actual comparison between values.
register int k = (int)Kblp->CompVal((int)i1, (int)i2);
register int k = Kblp->CompVal(i1, i2);
#ifdef DEBUG2
htrc("Compare done result=%d\n", k);
......@@ -2991,7 +2991,7 @@ int KXYCOL::CompVal(int i)
htrc("Compare done result=%d\n", k);
return k;
#endif
return (int)Kblp->CompVal(Valp, (int)i);
return Kblp->CompVal(Valp, i);
} // end of CompVal
/***********************************************************************/
......@@ -3000,7 +3000,7 @@ int KXYCOL::CompVal(int i)
int KXYCOL::CompBval(int i)
{
// Do the actual comparison between key values.
return (int)Blkp->CompVal(Valp, (int)i);
return Blkp->CompVal(Valp, i);
} // end of CompBval
/***********************************************************************/
......
This diff is collapsed.
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