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, ...@@ -251,7 +251,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
return true; return true;
} // endif tdbp } // endif tdbp
tdbp->SetMode(mode); //tdbp->SetMode(mode); done in ha_connect::GetTDB
if (!c1) { if (!c1) {
if (mode == MODE_INSERT) if (mode == MODE_INSERT)
...@@ -498,8 +498,8 @@ RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all) ...@@ -498,8 +498,8 @@ RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all)
if (!tdbp || tdbp->GetMode() != MODE_DELETE) if (!tdbp || tdbp->GetMode() != MODE_DELETE)
return RC_FX; return RC_FX;
// else else if (tdbp->IsReadOnly())
// ((PTDBDOX)tdbp)->SetModified(true); return RC_NF;
if (((PTDBASE)tdbp)->GetDef()->Indexable() && all) if (((PTDBASE)tdbp)->GetDef()->Indexable() && all)
((PTDBDOS)tdbp)->Cardinal= 0; ((PTDBDOS)tdbp)->Cardinal= 0;
...@@ -518,17 +518,13 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp) ...@@ -518,17 +518,13 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
int rc= RC_OK; int rc= RC_OK;
TDBDOX *tbxp= NULL; TDBDOX *tbxp= NULL;
if (!tdbp) if (!tdbp || tdbp->GetUse() != USE_OPEN)
return rc; // Already done return rc; // Nothing to do
if (xtrace) if (xtrace)
printf("CntCloseTable: tdbp=%p mode=%d\n", tdbp, tdbp->GetMode()); printf("CntCloseTable: tdbp=%p mode=%d\n", tdbp, tdbp->GetMode());
/*********************************************************************/ if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN)
/* This will close the table file(s) and also finalize write */
/* operations such as Insert, Update, or Delete. */
/*********************************************************************/
if (tdbp->GetMode() == MODE_DELETE)
rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine
// Prepare error return // Prepare error return
...@@ -543,6 +539,8 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp) ...@@ -543,6 +539,8 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
goto err; goto err;
} // endif } // endif
// This will close the table file(s) and also finalize write
// operations such as Insert, Update, or Delete.
tdbp->CloseDB(g); tdbp->CloseDB(g);
g->jump_level--; g->jump_level--;
......
...@@ -258,17 +258,21 @@ ha_create_table_option connect_field_option_list[]= ...@@ -258,17 +258,21 @@ ha_create_table_option connect_field_option_list[]=
/***********************************************************************/ /***********************************************************************/
/* Push G->Message as a MySQL warning. */ /* Push G->Message as a MySQL warning. */
/***********************************************************************/ /***********************************************************************/
bool PushWarning(PGLOBAL g, PTDBASE tdbp) bool PushWarning(PGLOBAL g, PTDBASE tdbp, int level)
{ {
PHC phc; PHC phc;
THD *thd; THD *thd;
MYCAT *cat= (MYCAT*)tdbp->GetDef()->GetCat(); MYCAT *cat= (MYCAT*)tdbp->GetDef()->GetCat();
Sql_condition::enum_warning_level wlvl;
if (!cat || !(phc= cat->GetHandler()) || !phc->GetTable() || if (!cat || !(phc= cat->GetHandler()) || !phc->GetTable() ||
!(thd= (phc->GetTable())->in_use)) !(thd= (phc->GetTable())->in_use))
return true; 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; return false;
} // end of PushWarning } // end of PushWarning
...@@ -1098,19 +1102,20 @@ PTDB ha_connect::GetTDB(PGLOBAL g) ...@@ -1098,19 +1102,20 @@ PTDB ha_connect::GetTDB(PGLOBAL g)
&& (tdbp->GetMode() == xmod && (tdbp->GetMode() == xmod
|| tdbp->GetAmType() == TYPE_AM_XML)) { || tdbp->GetAmType() == TYPE_AM_XML)) {
tp= tdbp; tp= tdbp;
tp->SetMode(xmod); // tp->SetMode(xmod);
} else if ((tp= CntGetTDB(g, table_name, xmod, this))) } else if ((tp= CntGetTDB(g, table_name, xmod, this)))
valid_query_id= xp->last_query_id; valid_query_id= xp->last_query_id;
else else
printf("GetTDB: %s\n", g->Message); printf("GetTDB: %s\n", g->Message);
tp->SetMode(xmod);
return tp; return tp;
} // end of GetTDB } // end of GetTDB
/****************************************************************************/ /****************************************************************************/
/* Open a CONNECT table, restricting column list if cols is true. */ /* 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; bool rc= false;
char *c1= NULL, *c2=NULL; char *c1= NULL, *c2=NULL;
...@@ -1118,11 +1123,11 @@ bool ha_connect::OpenTable(PGLOBAL g, bool del) ...@@ -1118,11 +1123,11 @@ bool ha_connect::OpenTable(PGLOBAL g, bool del)
// Double test to be on the safe side // Double test to be on the safe side
if (!g || !table) { if (!g || !table) {
printf("OpenTable logical error; g=%p table=%p\n", g, table); printf("OpenTable logical error; g=%p table=%p\n", g, table);
return true; return HA_ERR_INITIALIZATION;
} // endif g } // endif g
if (!(tdbp= GetTDB(g))) if (!(tdbp= GetTDB(g)))
return true; return RC_FX;
else if (tdbp->IsReadOnly()) else if (tdbp->IsReadOnly())
switch (xmod) { switch (xmod) {
case MODE_WRITE: case MODE_WRITE:
...@@ -1130,7 +1135,7 @@ bool ha_connect::OpenTable(PGLOBAL g, bool del) ...@@ -1130,7 +1135,7 @@ bool ha_connect::OpenTable(PGLOBAL g, bool del)
case MODE_UPDATE: case MODE_UPDATE:
case MODE_DELETE: case MODE_DELETE:
strcpy(g->Message, MSG(READ_ONLY)); strcpy(g->Message, MSG(READ_ONLY));
return true; return HA_ERR_TABLE_READONLY;
default: default:
break; break;
} // endswitch xmode } // endswitch xmode
...@@ -1207,7 +1212,7 @@ bool ha_connect::OpenTable(PGLOBAL g, bool del) ...@@ -1207,7 +1212,7 @@ bool ha_connect::OpenTable(PGLOBAL g, bool del)
valid_info= false; valid_info= false;
} // endif rc } // endif rc
return rc; return (rc) ? HA_ERR_INITIALIZATION : 0;
} // end of OpenTable } // end of OpenTable
...@@ -2006,14 +2011,8 @@ int ha_connect::write_row(uchar *buf) ...@@ -2006,14 +2011,8 @@ int ha_connect::write_row(uchar *buf)
if (IsOpened()) if (IsOpened())
CloseTable(g); CloseTable(g);
if (OpenTable(g)) { if ((rc= OpenTable(g)))
if (strstr(g->Message, "read only"))
rc= HA_ERR_TABLE_READONLY;
else
rc= HA_ERR_INITIALIZATION;
DBUG_RETURN(rc); DBUG_RETURN(rc);
} // endif tdbp
} // endif isopened } // endif isopened
...@@ -2378,6 +2377,7 @@ int ha_connect::index_next_same(uchar *buf, const uchar *key, uint keylen) ...@@ -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 ha_connect::rnd_init(bool scan)
{ {
int rc;
PGLOBAL g= ((table && table->in_use) ? GetPlug(table->in_use, xp) : PGLOBAL g= ((table && table->in_use) ? GetPlug(table->in_use, xp) :
(xp) ? xp->g : NULL); (xp) ? xp->g : NULL);
DBUG_ENTER("ha_connect::rnd_init"); DBUG_ENTER("ha_connect::rnd_init");
...@@ -2398,8 +2398,8 @@ int ha_connect::rnd_init(bool scan) ...@@ -2398,8 +2398,8 @@ int ha_connect::rnd_init(bool scan)
if (xmod == MODE_UPDATE) if (xmod == MODE_UPDATE)
bitmap_union(table->read_set, table->write_set); bitmap_union(table->read_set, table->write_set);
if (OpenTable(g, xmod == MODE_DELETE)) if ((rc= OpenTable(g, xmod == MODE_DELETE)))
DBUG_RETURN(HA_ERR_INITIALIZATION); DBUG_RETURN(rc);
xp->nrd= xp->fnd= xp->nfd= 0; xp->nrd= xp->fnd= xp->nfd= 0;
xp->tb1= my_interval_timer(); xp->tb1= my_interval_timer();
...@@ -2610,7 +2610,6 @@ int ha_connect::info(uint flag) ...@@ -2610,7 +2610,6 @@ int ha_connect::info(uint flag)
xp->CheckCleanup(); xp->CheckCleanup();
} // endif xmod } // endif xmod
// tdbp= OpenTable(g, xmod == MODE_DELETE);
tdbp= GetTDB(g); tdbp= GetTDB(g);
} // endif tdbp } // endif tdbp
...@@ -2705,18 +2704,19 @@ int ha_connect::delete_all_rows() ...@@ -2705,18 +2704,19 @@ int ha_connect::delete_all_rows()
PGLOBAL g= xp->g; PGLOBAL g= xp->g;
DBUG_ENTER("ha_connect::delete_all_rows"); 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 // Close and reopen the table so it will be deleted
rc= CloseTable(g); rc= CloseTable(g);
if (!(OpenTable(g))) { if (!(rc= OpenTable(g))) {
if (CntDeleteRow(g, tdbp, true)) { if (CntDeleteRow(g, tdbp, true)) {
printf("%s\n", g->Message); printf("%s\n", g->Message);
rc= HA_ERR_INTERNAL_ERROR; rc= HA_ERR_INTERNAL_ERROR;
} // endif } // endif
} else } // endif rc
rc= HA_ERR_INITIALIZATION;
DBUG_RETURN(rc); DBUG_RETURN(rc);
} // end of delete_all_rows } // end of delete_all_rows
......
...@@ -174,7 +174,7 @@ class ha_connect: public handler ...@@ -174,7 +174,7 @@ class ha_connect: public handler
bool IsSameIndex(PIXDEF xp1, PIXDEF xp2); bool IsSameIndex(PIXDEF xp1, PIXDEF xp2);
PTDB GetTDB(PGLOBAL g); PTDB GetTDB(PGLOBAL g);
bool OpenTable(PGLOBAL g, bool del= false); int OpenTable(PGLOBAL g, bool del= false);
bool IsOpened(void); bool IsOpened(void);
int CloseTable(PGLOBAL g); int CloseTable(PGLOBAL g);
int MakeRecord(char *buf); int MakeRecord(char *buf);
......
...@@ -48,7 +48,7 @@ salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F', ...@@ -48,7 +48,7 @@ salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F',
dept INT(4) NOT NULL FIELD_FORMAT='S' dept INT(4) NOT NULL FIELD_FORMAT='S'
) ENGINE=CONNECT TABLE_TYPE=BIN READONLY=Yes FILE_NAME='Testbal.dat'; ) ENGINE=CONNECT TABLE_TYPE=BIN READONLY=Yes FILE_NAME='Testbal.dat';
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777); 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; ALTER TABLE t1 READONLY=NO;
Warnings: Warnings:
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk 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` ( ...@@ -84,7 +84,7 @@ t1 CREATE TABLE `t1` (
`dept` int(4) NOT NULL `FIELD_FORMAT`='S' `dept` int(4) NOT NULL `FIELD_FORMAT`='S'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=BIN `FILE_NAME`='Testbal.dat' `READONLY`=YES ) 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); 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; DROP TABLE t1;
# #
# Testing that the underlying file is created # Testing that the underlying file is created
......
...@@ -50,13 +50,13 @@ children SMALLINT(2) NOT NULL ...@@ -50,13 +50,13 @@ children SMALLINT(2) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv' ) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
HEADER=1 SEP_CHAR=';' QUOTED=1 READONLY=yes; HEADER=1 SEP_CHAR=';' QUOTED=1 READONLY=yes;
INSERT INTO t1 VALUES ('BILL','1973-06-30',5); 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'; 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'; 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; 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; SELECT * FROM t1;
name birth children name birth children
Archibald 2001-05-17 3 Archibald 2001-05-17 3
...@@ -90,7 +90,7 @@ t1 CREATE TABLE `t1` ( ...@@ -90,7 +90,7 @@ t1 CREATE TABLE `t1` (
`children` smallint(2) NOT NULL `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 ) 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); 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; SELECT * FROM t1;
name birth children name birth children
Archibald 2001-05-17 3 Archibald 2001-05-17 3
......
...@@ -77,13 +77,13 @@ t1 CREATE TABLE `t1` ( ...@@ -77,13 +77,13 @@ t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL `a` int(11) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=DBF `FILE_NAME`='t1.dbf' `READONLY`=Yes ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=DBF `FILE_NAME`='t1.dbf' `READONLY`=Yes
INSERT INTO t1 VALUES (30); 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; 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; 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; 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; ALTER TABLE t1 READONLY=NO;
Warnings: Warnings:
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk 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` ( ...@@ -30,13 +30,13 @@ t1 CREATE TABLE `t1` (
`id` int(11) NOT NULL `id` int(11) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=FIX `FILE_NAME`='t1.txt' `READONLY`=1 ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=FIX `FILE_NAME`='t1.txt' `READONLY`=1
INSERT INTO t1 VALUES (20); 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; 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; 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; 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; ALTER TABLE t1 READONLY=0;
Warnings: Warnings:
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk 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` ( ...@@ -194,13 +194,13 @@ t1 CREATE TABLE `t1` (
`c2` char(60) DEFAULT NULL `c2` char(60) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=INI `FILE_NAME`='t1.ini' `READONLY`=1 ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=INI `FILE_NAME`='t1.ini' `READONLY`=1
INSERT INTO t1 VALUES ('US',40); 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; 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; 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; 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; ALTER TABLE t1 READONLY=0;
Warnings: Warnings:
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk 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` ( ...@@ -103,13 +103,13 @@ t1 CREATE TABLE `t1` (
`b` char(10) NOT NULL `b` char(10) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 MAX_ROWS=10 `TABLE_TYPE`=VEC `FILE_NAME`='t1vec' `READONLY`=yes ) ENGINE=CONNECT DEFAULT CHARSET=latin1 MAX_ROWS=10 `TABLE_TYPE`=VEC `FILE_NAME`='t1vec' `READONLY`=yes
INSERT INTO t1 VALUES (4,'test04'); 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; 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; 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; 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; ALTER TABLE t1 READONLY=no;
Warnings: Warnings:
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk 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`; let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/Testbal.dat $MYSQLD_DATADIR/test/Testbal.dat --copy_file $MTR_SUITE_DIR/std_data/Testbal.dat $MYSQLD_DATADIR/test/Testbal.dat
--echo # --echo #
--echo # Testing errors --echo # Testing errors
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
ID INT NOT NULL ID INT NOT NULL
) Engine=CONNECT TABLE_TYPE=BIN FILE_NAME='nonexistent.txt'; ) Engine=CONNECT TABLE_TYPE=BIN FILE_NAME='nonexistent.txt';
--replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/ --replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/
# TODO: check why this is needed for Windows # TODO: check why this is needed for Windows
--replace_result Open(rt) Open(rb) --replace_result Open(rt) Open(rb)
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
SET time_zone='+00:00'; SET time_zone='+00:00';
CREATE TABLE t1 CREATE TABLE t1
( (
fig INT(4) NOT NULL FIELD_FORMAT='C', fig INT(4) NOT NULL FIELD_FORMAT='C',
name CHAR(10) not null, name CHAR(10) not null,
birth DATE NOT NULL, birth DATE NOT NULL,
id CHAR(5) NOT NULL FIELD_FORMAT='S', id CHAR(5) NOT NULL FIELD_FORMAT='S',
salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F', salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F',
dept INT(4) NOT NULL FIELD_FORMAT='S' dept INT(4) NOT NULL FIELD_FORMAT='S'
) ENGINE=CONNECT TABLE_TYPE=BIN BLOCK_SIZE=5 FILE_NAME='Testbal.dat'; ) ENGINE=CONNECT TABLE_TYPE=BIN BLOCK_SIZE=5 FILE_NAME='Testbal.dat';
SELECT * FROM t1; SELECT * FROM t1;
--error ER_GET_ERRMSG --error ER_GET_ERRMSG
INSERT INTO t1 VALUES (55555,'RONALD','1980-02-26','3333',4444.44,555); 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); INSERT INTO t1 VALUES (5555,'RONALD','1980-02-26','3333',4444.44,555);
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--echo # --echo #
--echo # Testing READONLY tables --echo # Testing READONLY tables
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
fig INT(4) NOT NULL FIELD_FORMAT='C', fig INT(4) NOT NULL FIELD_FORMAT='C',
name CHAR(10) not null, name CHAR(10) not null,
birth DATE NOT NULL, birth DATE NOT NULL,
id CHAR(5) NOT NULL FIELD_FORMAT='S', id CHAR(5) NOT NULL FIELD_FORMAT='S',
salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F', salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F',
dept INT(4) NOT NULL FIELD_FORMAT='S' dept INT(4) NOT NULL FIELD_FORMAT='S'
) ENGINE=CONNECT TABLE_TYPE=BIN READONLY=Yes FILE_NAME='Testbal.dat'; ) ENGINE=CONNECT TABLE_TYPE=BIN READONLY=Yes FILE_NAME='Testbal.dat';
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777); INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
ALTER TABLE t1 READONLY=NO; ALTER TABLE t1 READONLY=NO;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777); INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
SELECT * FROM t1; SELECT * FROM t1;
ALTER TABLE t1 READONLY=YES; ALTER TABLE t1 READONLY=YES;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777); INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
DROP TABLE t1; DROP TABLE t1;
--echo # --echo #
--echo # Testing that the underlying file is created --echo # Testing that the underlying file is created
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
c CHAR(4) NOT NULL FIELD_FORMAT='C' c CHAR(4) NOT NULL FIELD_FORMAT='C'
) ENGINE=CONNECT TABLE_TYPE=BIN FILE_NAME='bin2.dat'; ) ENGINE=CONNECT TABLE_TYPE=BIN FILE_NAME='bin2.dat';
INSERT INTO t1 VALUES (10),(20),(300),(4000); INSERT INTO t1 VALUES (10),(20),(300),(4000);
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
# #
# Clean up # Clean up
# #
--remove_file $MYSQLD_DATADIR/test/Testbal.dat --remove_file $MYSQLD_DATADIR/test/Testbal.dat
--remove_file $MYSQLD_DATADIR/test/bin2.dat --remove_file $MYSQLD_DATADIR/test/bin2.dat
let $MYSQLD_DATADIR= `select @@datadir`; let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/people.csv $MYSQLD_DATADIR/test/people.csv --copy_file $MTR_SUITE_DIR/std_data/people.csv $MYSQLD_DATADIR/test/people.csv
SET NAMES utf8; SET NAMES utf8;
--echo # --echo #
--echo # Testing errors --echo # Testing errors
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
ID INT NOT NULL ID INT NOT NULL
) Engine=CONNECT TABLE_TYPE=CSV FILE_NAME='nonexistent.txt'; ) Engine=CONNECT TABLE_TYPE=CSV FILE_NAME='nonexistent.txt';
--replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/ --replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/
# TODO: check why this is needed for Windows # TODO: check why this is needed for Windows
--replace_result Open(rt) Open(rb) --replace_result Open(rt) Open(rb)
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--echo # --echo #
--echo # Testing examples from the manual --echo # Testing examples from the manual
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
name CHAR(12) NOT NULL, name CHAR(12) NOT NULL,
birth DATE NOT NULL DATE_FORMAT='DD/MM/YY', birth DATE NOT NULL DATE_FORMAT='DD/MM/YY',
children SMALLINT(2) NOT NULL children SMALLINT(2) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv' ) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
HEADER=1 SEP_CHAR=';' QUOTED=1; HEADER=1 SEP_CHAR=';' QUOTED=1;
SELECT * FROM t1; SELECT * FROM t1;
INSERT INTO t1 VALUES ('RONALD','1980-02-26',4); INSERT INTO t1 VALUES ('RONALD','1980-02-26',4);
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/people.csv --chmod 0777 $MYSQLD_DATADIR/test/people.csv
--replace_result $MYSQLD_DATADIR DATADIR --replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/people.csv'),'\r\n','\n'); --eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/people.csv'),'\r\n','\n');
--echo # --echo #
--echo # Testing READONLY tables --echo # Testing READONLY tables
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
name CHAR(12) NOT NULL, name CHAR(12) NOT NULL,
birth DATE NOT NULL DATE_FORMAT='DD/MM/YY', birth DATE NOT NULL DATE_FORMAT='DD/MM/YY',
children SMALLINT(2) NOT NULL children SMALLINT(2) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv' ) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
HEADER=1 SEP_CHAR=';' QUOTED=1 READONLY=yes; HEADER=1 SEP_CHAR=';' QUOTED=1 READONLY=yes;
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES ('BILL','1973-06-30',5); INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
UPDATE t1 SET children=6 WHERE name='BILL'; UPDATE t1 SET children=6 WHERE name='BILL';
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
DELETE FROM t1 WHERE name='BILL'; DELETE FROM t1 WHERE name='BILL';
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
SELECT * FROM t1; SELECT * FROM t1;
ALTER TABLE t1 READONLY=no; ALTER TABLE t1 READONLY=no;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ('BILL','1973-06-30',5); INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
SELECT * FROM t1; SELECT * FROM t1;
ALTER TABLE t1 READONLY=1; ALTER TABLE t1 READONLY=1;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES ('BILL','1973-06-30',5); INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--echo # --echo #
--echo # Testing that the underlying file is created --echo # Testing that the underlying file is created
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
c1 CHAR(12) NOT NULL, c1 CHAR(12) NOT NULL,
c2 CHAR(12) NOT NULL c2 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='tmp.csv' ) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='tmp.csv'
HEADER=1 SEP_CHAR=',' QUOTED=1; HEADER=1 SEP_CHAR=',' QUOTED=1;
INSERT INTO t1 VALUES (10,10),(20,20),(300,300),(4000,4000), ('a b','c d'); INSERT INTO t1 VALUES (10,10),(20,20),(300,300),(4000,4000), ('a b','c d');
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/tmp.csv --chmod 0777 $MYSQLD_DATADIR/test/tmp.csv
--replace_result $MYSQLD_DATADIR DATADIR --replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/tmp.csv'),'\r\n','\n'); --eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/tmp.csv'),'\r\n','\n');
--echo # --echo #
--echo # Creating a CSV table from a MyISAM table --echo # Creating a CSV table from a MyISAM table
--echo # --echo #
CREATE TABLE t1 (a VARCHAR(10) NOT NULL, b INT NOT NULL) ENGINE=MyISAM; CREATE TABLE t1 (a VARCHAR(10) NOT NULL, b INT NOT NULL) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('test1',1), ('test2',2); INSERT INTO t1 VALUES ('test1',1), ('test2',2);
CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t2.csv' CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t2.csv'
AS SELECT * FROM t1; AS SELECT * FROM t1;
SELECT * FROM t2; SELECT * FROM t2;
DROP TABLE t2; DROP TABLE t2;
DROP TABLE t1; DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t2.csv --chmod 0777 $MYSQLD_DATADIR/test/t2.csv
--replace_result $MYSQLD_DATADIR DATADIR --replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t2.csv'),'\r\n','\n'); --eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t2.csv'),'\r\n','\n');
--remove_file $MYSQLD_DATADIR/test/t2.csv --remove_file $MYSQLD_DATADIR/test/t2.csv
--echo # --echo #
--echo # Testing international data --echo # Testing international data
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
c1 CHAR(12) NOT NULL c1 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv' ) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
CHARSET=utf8; CHARSET=utf8;
INSERT INTO t1 VALUES ('á'); INSERT INTO t1 VALUES ('á');
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv --chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR --replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n')); --eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv --remove_file $MYSQLD_DATADIR/test/t1.csv
CREATE TABLE t1 CREATE TABLE t1
( (
c1 CHAR(12) NOT NULL c1 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv' ) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
CHARSET=utf8 DATA_CHARSET=latin1; CHARSET=utf8 DATA_CHARSET=latin1;
INSERT INTO t1 VALUES ('á'); INSERT INTO t1 VALUES ('á');
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv --chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR --replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n')); --eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv --remove_file $MYSQLD_DATADIR/test/t1.csv
CREATE TABLE t1 CREATE TABLE t1
( (
c1 CHAR(12) NOT NULL c1 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'; ) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv';
INSERT INTO t1 VALUES ('á'); INSERT INTO t1 VALUES ('á');
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv --chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR --replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n')); --eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv --remove_file $MYSQLD_DATADIR/test/t1.csv
CREATE TABLE t1 CREATE TABLE t1
( (
c1 CHAR(12) NOT NULL c1 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv' ) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
CHARSET=latin1; CHARSET=latin1;
INSERT INTO t1 VALUES ('á'); INSERT INTO t1 VALUES ('á');
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv --chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR --replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n')); --eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv --remove_file $MYSQLD_DATADIR/test/t1.csv
CREATE TABLE t1 CREATE TABLE t1
( (
c1 CHAR(12) NOT NULL c1 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv' ) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
CHARSET=latin1 DATA_CHARSET=utf8; CHARSET=latin1 DATA_CHARSET=utf8;
INSERT INTO t1 VALUES ('á'); INSERT INTO t1 VALUES ('á');
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv --chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR --replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n')); --eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv --remove_file $MYSQLD_DATADIR/test/t1.csv
CREATE TABLE t1 CREATE TABLE t1
( (
c1 CHAR(12) CHARACTER SET latin1 NOT NULL, c1 CHAR(12) CHARACTER SET latin1 NOT NULL,
c2 CHAR(12) CHARACTER SET utf8 NOT NULL c2 CHAR(12) CHARACTER SET utf8 NOT NULL
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'; ) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv';
INSERT INTO t1 VALUES ('á','á'); INSERT INTO t1 VALUES ('á','á');
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.csv --chmod 0777 $MYSQLD_DATADIR/test/t1.csv
--replace_result $MYSQLD_DATADIR DATADIR --replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n')); --eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
--remove_file $MYSQLD_DATADIR/test/t1.csv --remove_file $MYSQLD_DATADIR/test/t1.csv
# #
# Clean up # Clean up
# #
--remove_file $MYSQLD_DATADIR/test/people.csv --remove_file $MYSQLD_DATADIR/test/people.csv
--remove_file $MYSQLD_DATADIR/test/tmp.csv --remove_file $MYSQLD_DATADIR/test/tmp.csv
let $MYSQLD_DATADIR= `select @@datadir`; let $MYSQLD_DATADIR= `select @@datadir`;
--echo # --echo #
--echo # Testing errors --echo # Testing errors
--echo # --echo #
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
--replace_regex /on .*test.t1.dbf/on DATADIR\/test\/t1.dbf/ --replace_regex /on .*test.t1.dbf/on DATADIR\/test\/t1.dbf/
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--replace_regex /Cannot open .*test.t1.dbf/Cannot open DATADIR\/test\/t1.dbf/ --replace_regex /Cannot open .*test.t1.dbf/Cannot open DATADIR\/test\/t1.dbf/
--error ER_UNKNOWN_ERROR --error ER_UNKNOWN_ERROR
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; 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/ --replace_regex /Cannot open .*test.t1.dbf/Cannot open DATADIR\/test\/t1.dbf/
SHOW WARNINGS; SHOW WARNINGS;
DELIMITER //; DELIMITER //;
CREATE PROCEDURE test.dbf_field(in fieldno INT, in content BLOB) DETERMINISTIC CREATE PROCEDURE test.dbf_field(in fieldno INT, in content BLOB) DETERMINISTIC
BEGIN BEGIN
SELECT '---'; SELECT '---';
SELECT fieldno AS `FieldN`; SELECT fieldno AS `FieldN`;
SELECT TRIM(TRAILING 0x00 FROM LEFT(content, 10)) AS `Name`; SELECT TRIM(TRAILING 0x00 FROM LEFT(content, 10)) AS `Name`;
SELECT SUBSTRING(content, 12, 1) AS `Type`; 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,13,4))),16,10) AS `Offset`;
SELECT CONV(HEX(REVERSE(SUBSTRING(content,17,1))),16,10) AS `Length`; 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 CONV(HEX(REVERSE(SUBSTRING(content,18,1))),16,10) AS `Dec`;
SELECT HEX(REVERSE(SUBSTRING(content,19,1))) AS `Flags`; 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,20,4))),16,10) AS `Next`;
-- SELECT CONV(HEX(REVERSE(SUBSTRING(content,24,4))),16,10) AS `Step`; -- SELECT CONV(HEX(REVERSE(SUBSTRING(content,24,4))),16,10) AS `Step`;
END// END//
CREATE PROCEDURE test.dbf_header(in fname VARCHAR(1024)) DETERMINISTIC CREATE PROCEDURE test.dbf_header(in fname VARCHAR(1024)) DETERMINISTIC
BEGIN BEGIN
DECLARE content BLOB; DECLARE content BLOB;
DECLARE offset INT; DECLARE offset INT;
DECLARE fieldno INT; DECLARE fieldno INT;
SELECT '--------'; SELECT '--------';
SELECT LOAD_FILE(fname) INTO content; SELECT LOAD_FILE(fname) INTO content;
SELECT LENGTH(content) AS FileSize; SELECT LENGTH(content) AS FileSize;
SELECT HEX(LEFT(content, 1)) AS DBF_Version; 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,5,4))),16,10) AS NRecords;
SELECT CONV(HEX(REVERSE(SUBSTRING(content,9,2))),16,10) AS FirstRecPos; 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 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,29,2))) AS TableFlags;
SELECT HEX(REVERSE(SUBSTRING(content,30,1))) AS CodePageMark; SELECT HEX(REVERSE(SUBSTRING(content,30,1))) AS CodePageMark;
SET offset=33; SET offset=33;
SET fieldno=0; SET fieldno=0;
WHILE SUBSTR(content, offset, 1) <> 0x0D AND offset + 32 < LENGTH(content) DO WHILE SUBSTR(content, offset, 1) <> 0x0D AND offset + 32 < LENGTH(content) DO
CALL dbf_field(fieldno, SUBSTRING(content, offset, 32)); CALL dbf_field(fieldno, SUBSTRING(content, offset, 32));
SET offset=offset + 32; SET offset=offset + 32;
SET fieldno=fieldno + 1; SET fieldno=fieldno + 1;
END WHILE; END WHILE;
SELECT '--------'; SELECT '--------';
END// END//
DELIMITER ;// DELIMITER ;//
--echo # --echo #
--echo # Testing READONLY tables --echo # Testing READONLY tables
--echo # --echo #
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (10),(20); INSERT INTO t1 VALUES (10),(20);
SELECT * FROM t1; SELECT * FROM t1;
ALTER TABLE t1 READONLY=Yes; ALTER TABLE t1 READONLY=Yes;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES (30); INSERT INTO t1 VALUES (30);
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
UPDATE t1 SET a=30 WHERE a=10; UPDATE t1 SET a=30 WHERE a=10;
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
DELETE FROM t1 WHERE a=10; DELETE FROM t1 WHERE a=10;
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
ALTER TABLE t1 READONLY=NO; ALTER TABLE t1 READONLY=NO;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (30); INSERT INTO t1 VALUES (30);
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf --remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo # --echo #
--echo # This SQL script crashed (dbf01.sql) --echo # This SQL script crashed (dbf01.sql)
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
a int(11) NOT NULL, a int(11) NOT NULL,
b char(10) NOT NULL, b char(10) NOT NULL,
c varchar(10) NOT NULL c varchar(10) NOT NULL
) ENGINE=CONNECT table_type=DBF file_name='t1.dbf'; ) ENGINE=CONNECT table_type=DBF file_name='t1.dbf';
INSERT INTO t1 VALUES (1,'1','1'); INSERT INTO t1 VALUES (1,'1','1');
INSERT INTO t1 VALUES (2,'2','2'); INSERT INTO t1 VALUES (2,'2','2');
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf --remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo # --echo #
--echo # Testing that table options in lower case and mixed case are understood: --echo # Testing that table options in lower case and mixed case are understood:
--echo # --echo #
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT table_type=dbf file_name='t1.dbf'; CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT table_type=dbf file_name='t1.dbf';
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (10); INSERT INTO t1 VALUES (10);
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf --remove_file $MYSQLD_DATADIR/test/t1.dbf
CREATE TABLE t1 (a CHAR(10) NOT NULL) ENGINE=CONNECT Table_Type=dbf File_Name='t1.dbf'; CREATE TABLE t1 (a CHAR(10) NOT NULL) ENGINE=CONNECT Table_Type=dbf File_Name='t1.dbf';
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ('test'); INSERT INTO t1 VALUES ('test');
SELECT * FROM t1; SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf --chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results --vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf'); eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results --horizontal_results
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf --remove_file $MYSQLD_DATADIR/test/t1.dbf
# #
# TODO: this creates DBF record with length=32, which looks wrong # TODO: this creates DBF record with length=32, which looks wrong
# #
--echo # --echo #
--echo # Testing multiple columns --echo # Testing multiple columns
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
a INT NOT NULL, a INT NOT NULL,
b CHAR(10) NOT NULL, b CHAR(10) NOT NULL,
c VARCHAR(10) NOT NULL c VARCHAR(10) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (1,'1','1'); INSERT INTO t1 VALUES (1,'1','1');
INSERT INTO t1 VALUES (2,'2','2'); INSERT INTO t1 VALUES (2,'2','2');
SELECT * FROM t1; SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf --chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results --vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf'); eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results --horizontal_results
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf --remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo # --echo #
--echo # Testing long column name --echo # Testing long column name
--echo # --echo #
--error ER_UNKNOWN_ERROR --error ER_UNKNOWN_ERROR
CREATE TABLE t1 CREATE TABLE t1
( (
a012345678901234567890123456789 INT NOT NULL a012345678901234567890123456789 INT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--echo # --echo #
--echo # Testing 2 columns with long names (12) --echo # Testing 2 columns with long names (12)
--echo # --echo #
--error ER_UNKNOWN_ERROR --error ER_UNKNOWN_ERROR
CREATE TABLE t1 CREATE TABLE t1
( (
a0123456789a INT NOT NULL, a0123456789a INT NOT NULL,
b0123456789b INT NOT NULL b0123456789b INT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t02x11.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t02x11.dbf';
--echo # --echo #
--echo # Testing 2 columns with long names (11) --echo # Testing 2 columns with long names (11)
--echo # --echo #
--error ER_UNKNOWN_ERROR --error ER_UNKNOWN_ERROR
CREATE TABLE t1 CREATE TABLE t1
( (
a012345678a INT NOT NULL, a012345678a INT NOT NULL,
b012345678b INT NOT NULL b012345678b INT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t02x12.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t02x12.dbf';
--echo # --echo #
--echo # Testing 2 columns name length 10 (maximum possible length) --echo # Testing 2 columns name length 10 (maximum possible length)
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
a01234567a INT NOT NULL, a01234567a INT NOT NULL,
b01234567b INT NOT NULL b01234567b INT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t02x13.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t02x13.dbf';
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (1,2); INSERT INTO t1 VALUES (1,2);
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t02x13.dbf --remove_file $MYSQLD_DATADIR/test/t02x13.dbf
--echo # --echo #
--echo # Testing BIGINT --echo # Testing BIGINT
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
a bigint NOT NULL a bigint NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (0x7FFFFFFFFFFFFFFF); INSERT INTO t1 VALUES (0x7FFFFFFFFFFFFFFF);
INSERT INTO t1 VALUES (-0x8000000000000000); INSERT INTO t1 VALUES (-0x8000000000000000);
SELECT * FROM t1; SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf --chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results --vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf'); eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results --horizontal_results
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf --remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo # --echo #
--echo # Testing TINYINT --echo # Testing TINYINT
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
a TINYINT NOT NULL a TINYINT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (123); INSERT INTO t1 VALUES (123);
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf --remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo # --echo #
--echo # Testing SMALLINT --echo # Testing SMALLINT
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
a SMALLINT NOT NULL a SMALLINT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (0x7FFF); INSERT INTO t1 VALUES (0x7FFF);
INSERT INTO t1 VALUES (-0x8000); INSERT INTO t1 VALUES (-0x8000);
SELECT * FROM t1; SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf --chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results --vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf'); eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results --horizontal_results
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf --remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo # --echo #
--echo # Testing VARCHAR --echo # Testing VARCHAR
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
a VARCHAR(255) NOT NULL a VARCHAR(255) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (REPEAT('a',255)); INSERT INTO t1 VALUES (REPEAT('a',255));
SELECT LENGTH(a) FROM t1; SELECT LENGTH(a) FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf --chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results --vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf'); eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results --horizontal_results
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf --remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo # --echo #
--echo # Testing too long CHAR --echo # Testing too long CHAR
--echo # All columns longer than 255 bytes should be rejected --echo # All columns longer than 255 bytes should be rejected
--echo # --echo #
--error ER_UNKNOWN_ERROR --error ER_UNKNOWN_ERROR
CREATE TABLE t1 CREATE TABLE t1
( (
a CHAR(86) CHARACTER SET utf8 NOT NULL a CHAR(86) CHARACTER SET utf8 NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR --error ER_UNKNOWN_ERROR
--echo # --echo #
--echo # Testing too long VARCHAR --echo # Testing too long VARCHAR
--echo # All columns longer than 255 bytes should be rejected --echo # All columns longer than 255 bytes should be rejected
--echo # --echo #
--error ER_UNKNOWN_ERROR --error ER_UNKNOWN_ERROR
CREATE TABLE t1 CREATE TABLE t1
( (
a VARCHAR(256) NOT NULL a VARCHAR(256) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR --error ER_UNKNOWN_ERROR
CREATE TABLE t1 CREATE TABLE t1
( (
a VARCHAR(86) CHARACTER SET utf8 NOT NULL a VARCHAR(86) CHARACTER SET utf8 NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR --error ER_UNKNOWN_ERROR
CREATE TABLE t1 CREATE TABLE t1
( (
a VARCHAR(64000) NOT NULL a VARCHAR(64000) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--echo # --echo #
--echo # Testing BLOB --echo # Testing BLOB
--echo # --echo #
--error ER_UNKNOWN_ERROR --error ER_UNKNOWN_ERROR
CREATE TABLE t1 CREATE TABLE t1
( (
a BLOB a BLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR --error ER_UNKNOWN_ERROR
CREATE TABLE t1 CREATE TABLE t1
( (
a TINYBLOB a TINYBLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR --error ER_UNKNOWN_ERROR
CREATE TABLE t1 CREATE TABLE t1
( (
a MEDIUMBLOB a MEDIUMBLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR --error ER_UNKNOWN_ERROR
CREATE TABLE t1 CREATE TABLE t1
( (
a LONGBLOB a LONGBLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
# TODO: utf8 does not work # TODO: utf8 does not work
#--echo # #--echo #
#--echo # Testing varchar with utf8 #--echo # Testing varchar with utf8
#--echo # #--echo #
#SET NAMES utf8; #SET NAMES utf8;
#CREATE TABLE t1 #CREATE TABLE t1
#( #(
# a VARCHAR(10) CHARACTER SET utf8 # a VARCHAR(10) CHARACTER SET utf8
#) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; #) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
#INSERT INTO t1 VALUES (REPEAT(_ucs2 0x00DF,10)); #INSERT INTO t1 VALUES (REPEAT(_ucs2 0x00DF,10));
#SELECT * FROM t1; #SELECT * FROM t1;
#DROP TABLE IF EXISTS t1; #DROP TABLE IF EXISTS t1;
#--remove_file $MYSQLD_DATADIR/test/t1.dbf #--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo # --echo #
--echo # Testing DATE --echo # Testing DATE
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
a DATE NOT NULL a DATE NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES ('2001-01-01'); INSERT INTO t1 VALUES ('2001-01-01');
SELECT * FROM t1; SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf --chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results --vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf'); eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results --horizontal_results
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf --remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo # --echo #
--echo # Testing FLOAT --echo # Testing FLOAT
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
a FLOAT(12,4) NOT NULL a FLOAT(12,4) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (123); INSERT INTO t1 VALUES (123);
SELECT * FROM t1; SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf --chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results --vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf'); eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results --horizontal_results
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf --remove_file $MYSQLD_DATADIR/test/t1.dbf
# #
# TODO: this return error: # TODO: this return error:
# Got error 122 'Value 123.0000000000 too long for column a of length 12' # Got error 122 'Value 123.0000000000 too long for column a of length 12'
# from CONNECT # from CONNECT
# #
#CREATE TABLE t1 #CREATE TABLE t1
#( #(
# a FLOAT NOT NULL # a FLOAT NOT NULL
#) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; #) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
#--error ER_GET_ERRMSG - why this error? #--error ER_GET_ERRMSG - why this error?
#INSERT INTO t1 VALUES (123); #INSERT INTO t1 VALUES (123);
#SELECT * FROM t1; #SELECT * FROM t1;
#DROP TABLE IF EXISTS t1; #DROP TABLE IF EXISTS t1;
#--remove_file $MYSQLD_DATADIR/test/t1.dbf #--remove_file $MYSQLD_DATADIR/test/t1.dbf
# #
# TODO: this creates a column of type 'D' (date), which is wrong # TODO: this creates a column of type 'D' (date), which is wrong
# #
#--echo # #--echo #
#--echo # Testing DATETIME #--echo # Testing DATETIME
#--echo # #--echo #
#CREATE TABLE t1 #CREATE TABLE t1
#( #(
# a DATETIME NOT NULL # a DATETIME NOT NULL
#) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; #) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
#INSERT INTO t1 VALUES ('2013-02-01'); #INSERT INTO t1 VALUES ('2013-02-01');
#SELECT * FROM t1; #SELECT * FROM t1;
#DROP TABLE t1; #DROP TABLE t1;
#--remove_file $MYSQLD_DATADIR/test/t1.dbf #--remove_file $MYSQLD_DATADIR/test/t1.dbf
# #
# TODO: this creates a column of type 'D' (date), which is wrong # TODO: this creates a column of type 'D' (date), which is wrong
# #
#--echo # #--echo #
#--echo # Testing TIMESTAMP #--echo # Testing TIMESTAMP
#--echo # #--echo #
#CREATE TABLE t1 #CREATE TABLE t1
#( #(
# a TIMESTAMP # a TIMESTAMP
#) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; #) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
#INSERT INTO t1 VALUES ('2013-02-01'); #INSERT INTO t1 VALUES ('2013-02-01');
#SELECT * FROM t1; #SELECT * FROM t1;
#DROP TABLE t1; #DROP TABLE t1;
#--remove_file $MYSQLD_DATADIR/test/t1.dbf #--remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo # --echo #
--echo # Testing double --echo # Testing double
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
a DOUBLE(20,5) NOT NULL a DOUBLE(20,5) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES (123); INSERT INTO t1 VALUES (123);
INSERT INTO t1 VALUES (123456789.12345); INSERT INTO t1 VALUES (123456789.12345);
SELECT * FROM t1; SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf --chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results --vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf'); eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results --horizontal_results
DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf --remove_file $MYSQLD_DATADIR/test/t1.dbf
# TODO: # TODO:
# Testing with no FILE_NAME specified # Testing with no FILE_NAME specified
# Currently it returns: # Currently it returns:
# ERROR 1296 (HY000): Got error 174 'Open(a+) error 21 # ERROR 1296 (HY000): Got error 174 'Open(a+) error 21
# on /opt/mariadb-5.5/data/: Is a directory' from CONNECT # on /opt/mariadb-5.5/data/: Is a directory' from CONNECT
#CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=DBF; #CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=DBF;
--echo # --echo #
--echo # Testing ALTER --echo # Testing ALTER
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
a VARCHAR(10) NOT NULL a VARCHAR(10) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES ('10'); INSERT INTO t1 VALUES ('10');
SELECT * FROM t1; SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf --chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results --vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf'); eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results --horizontal_results
ALTER TABLE t1 MODIFY a VARCHAR(10) NOT NULL; ALTER TABLE t1 MODIFY a VARCHAR(10) NOT NULL;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
SELECT * FROM t1; SELECT * FROM t1;
--vertical_results --vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf'); eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results --horizontal_results
ALTER TABLE t1 MODIFY a INT(10) NOT NULL; ALTER TABLE t1 MODIFY a INT(10) NOT NULL;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
SELECT * FROM t1; SELECT * FROM t1;
--vertical_results --vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf'); eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results --horizontal_results
# TODO: this does not work on Windows # TODO: this does not work on Windows
#ALTER TABLE t1 MODIFY a INT(8) NOT NULL; #ALTER TABLE t1 MODIFY a INT(8) NOT NULL;
#SHOW CREATE TABLE t1; #SHOW CREATE TABLE t1;
#--error ER_GET_ERRMSG #--error ER_GET_ERRMSG
#SELECT * FROM t1; #SELECT * FROM t1;
#--vertical_results #--vertical_results
#--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR #--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
#eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf'); #eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
#--horizontal_results #--horizontal_results
DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf --remove_file $MYSQLD_DATADIR/test/t1.dbf
--echo # --echo #
--echo # Testing NULL --echo # Testing NULL
--echo # --echo #
# TODO: NULLs should probably change to DEFAULT and produce a warning # TODO: NULLs should probably change to DEFAULT and produce a warning
CREATE TABLE t1 CREATE TABLE t1
( (
c1 VARCHAR(10) NOT NULL, c1 VARCHAR(10) NOT NULL,
c2 VARCHAR(10) NOT NULL DEFAULT 'def', c2 VARCHAR(10) NOT NULL DEFAULT 'def',
i1 INT NOT NULL, i1 INT NOT NULL,
i2 INT NOT NULL DEFAULT 123 i2 INT NOT NULL DEFAULT 123
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf'; ) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
INSERT INTO t1 VALUES ('10','10',10,10); INSERT INTO t1 VALUES ('10','10',10,10);
#INSERT INTO t1 VALUES (NULL,NULL,NULL,NULL); #INSERT INTO t1 VALUES (NULL,NULL,NULL,NULL);
INSERT INTO t1(c1,i1) VALUES ('20',20); INSERT INTO t1(c1,i1) VALUES ('20',20);
INSERT INTO t1 VALUES ('30',DEFAULT,30,DEFAULT); INSERT INTO t1 VALUES ('30',DEFAULT,30,DEFAULT);
SELECT * FROM t1; SELECT * FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.dbf --chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
--vertical_results --vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf'); eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
--horizontal_results --horizontal_results
DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t1;
--remove_file $MYSQLD_DATADIR/test/t1.dbf --remove_file $MYSQLD_DATADIR/test/t1.dbf
DROP PROCEDURE test.dbf_field; DROP PROCEDURE test.dbf_field;
DROP PROCEDURE test.dbf_header; DROP PROCEDURE test.dbf_header;
let $MYSQLD_DATADIR= `select @@datadir`; 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/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/boys.txt $MYSQLD_DATADIR/test/boys.txt
--copy_file $MTR_SUITE_DIR/std_data/boyswin.txt $MYSQLD_DATADIR/test/boyswin.txt --copy_file $MTR_SUITE_DIR/std_data/boyswin.txt $MYSQLD_DATADIR/test/boyswin.txt
--echo # --echo #
--echo # Testing errors --echo # Testing errors
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
ID INT NOT NULL ID INT NOT NULL
) Engine=CONNECT TABLE_TYPE=DOS FILE_NAME='nonexistent.txt'; ) Engine=CONNECT TABLE_TYPE=DOS FILE_NAME='nonexistent.txt';
--replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/ --replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/
# TODO: check why this is needed for Windows # TODO: check why this is needed for Windows
--replace_result Open(rt) Open(rb) --replace_result Open(rt) Open(rb)
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--echo # --echo #
--echo # Testing READONLY tables --echo # Testing READONLY tables
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
id INT NOT NULL id INT NOT NULL
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='t1.txt'; ) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='t1.txt';
INSERT INTO t1 VALUES (10); INSERT INTO t1 VALUES (10);
SELECT * FROM t1; SELECT * FROM t1;
ALTER TABLE t1 READONLY=1; ALTER TABLE t1 READONLY=1;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES (20); INSERT INTO t1 VALUES (20);
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
UPDATE t1 SET id=20 WHERE id=10; UPDATE t1 SET id=20 WHERE id=10;
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
DELETE FROM t1 WHERE id=10; DELETE FROM t1 WHERE id=10;
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
ALTER TABLE t1 READONLY=0; ALTER TABLE t1 READONLY=0;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (20); INSERT INTO t1 VALUES (20);
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.txt --remove_file $MYSQLD_DATADIR/test/t1.txt
--echo # --echo #
--echo # Testing manual examples --echo # Testing manual examples
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
number CHAR(4) not null, number CHAR(4) not null,
location CHAR(15) NOT NULL flag=5, location CHAR(15) NOT NULL flag=5,
director CHAR(5) NOT NULL flag=20, director CHAR(5) NOT NULL flag=20,
function CHAR(12) NOT NULL flag=26, function CHAR(12) NOT NULL flag=26,
name CHAR(22) NOT NULL flag=38 name CHAR(22) NOT NULL flag=38
) ENGINE=CONNECT TABLE_TYPE=DOS FILE_NAME='dept.dat'; ) ENGINE=CONNECT TABLE_TYPE=DOS FILE_NAME='dept.dat';
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 CREATE TABLE t1
( (
name char(12) not null, name char(12) not null,
city char(12) not null, city char(12) not null,
birth date not null date_format='DD/MM/YYYY', birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36 hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' ENDING=1; ) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' ENDING=1;
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 CREATE TABLE t1
( (
name char(12) not null, name char(12) not null,
city char(12) not null, city char(12) not null,
birth date not null date_format='DD/MM/YYYY', birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36 hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' LRECL=47 ENDING=1; ) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' LRECL=47 ENDING=1;
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 CREATE TABLE t1
( (
name char(12) not null, name char(12) not null,
city char(12) not null, city char(12) not null,
birth date not null date_format='DD/MM/YYYY', birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36 hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boyswin.txt' ENDING=2; ) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boyswin.txt' ENDING=2;
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 CREATE TABLE t1
( (
name char(12) not null, name char(12) not null,
city char(12) not null, city char(12) not null,
birth date not null date_format='DD/MM/YYYY', birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36 hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boyswin.txt' LRECL=47 ENDING=2; ) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boyswin.txt' LRECL=47 ENDING=2;
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
# #
# Clean up # Clean up
# #
--remove_file $MYSQLD_DATADIR/test/dept.dat --remove_file $MYSQLD_DATADIR/test/dept.dat
--remove_file $MYSQLD_DATADIR/test/boys.txt --remove_file $MYSQLD_DATADIR/test/boys.txt
--remove_file $MYSQLD_DATADIR/test/boyswin.txt --remove_file $MYSQLD_DATADIR/test/boyswin.txt
let $MYSQLD_DATADIR= `select @@datadir`; let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/contact.ini $MYSQLD_DATADIR/test/contact.ini --copy_file $MTR_SUITE_DIR/std_data/contact.ini $MYSQLD_DATADIR/test/contact.ini
--echo # --echo #
--echo # Testing errors --echo # Testing errors
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
ID INT ID INT
) Engine=CONNECT TABLE_TYPE=INI FILE_NAME='nonexistent.txt'; ) Engine=CONNECT TABLE_TYPE=INI FILE_NAME='nonexistent.txt';
--replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/ --replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/
# TODO: check why this is needed for Windows # TODO: check why this is needed for Windows
--replace_result Open(rt) Open(rb) --replace_result Open(rt) Open(rb)
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--echo # --echo #
--echo # Testing examples from the manual --echo # Testing examples from the manual
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
contact CHAR(16) flag=1, contact CHAR(16) flag=1,
name CHAR(20), name CHAR(20),
forename CHAR(32), forename CHAR(32),
hired date date_format='DD/MM/YYYY', hired date date_format='DD/MM/YYYY',
address CHAR(64), address CHAR(64),
city CHAR(20), city CHAR(20),
zipcode CHAR(8), zipcode CHAR(8),
tel CHAR(16) tel CHAR(16)
) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='contact.ini'; ) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='contact.ini';
SELECT contact, name, hired, city, tel FROM t1; SELECT contact, name, hired, city, tel FROM t1;
UPDATE t1 SET forename= 'Harry' where contact='UK1'; UPDATE t1 SET forename= 'Harry' where contact='UK1';
SELECT * FROM t1 WHERE contact='UK1'; SELECT * FROM t1 WHERE contact='UK1';
INSERT INTO t1 (contact,forename) VALUES ('UK1','Harrison'); INSERT INTO t1 (contact,forename) VALUES ('UK1','Harrison');
SELECT * FROM t1 WHERE contact='UK1'; SELECT * FROM t1 WHERE contact='UK1';
INSERT INTO t1 (contact,forename) VALUES ('UK2','John'); INSERT INTO t1 (contact,forename) VALUES ('UK2','John');
SELECT * FROM t1 WHERE contact='UK2'; SELECT * FROM t1 WHERE contact='UK2';
DROP TABLE t1; DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/contact.ini --chmod 0777 $MYSQLD_DATADIR/test/contact.ini
--replace_result $MYSQLD_DATADIR DATADIR --replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/contact.ini'),'\r\n','\n'),'\n\n','\n'); --eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/contact.ini'),'\r\n','\n'),'\n\n','\n');
CREATE TABLE t1 CREATE TABLE t1
( (
section CHAR(16) flag=1, section CHAR(16) flag=1,
keyname CHAR(16) flag=2, keyname CHAR(16) flag=2,
value CHAR(32) value CHAR(32)
) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='contact.ini' ) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='contact.ini'
OPTION_LIST='Layout=Row'; OPTION_LIST='Layout=Row';
UPDATE t1 SET value='Paul' WHERE section='UK2' AND keyname='forename'; UPDATE t1 SET value='Paul' WHERE section='UK2' AND keyname='forename';
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/contact.ini --chmod 0777 $MYSQLD_DATADIR/test/contact.ini
--replace_result $MYSQLD_DATADIR DATADIR --replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/contact.ini'),'\r\n','\n'),'\n\n','\n'); --eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/contact.ini'),'\r\n','\n'),'\n\n','\n');
--echo # --echo #
--echo # Testing that the underlying file is created --echo # Testing that the underlying file is created
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
contact CHAR(12) NOT NULL flag=1, contact CHAR(12) NOT NULL flag=1,
c2 CHAR(12) NOT NULL c2 CHAR(12) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='tmp.ini'; ) 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'); INSERT INTO t1 VALUES (10,10),(20,20),(300,300),(4000,4000), ('a b','c d');
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--chmod 0777 $MYSQLD_DATADIR/test/tmp.ini --chmod 0777 $MYSQLD_DATADIR/test/tmp.ini
--replace_result $MYSQLD_DATADIR DATADIR --replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/tmp.ini'),'\r\n','\n'),'\n\n','\n'); --eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/tmp.ini'),'\r\n','\n'),'\n\n','\n');
--echo # --echo #
--echo # Testing bad table --echo # Testing bad table
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
id INT id INT
) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.ini'; ) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.ini';
--error ER_GET_ERRMSG --error ER_GET_ERRMSG
INSERT INTO t1 VALUES (10); INSERT INTO t1 VALUES (10);
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--echo # --echo #
--echo # Testing READONLY tables --echo # Testing READONLY tables
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t1
( (
contact CHAR(10) flag=1, contact CHAR(10) flag=1,
c2 CHAR(60) c2 CHAR(60)
) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.ini'; ) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.ini';
INSERT INTO t1 VALUES ('UK',10),('FR',20),('RU',30); INSERT INTO t1 VALUES ('UK',10),('FR',20),('RU',30);
SELECT * FROM t1; SELECT * FROM t1;
ALTER TABLE t1 READONLY=1; ALTER TABLE t1 READONLY=1;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES ('US',40); INSERT INTO t1 VALUES ('US',40);
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
UPDATE t1 SET c2=20 WHERE c2=10; UPDATE t1 SET c2=20 WHERE c2=10;
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
DELETE FROM t1 WHERE c2=10; DELETE FROM t1 WHERE c2=10;
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
ALTER TABLE t1 READONLY=0; ALTER TABLE t1 READONLY=0;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ('US',40); INSERT INTO t1 VALUES ('US',40);
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.ini --remove_file $MYSQLD_DATADIR/test/t1.ini
# #
# Clean up # Clean up
# #
--remove_file $MYSQLD_DATADIR/test/contact.ini --remove_file $MYSQLD_DATADIR/test/contact.ini
--remove_file $MYSQLD_DATADIR/test/tmp.ini --remove_file $MYSQLD_DATADIR/test/tmp.ini
--echo # --echo #
--echo # Bug: TABLE_TYPE=ini does not clear memory between CREATE TABLEs --echo # Bug: TABLE_TYPE=ini does not clear memory between CREATE TABLEs
--echo # --echo #
CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL) CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=INI; ENGINE=CONNECT TABLE_TYPE=INI;
INSERT INTO t1 VALUES ('sec1','val1'),('sec2','val2'); INSERT INTO t1 VALUES ('sec1','val1'),('sec2','val2');
SELECT sec AS s, val AS v FROM t1; SELECT sec AS s, val AS v FROM t1;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (sec2 CHAR(10) NOT NULL FLAG=1, val2 CHAR(10) NOT NULL) CREATE TABLE t1 (sec2 CHAR(10) NOT NULL FLAG=1, val2 CHAR(10) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=INI; ENGINE=CONNECT TABLE_TYPE=INI;
INSERT INTO t1 VALUES ('sec1','val11'),('sec2','val22'); INSERT INTO t1 VALUES ('sec1','val11'),('sec2','val22');
SELECT sec2 AS s, val2 AS v FROM t1; SELECT sec2 AS s, val2 AS v FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.ini --chmod 0777 $MYSQLD_DATADIR/test/t1.ini
--replace_result $MYSQLD_DATADIR DATADIR --replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.ini'),'\r\n','\n'),'\n\n','\n'); --eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.ini'),'\r\n','\n'),'\n\n','\n');
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL) CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=INI; ENGINE=CONNECT TABLE_TYPE=INI;
CREATE TABLE t2 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL) CREATE TABLE t2 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=INI; ENGINE=CONNECT TABLE_TYPE=INI;
INSERT INTO t1 VALUES('1sec1','1val1'),('1sec2','1val2'); INSERT INTO t1 VALUES('1sec1','1val1'),('1sec2','1val2');
INSERT INTO t2 VALUES('2sec1','2val1'),('2sec2','2val2'); INSERT INTO t2 VALUES('2sec1','2val1'),('2sec2','2val2');
SELECT sec AS s, val AS v FROM t1; SELECT sec AS s, val AS v FROM t1;
--chmod 0777 $MYSQLD_DATADIR/test/t1.ini --chmod 0777 $MYSQLD_DATADIR/test/t1.ini
--replace_result $MYSQLD_DATADIR DATADIR --replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.ini'),'\r\n','\n'),'\n\n','\n'); --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; SELECT sec AS s, val AS v FROM t2;
--chmod 0777 $MYSQLD_DATADIR/test/t2.ini --chmod 0777 $MYSQLD_DATADIR/test/t2.ini
--replace_result $MYSQLD_DATADIR DATADIR --replace_result $MYSQLD_DATADIR DATADIR
--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t2.ini'),'\r\n','\n'),'\n\n','\n'); --eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t2.ini'),'\r\n','\n'),'\n\n','\n');
DROP TABLE t1, t2; DROP TABLE t1, t2;
let $MYSQLD_DATADIR= `select @@datadir`; let $MYSQLD_DATADIR= `select @@datadir`;
CREATE TABLE dir1 ( CREATE TABLE dir1 (
spath VARCHAR(256) NOT NULL flag=1, spath VARCHAR(256) NOT NULL flag=1,
fname VARCHAR(256) NOT NULL, fname VARCHAR(256) NOT NULL,
ftype CHAR(4) NOT NULL, ftype CHAR(4) NOT NULL,
size DOUBLE(12,0) NOT NULL flag=5 size DOUBLE(12,0) NOT NULL flag=5
) ENGINE=CONNECT TABLE_TYPE=DIR FILE_NAME='*vec*'; ) ENGINE=CONNECT TABLE_TYPE=DIR FILE_NAME='*vec*';
CREATE TABLE t1 CREATE TABLE t1
( (
a INT NOT NULL, a INT NOT NULL,
b CHAR(10) NOT NULL b CHAR(10) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=VEC FILE_NAME='t1vec'; ) ENGINE=CONNECT TABLE_TYPE=VEC FILE_NAME='t1vec';
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
# Testing SELECT on empty file # Testing SELECT on empty file
--replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/ --replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
SELECT * FROM t1; SELECT * FROM t1;
INSERT INTO t1 VALUES (0,'test01'), (1,'test01'), (2,'test02'), (3,'test03'); INSERT INTO t1 VALUES (0,'test01'), (1,'test01'), (2,'test02'), (3,'test03');
SELECT * FROM t1; SELECT * FROM t1;
SELECT a FROM t1; SELECT a FROM t1;
SELECT b FROM t1; SELECT b FROM t1;
--replace_result $MYSQLD_DATADIR DATADIR/ --replace_result $MYSQLD_DATADIR DATADIR/
SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype; SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype;
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1vec1 --remove_file $MYSQLD_DATADIR/test/t1vec1
--remove_file $MYSQLD_DATADIR/test/t1vec2 --remove_file $MYSQLD_DATADIR/test/t1vec2
CREATE TABLE t1 CREATE TABLE t1
( (
a INT NOT NULL, a INT NOT NULL,
b CHAR(10) NOT NULL b CHAR(10) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=VEC FILE_NAME='t1vec' MAX_ROWS=10; ) ENGINE=CONNECT TABLE_TYPE=VEC FILE_NAME='t1vec' MAX_ROWS=10;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
# Testing SELECTs on empty file # Testing SELECTs on empty file
--replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/ --replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
SELECT * FROM t1; SELECT * FROM t1;
--replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/ --replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
SELECT a FROM t1; SELECT a FROM t1;
--replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/ --replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
SELECT b FROM t1; SELECT b FROM t1;
INSERT INTO t1 VALUES (0,'test01'), (1,'test01'), (2,'test02'), (3,'test03'); INSERT INTO t1 VALUES (0,'test01'), (1,'test01'), (2,'test02'), (3,'test03');
SELECT * FROM t1; SELECT * FROM t1;
SELECT a FROM t1; SELECT a FROM t1;
SELECT b FROM t1; SELECT b FROM t1;
--replace_result $MYSQLD_DATADIR DATADIR/ --replace_result $MYSQLD_DATADIR DATADIR/
SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype; SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype;
--echo # --echo #
--echo # Testing READONLY --echo # Testing READONLY
--echo # --echo #
ALTER TABLE t1 READONLY=yes; ALTER TABLE t1 READONLY=yes;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES (4,'test04'); INSERT INTO t1 VALUES (4,'test04');
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
UPDATE t1 SET b='test04' WHERE a=3; UPDATE t1 SET b='test04' WHERE a=3;
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
DELETE FROM t1 WHERE a=3; DELETE FROM t1 WHERE a=3;
--error ER_GET_ERRMSG --error ER_OPEN_AS_READONLY
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
ALTER TABLE t1 READONLY=no; ALTER TABLE t1 READONLY=no;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (4,'test04'); INSERT INTO t1 VALUES (4,'test04');
UPDATE t1 SET b='test04a' WHERE a=4; UPDATE t1 SET b='test04a' WHERE a=4;
DELETE FROM t1 WHERE a=0; DELETE FROM t1 WHERE a=0;
SELECT * FROM t1; SELECT * FROM t1;
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype; SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype;
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1vec --remove_file $MYSQLD_DATADIR/test/t1vec
--remove_file $MYSQLD_DATADIR/test/t1vec.blk --remove_file $MYSQLD_DATADIR/test/t1vec.blk
--echo # --echo #
--echo # Clean up --echo # Clean up
--echo # --echo #
DROP TABLE dir1; DROP TABLE dir1;
...@@ -873,7 +873,8 @@ ODBConn::ODBConn(PGLOBAL g, TDBODBC *tdbp) ...@@ -873,7 +873,8 @@ ODBConn::ODBConn(PGLOBAL g, TDBODBC *tdbp)
m_Connect = NULL; m_Connect = NULL;
m_Updatable = true; m_Updatable = true;
m_Transact = false; m_Transact = false;
m_IDQuoteChar = '\''; m_IDQuoteChar[0] = '"';
m_IDQuoteChar[1] = 0;
//*m_ErrMsg = '\0'; //*m_ErrMsg = '\0';
} // end of ODBConn } // end of ODBConn
...@@ -1232,16 +1233,9 @@ void ODBConn::GetConnectInfo() ...@@ -1232,16 +1233,9 @@ void ODBConn::GetConnectInfo()
SQL_MODE_READ_ONLY); SQL_MODE_READ_ONLY);
#endif // 0 #endif // 0
// Cache the quote char to use when constructing SQL // Get the quote char to use when constructing SQL
char QuoteChar[2];
rc = SQLGetInfo(m_hdbc, SQL_IDENTIFIER_QUOTE_CHAR, rc = SQLGetInfo(m_hdbc, SQL_IDENTIFIER_QUOTE_CHAR,
QuoteChar, sizeof(QuoteChar), &nResult); m_IDQuoteChar, sizeof(m_IDQuoteChar), &nResult);
if (Check(rc) && nResult == 1)
m_IDQuoteChar = QuoteChar[0];
else
m_IDQuoteChar = ' ';
if (trace) if (trace)
htrc("DBMS: %s, Version: %s\n", htrc("DBMS: %s, Version: %s\n",
......
...@@ -127,7 +127,7 @@ class ODBConn : public BLOCK { ...@@ -127,7 +127,7 @@ class ODBConn : public BLOCK {
// Attributes // Attributes
public: public:
char GetQuoteChar(void) {return m_IDQuoteChar;} char *GetQuoteChar(void) {return m_IDQuoteChar;}
// Database successfully opened? // Database successfully opened?
bool IsOpen(void) {return m_hdbc != SQL_NULL_HDBC;} bool IsOpen(void) {return m_hdbc != SQL_NULL_HDBC;}
PSZ GetStringInfo(ushort infotype); PSZ GetStringInfo(ushort infotype);
...@@ -184,9 +184,9 @@ class ODBConn : public BLOCK { ...@@ -184,9 +184,9 @@ class ODBConn : public BLOCK {
DWORD m_QueryTimeout; DWORD m_QueryTimeout;
DWORD m_UpdateOptions; DWORD m_UpdateOptions;
DWORD m_RowsetSize; DWORD m_RowsetSize;
char m_IDQuoteChar[2];
int m_Catver; int m_Catver;
PSZ m_Connect; PSZ m_Connect;
bool m_Updatable; bool m_Updatable;
bool m_Transact; bool m_Transact;
char m_IDQuoteChar;
}; // end of ODBConn class definition }; // end of ODBConn class definition
...@@ -593,4 +593,4 @@ int global_open(GLOBAL *g, int msgid, const char *filename, int flags, int mode) ...@@ -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); DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR name, LPCSTR dir);
char *MakeEscape(PGLOBAL g, char* str, char q); 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) ...@@ -524,6 +524,7 @@ bool TDBCAT::OpenDB(PGLOBAL g)
if (Initialize(g)) if (Initialize(g))
return true; return true;
Use = USE_OPEN;
return InitCol(g); return InitCol(g);
} // end of OpenDB } // end of OpenDB
......
...@@ -495,6 +495,7 @@ bool TDBOCCUR::OpenDB(PGLOBAL g) ...@@ -495,6 +495,7 @@ bool TDBOCCUR::OpenDB(PGLOBAL g)
if (Tdbp->OpenDB(g)) if (Tdbp->OpenDB(g))
return TRUE; return TRUE;
Use = USE_OPEN;
return ViewColumnList(g); return ViewColumnList(g);
} // end of OpenDB } // end of OpenDB
......
...@@ -90,8 +90,8 @@ extern int num_read, num_there, num_eq[2]; // Statistics ...@@ -90,8 +90,8 @@ extern int num_read, num_there, num_eq[2]; // Statistics
/***********************************************************************/ /***********************************************************************/
ODBCDEF::ODBCDEF(void) ODBCDEF::ODBCDEF(void)
{ {
Connect = Tabname = Tabowner = Tabqual = Srcdef = Qchar = Qrystr = NULL; Connect = Tabname = Tabowner = Tabqual = Srcdef = Qrystr = NULL;
Catver = Options = 0; Catver = Options = Quoted = 0;
Xsrc = false; Xsrc = false;
} // end of ODBCDEF constructor } // end of ODBCDEF constructor
...@@ -107,11 +107,11 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -107,11 +107,11 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Tabowner = Cat->GetStringCatInfo(g, "Owner", ""); Tabowner = Cat->GetStringCatInfo(g, "Owner", "");
Tabqual = Cat->GetStringCatInfo(g, "Qualifier", ""); Tabqual = Cat->GetStringCatInfo(g, "Qualifier", "");
Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL); Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL);
Qchar = Cat->GetStringCatInfo(g, "Qchar", "");
Qrystr = Cat->GetStringCatInfo(g, "Query_String", "?"); Qrystr = Cat->GetStringCatInfo(g, "Query_String", "?");
Catver = Cat->GetIntCatInfo("Catver", 2); Catver = Cat->GetIntCatInfo("Catver", 2);
Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE); Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE);
Mxr = Cat->GetIntCatInfo("Maxerr", 0); Mxr = Cat->GetIntCatInfo("Maxerr", 0);
Quoted = Cat->GetIntCatInfo("Quoted", 0);
Options = ODBConn::noOdbcDialog; Options = ODBConn::noOdbcDialog;
Pseudo = 2; // FILID is Ok but not ROWID Pseudo = 2; // FILID is Ok but not ROWID
return false; return false;
...@@ -171,9 +171,9 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp) ...@@ -171,9 +171,9 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
Owner = tdp->Tabowner; Owner = tdp->Tabowner;
Qualifier = tdp->Tabqual; Qualifier = tdp->Tabqual;
Srcdef = tdp->Srcdef; Srcdef = tdp->Srcdef;
Quote = tdp->GetQchar();
Qrystr = tdp->Qrystr; Qrystr = tdp->Qrystr;
Options = tdp->Options; Options = tdp->Options;
Quoted = max(0, tdp->GetQuoted());
Rows = tdp->GetElemt(); Rows = tdp->GetElemt();
Catver = tdp->Catver; Catver = tdp->Catver;
} else { } else {
...@@ -182,13 +182,14 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp) ...@@ -182,13 +182,14 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
Owner = NULL; Owner = NULL;
Qualifier = NULL; Qualifier = NULL;
Srcdef = NULL; Srcdef = NULL;
Quote = NULL;
Qrystr = NULL; Qrystr = NULL;
Options = 0; Options = 0;
Quoted = 0;
Rows = 0; Rows = 0;
Catver = 0; Catver = 0;
} // endif tdp } // endif tdp
Quote = NULL;
Query = NULL; Query = NULL;
Count = NULL; Count = NULL;
//Where = NULL; //Where = NULL;
...@@ -211,14 +212,15 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp) ...@@ -211,14 +212,15 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp)
Owner = tdbp->Owner; Owner = tdbp->Owner;
Qualifier = tdbp->Qualifier; Qualifier = tdbp->Qualifier;
Srcdef = tdbp->Srcdef; Srcdef = tdbp->Srcdef;
Quote = tdbp->Quote;
Qrystr = tdbp->Qrystr; Qrystr = tdbp->Qrystr;
Quote = tdbp->Quote;
Query = tdbp->Query; Query = tdbp->Query;
Count = tdbp->Count; Count = tdbp->Count;
//Where = tdbp->Where; //Where = tdbp->Where;
MulConn = tdbp->MulConn; MulConn = tdbp->MulConn;
DBQ = tdbp->DBQ; DBQ = tdbp->DBQ;
Options = tdbp->Options; Options = tdbp->Options;
Quoted = tdbp->Quoted;
Rows = tdbp->Rows; Rows = tdbp->Rows;
Fpos = tdbp->Fpos; Fpos = tdbp->Fpos;
AftRows = tdbp->AftRows; AftRows = tdbp->AftRows;
...@@ -445,21 +447,18 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt) ...@@ -445,21 +447,18 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
/***********************************************************************/ /***********************************************************************/
/* MakeInsert: make the Insert statement used with ODBC connection. */ /* 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 = "`"; // char *tk = "`";
int len = 0; int len = 0;
bool b = FALSE; bool b = FALSE;
PCOL colp; PCOL colp;
if (Query)
return false; // already done
for (colp = Columns; colp; colp = colp->GetNext()) for (colp = Columns; colp; colp = colp->GetNext())
if (colp->IsSpecial()) { if (colp->IsSpecial()) {
strcpy(g->Message, MSG(NO_ODBC_SPECOL)); strcpy(g->Message, MSG(NO_ODBC_SPECOL));
return true; return NULL;
} else { } else {
len += (strlen(colp->GetName()) + 4); len += (strlen(colp->GetName()) + 4);
((PODBCCOL)colp)->Rank = ++Nparm; ((PODBCCOL)colp)->Rank = ++Nparm;
...@@ -487,18 +486,18 @@ bool TDBODBC::MakeInsert(PGLOBAL g) ...@@ -487,18 +486,18 @@ bool TDBODBC::MakeInsert(PGLOBAL g)
// Below 32 is enough to contain the fixed part of the query // Below 32 is enough to contain the fixed part of the query
len = (strlen(TableName) + strlen(colist) + strlen(valist) + 32); len = (strlen(TableName) + strlen(colist) + strlen(valist) + 32);
Query = (char*)PlugSubAlloc(g, NULL, len); stmt = (char*)PlugSubAlloc(g, NULL, len);
strcpy(Query, "INSERT INTO "); strcpy(stmt, "INSERT INTO ");
if (Quote) if (Quote)
strcat(strcat(strcat(Query, Quote), TableName), Quote); strcat(strcat(strcat(stmt, Quote), TableName), Quote);
else else
strcat(Query, TableName); strcat(stmt, TableName);
strcat(strcat(strcat(Query, " ("), colist), ") VALUES ("); strcat(strcat(strcat(stmt, " ("), colist), ") VALUES (");
strcat(strcat(Query, valist), ")"); strcat(strcat(stmt, valist), ")");
return false; return stmt;
} // end of MakeInsert } // end of MakeInsert
/***********************************************************************/ /***********************************************************************/
...@@ -520,27 +519,58 @@ bool TDBODBC::BindParameters(PGLOBAL g) ...@@ -520,27 +519,58 @@ bool TDBODBC::BindParameters(PGLOBAL g)
} // end of BindParameters } // 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]; char *qc, *stmt = NULL, cmd[8], tab[96], end[1024];
int n = (Mode == MODE_DELETE) ? 1 : 2;
stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64); stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
*end = 0; memset(end, 0, sizeof(end));
qc = (Quote) ? Quote : "\"";
if (sscanf(Qrystr, "%s `%[^`]`%511c", cmd, tab, end) > n || if (sscanf(Qrystr, "%s `%[^`]`%1023c", cmd, tab, end) > 2 ||
sscanf(Qrystr, "%s \"%[^\"]\"%511c", cmd, tab, end) > n || sscanf(Qrystr, "%s \"%[^\"]\"%1023c", cmd, tab, end) > 2)
sscanf(Qrystr, "%s %s%511c", cmd, tab, end) > n) qc = Ocp->GetQuoteChar();
strcat(strcat(strcpy(tab, qc), TableName), qc); else if (sscanf(Qrystr, "%s %s%1023c", cmd, tab, end) > 2)
qc = (Quoted) ? Quote : "";
else { else {
strcpy(g->Message, "Cannot use this UPDATE/DELETE command"); strcpy(g->Message, "Cannot use this UPDATE command");
return NULL; return NULL;
} // endif sscanf } // 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) { if (*end) {
for (int i = 0; end[i]; i++) for (int i = 0; end[i]; i++)
...@@ -551,7 +581,7 @@ char *TDBODBC::MakeStmt(PGLOBAL g) ...@@ -551,7 +581,7 @@ char *TDBODBC::MakeStmt(PGLOBAL g)
} // endif end } // endif end
return stmt; return stmt;
} // end of MakeStmt } // end of MakeDelete
/***********************************************************************/ /***********************************************************************/
/* ResetSize: call by TDBMUL when calculating size estimate. */ /* ResetSize: call by TDBMUL when calculating size estimate. */
...@@ -572,7 +602,7 @@ int TDBODBC::GetMaxSize(PGLOBAL g) ...@@ -572,7 +602,7 @@ int TDBODBC::GetMaxSize(PGLOBAL g)
{ {
if (MaxSize < 0) { if (MaxSize < 0) {
// Make MariaDB happy // Make MariaDB happy
MaxSize = 100; MaxSize = (Mode == MODE_READ) ? 100 : 0;
#if 0 #if 0
// This is unuseful and takes time // This is unuseful and takes time
if (Srcdef) { if (Srcdef) {
...@@ -655,51 +685,42 @@ bool TDBODBC::OpenDB(PGLOBAL g) ...@@ -655,51 +685,42 @@ bool TDBODBC::OpenDB(PGLOBAL g)
if (Ocp->Open(Connect, Options) < 1) if (Ocp->Open(Connect, Options) < 1)
return true; return true;
else if (Quoted)
Quote = Ocp->GetQuoteChar();
Use = USE_OPEN; // Do it now in case we are recursively called 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) { if (Mode == MODE_READ) {
/*******************************************************************/ if ((Query = MakeSQL(g, false))) {
/* The issue here is that if max result size is needed, it must be */ for (PODBCCOL colp = (PODBCCOL)Columns; colp;
/* calculated before the result set for the final data retrieval is*/ colp = (PODBCCOL)colp->GetNext())
/* allocated and the final statement prepared so we call GetMaxSize*/ if (!colp->IsSpecial())
/* here. It can be a waste of time if the max size is not needed */ colp->AllocateBuffers(g, Rows);
/* 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 (!rc)
rc = ((Rows = Ocp->ExecDirectSQL(Query, (PODBCCOL)Columns)) < 0); rc = ((Rows = Ocp->ExecDirectSQL(Query, (PODBCCOL)Columns)) < 0);
} // endif Query
} else if (Mode == MODE_INSERT) { } else if (Mode == MODE_INSERT) {
if (!(rc = MakeInsert(g))) if ((Query = MakeInsert(g))) {
if (Nparm != Ocp->PrepareSQL(Query)) { if (Nparm != Ocp->PrepareSQL(Query)) {
strcpy(g->Message, MSG(PARM_CNT_MISS)); strcpy(g->Message, MSG(PARM_CNT_MISS));
rc = true; rc = true;
} else } else
rc = BindParameters(g); rc = BindParameters(g);
} else { } // endif Query
strcpy(g->Message, "No DELETE/UPDATE of ODBC tablesd");
return true; } else if (Mode == MODE_UPDATE)
} // endelse 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(); Ocp->Close();
return true; return true;
} // endif rc } // endif rc
...@@ -730,6 +751,21 @@ int TDBODBC::ReadDB(PGLOBAL g) ...@@ -730,6 +751,21 @@ int TDBODBC::ReadDB(PGLOBAL g)
htrc("ODBC ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n", htrc("ODBC ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n",
GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex); 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) { if (To_Kindex) {
// Direct access of ODBC tables is not implemented yet // Direct access of ODBC tables is not implemented yet
strcpy(g->Message, MSG(NO_ODBC_DIRECT)); strcpy(g->Message, MSG(NO_ODBC_DIRECT));
...@@ -775,8 +811,22 @@ int TDBODBC::WriteDB(PGLOBAL g) ...@@ -775,8 +811,22 @@ int TDBODBC::WriteDB(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
int TDBODBC::DeleteDB(PGLOBAL g, int irc) int TDBODBC::DeleteDB(PGLOBAL g, int irc)
{ {
strcpy(g->Message, MSG(NO_ODBC_DELETE)); if (irc == RC_FX) {
return 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 } // end of DeleteDB
/***********************************************************************/ /***********************************************************************/
...@@ -790,6 +840,7 @@ void TDBODBC::CloseDB(PGLOBAL g) ...@@ -790,6 +840,7 @@ void TDBODBC::CloseDB(PGLOBAL g)
// } // endif // } // endif
if (Ocp) if (Ocp)
Ocp->Close(); Ocp->Close();
if (trace) if (trace)
...@@ -1226,6 +1277,15 @@ int TDBXDBC::WriteDB(PGLOBAL g) ...@@ -1226,6 +1277,15 @@ int TDBXDBC::WriteDB(PGLOBAL g)
return RC_FX; return RC_FX;
} // end of DeleteDB } // 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 ------------------------------- */ /* --------------------------- XSRCCOL ------------------------------- */
/***********************************************************************/ /***********************************************************************/
......
...@@ -34,7 +34,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */ ...@@ -34,7 +34,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
PSZ GetTabowner(void) {return Tabowner;} PSZ GetTabowner(void) {return Tabowner;}
PSZ GetTabqual(void) {return Tabqual;} PSZ GetTabqual(void) {return Tabqual;}
PSZ GetSrcdef(void) {return Srcdef;} PSZ GetSrcdef(void) {return Srcdef;}
PSZ GetQchar(void) {return (Qchar && *Qchar) ? Qchar : NULL;} int GetQuoted(void) {return Quoted;}
int GetCatver(void) {return Catver;} int GetCatver(void) {return Catver;}
int GetOptions(void) {return Options;} int GetOptions(void) {return Options;}
...@@ -53,6 +53,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */ ...@@ -53,6 +53,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
PSZ Qrystr; /* The original query */ PSZ Qrystr; /* The original query */
int Catver; /* ODBC version for catalog functions */ int Catver; /* ODBC version for catalog functions */
int Options; /* Open connection options */ int Options; /* Open connection options */
int Quoted; /* Identifier quoting level */
int Mxr; /* Maxerr for an Exec table */ int Mxr; /* Maxerr for an Exec table */
bool Xsrc; /* Execution type */ bool Xsrc; /* Execution type */
}; // end of ODBCDEF }; // end of ODBCDEF
...@@ -100,10 +101,11 @@ class TDBODBC : public TDBASE { ...@@ -100,10 +101,11 @@ class TDBODBC : public TDBASE {
// Internal functions // 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); char *MakeSQL(PGLOBAL g, bool cnt);
bool MakeInsert(PGLOBAL g); char *MakeInsert(PGLOBAL g);
//bool MakeFilter(PGLOBAL g, bool c); //bool MakeFilter(PGLOBAL g, bool c);
bool BindParameters(PGLOBAL g); bool BindParameters(PGLOBAL g);
char *MakeStmt(PGLOBAL g); char *MakeUpdate(PGLOBAL g);
char *MakeDelete(PGLOBAL g);
// Members // Members
ODBConn *Ocp; // Points to an ODBC connection class ODBConn *Ocp; // Points to an ODBC connection class
...@@ -121,6 +123,7 @@ class TDBODBC : public TDBASE { ...@@ -121,6 +123,7 @@ class TDBODBC : public TDBASE {
char *DBQ; // The address part of Connect string char *DBQ; // The address part of Connect string
char *Qrystr; // The original query char *Qrystr; // The original query
int Options; // Connect options int Options; // Connect options
int Quoted; // The identifier quoting level
int Fpos; // Position of last read record int Fpos; // Position of last read record
int AftRows; // The number of affected rows int AftRows; // The number of affected rows
int Rows; // Rowset size int Rows; // Rowset size
...@@ -206,7 +209,7 @@ class TDBXDBC : public TDBODBC { ...@@ -206,7 +209,7 @@ class TDBXDBC : public TDBODBC {
virtual bool OpenDB(PGLOBAL g); virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g); virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(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); //virtual void CloseDB(PGLOBAL g);
protected: protected:
......
...@@ -607,6 +607,8 @@ bool TDBPIVOT::OpenDB(PGLOBAL g) ...@@ -607,6 +607,8 @@ bool TDBPIVOT::OpenDB(PGLOBAL g)
if (Tdbp->OpenDB(g)) if (Tdbp->OpenDB(g))
return TRUE; return TRUE;
Use = USE_OPEN; // Do it now in case we are recursively called
/*********************************************************************/ /*********************************************************************/
/* Make all required pivot columns for object views. */ /* Make all required pivot columns for object views. */
/*********************************************************************/ /*********************************************************************/
......
...@@ -495,6 +495,7 @@ bool TDBPRX::OpenDB(PGLOBAL g) ...@@ -495,6 +495,7 @@ bool TDBPRX::OpenDB(PGLOBAL g)
if (Tdbp->OpenDB(g)) if (Tdbp->OpenDB(g))
return TRUE; return TRUE;
Use = USE_OPEN;
return FALSE; return FALSE;
} // end of OpenDB } // end of OpenDB
......
...@@ -667,6 +667,8 @@ bool TDBWMI::OpenDB(PGLOBAL g) ...@@ -667,6 +667,8 @@ bool TDBWMI::OpenDB(PGLOBAL g)
} else } else
DoubleSlash(g); DoubleSlash(g);
Use = USE_OPEN; // Do it now in case we are recursively called
/*********************************************************************/ /*********************************************************************/
/* Initialize the WMI processing. */ /* Initialize the WMI processing. */
/*********************************************************************/ /*********************************************************************/
......
...@@ -193,6 +193,7 @@ bool TDBXCL::OpenDB(PGLOBAL g) ...@@ -193,6 +193,7 @@ bool TDBXCL::OpenDB(PGLOBAL g)
if (Tdbp->OpenDB(g)) if (Tdbp->OpenDB(g))
return TRUE; return TRUE;
Use = USE_OPEN;
return FALSE; return FALSE;
} // end of OpenDB } // 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