Commit e1096934 authored by Olivier Bertrand's avatar Olivier Bertrand

- Check field option changes on ALTER TABLE in check_if_supported_inplace_alter.

  If yes, the in-place algorithm cannot be used (inward tables)
modified:
  storage/connect/ha_connect.cc
  storage/connect/ha_connect.h

- add a test on ALTER TABLE
added:
  storage/connect/mysql-test/connect/r/alter.result
  storage/connect/mysql-test/connect/t/alter.test
parent 78f11e8e
...@@ -2043,7 +2043,8 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT* check_opt) ...@@ -2043,7 +2043,8 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT* check_opt)
if (tdbp || (tdbp= GetTDB(g))) { if (tdbp || (tdbp= GetTDB(g))) {
if (!((PTDBASE)tdbp)->GetDef()->Indexable()) { if (!((PTDBASE)tdbp)->GetDef()->Indexable()) {
sprintf(g->Message, "optimize: Table %s is not indexable", tdbp->GetName()); sprintf(g->Message, "optimize: Table %s is not indexable", tdbp->GetName());
rc= HA_ERR_INTERNAL_ERROR; my_message(ER_INDEX_REBUILD, g->Message, MYF(0));
rc= HA_ERR_UNSUPPORTED;
} else if ((rc= ((PTDBASE)tdbp)->ResetTableOpt(g, true))) { } else if ((rc= ((PTDBASE)tdbp)->ResetTableOpt(g, true))) {
if (rc == RC_INFO) { if (rc == RC_INFO) {
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
...@@ -4610,7 +4611,10 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -4610,7 +4611,10 @@ int ha_connect::create(const char *name, TABLE *table_arg,
(options->tabname) ? "PROXY" : "DOS"; (options->tabname) ? "PROXY" : "DOS";
type= GetTypeID(options->type); type= GetTypeID(options->type);
sprintf(g->Message, "No table_type. Will be set to %s", options->type); sprintf(g->Message, "No table_type. Will be set to %s", options->type);
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
if (sqlcom == SQLCOM_CREATE_TABLE)
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
} else if (type == TAB_NIY) { } else if (type == TAB_NIY) {
sprintf(g->Message, "Unsupported table type %s", options->type); sprintf(g->Message, "Unsupported table type %s", options->type);
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
...@@ -4898,7 +4902,10 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -4898,7 +4902,10 @@ int ha_connect::create(const char *name, TABLE *table_arg,
strcat(strcat(buf, "."), lwt); strcat(strcat(buf, "."), lwt);
sprintf(g->Message, "No file name. Table will use %s", buf); sprintf(g->Message, "No file name. Table will use %s", buf);
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
if (sqlcom == SQLCOM_CREATE_TABLE)
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
strcat(strcat(strcpy(dbpath, "./"), table->s->db.str), "/"); strcat(strcat(strcpy(dbpath, "./"), table->s->db.str), "/");
PlugSetPath(fn, buf, dbpath); PlugSetPath(fn, buf, dbpath);
...@@ -4908,13 +4915,12 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -4908,13 +4915,12 @@ int ha_connect::create(const char *name, TABLE *table_arg,
else else
sprintf(g->Message, "Error %d creating file %s", errno, fn); sprintf(g->Message, "Error %d creating file %s", errno, fn);
push_warning(table->in_use, push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
} else } else
::close(h); ::close(h);
if (type == TAB_FMT || options->readonly) if (type == TAB_FMT || options->readonly)
push_warning(table->in_use, Sql_condition::WARN_LEVEL_WARN, 0, push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0,
"Congratulation, you just created a read-only void table!"); "Congratulation, you just created a read-only void table!");
} // endif } // endif
...@@ -4962,7 +4968,7 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -4962,7 +4968,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} else { } else {
sprintf(g->Message, "Table type %s is not indexable", options->type); sprintf(g->Message, "Table type %s is not indexable", options->type);
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
rc= HA_ERR_INTERNAL_ERROR; rc= HA_ERR_UNSUPPORTED;
} // endif Indexable } // endif Indexable
} // endif xdp } // endif xdp
...@@ -5082,28 +5088,32 @@ bool ha_connect::FileExists(const char *fn) ...@@ -5082,28 +5088,32 @@ bool ha_connect::FileExists(const char *fn)
return true; return true;
} // end of FileExists } // end of FileExists
// Called by SameString and NoFieldOptionChange
bool ha_connect::CheckString(const char *str1, const char *str2)
{
bool b1= (!str1 || !*str1), b2= (!str2 || !*str2);
if (b1 && b2)
return true;
else if ((b1 && !b2) || (!b1 && b2) || stricmp(str1, str2))
return false;
return true;
} // end of CheckString
/** /**
check whether a string option have changed check whether a string option have changed
*/ */
bool ha_connect::SameChar(TABLE *tab, char *opn) bool ha_connect::SameString(TABLE *tab, char *opn)
{ {
char *str1, *str2; char *str1, *str2;
bool b1, b2;
tshp= tab->s; // The altered table tshp= tab->s; // The altered table
str1= GetStringOption(opn); str1= GetStringOption(opn);
tshp= NULL; tshp= NULL;
str2= GetStringOption(opn); str2= GetStringOption(opn);
b1= (!str1 || !*str1); return CheckString(str1, str2);
b2= (!str2 || !*str2); } // end of SameString
if (b1 && b2)
return true;
else if ((b1 && !b2) || (!b1 && b2) || stricmp(str1, str2))
return false;
return true;
} // end of SameChar
/** /**
check whether a Boolean option have changed check whether a Boolean option have changed
...@@ -5140,6 +5150,29 @@ bool ha_connect::SameInt(TABLE *tab, char *opn) ...@@ -5140,6 +5150,29 @@ bool ha_connect::SameInt(TABLE *tab, char *opn)
} // end of SameInt } // end of SameInt
/**
check whether a field option have changed
*/
bool ha_connect::NoFieldOptionChange(TABLE *tab)
{
bool rc= true;
ha_field_option_struct *fop1, *fop2;
Field* *fld1= table->s->field;
Field* *fld2= tab->s->field;
for (; rc && *fld1 && *fld2; fld1++, fld2++) {
fop1= (*fld1)->option_struct;
fop2= (*fld2)->option_struct;
rc= (fop1->offset == fop2->offset &&
fop1->fldlen == fop2->fldlen &&
CheckString(fop1->dateformat, fop2->dateformat) &&
CheckString(fop1->fieldformat, fop2->fieldformat) &&
CheckString(fop1->special, fop2->special));
} // endfor fld
return rc;
} // end of NoFieldOptionChange
/** /**
Check if a storage engine supports a particular alter table in-place Check if a storage engine supports a particular alter table in-place
...@@ -5224,7 +5257,7 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table, ...@@ -5224,7 +5257,7 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table,
Alter_inplace_info::ALTER_RENAME | index_operations; Alter_inplace_info::ALTER_RENAME | index_operations;
if (ha_alter_info->handler_flags & index_operations || if (ha_alter_info->handler_flags & index_operations ||
!SameChar(altered_table, "optname") || !SameString(altered_table, "optname") ||
!SameBool(altered_table, "sepindex")) { !SameBool(altered_table, "sepindex")) {
if (!IsTypeIndexable(type)) { if (!IsTypeIndexable(type)) {
sprintf(g->Message, "Table type %s is not indexable", oldopt->type); sprintf(g->Message, "Table type %s is not indexable", oldopt->type);
...@@ -5258,25 +5291,25 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table, ...@@ -5258,25 +5291,25 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table,
} // endif index operation } // endif index operation
if (!SameChar(altered_table, "filename")) { if (!SameString(altered_table, "filename")) {
if (!outward) { if (!outward) {
// Conversion to outward table is only allowed for file based // Conversion to outward table is only allowed for file based
// tables whose file does not exist. // tables whose file does not exist.
tshp= altered_table->s; tshp= altered_table->s;
char *fn= GetStringOption("filename"); char *fn= GetStringOption("filename");
tshp= NULL; tshp= NULL;
if (FileExists(fn)) {
strcpy(g->Message, "Operation denied. Table data would be lost.");
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
DBUG_RETURN(HA_ALTER_ERROR);
} else
goto fin;
if (FileExists(fn)) {
strcpy(g->Message, "Operation denied. Table data would be lost.");
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
DBUG_RETURN(HA_ALTER_ERROR);
} else } else
goto fin; goto fin;
} // endif filename } else
goto fin;
} // endif filename
/* Is there at least one operation that requires copy algorithm? */ /* Is there at least one operation that requires copy algorithm? */
if (ha_alter_info->handler_flags & ~inplace_offline_operations) if (ha_alter_info->handler_flags & ~inplace_offline_operations)
...@@ -5309,7 +5342,8 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table, ...@@ -5309,7 +5342,8 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table,
#endif // 0 #endif // 0
// This was in check_if_incompatible_data // This was in check_if_incompatible_data
if (type == newtyp && if (NoFieldOptionChange(altered_table) &&
type == newtyp &&
SameInt(altered_table, "lrecl") && SameInt(altered_table, "lrecl") &&
SameInt(altered_table, "elements") && SameInt(altered_table, "elements") &&
SameInt(altered_table, "header") && SameInt(altered_table, "header") &&
...@@ -5321,7 +5355,7 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table, ...@@ -5321,7 +5355,7 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table,
fin: fin:
if (idx) { if (idx) {
// Indexing is only supported inplace // Indexing is only supported inplace
my_message(ER_UNKNOWN_ERROR, my_message(ER_ALTER_OPERATION_NOT_SUPPORTED,
"Alter operations not supported together by CONNECT", MYF(0)); "Alter operations not supported together by CONNECT", MYF(0));
DBUG_RETURN(HA_ALTER_ERROR); DBUG_RETURN(HA_ALTER_ERROR);
} else if (outward) { } else if (outward) {
......
...@@ -173,11 +173,13 @@ class ha_connect: public handler ...@@ -173,11 +173,13 @@ class ha_connect: public handler
bool GetBooleanOption(char *opname, bool bdef); bool GetBooleanOption(char *opname, bool bdef);
bool SetBooleanOption(char *opname, bool b); bool SetBooleanOption(char *opname, bool b);
int GetIntegerOption(char *opname); int GetIntegerOption(char *opname);
bool CheckString(const char *str1, const char *str2);
bool SameString(TABLE *tab, char *opn);
bool SetIntegerOption(char *opname, int n); bool SetIntegerOption(char *opname, int n);
bool SameChar(TABLE *tab, char *opn);
bool SameInt(TABLE *tab, char *opn); bool SameInt(TABLE *tab, char *opn);
bool SameBool(TABLE *tab, char *opn); bool SameBool(TABLE *tab, char *opn);
bool FileExists(const char *fn); bool FileExists(const char *fn);
bool NoFieldOptionChange(TABLE *tab);
PFOS GetFieldOptionStruct(Field *fp); PFOS GetFieldOptionStruct(Field *fp);
void *GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf); void *GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf);
PIXDEF GetIndexInfo(TABLE_SHARE *s= NULL); PIXDEF GetIndexInfo(TABLE_SHARE *s= NULL);
......
#
# Testing indexing with ALTER on inward table (in-place)
#
CREATE TABLE t1 (c INT NOT NULL, d CHAR(10) NOT NULL) ENGINE=CONNECT;
Warnings:
Warning 1105 No table_type. Will be set to DOS
Warning 1105 No file name. Table will use t1.dos
INSERT INTO t1 VALUES (1,'One'), (2,'Two'), (3,'Three');
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
CREATE INDEX xc ON t1(c);
DESCRIBE SELECT * FROM t1 WHERE c = 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref xc xc 4 const 1
DROP INDEX xc ON t1;
CREATE INDEX xd ON t1(d);
DROP INDEX xd ON t1;
ALTER TABLE t1 ADD INDEX xc (c), ADD INDEX xd (d);
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 1 xc 1 c NULL NULL NULL NULL XPLUG
t1 1 xd 1 d NULL NULL NULL NULL XPLUG
ALTER TABLE t1 DROP INDEX xc, DROP INDEX xd;
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
#
# Testing modifying columns inward table (not in-place)
#
ALTER TABLE t1 MODIFY COLUMN c CHAR(5) NOT NULL;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` char(5) NOT NULL,
`d` char(10) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
ALTER TABLE t1 MODIFY COLUMN c INT NOT NULL;
#
# Fails because indexing must be in-place
#
ALTER TABLE t1 MODIFY COLUMN c CHAR(10) NOT NULL, ADD INDEX xd (d);
ERROR 0A000: Alter operations not supported together by CONNECT
#
# Testing changing table type (not in-place)
#
ALTER TABLE t1 TABLE_TYPE=CSV HEADER=1 QUOTED=1;
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` int(11) NOT NULL,
`d` char(10) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=CSV `HEADER`=1 `QUOTED`=1
# create an outward table used to see the t1 file
CREATE TABLE t2 (line VARCHAR(100) NOT NULL) ENGINE=CONNECT FILE_NAME='t1.csv';
Warnings:
Warning 1105 No table_type. Will be set to DOS
SELECT * FROM t2;
line
"c","d"
1,"One"
2,"Two"
3,"Three"
# This would fail if the top node name is not specified.
# This is because the XML top node name defaults to the table name.
# Sure enough the temporary table name begins with '#' and is rejected by XML.
# Therefore the top node name must be specified (along with the row nodes name).
ALTER TABLE t1 TABLE_TYPE=XML TABNAME=t1 OPTION_LIST='rownode=row';
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` int(11) NOT NULL,
`d` char(10) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `HEADER`=1 `QUOTED`=1 `TABLE_TYPE`=XML `TABNAME`=t1 `OPTION_LIST`='rownode=row'
# Let us see the XML file
ALTER TABLE t2 FILE_NAME='t1.xml';
Warnings:
Warning 1105 This is an outward table, table data were not modified.
SELECT * FROM t2;
line
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created by CONNECT Version 1.02.0001 February 03, 2014 -->
<t1>
<row>
<TH>c</TH>
<TH>d</TH>
</row>
<row>
<c>1</c>
<d>One</d>
</row>
<row>
<c>2</c>
<d>Two</d>
</row>
<row>
<c>3</c>
<d>Three</d>
</row>
</t1>
# NOTE: The first (ignored) row is due to the remaining HEADER=1 option.
# Testing field option modification
ALTER TABLE t1 MODIFY d CHAR(10) NOT NULL FIELD_FORMAT='@', HEADER=0;
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` int(11) NOT NULL,
`d` char(10) NOT NULL `FIELD_FORMAT`='@'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `QUOTED`=1 `TABLE_TYPE`=XML `TABNAME`=t1 `OPTION_LIST`='rownode=row' `HEADER`=0
SELECT * FROM t2;
line
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created by CONNECT Version 1.02.0001 February 03, 2014 -->
<t1>
<row d="One">
<c>1</c>
</row>
<row d="Two">
<c>2</c>
</row>
<row d="Three">
<c>3</c>
</row>
</t1>
#
# Testing changing engine
#
DROP TABLE t1;
CREATE TABLE t1 (c INT NOT NULL, d CHAR(10) NOT NULL) ENGINE=CONNECT;
Warnings:
Warning 1105 No table_type. Will be set to DOS
Warning 1105 No file name. Table will use t1.dos
INSERT INTO t1 VALUES (1,'One'), (2,'Two'), (3,'Three');
ALTER TABLE t1 ADD INDEX xc (c), ADD INDEX xd (d);
ALTER TABLE t1 ENGINE = MYISAM;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` int(11) NOT NULL,
`d` char(10) NOT NULL,
KEY `xc` (`c`),
KEY `xd` (`d`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 1 xc 1 c A NULL NULL NULL BTREE
t1 1 xd 1 d A NULL NULL NULL BTREE
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
ALTER TABLE t1 ENGINE = CONNECT TABLE_TYPE=DBF;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` int(11) NOT NULL,
`d` char(10) NOT NULL,
KEY `xc` (`c`),
KEY `xd` (`d`)
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=DBF
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 1 xc 1 c NULL NULL NULL NULL XPLUG
t1 1 xd 1 d NULL NULL NULL NULL XPLUG
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
DROP TABLE t1, t2;
#
# Testing ALTER on outward tables
#
CREATE TABLE t1 (c INT NOT NULL, d CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='tf1.txt';
INSERT INTO t1 VALUES (1,'One'), (2,'Two'), (3,'Three');
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
CREATE TABLE t2 (line VARCHAR(100) NOT NULL) ENGINE=CONNECT FILE_NAME='tf1.txt';
Warnings:
Warning 1105 No table_type. Will be set to DOS
SELECT * FROM t2;
line
1One
2Two
3Three
#
# Indexing works the same
#
ALTER TABLE t1 ADD INDEX xc (c), ADD INDEX xd (d);
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 1 xc 1 c NULL NULL NULL NULL XPLUG
t1 1 xd 1 d NULL NULL NULL NULL XPLUG
SELECT d FROM t1 WHERE c = 2;
d
Two
ALTER TABLE t1 DROP INDEX xc, DROP INDEX xd;
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
#
# Other alterations do not modify the file
#
ALTER TABLE t1 MODIFY COLUMN c CHAR(5) NOT NULL;
Warnings:
Warning 1105 This is an outward table, table data were not modified.
SELECT * FROM t2;
line
1One
2Two
3Three
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` char(5) NOT NULL,
`d` char(10) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=fix `FILE_NAME`='tf1.txt'
SELECT * FROM t1;
ERROR HY000: Got error 174 'File tf1.txt is not fixed length, len=69 lrecl=17' from CONNECT
ALTER TABLE t1 MODIFY COLUMN c INT NOT NULL;
Warnings:
Warning 1105 This is an outward table, table data were not modified.
#
# Changing column order
#
ALTER TABLE t1 MODIFY COLUMN c INT NOT NULL AFTER d;
Warnings:
Warning 1105 This is an outward table, table data were not modified.
SELECT * FROM t2;
line
1One
2Two
3Three
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`d` char(10) NOT NULL,
`c` int(11) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=fix `FILE_NAME`='tf1.txt'
# Wrong result
SELECT * FROM t1;
d c
1
2
3
ALTER TABLE t1 MODIFY COLUMN c INT NOT NULL FIRST;
Warnings:
Warning 1105 This is an outward table, table data were not modified.
# What should have been done
ALTER TABLE t1 MODIFY c INT NOT NULL FLAG=0 AFTER d, MODIFY d CHAR(10) NOT NULL FLAG=11;
Warnings:
Warning 1105 This is an outward table, table data were not modified.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`d` char(10) NOT NULL `FLAG`=11,
`c` int(11) NOT NULL `FLAG`=0
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=fix `FILE_NAME`='tf1.txt'
SELECT * FROM t1;
d c
One 1
Two 2
Three 3
#
# Changing to another engine is Ok
# However, the data file is not deleted.
#
ALTER TABLE t1 ENGINE=MARIA;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`d` char(10) NOT NULL `FLAG`=11,
`c` int(11) NOT NULL `FLAG`=0
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 `TABLE_TYPE`=fix `FILE_NAME`='tf1.txt'
SELECT * from t1;
d c
One 1
Two 2
Three 3
SELECT * from t2;
line
1One
2Two
3Three
#
# Changing back to CONNECT fails
# Sure enough, the data file was not deleted.
#
ALTER TABLE t1 ENGINE=CONNECT;
ERROR HY000: Operation denied. Table data would be lost.
#
# But changing back to CONNECT succeed
# if the data file does not exist.
#
ALTER TABLE t1 ENGINE=CONNECT;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`d` char(10) NOT NULL `FLAG`=11,
`c` int(11) NOT NULL `FLAG`=0
) ENGINE=CONNECT DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 `TABLE_TYPE`=fix `FILE_NAME`='tf1.txt'
SELECT * from t1;
d c
One 1
Two 2
Three 3
SELECT * from t2;
line
1One
2Two
3Three
DROP TABLE t1, t2;
let $MYSQLD_DATADIR= `select @@datadir`;
--echo #
--echo # Testing indexing with ALTER on inward table (in-place)
--echo #
CREATE TABLE t1 (c INT NOT NULL, d CHAR(10) NOT NULL) ENGINE=CONNECT;
INSERT INTO t1 VALUES (1,'One'), (2,'Two'), (3,'Three');
SELECT * FROM t1;
CREATE INDEX xc ON t1(c);
DESCRIBE SELECT * FROM t1 WHERE c = 2;
DROP INDEX xc ON t1;
CREATE INDEX xd ON t1(d);
DROP INDEX xd ON t1;
ALTER TABLE t1 ADD INDEX xc (c), ADD INDEX xd (d);
SHOW INDEX FROM t1;
ALTER TABLE t1 DROP INDEX xc, DROP INDEX xd;
SHOW INDEX FROM t1;
--echo #
--echo # Testing modifying columns inward table (not in-place)
--echo #
ALTER TABLE t1 MODIFY COLUMN c CHAR(5) NOT NULL;
SHOW CREATE TABLE t1;
SELECT * FROM t1;
ALTER TABLE t1 MODIFY COLUMN c INT NOT NULL;
--echo #
--echo # Fails because indexing must be in-place
--echo #
--error ER_ALTER_OPERATION_NOT_SUPPORTED
ALTER TABLE t1 MODIFY COLUMN c CHAR(10) NOT NULL, ADD INDEX xd (d);
--echo #
--echo # Testing changing table type (not in-place)
--echo #
ALTER TABLE t1 TABLE_TYPE=CSV HEADER=1 QUOTED=1;
SELECT * FROM t1;
SHOW CREATE TABLE t1;
--echo # create an outward table used to see the t1 file
CREATE TABLE t2 (line VARCHAR(100) NOT NULL) ENGINE=CONNECT FILE_NAME='t1.csv';
SELECT * FROM t2;
--echo # This would fail if the top node name is not specified.
--echo # This is because the XML top node name defaults to the table name.
--echo # Sure enough the temporary table name begins with '#' and is rejected by XML.
--echo # Therefore the top node name must be specified (along with the row nodes name).
ALTER TABLE t1 TABLE_TYPE=XML TABNAME=t1 OPTION_LIST='rownode=row';
SELECT * FROM t1;
SHOW CREATE TABLE t1;
--echo # Let us see the XML file
ALTER TABLE t2 FILE_NAME='t1.xml';
SELECT * FROM t2;
--echo # NOTE: The first (ignored) row is due to the remaining HEADER=1 option.
--echo # Testing field option modification
ALTER TABLE t1 MODIFY d CHAR(10) NOT NULL FIELD_FORMAT='@', HEADER=0;
SELECT * FROM t1;
SHOW CREATE TABLE t1;
SELECT * FROM t2;
--echo #
--echo # Testing changing engine
--echo #
DROP TABLE t1;
CREATE TABLE t1 (c INT NOT NULL, d CHAR(10) NOT NULL) ENGINE=CONNECT;
INSERT INTO t1 VALUES (1,'One'), (2,'Two'), (3,'Three');
ALTER TABLE t1 ADD INDEX xc (c), ADD INDEX xd (d);
ALTER TABLE t1 ENGINE = MYISAM;
SHOW CREATE TABLE t1;
SHOW INDEX FROM t1;
SELECT * FROM t1;
ALTER TABLE t1 ENGINE = CONNECT TABLE_TYPE=DBF;
SHOW CREATE TABLE t1;
SHOW INDEX FROM t1;
SELECT * FROM t1;
DROP TABLE t1, t2;
--echo #
--echo # Testing ALTER on outward tables
--echo #
CREATE TABLE t1 (c INT NOT NULL, d CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='tf1.txt';
INSERT INTO t1 VALUES (1,'One'), (2,'Two'), (3,'Three');
SELECT * FROM t1;
CREATE TABLE t2 (line VARCHAR(100) NOT NULL) ENGINE=CONNECT FILE_NAME='tf1.txt';
SELECT * FROM t2;
--echo #
--echo # Indexing works the same
--echo #
ALTER TABLE t1 ADD INDEX xc (c), ADD INDEX xd (d);
SHOW INDEX FROM t1;
SELECT d FROM t1 WHERE c = 2;
ALTER TABLE t1 DROP INDEX xc, DROP INDEX xd;
SHOW INDEX FROM t1;
--echo #
--echo # Other alterations do not modify the file
--echo #
ALTER TABLE t1 MODIFY COLUMN c CHAR(5) NOT NULL;
SELECT * FROM t2;
SHOW CREATE TABLE t1;
#Wrong result
--error ER_GET_ERRMSG
SELECT * FROM t1;
ALTER TABLE t1 MODIFY COLUMN c INT NOT NULL;
--echo #
--echo # Changing column order
--echo #
ALTER TABLE t1 MODIFY COLUMN c INT NOT NULL AFTER d;
SELECT * FROM t2;
SHOW CREATE TABLE t1;
--echo # Wrong result
SELECT * FROM t1;
ALTER TABLE t1 MODIFY COLUMN c INT NOT NULL FIRST;
--echo # What should have been done
ALTER TABLE t1 MODIFY c INT NOT NULL FLAG=0 AFTER d, MODIFY d CHAR(10) NOT NULL FLAG=11;
SHOW CREATE TABLE t1;
SELECT * FROM t1;
--echo #
--echo # Changing to another engine is Ok
--echo # However, the data file is not deleted.
--echo #
ALTER TABLE t1 ENGINE=MARIA;
SHOW CREATE TABLE t1;
SELECT * from t1;
SELECT * from t2;
--echo #
--echo # Changing back to CONNECT fails
--echo # Sure enough, the data file was not deleted.
--echo #
--error ER_UNKNOWN_ERROR
ALTER TABLE t1 ENGINE=CONNECT;
--echo #
--echo # But changing back to CONNECT succeed
--echo # if the data file does not exist.
--echo #
--remove_file $MYSQLD_DATADIR/test/tf1.txt
ALTER TABLE t1 ENGINE=CONNECT;
SHOW CREATE TABLE t1;
SELECT * from t1;
SELECT * from t2;
DROP TABLE t1, t2;
#
# Clean up
#
--remove_file $MYSQLD_DATADIR/test/tf1.txt
...@@ -1314,7 +1314,7 @@ void XMLCOL::WriteColumn(PGLOBAL g) ...@@ -1314,7 +1314,7 @@ void XMLCOL::WriteColumn(PGLOBAL g)
PXNODE TopNode = NULL; PXNODE TopNode = NULL;
//PXATTR AttNode = NULL; //PXATTR AttNode = NULL;
if (trace) if (trace > 1)
htrc("XML WriteColumn: col %s R%d coluse=%.4X status=%.4X\n", htrc("XML WriteColumn: col %s R%d coluse=%.4X status=%.4X\n",
Name, Tdbp->GetTdb_No(), ColUse, Status); Name, Tdbp->GetTdb_No(), ColUse, Status);
......
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