Commit eca84a9b authored by Olivier Bertrand's avatar Olivier Bertrand

- Add (limited) support for UPDATE and DELETE to ODBC tables

  (also provide the possibility to issue NOTE warnings)

modified:
  storage/connect/connect.cc
  storage/connect/ha_connect.cc
  storage/connect/ha_connect.h
  storage/connect/odbconn.cpp
  storage/connect/odbconn.h
  storage/connect/plgdbsem.h
  storage/connect/tabodbc.cpp
  storage/connect/tabodbc.h

- Return proper error number when modifying read only tables

modified:
  storage/connect/connect.cc
  storage/connect/ha_connect.cc
  storage/connect/ha_connect.h
  storage/connect/mysql-test/connect/r/bin.result
  storage/connect/mysql-test/connect/r/csv.result
  storage/connect/mysql-test/connect/r/dbf.result
  storage/connect/mysql-test/connect/r/fix.result
  storage/connect/mysql-test/connect/r/ini.result
  storage/connect/mysql-test/connect/r/vec.result
  storage/connect/mysql-test/connect/t/bin.test
  storage/connect/mysql-test/connect/t/csv.test
  storage/connect/mysql-test/connect/t/dbf.test
  storage/connect/mysql-test/connect/t/fix.test
  storage/connect/mysql-test/connect/t/ini.test
  storage/connect/mysql-test/connect/t/vec.test
  storage/connect/table.cpp
  storage/connect/taboccur.cpp
  storage/connect/tabpivot.cpp
  storage/connect/tabutil.cpp
  storage/connect/tabwmi.cpp
  storage/connect/tabxcl.cpp
parent e5c589a8
......@@ -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--;
......
......@@ -258,17 +258,21 @@ ha_create_table_option connect_field_option_list[]=
/***********************************************************************/
/* Push G->Message as a MySQL warning. */
/***********************************************************************/
bool PushWarning(PGLOBAL g, PTDBASE tdbp)
bool PushWarning(PGLOBAL g, PTDBASE tdbp, int level)
{
PHC phc;
THD *thd;
MYCAT *cat= (MYCAT*)tdbp->GetDef()->GetCat();
Sql_condition::enum_warning_level wlvl;
if (!cat || !(phc= cat->GetHandler()) || !phc->GetTable() ||
!(thd= (phc->GetTable())->in_use))
return true;
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
//push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
wlvl= (Sql_condition::enum_warning_level)level;
push_warning(thd, wlvl, 0, g->Message);
return false;
} // end of PushWarning
......@@ -1098,19 +1102,20 @@ PTDB ha_connect::GetTDB(PGLOBAL g)
&& (tdbp->GetMode() == xmod
|| tdbp->GetAmType() == TYPE_AM_XML)) {
tp= tdbp;
tp->SetMode(xmod);
// tp->SetMode(xmod);
} else if ((tp= CntGetTDB(g, table_name, xmod, this)))
valid_query_id= xp->last_query_id;
else
printf("GetTDB: %s\n", g->Message);
tp->SetMode(xmod);
return tp;
} // end of GetTDB
/****************************************************************************/
/* Open a CONNECT table, restricting column list if cols is true. */
/****************************************************************************/
bool ha_connect::OpenTable(PGLOBAL g, bool del)
int ha_connect::OpenTable(PGLOBAL g, bool del)
{
bool rc= false;
char *c1= NULL, *c2=NULL;
......@@ -1118,11 +1123,11 @@ bool ha_connect::OpenTable(PGLOBAL g, bool del)
// Double test to be on the safe side
if (!g || !table) {
printf("OpenTable logical error; g=%p table=%p\n", g, table);
return true;
return HA_ERR_INITIALIZATION;
} // endif g
if (!(tdbp= GetTDB(g)))
return true;
return RC_FX;
else if (tdbp->IsReadOnly())
switch (xmod) {
case MODE_WRITE:
......@@ -1130,7 +1135,7 @@ bool ha_connect::OpenTable(PGLOBAL g, bool del)
case MODE_UPDATE:
case MODE_DELETE:
strcpy(g->Message, MSG(READ_ONLY));
return true;
return HA_ERR_TABLE_READONLY;
default:
break;
} // endswitch xmode
......@@ -1207,7 +1212,7 @@ bool ha_connect::OpenTable(PGLOBAL g, bool del)
valid_info= false;
} // endif rc
return rc;
return (rc) ? HA_ERR_INITIALIZATION : 0;
} // end of OpenTable
......@@ -2006,14 +2011,8 @@ int ha_connect::write_row(uchar *buf)
if (IsOpened())
CloseTable(g);
if (OpenTable(g)) {
if (strstr(g->Message, "read only"))
rc= HA_ERR_TABLE_READONLY;
else
rc= HA_ERR_INITIALIZATION;
if ((rc= OpenTable(g)))
DBUG_RETURN(rc);
} // endif tdbp
} // endif isopened
......@@ -2378,6 +2377,7 @@ int ha_connect::index_next_same(uchar *buf, const uchar *key, uint keylen)
*/
int ha_connect::rnd_init(bool scan)
{
int rc;
PGLOBAL g= ((table && table->in_use) ? GetPlug(table->in_use, xp) :
(xp) ? xp->g : NULL);
DBUG_ENTER("ha_connect::rnd_init");
......@@ -2398,8 +2398,8 @@ int ha_connect::rnd_init(bool scan)
if (xmod == MODE_UPDATE)
bitmap_union(table->read_set, table->write_set);
if (OpenTable(g, xmod == MODE_DELETE))
DBUG_RETURN(HA_ERR_INITIALIZATION);
if ((rc= OpenTable(g, xmod == MODE_DELETE)))
DBUG_RETURN(rc);
xp->nrd= xp->fnd= xp->nfd= 0;
xp->tb1= my_interval_timer();
......@@ -2610,7 +2610,6 @@ int ha_connect::info(uint flag)
xp->CheckCleanup();
} // endif xmod
// tdbp= OpenTable(g, xmod == MODE_DELETE);
tdbp= GetTDB(g);
} // endif tdbp
......@@ -2705,18 +2704,19 @@ int ha_connect::delete_all_rows()
PGLOBAL g= xp->g;
DBUG_ENTER("ha_connect::delete_all_rows");
if (tdbp && tdbp->GetAmType() != TYPE_AM_XML)
if (tdbp && tdbp->GetUse() == USE_OPEN &&
tdbp->GetAmType() != TYPE_AM_XML &&
((PTDBASE)tdbp)->GetFtype() != RECFM_NAF)
// Close and reopen the table so it will be deleted
rc= CloseTable(g);
if (!(OpenTable(g))) {
if (!(rc= OpenTable(g))) {
if (CntDeleteRow(g, tdbp, true)) {
printf("%s\n", g->Message);
rc= HA_ERR_INTERNAL_ERROR;
} // endif
} else
rc= HA_ERR_INITIALIZATION;
} // endif rc
DBUG_RETURN(rc);
} // end of delete_all_rows
......
......@@ -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);
......
......@@ -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
......
......@@ -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
......
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/people.csv $MYSQLD_DATADIR/test/people.csv
SET NAMES utf8;
--echo #
--echo # Testing errors
--echo #
CREATE TABLE t1
(
ID INT NOT NULL
) Engine=CONNECT TABLE_TYPE=CSV 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
(
name CHAR(12) NOT NULL,
birth DATE NOT NULL DATE_FORMAT='DD/MM/YY',
children SMALLINT(2) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
HEADER=1 SEP_CHAR=';' QUOTED=1;
SELECT * FROM t1;
INSERT INTO t1 VALUES ('RONALD','1980-02-26',4);
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/people.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/people.csv'),'\r\n','\n');
--echo #
--echo # Testing READONLY tables
--echo #
CREATE TABLE t1
(
name CHAR(12) NOT NULL,
birth DATE NOT NULL DATE_FORMAT='DD/MM/YY',
children SMALLINT(2) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
HEADER=1 SEP_CHAR=';' QUOTED=1 READONLY=yes;
--error ER_GET_ERRMSG
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
--error ER_GET_ERRMSG
UPDATE t1 SET children=6 WHERE name='BILL';
--error ER_GET_ERRMSG
DELETE FROM t1 WHERE name='BILL';
--error ER_GET_ERRMSG
TRUNCATE TABLE t1;
SELECT * FROM t1;
ALTER TABLE t1 READONLY=no;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
SELECT * FROM t1;
ALTER TABLE t1 READONLY=1;
SHOW CREATE TABLE t1;
--error ER_GET_ERRMSG
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Testing that the underlying file is created
--echo #
CREATE TABLE t1
(
c1 CHAR(12) NOT NULL,
c2 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='tmp.csv'
HEADER=1 SEP_CHAR=',' QUOTED=1;
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.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/tmp.csv'),'\r\n','\n');
--echo #
--echo # Creating a CSV table from a MyISAM table
--echo #
CREATE TABLE t1 (a VARCHAR(10) NOT NULL, b INT NOT NULL) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('test1',1), ('test2',2);
CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t2.csv'
AS SELECT * FROM t1;
SELECT * FROM t2;
DROP TABLE t2;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t2.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t2.csv'),'\r\n','\n');
--remove_file $MYSQLD_DATADIR/test/t2.csv
--echo #
--echo # Testing international data
--echo #
CREATE TABLE t1
(
c1 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
CHARSET=utf8;
INSERT INTO t1 VALUES ('á');
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv
CREATE TABLE t1
(
c1 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
CHARSET=utf8 DATA_CHARSET=latin1;
INSERT INTO t1 VALUES ('á');
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv
CREATE TABLE t1
(
c1 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv';
INSERT INTO t1 VALUES ('á');
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv
CREATE TABLE t1
(
c1 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
CHARSET=latin1;
INSERT INTO t1 VALUES ('á');
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv
CREATE TABLE t1
(
c1 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
CHARSET=latin1 DATA_CHARSET=utf8;
INSERT INTO t1 VALUES ('á');
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv
CREATE TABLE t1
(
c1 CHAR(12) CHARACTER SET latin1 NOT NULL,
c2 CHAR(12) CHARACTER SET utf8 NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv';
INSERT INTO t1 VALUES ('á','á');
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv
#
# Clean up
#
--remove_file $MYSQLD_DATADIR/test/people.csv
--remove_file $MYSQLD_DATADIR/test/tmp.csv
let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/people.csv $MYSQLD_DATADIR/test/people.csv
SET NAMES utf8;
--echo #
--echo # Testing errors
--echo #
CREATE TABLE t1
(
ID INT NOT NULL
) Engine=CONNECT TABLE_TYPE=CSV 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
(
name CHAR(12) NOT NULL,
birth DATE NOT NULL DATE_FORMAT='DD/MM/YY',
children SMALLINT(2) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
HEADER=1 SEP_CHAR=';' QUOTED=1;
SELECT * FROM t1;
INSERT INTO t1 VALUES ('RONALD','1980-02-26',4);
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/people.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/people.csv'),'\r\n','\n');
--echo #
--echo # Testing READONLY tables
--echo #
CREATE TABLE t1
(
name CHAR(12) NOT NULL,
birth DATE NOT NULL DATE_FORMAT='DD/MM/YY',
children SMALLINT(2) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
HEADER=1 SEP_CHAR=';' QUOTED=1 READONLY=yes;
--error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
--error ER_OPEN_AS_READONLY
UPDATE t1 SET children=6 WHERE name='BILL';
--error ER_OPEN_AS_READONLY
DELETE FROM t1 WHERE name='BILL';
--error ER_OPEN_AS_READONLY
TRUNCATE TABLE t1;
SELECT * FROM t1;
ALTER TABLE t1 READONLY=no;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
SELECT * FROM t1;
ALTER TABLE t1 READONLY=1;
SHOW CREATE TABLE t1;
--error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Testing that the underlying file is created
--echo #
CREATE TABLE t1
(
c1 CHAR(12) NOT NULL,
c2 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='tmp.csv'
HEADER=1 SEP_CHAR=',' QUOTED=1;
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.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/tmp.csv'),'\r\n','\n');
--echo #
--echo # Creating a CSV table from a MyISAM table
--echo #
CREATE TABLE t1 (a VARCHAR(10) NOT NULL, b INT NOT NULL) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('test1',1), ('test2',2);
CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t2.csv'
AS SELECT * FROM t1;
SELECT * FROM t2;
DROP TABLE t2;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t2.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t2.csv'),'\r\n','\n');
--remove_file $MYSQLD_DATADIR/test/t2.csv
--echo #
--echo # Testing international data
--echo #
CREATE TABLE t1
(
c1 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
CHARSET=utf8;
INSERT INTO t1 VALUES ('á');
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv
CREATE TABLE t1
(
c1 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
CHARSET=utf8 DATA_CHARSET=latin1;
INSERT INTO t1 VALUES ('á');
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv
CREATE TABLE t1
(
c1 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv';
INSERT INTO t1 VALUES ('á');
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv
CREATE TABLE t1
(
c1 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
CHARSET=latin1;
INSERT INTO t1 VALUES ('á');
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv
CREATE TABLE t1
(
c1 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
CHARSET=latin1 DATA_CHARSET=utf8;
INSERT INTO t1 VALUES ('á');
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv
CREATE TABLE t1
(
c1 CHAR(12) CHARACTER SET latin1 NOT NULL,
c2 CHAR(12) CHARACTER SET utf8 NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv';
INSERT INTO t1 VALUES ('á','á');
SELECT * FROM t1;
DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv
#
# Clean up
#
--remove_file $MYSQLD_DATADIR/test/people.csv
--remove_file $MYSQLD_DATADIR/test/tmp.csv
let $MYSQLD_DATADIR= `select @@datadir`;
--echo #
--echo # Testing errors
--echo #
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
SHOW CREATE TABLE t1;
--replace_regex /on .*test.t1.dbf/on DATADIR\/test\/t1.dbf/
SELECT * FROM t1;
DROP TABLE t1;
--replace_regex /Cannot open .*test.t1.dbf/Cannot open DATADIR\/test\/t1.dbf/
--error ER_UNKNOWN_ERROR
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--replace_regex /Cannot open .*test.t1.dbf/Cannot open DATADIR\/test\/t1.dbf/
SHOW WARNINGS;
DELIMITER //;
CREATE PROCEDURE test.dbf_field(in fieldno INT, in content BLOB) DETERMINISTIC
BEGIN
SELECT '---';
SELECT fieldno AS `FieldN`;
SELECT TRIM(TRAILING 0x00 FROM LEFT(content, 10)) AS `Name`;
SELECT SUBSTRING(content, 12, 1) AS `Type`;
SELECT CONV(HEX(REVERSE(SUBSTRING(content,13,4))),16,10) AS `Offset`;
SELECT CONV(HEX(REVERSE(SUBSTRING(content,17,1))),16,10) AS `Length`;
SELECT CONV(HEX(REVERSE(SUBSTRING(content,18,1))),16,10) AS `Dec`;
SELECT HEX(REVERSE(SUBSTRING(content,19,1))) AS `Flags`;
-- SELECT CONV(HEX(REVERSE(SUBSTRING(content,20,4))),16,10) AS `Next`;
-- SELECT CONV(HEX(REVERSE(SUBSTRING(content,24,4))),16,10) AS `Step`;
END//
CREATE PROCEDURE test.dbf_header(in fname VARCHAR(1024)) DETERMINISTIC
BEGIN
DECLARE content BLOB;
DECLARE offset INT;
DECLARE fieldno INT;
SELECT '--------';
SELECT LOAD_FILE(fname) INTO content;
SELECT LENGTH(content) AS FileSize;
SELECT HEX(LEFT(content, 1)) AS DBF_Version;
SELECT CONV(HEX(REVERSE(SUBSTRING(content,5,4))),16,10) AS NRecords;
SELECT CONV(HEX(REVERSE(SUBSTRING(content,9,2))),16,10) AS FirstRecPos;
SELECT CONV(HEX(REVERSE(SUBSTRING(content,11,2))),16,10) AS RecLength;
SELECT HEX(REVERSE(SUBSTRING(content,29,2))) AS TableFlags;
SELECT HEX(REVERSE(SUBSTRING(content,30,1))) AS CodePageMark;
SET offset=33;
SET fieldno=0;
WHILE SUBSTR(content, offset, 1) <> 0x0D AND offset + 32 < LENGTH(content) DO
CALL dbf_field(fieldno, SUBSTRING(content, offset, 32));
SET offset=offset + 32;
SET fieldno=fieldno + 1;
END WHILE;
SELECT '--------';
END//
DELIMITER ;//
--echo #
--echo # Testing READONLY tables
--echo #
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (10),(20);
SELECT * FROM t1;
ALTER TABLE t1 READONLY=Yes;
SHOW CREATE TABLE t1;
--error ER_GET_ERRMSG
INSERT INTO t1 VALUES (30);
--error ER_GET_ERRMSG
UPDATE t1 SET a=30 WHERE a=10;
--error ER_GET_ERRMSG
DELETE FROM t1 WHERE a=10;
--error ER_GET_ERRMSG
TRUNCATE TABLE t1;
ALTER TABLE t1 READONLY=NO;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (30);
SELECT * FROM t1;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # This SQL script crashed (dbf01.sql)
--echo #
CREATE TABLE t1
(
a int(11) NOT NULL,
b char(10) NOT NULL,
c varchar(10) NOT NULL
) ENGINE=CONNECT table_type=DBF file_name='t1.dbf';
INSERT INTO t1 VALUES (1,'1','1');
INSERT INTO t1 VALUES (2,'2','2');
SELECT * FROM t1;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing that table options in lower case and mixed case are understood:
--echo #
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT table_type=dbf file_name='t1.dbf';
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (10);
SELECT * FROM t1;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
CREATE TABLE t1 (a CHAR(10) NOT NULL) ENGINE=CONNECT Table_Type=dbf File_Name='t1.dbf';
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ('test');
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
#
# TODO: this creates DBF record with length=32, which looks wrong
#
--echo #
--echo # Testing multiple columns
--echo #
CREATE TABLE t1
(
a INT NOT NULL,
b CHAR(10) NOT NULL,
c VARCHAR(10) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (1,'1','1');
INSERT INTO t1 VALUES (2,'2','2');
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing long column name
--echo #
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a012345678901234567890123456789 INT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--echo #
--echo # Testing 2 columns with long names (12)
--echo #
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a0123456789a INT NOT NULL,
b0123456789b INT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t02x11.dbf';
--echo #
--echo # Testing 2 columns with long names (11)
--echo #
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a012345678a INT NOT NULL,
b012345678b INT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t02x12.dbf';
--echo #
--echo # Testing 2 columns name length 10 (maximum possible length)
--echo #
CREATE TABLE t1
(
a01234567a INT NOT NULL,
b01234567b INT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t02x13.dbf';
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (1,2);
SELECT * FROM t1;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t02x13.dbf
--echo #
--echo # Testing BIGINT
--echo #
CREATE TABLE t1
(
a bigint NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (0x7FFFFFFFFFFFFFFF);
INSERT INTO t1 VALUES (-0x8000000000000000);
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing TINYINT
--echo #
CREATE TABLE t1
(
a TINYINT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (123);
SELECT * FROM t1;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing SMALLINT
--echo #
CREATE TABLE t1
(
a SMALLINT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (0x7FFF);
INSERT INTO t1 VALUES (-0x8000);
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing VARCHAR
--echo #
CREATE TABLE t1
(
a VARCHAR(255) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (REPEAT('a',255));
SELECT LENGTH(a) FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing too long CHAR
--echo # All columns longer than 255 bytes should be rejected
--echo #
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a CHAR(86) CHARACTER SET utf8 NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR
--echo #
--echo # Testing too long VARCHAR
--echo # All columns longer than 255 bytes should be rejected
--echo #
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a VARCHAR(256) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a VARCHAR(86) CHARACTER SET utf8 NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a VARCHAR(64000) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--echo #
--echo # Testing BLOB
--echo #
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a BLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a TINYBLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a MEDIUMBLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a LONGBLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
# TODO: utf8 does not work
#--echo #
#--echo # Testing varchar with utf8
#--echo #
#SET NAMES utf8;
#CREATE TABLE t1
#(
# a VARCHAR(10) CHARACTER SET utf8
#) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
#INSERT INTO t1 VALUES (REPEAT(_ucs2 0x00DF,10));
#SELECT * FROM t1;
#DROP TABLE IF EXISTS t1;
#--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing DATE
--echo #
CREATE TABLE t1
(
a DATE NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES ('2001-01-01');
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing FLOAT
--echo #
CREATE TABLE t1
(
a FLOAT(12,4) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (123);
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
#
# TODO: this return error:
# Got error 122 'Value 123.0000000000 too long for column a of length 12'
# from CONNECT
#
#CREATE TABLE t1
#(
# a FLOAT NOT NULL
#) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
#--error ER_GET_ERRMSG - why this error?
#INSERT INTO t1 VALUES (123);
#SELECT * FROM t1;
#DROP TABLE IF EXISTS t1;
#--remove_file $MYSQLD_DATADIR/test/t1.dbf
#
# TODO: this creates a column of type 'D' (date), which is wrong
#
#--echo #
#--echo # Testing DATETIME
#--echo #
#CREATE TABLE t1
#(
# a DATETIME NOT NULL
#) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
#INSERT INTO t1 VALUES ('2013-02-01');
#SELECT * FROM t1;
#DROP TABLE t1;
#--remove_file $MYSQLD_DATADIR/test/t1.dbf
#
# TODO: this creates a column of type 'D' (date), which is wrong
#
#--echo #
#--echo # Testing TIMESTAMP
#--echo #
#CREATE TABLE t1
#(
# a TIMESTAMP
#) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
#INSERT INTO t1 VALUES ('2013-02-01');
#SELECT * FROM t1;
#DROP TABLE t1;
#--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing double
--echo #
CREATE TABLE t1
(
a DOUBLE(20,5) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (123);
INSERT INTO t1 VALUES (123456789.12345);
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE IF EXISTS t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
# TODO:
# Testing with no FILE_NAME specified
# Currently it returns:
# ERROR 1296 (HY000): Got error 174 'Open(a+) error 21
# on /opt/mariadb-5.5/data/: Is a directory' from CONNECT
#CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=DBF;
--echo #
--echo # Testing ALTER
--echo #
CREATE TABLE t1
(
a VARCHAR(10) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES ('10');
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
ALTER TABLE t1 MODIFY a VARCHAR(10) NOT NULL;
SHOW CREATE TABLE t1;
SELECT * FROM t1;
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
ALTER TABLE t1 MODIFY a INT(10) NOT NULL;
SHOW CREATE TABLE t1;
SELECT * FROM t1;
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
# TODO: this does not work on Windows
#ALTER TABLE t1 MODIFY a INT(8) NOT NULL;
#SHOW CREATE TABLE t1;
#--error ER_GET_ERRMSG
#SELECT * FROM t1;
#--vertical_results
#--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
#eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
#--horizontal_results
DROP TABLE IF EXISTS t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing NULL
--echo #
# TODO: NULLs should probably change to DEFAULT and produce a warning
CREATE TABLE t1
(
c1 VARCHAR(10) NOT NULL,
c2 VARCHAR(10) NOT NULL DEFAULT 'def',
i1 INT NOT NULL,
i2 INT NOT NULL DEFAULT 123
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES ('10','10',10,10);
#INSERT INTO t1 VALUES (NULL,NULL,NULL,NULL);
INSERT INTO t1(c1,i1) VALUES ('20',20);
INSERT INTO t1 VALUES ('30',DEFAULT,30,DEFAULT);
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE IF EXISTS t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
DROP PROCEDURE test.dbf_field;
DROP PROCEDURE test.dbf_header;
let $MYSQLD_DATADIR= `select @@datadir`;
--echo #
--echo # Testing errors
--echo #
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
SHOW CREATE TABLE t1;
--replace_regex /on .*test.t1.dbf/on DATADIR\/test\/t1.dbf/
SELECT * FROM t1;
DROP TABLE t1;
--replace_regex /Cannot open .*test.t1.dbf/Cannot open DATADIR\/test\/t1.dbf/
--error ER_UNKNOWN_ERROR
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--replace_regex /Cannot open .*test.t1.dbf/Cannot open DATADIR\/test\/t1.dbf/
SHOW WARNINGS;
DELIMITER //;
CREATE PROCEDURE test.dbf_field(in fieldno INT, in content BLOB) DETERMINISTIC
BEGIN
SELECT '---';
SELECT fieldno AS `FieldN`;
SELECT TRIM(TRAILING 0x00 FROM LEFT(content, 10)) AS `Name`;
SELECT SUBSTRING(content, 12, 1) AS `Type`;
SELECT CONV(HEX(REVERSE(SUBSTRING(content,13,4))),16,10) AS `Offset`;
SELECT CONV(HEX(REVERSE(SUBSTRING(content,17,1))),16,10) AS `Length`;
SELECT CONV(HEX(REVERSE(SUBSTRING(content,18,1))),16,10) AS `Dec`;
SELECT HEX(REVERSE(SUBSTRING(content,19,1))) AS `Flags`;
-- SELECT CONV(HEX(REVERSE(SUBSTRING(content,20,4))),16,10) AS `Next`;
-- SELECT CONV(HEX(REVERSE(SUBSTRING(content,24,4))),16,10) AS `Step`;
END//
CREATE PROCEDURE test.dbf_header(in fname VARCHAR(1024)) DETERMINISTIC
BEGIN
DECLARE content BLOB;
DECLARE offset INT;
DECLARE fieldno INT;
SELECT '--------';
SELECT LOAD_FILE(fname) INTO content;
SELECT LENGTH(content) AS FileSize;
SELECT HEX(LEFT(content, 1)) AS DBF_Version;
SELECT CONV(HEX(REVERSE(SUBSTRING(content,5,4))),16,10) AS NRecords;
SELECT CONV(HEX(REVERSE(SUBSTRING(content,9,2))),16,10) AS FirstRecPos;
SELECT CONV(HEX(REVERSE(SUBSTRING(content,11,2))),16,10) AS RecLength;
SELECT HEX(REVERSE(SUBSTRING(content,29,2))) AS TableFlags;
SELECT HEX(REVERSE(SUBSTRING(content,30,1))) AS CodePageMark;
SET offset=33;
SET fieldno=0;
WHILE SUBSTR(content, offset, 1) <> 0x0D AND offset + 32 < LENGTH(content) DO
CALL dbf_field(fieldno, SUBSTRING(content, offset, 32));
SET offset=offset + 32;
SET fieldno=fieldno + 1;
END WHILE;
SELECT '--------';
END//
DELIMITER ;//
--echo #
--echo # Testing READONLY tables
--echo #
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (10),(20);
SELECT * FROM t1;
ALTER TABLE t1 READONLY=Yes;
SHOW CREATE TABLE t1;
--error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES (30);
--error ER_OPEN_AS_READONLY
UPDATE t1 SET a=30 WHERE a=10;
--error ER_OPEN_AS_READONLY
DELETE FROM t1 WHERE a=10;
--error ER_OPEN_AS_READONLY
TRUNCATE TABLE t1;
ALTER TABLE t1 READONLY=NO;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (30);
SELECT * FROM t1;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # This SQL script crashed (dbf01.sql)
--echo #
CREATE TABLE t1
(
a int(11) NOT NULL,
b char(10) NOT NULL,
c varchar(10) NOT NULL
) ENGINE=CONNECT table_type=DBF file_name='t1.dbf';
INSERT INTO t1 VALUES (1,'1','1');
INSERT INTO t1 VALUES (2,'2','2');
SELECT * FROM t1;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing that table options in lower case and mixed case are understood:
--echo #
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT table_type=dbf file_name='t1.dbf';
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (10);
SELECT * FROM t1;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
CREATE TABLE t1 (a CHAR(10) NOT NULL) ENGINE=CONNECT Table_Type=dbf File_Name='t1.dbf';
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ('test');
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
#
# TODO: this creates DBF record with length=32, which looks wrong
#
--echo #
--echo # Testing multiple columns
--echo #
CREATE TABLE t1
(
a INT NOT NULL,
b CHAR(10) NOT NULL,
c VARCHAR(10) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (1,'1','1');
INSERT INTO t1 VALUES (2,'2','2');
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing long column name
--echo #
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a012345678901234567890123456789 INT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--echo #
--echo # Testing 2 columns with long names (12)
--echo #
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a0123456789a INT NOT NULL,
b0123456789b INT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t02x11.dbf';
--echo #
--echo # Testing 2 columns with long names (11)
--echo #
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a012345678a INT NOT NULL,
b012345678b INT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t02x12.dbf';
--echo #
--echo # Testing 2 columns name length 10 (maximum possible length)
--echo #
CREATE TABLE t1
(
a01234567a INT NOT NULL,
b01234567b INT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t02x13.dbf';
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (1,2);
SELECT * FROM t1;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t02x13.dbf
--echo #
--echo # Testing BIGINT
--echo #
CREATE TABLE t1
(
a bigint NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (0x7FFFFFFFFFFFFFFF);
INSERT INTO t1 VALUES (-0x8000000000000000);
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing TINYINT
--echo #
CREATE TABLE t1
(
a TINYINT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (123);
SELECT * FROM t1;
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing SMALLINT
--echo #
CREATE TABLE t1
(
a SMALLINT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (0x7FFF);
INSERT INTO t1 VALUES (-0x8000);
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing VARCHAR
--echo #
CREATE TABLE t1
(
a VARCHAR(255) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (REPEAT('a',255));
SELECT LENGTH(a) FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing too long CHAR
--echo # All columns longer than 255 bytes should be rejected
--echo #
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a CHAR(86) CHARACTER SET utf8 NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR
--echo #
--echo # Testing too long VARCHAR
--echo # All columns longer than 255 bytes should be rejected
--echo #
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a VARCHAR(256) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a VARCHAR(86) CHARACTER SET utf8 NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a VARCHAR(64000) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--echo #
--echo # Testing BLOB
--echo #
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a BLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a TINYBLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a MEDIUMBLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR
CREATE TABLE t1
(
a LONGBLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
# TODO: utf8 does not work
#--echo #
#--echo # Testing varchar with utf8
#--echo #
#SET NAMES utf8;
#CREATE TABLE t1
#(
# a VARCHAR(10) CHARACTER SET utf8
#) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
#INSERT INTO t1 VALUES (REPEAT(_ucs2 0x00DF,10));
#SELECT * FROM t1;
#DROP TABLE IF EXISTS t1;
#--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing DATE
--echo #
CREATE TABLE t1
(
a DATE NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES ('2001-01-01');
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing FLOAT
--echo #
CREATE TABLE t1
(
a FLOAT(12,4) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (123);
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
#
# TODO: this return error:
# Got error 122 'Value 123.0000000000 too long for column a of length 12'
# from CONNECT
#
#CREATE TABLE t1
#(
# a FLOAT NOT NULL
#) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
#--error ER_GET_ERRMSG - why this error?
#INSERT INTO t1 VALUES (123);
#SELECT * FROM t1;
#DROP TABLE IF EXISTS t1;
#--remove_file $MYSQLD_DATADIR/test/t1.dbf
#
# TODO: this creates a column of type 'D' (date), which is wrong
#
#--echo #
#--echo # Testing DATETIME
#--echo #
#CREATE TABLE t1
#(
# a DATETIME NOT NULL
#) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
#INSERT INTO t1 VALUES ('2013-02-01');
#SELECT * FROM t1;
#DROP TABLE t1;
#--remove_file $MYSQLD_DATADIR/test/t1.dbf
#
# TODO: this creates a column of type 'D' (date), which is wrong
#
#--echo #
#--echo # Testing TIMESTAMP
#--echo #
#CREATE TABLE t1
#(
# a TIMESTAMP
#) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
#INSERT INTO t1 VALUES ('2013-02-01');
#SELECT * FROM t1;
#DROP TABLE t1;
#--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing double
--echo #
CREATE TABLE t1
(
a DOUBLE(20,5) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (123);
INSERT INTO t1 VALUES (123456789.12345);
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE IF EXISTS t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
# TODO:
# Testing with no FILE_NAME specified
# Currently it returns:
# ERROR 1296 (HY000): Got error 174 'Open(a+) error 21
# on /opt/mariadb-5.5/data/: Is a directory' from CONNECT
#CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=DBF;
--echo #
--echo # Testing ALTER
--echo #
CREATE TABLE t1
(
a VARCHAR(10) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES ('10');
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
ALTER TABLE t1 MODIFY a VARCHAR(10) NOT NULL;
SHOW CREATE TABLE t1;
SELECT * FROM t1;
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
ALTER TABLE t1 MODIFY a INT(10) NOT NULL;
SHOW CREATE TABLE t1;
SELECT * FROM t1;
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
# TODO: this does not work on Windows
#ALTER TABLE t1 MODIFY a INT(8) NOT NULL;
#SHOW CREATE TABLE t1;
#--error ER_GET_ERRMSG
#SELECT * FROM t1;
#--vertical_results
#--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
#eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
#--horizontal_results
DROP TABLE IF EXISTS t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo #
--echo # Testing NULL
--echo #
# TODO: NULLs should probably change to DEFAULT and produce a warning
CREATE TABLE t1
(
c1 VARCHAR(10) NOT NULL,
c2 VARCHAR(10) NOT NULL DEFAULT 'def',
i1 INT NOT NULL,
i2 INT NOT NULL DEFAULT 123
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES ('10','10',10,10);
#INSERT INTO t1 VALUES (NULL,NULL,NULL,NULL);
INSERT INTO t1(c1,i1) VALUES ('20',20);
INSERT INTO t1 VALUES ('30',DEFAULT,30,DEFAULT);
SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results
DROP TABLE IF EXISTS t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf
DROP PROCEDURE test.dbf_field;
DROP PROCEDURE test.dbf_header;
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;
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;
......@@ -873,7 +873,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
......@@ -1232,16 +1233,9 @@ 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\n",
......
......@@ -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);
......@@ -184,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
......@@ -593,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);
......@@ -524,6 +524,7 @@ bool TDBCAT::OpenDB(PGLOBAL g)
if (Initialize(g))
return true;
Use = USE_OPEN;
return InitCol(g);
} // end of OpenDB
......
......@@ -495,6 +495,7 @@ bool TDBOCCUR::OpenDB(PGLOBAL g)
if (Tdbp->OpenDB(g))
return TRUE;
Use = USE_OPEN;
return ViewColumnList(g);
} // end of OpenDB
......
......@@ -90,8 +90,8 @@ extern int num_read, num_there, num_eq[2]; // Statistics
/***********************************************************************/
ODBCDEF::ODBCDEF(void)
{
Connect = Tabname = Tabowner = Tabqual = Srcdef = Qchar = Qrystr = NULL;
Catver = Options = 0;
Connect = Tabname = Tabowner = Tabqual = Srcdef = Qrystr = NULL;
Catver = Options = Quoted = 0;
Xsrc = false;
} // end of ODBCDEF constructor
......@@ -107,11 +107,11 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Tabowner = Cat->GetStringCatInfo(g, "Owner", "");
Tabqual = Cat->GetStringCatInfo(g, "Qualifier", "");
Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL);
Qchar = Cat->GetStringCatInfo(g, "Qchar", "");
Qrystr = Cat->GetStringCatInfo(g, "Query_String", "?");
Catver = Cat->GetIntCatInfo("Catver", 2);
Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE);
Mxr = Cat->GetIntCatInfo("Maxerr", 0);
Quoted = Cat->GetIntCatInfo("Quoted", 0);
Options = ODBConn::noOdbcDialog;
Pseudo = 2; // FILID is Ok but not ROWID
return false;
......@@ -171,9 +171,9 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
Owner = tdp->Tabowner;
Qualifier = tdp->Tabqual;
Srcdef = tdp->Srcdef;
Quote = tdp->GetQchar();
Qrystr = tdp->Qrystr;
Options = tdp->Options;
Quoted = max(0, tdp->GetQuoted());
Rows = tdp->GetElemt();
Catver = tdp->Catver;
} else {
......@@ -182,13 +182,14 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
Owner = NULL;
Qualifier = NULL;
Srcdef = NULL;
Quote = NULL;
Qrystr = NULL;
Options = 0;
Quoted = 0;
Rows = 0;
Catver = 0;
} // endif tdp
Quote = NULL;
Query = NULL;
Count = NULL;
//Where = NULL;
......@@ -211,14 +212,15 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp)
Owner = tdbp->Owner;
Qualifier = tdbp->Qualifier;
Srcdef = tdbp->Srcdef;
Quote = tdbp->Quote;
Qrystr = tdbp->Qrystr;
Quote = tdbp->Quote;
Query = tdbp->Query;
Count = tdbp->Count;
//Where = tdbp->Where;
MulConn = tdbp->MulConn;
DBQ = tdbp->DBQ;
Options = tdbp->Options;
Quoted = tdbp->Quoted;
Rows = tdbp->Rows;
Fpos = tdbp->Fpos;
AftRows = tdbp->AftRows;
......@@ -445,21 +447,18 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
/***********************************************************************/
/* MakeInsert: make the Insert statement used with ODBC connection. */
/***********************************************************************/
bool TDBODBC::MakeInsert(PGLOBAL g)
char *TDBODBC::MakeInsert(PGLOBAL g)
{
char *colist, *valist;
char *stmt, *colist, *valist;
// char *tk = "`";
int len = 0;
bool b = FALSE;
PCOL colp;
if (Query)
return false; // already done
for (colp = Columns; colp; colp = colp->GetNext())
if (colp->IsSpecial()) {
strcpy(g->Message, MSG(NO_ODBC_SPECOL));
return true;
return NULL;
} else {
len += (strlen(colp->GetName()) + 4);
((PODBCCOL)colp)->Rank = ++Nparm;
......@@ -487,18 +486,18 @@ bool TDBODBC::MakeInsert(PGLOBAL g)
// Below 32 is enough to contain the fixed part of the query
len = (strlen(TableName) + strlen(colist) + strlen(valist) + 32);
Query = (char*)PlugSubAlloc(g, NULL, len);
strcpy(Query, "INSERT INTO ");
stmt = (char*)PlugSubAlloc(g, NULL, len);
strcpy(stmt, "INSERT INTO ");
if (Quote)
strcat(strcat(strcat(Query, Quote), TableName), Quote);
strcat(strcat(strcat(stmt, Quote), TableName), Quote);
else
strcat(Query, TableName);
strcat(stmt, TableName);
strcat(strcat(strcat(Query, " ("), colist), ") VALUES (");
strcat(strcat(Query, valist), ")");
strcat(strcat(strcat(stmt, " ("), colist), ") VALUES (");
strcat(strcat(stmt, valist), ")");
return false;
return stmt;
} // end of MakeInsert
/***********************************************************************/
......@@ -520,27 +519,58 @@ bool TDBODBC::BindParameters(PGLOBAL g)
} // end of BindParameters
/***********************************************************************/
/* MakeCMD: make the SQL statement to send to ODBC connection. */
/* MakeUpdate: make the SQL statement to send to ODBC connection. */
/***********************************************************************/
char *TDBODBC::MakeStmt(PGLOBAL g)
char *TDBODBC::MakeUpdate(PGLOBAL g)
{
char *qc, *stmt = NULL, cmd[8], tab[96], end[512];
int n = (Mode == MODE_DELETE) ? 1 : 2;
char *qc, *stmt = NULL, cmd[8], tab[96], end[1024];
stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
*end = 0;
qc = (Quote) ? Quote : "\"";
memset(end, 0, sizeof(end));
if (sscanf(Qrystr, "%s `%[^`]`%511c", cmd, tab, end) > n ||
sscanf(Qrystr, "%s \"%[^\"]\"%511c", cmd, tab, end) > n ||
sscanf(Qrystr, "%s %s%511c", cmd, tab, end) > n)
strcat(strcat(strcpy(tab, qc), TableName), qc);
if (sscanf(Qrystr, "%s `%[^`]`%1023c", cmd, tab, end) > 2 ||
sscanf(Qrystr, "%s \"%[^\"]\"%1023c", cmd, tab, end) > 2)
qc = Ocp->GetQuoteChar();
else if (sscanf(Qrystr, "%s %s%1023c", cmd, tab, end) > 2)
qc = (Quoted) ? Quote : "";
else {
strcpy(g->Message, "Cannot use this UPDATE/DELETE command");
strcpy(g->Message, "Cannot use this UPDATE command");
return NULL;
} // endif sscanf
strcat(strcat(strcpy(stmt, cmd), " "), tab);
assert(!stricmp(cmd, "update"));
strcat(strcat(strcat(strcpy(stmt, "UPDATE "), qc), TableName), qc);
for (int i = 0; end[i]; i++)
if (end[i] == '`')
end[i] = *qc;
strcat(stmt, end);
return stmt;
} // end of MakeUpdate
/***********************************************************************/
/* MakeDelete: make the SQL statement to send to ODBC connection. */
/***********************************************************************/
char *TDBODBC::MakeDelete(PGLOBAL g)
{
char *qc, *stmt = NULL, cmd[8], from[8], tab[96], end[512];
stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
memset(end, 0, sizeof(end));
if (sscanf(Qrystr, "%s %s `%[^`]`%511c", cmd, from, tab, end) > 2 ||
sscanf(Qrystr, "%s %s \"%[^\"]\"%511c", cmd, from, tab, end) > 2)
qc = Ocp->GetQuoteChar();
else if (sscanf(Qrystr, "%s %s %s%511c", cmd, from, tab, end) > 2)
qc = (Quoted) ? Quote : "";
else {
strcpy(g->Message, "Cannot use this DELETE command");
return NULL;
} // endif sscanf
assert(!stricmp(cmd, "delete") && !stricmp(from, "from"));
strcat(strcat(strcat(strcpy(stmt, "DELETE FROM "), qc), TableName), qc);
if (*end) {
for (int i = 0; end[i]; i++)
......@@ -551,7 +581,7 @@ char *TDBODBC::MakeStmt(PGLOBAL g)
} // endif end
return stmt;
} // end of MakeStmt
} // end of MakeDelete
/***********************************************************************/
/* ResetSize: call by TDBMUL when calculating size estimate. */
......@@ -572,7 +602,7 @@ int TDBODBC::GetMaxSize(PGLOBAL g)
{
if (MaxSize < 0) {
// Make MariaDB happy
MaxSize = 100;
MaxSize = (Mode == MODE_READ) ? 100 : 0;
#if 0
// This is unuseful and takes time
if (Srcdef) {
......@@ -655,51 +685,42 @@ bool TDBODBC::OpenDB(PGLOBAL g)
if (Ocp->Open(Connect, Options) < 1)
return true;
else if (Quoted)
Quote = Ocp->GetQuoteChar();
Use = USE_OPEN; // Do it now in case we are recursively called
/*********************************************************************/
/* Allocate whatever is used for getting results. */
/* Make the command and allocate whatever is used for getting results. */
/*********************************************************************/
if (Mode == MODE_READ) {
/*******************************************************************/
/* The issue here is that if max result size is needed, it must be */
/* calculated before the result set for the final data retrieval is*/
/* allocated and the final statement prepared so we call GetMaxSize*/
/* here. It can be a waste of time if the max size is not needed */
/* but currently we always are asking for it (for progress info). */
/*******************************************************************/
GetMaxSize(g); // Will be set for next call
if (!Query)
if ((Query = MakeSQL(g, false))) {
for (PODBCCOL colp = (PODBCCOL)Columns;
colp; colp = (PODBCCOL)colp->GetNext())
if (!colp->IsSpecial())
colp->AllocateBuffers(g, Rows);
} else {
Ocp->Close();
return true;
} // endif Query
if ((Query = MakeSQL(g, false))) {
for (PODBCCOL colp = (PODBCCOL)Columns; colp;
colp = (PODBCCOL)colp->GetNext())
if (!colp->IsSpecial())
colp->AllocateBuffers(g, Rows);
if (!rc)
rc = ((Rows = Ocp->ExecDirectSQL(Query, (PODBCCOL)Columns)) < 0);
} // endif Query
} else if (Mode == MODE_INSERT) {
if (!(rc = MakeInsert(g)))
if ((Query = MakeInsert(g))) {
if (Nparm != Ocp->PrepareSQL(Query)) {
strcpy(g->Message, MSG(PARM_CNT_MISS));
rc = true;
} else
rc = BindParameters(g);
} else {
strcpy(g->Message, "No DELETE/UPDATE of ODBC tablesd");
return true;
} // endelse
} // endif Query
} else if (Mode == MODE_UPDATE)
Query = MakeUpdate(g);
else if (Mode == MODE_DELETE)
Query = MakeDelete(g);
else
sprintf(g->Message, "Invalid mode %d", Mode);
if (rc) {
if (!Query || rc) {
Ocp->Close();
return true;
} // endif rc
......@@ -730,6 +751,21 @@ int TDBODBC::ReadDB(PGLOBAL g)
htrc("ODBC ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n",
GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex);
if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
// Send the UPDATE/DELETE command to the remote table
if (!Ocp->ExecSQLcommand(Query)) {
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
if (trace)
htrc("%s\n", g->Message);
PushWarning(g, this, 0); // 0 means a Note
return RC_EF; // Nothing else to do
} else
return RC_FX; // Error
} // endif Mode
if (To_Kindex) {
// Direct access of ODBC tables is not implemented yet
strcpy(g->Message, MSG(NO_ODBC_DIRECT));
......@@ -775,8 +811,22 @@ int TDBODBC::WriteDB(PGLOBAL g)
/***********************************************************************/
int TDBODBC::DeleteDB(PGLOBAL g, int irc)
{
strcpy(g->Message, MSG(NO_ODBC_DELETE));
return RC_FX;
if (irc == RC_FX) {
// Send the DELETE (all) command to the remote table
if (!Ocp->ExecSQLcommand(Query)) {
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
if (trace)
htrc("%s\n", g->Message);
PushWarning(g, this, 0); // 0 means a Note
return RC_OK; // This is a delete all
} else
return RC_FX; // Error
} else
return RC_OK; // Ignore
} // end of DeleteDB
/***********************************************************************/
......@@ -790,6 +840,7 @@ void TDBODBC::CloseDB(PGLOBAL g)
// } // endif
if (Ocp)
Ocp->Close();
if (trace)
......@@ -1226,6 +1277,15 @@ int TDBXDBC::WriteDB(PGLOBAL g)
return RC_FX;
} // end of DeleteDB
/***********************************************************************/
/* Data Base delete line routine for ODBC access method. */
/***********************************************************************/
int TDBXDBC::DeleteDB(PGLOBAL g, int irc)
{
strcpy(g->Message, MSG(NO_ODBC_DELETE));
return RC_FX;
} // end of DeleteDB
/* --------------------------- XSRCCOL ------------------------------- */
/***********************************************************************/
......
......@@ -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;}
......@@ -53,6 +53,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
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
......@@ -100,10 +101,11 @@ class TDBODBC : public TDBASE {
// Internal functions
int Decode(char *utf, char *buf, size_t n);
char *MakeSQL(PGLOBAL g, bool cnt);
bool MakeInsert(PGLOBAL g);
char *MakeInsert(PGLOBAL g);
//bool MakeFilter(PGLOBAL g, bool c);
bool BindParameters(PGLOBAL g);
char *MakeStmt(PGLOBAL g);
char *MakeUpdate(PGLOBAL g);
char *MakeDelete(PGLOBAL g);
// Members
ODBConn *Ocp; // Points to an ODBC connection class
......@@ -121,6 +123,7 @@ class TDBODBC : public TDBASE {
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
......@@ -206,7 +209,7 @@ 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:
......
......@@ -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. */
/*********************************************************************/
......
......@@ -495,6 +495,7 @@ bool TDBPRX::OpenDB(PGLOBAL g)
if (Tdbp->OpenDB(g))
return TRUE;
Use = USE_OPEN;
return FALSE;
} // end of OpenDB
......
......@@ -667,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
......
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