diff options
author | Sachin Setiya <sachin.setiya@mariadb.com> | 2017-12-14 19:17:27 +0530 |
---|---|---|
committer | Sachin Setiya <sachin.setiya@mariadb.com> | 2017-12-15 02:41:52 +0530 |
commit | 0bc3c0fbc8d2dde151ab486c204075251a929c35 (patch) | |
tree | b23637433eba278e3196e9236b5d552780c42bb7 | |
parent | c90db2c8beed5aba00a348fb4854d809c560501e (diff) | |
download | mariadb-git-0bc3c0fbc8d2dde151ab486c204075251a929c35.tar.gz |
mysqldump fix for invisible column
Actually there are 2 issues in the case of invisible columns
1st `select fields from t1` will have more fields then `select * from t1`.
So instead of `select * from t1` we are using `select a,b,invisible from t1`
these fields are supplied from `select fields from t1`.
2nd We are using --complete-insert when we detect that this table is using
invisible columns.
-rw-r--r-- | client/mysqldump.c | 65 | ||||
-rw-r--r-- | mysql-test/r/mysqldump.result | 182 | ||||
-rw-r--r-- | mysql-test/r/show_check.result | 24 | ||||
-rw-r--r-- | mysql-test/t/mysqldump.test | 43 | ||||
-rw-r--r-- | mysql-test/t/show_check.test | 54 |
5 files changed, 300 insertions, 68 deletions
diff --git a/client/mysqldump.c b/client/mysqldump.c index a260065c64c..72e86db6e43 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -115,10 +115,11 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_no_data_m opt_events= 0, opt_comments_used= 0, opt_alltspcs=0, opt_notspcs= 0, opt_logging, opt_drop_trigger= 0 ; -static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0; +static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0, + select_field_names_inited= 0; static ulong opt_max_allowed_packet, opt_net_buffer_length; static MYSQL mysql_connection,*mysql=0; -static DYNAMIC_STRING insert_pat; +static DYNAMIC_STRING insert_pat, select_field_names; static char *opt_password=0,*current_user=0, *current_host=0,*path=0,*fields_terminated=0, *lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0, @@ -1641,6 +1642,7 @@ static void free_resources() dynstr_free(&extended_row); dynstr_free(&dynamic_where); dynstr_free(&insert_pat); + dynstr_free(&select_field_names); if (defaults_argv) free_defaults(defaults_argv); mysql_library_end(); @@ -2735,7 +2737,13 @@ static uint get_table_structure(char *table, char *db, char *table_type, else dynstr_set_checked(&insert_pat, ""); } - + if (!select_field_names_inited) + { + select_field_names_inited= 1; + init_dynamic_string_checked(&select_field_names, "", 1024, 1024); + } + else + dynstr_set_checked(&select_field_names, ""); insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " : delayed ? " DELAYED " : opt_ignore ? " IGNORE " : ""); @@ -2971,6 +2979,19 @@ static uint get_table_structure(char *table, char *db, char *table_type, DBUG_RETURN(0); } + while ((row= mysql_fetch_row(result))) + { + if (strlen(row[SHOW_EXTRA]) && strstr(row[SHOW_EXTRA],"INVISIBLE")) + complete_insert= 1; + if (init) + { + dynstr_append_checked(&select_field_names, ", "); + } + init=1; + dynstr_append_checked(&select_field_names, + quote_name(row[SHOW_FIELDNAME], name_buff, 0)); + } + init=0; /* If write_data is true, then we build up insert statements for the table's data. Note: in subsequent lines of code, this test @@ -2998,19 +3019,8 @@ static uint get_table_structure(char *table, char *db, char *table_type, } } - while ((row= mysql_fetch_row(result))) - { - if (complete_insert) - { - if (init) - { - dynstr_append_checked(&insert_pat, ", "); - } - init=1; - dynstr_append_checked(&insert_pat, - quote_name(row[SHOW_FIELDNAME], name_buff, 0)); - } - } + if (complete_insert) + dynstr_append_checked(&insert_pat, select_field_names.str); num_fields= mysql_num_rows(result); mysql_free_result(result); } @@ -3070,6 +3080,21 @@ static uint get_table_structure(char *table, char *db, char *table_type, while ((row= mysql_fetch_row(result))) { + if (strlen(row[SHOW_EXTRA]) && strstr(row[SHOW_EXTRA],"INVISIBLE")) + complete_insert= 1; + if (init) + { + dynstr_append_checked(&select_field_names, ", "); + } + dynstr_append_checked(&select_field_names, + quote_name(row[SHOW_FIELDNAME], name_buff, 0)); + init=1; + } + init=0; + mysql_data_seek(result, 0); + + while ((row= mysql_fetch_row(result))) + { ulong *lengths= mysql_fetch_lengths(result); if (init) { @@ -3708,7 +3733,9 @@ static void dump_table(char *table, char *db) /* now build the query string */ - dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '"); + dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ "); + dynstr_append_checked(&query_string, select_field_names.str); + dynstr_append_checked(&query_string, " INTO OUTFILE '"); dynstr_append_checked(&query_string, filename); dynstr_append_checked(&query_string, "'"); @@ -3757,7 +3784,9 @@ static void dump_table(char *table, char *db) "\n--\n-- Dumping data for table %s\n--\n", fix_for_comment(result_table)); - dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM "); + dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ "); + dynstr_append_checked(&query_string, select_field_names.str); + dynstr_append_checked(&query_string, " FROM "); dynstr_append_checked(&query_string, result_table); if (where) diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 7f6107db5e4..9d587b013f0 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -1917,7 +1917,7 @@ drop table t1, t2, t3; # Bug#21288 mysqldump segmentation fault when using --where # create table t1 (a int); -mysqldump: Couldn't execute 'SELECT /*!40001 SQL_NO_CACHE */ * FROM `t1` WHERE xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 (1064) +mysqldump: Couldn't execute 'SELECT /*!40001 SQL_NO_CACHE */ `a` FROM `t1` WHERE xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 (1064) mysqldump: Got error: 1064: "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1" when retrieving data from server /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; @@ -5646,3 +5646,183 @@ DELIMITER ; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; DROP TABLE t1; +# +# Test for Invisible columns +# +create database d; +use d; +# Invisble field table +create table t1(a int , b int invisible); +insert into t1 values(1); +insert into t1(a,b) values(1,2); +# not invisible field table --complete-insert wont be used +create table t2(a int , b int); +insert into t2(a,b) values(1,2); +insert into t2(a,b) values(1,2); +# Invisble field table +create table t3(invisible int , `a b c & $!@#$%^&*( )` int invisible default 4, `ds=~!@ \# $% ^ & * ( ) _ - = +` int invisible default 5); +insert into t3 values(1); +insert into t3 values(5); +insert into t3 values(2); +insert into t3(`invisible`, `a b c & $!@#$%^&*( )`, `ds=~!@ \# $% ^ & * ( ) _ - = +` ) values(1,2,3); +CREATE TABLE t4(ËÏÌÏÎËÁ1 INT); +insert into t4 values(1); +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) INVISIBLE DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO `t1` (`a`, `b`) VALUES (1,NULL),(1,2); +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO `t2` VALUES (1,2),(1,2); +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t3` ( + `invisible` int(11) DEFAULT NULL, + `a b c & $!@#$%^&*( )` int(11) INVISIBLE DEFAULT 4, + `ds=~!@ \# $% ^ & * ( ) _ - = +` int(11) INVISIBLE DEFAULT 5 +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO `t3` (`invisible`, `a b c & $!@#$%^&*( )`, `ds=~!@ \# $% ^ & * ( ) _ - = +`) VALUES (1,4,5),(5,4,5),(2,4,5),(1,2,3); +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t4` ( + `ËÏÌÏÎËÁ1` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO `t4` VALUES (1); +#Check side effect on --complete insert +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) INVISIBLE DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO `t1` (`a`, `b`) VALUES (1,NULL),(1,2); +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO `t2` (`a`, `b`) VALUES (1,2),(1,2); +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t3` ( + `invisible` int(11) DEFAULT NULL, + `a b c & $!@#$%^&*( )` int(11) INVISIBLE DEFAULT 4, + `ds=~!@ \# $% ^ & * ( ) _ - = +` int(11) INVISIBLE DEFAULT 5 +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO `t3` (`invisible`, `a b c & $!@#$%^&*( )`, `ds=~!@ \# $% ^ & * ( ) _ - = +`) VALUES (1,4,5),(5,4,5),(2,4,5),(1,2,3); +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t4` ( + `ËÏÌÏÎËÁ1` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO `t4` (`ËÏÌÏÎËÁ1`) VALUES (1); +#Check xml +<?xml version="1.0"?> +<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> +<database name="d"> + <table_structure name="t1"> + <field Field="a" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="" Comment="" /> + <field Field="b" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="INVISIBLE" Comment="" /> + </table_structure> + <table_data name="t1"> + <row> + <field name="a">1</field> + <field name="b" xsi:nil="true" /> + </row> + <row> + <field name="a">1</field> + <field name="b">2</field> + </row> + </table_data> + <table_structure name="t2"> + <field Field="a" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="" Comment="" /> + <field Field="b" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="" Comment="" /> + </table_structure> + <table_data name="t2"> + <row> + <field name="a">1</field> + <field name="b">2</field> + </row> + <row> + <field name="a">1</field> + <field name="b">2</field> + </row> + </table_data> + <table_structure name="t3"> + <field Field="invisible" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="" Comment="" /> + <field Field="a b c & $!@#$%^&*( )" Type="int(11)" Null="YES" Key="" Default="4" Extra="INVISIBLE" Comment="" /> + <field Field="ds=~!@ \# $% ^ & * ( ) _ - = +" Type="int(11)" Null="YES" Key="" Default="5" Extra="INVISIBLE" Comment="" /> + </table_structure> + <table_data name="t3"> + <row> + <field name="invisible">1</field> + <field name="a b c & $!@#$%^&*( )">4</field> + <field name="ds=~!@ \# $% ^ & * ( ) _ - = +">5</field> + </row> + <row> + <field name="invisible">5</field> + <field name="a b c & $!@#$%^&*( )">4</field> + <field name="ds=~!@ \# $% ^ & * ( ) _ - = +">5</field> + </row> + <row> + <field name="invisible">2</field> + <field name="a b c & $!@#$%^&*( )">4</field> + <field name="ds=~!@ \# $% ^ & * ( ) _ - = +">5</field> + </row> + <row> + <field name="invisible">1</field> + <field name="a b c & $!@#$%^&*( )">2</field> + <field name="ds=~!@ \# $% ^ & * ( ) _ - = +">3</field> + </row> + </table_data> + <table_structure name="t4"> + <field Field="ËÏÌÏÎËÁ1" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="" Comment="" /> + </table_structure> + <table_data name="t4"> + <row> + <field name="ËÏÌÏÎËÁ1">1</field> + </row> + </table_data> +</database> +</mysqldump> +DROP table t1,t2,t3; +select * from t1; +a +1 +1 +select a,b from t1; +a b +1 NULL +1 2 +select * from t2; +a b +1 2 +1 2 +select * from t3; +invisible +1 +5 +2 +1 +desc t3; +Field Type Null Key Default Extra +invisible int(11) YES NULL +a b c & $!@#$%^&*( ) int(11) YES 4 INVISIBLE +ds=~!@ \# $% ^ & * ( ) _ - = + int(11) YES 5 INVISIBLE +drop database d; diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index d17469abae5..af0fadb4038 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -1206,26 +1206,6 @@ DROP TABLE t1; DROP VIEW v1; DROP PROCEDURE p1; DROP FUNCTION f1; -set names koi8r; -DROP DATABASE IF EXISTS mysqltest1; -CREATE DATABASE mysqltest1; -use mysqltest1; -CREATE TABLE t1(1 INT); - ----> Dumping mysqltest1 to outfile1 - - -DROP DATABASE mysqltest1; - - ----> Restoring mysqltest1... -SHOW CREATE TABLE mysqltest1.t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `1` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 -DROP DATABASE mysqltest1; -use test; flush status; show variables like "log_queries_not_using_indexes"; Variable_name Value @@ -1273,8 +1253,8 @@ PRIMARY KEY (Codigo) ) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; show create table t1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def Table 253 64 2 N 1 39 7 -def Create Table 253 1024 458 N 1 39 7 +def Table 253 192 2 N 1 39 33 +def Create Table 253 3072 458 N 1 39 33 Table Create Table t1 CREATE TABLE `t1` ( `Codigo` int(10) unsigned NOT NULL AUTO_INCREMENT, diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 9f74f4ad9c0..85f60964c3b 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -2646,3 +2646,46 @@ CREATE TRIGGER tt1_t1 BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t1 (a) VALUES (1),(2),(3); --exec $MYSQL_DUMP --triggers --no-data --no-create-info --add-drop-trigger --skip-comments --databases test DROP TABLE t1; +--echo # +--echo # Test for Invisible columns +--echo # +create database d; +use d; + +--echo # Invisble field table +create table t1(a int , b int invisible); +insert into t1 values(1); +insert into t1(a,b) values(1,2); + +--echo # not invisible field table --complete-insert wont be used +create table t2(a int , b int); +insert into t2(a,b) values(1,2); +insert into t2(a,b) values(1,2); + +--echo # Invisble field table +create table t3(invisible int , `a b c & $!@#$%^&*( )` int invisible default 4, `ds=~!@ \# $% ^ & * ( ) _ - = +` int invisible default 5); +insert into t3 values(1); +insert into t3 values(5); +insert into t3 values(2); +insert into t3(`invisible`, `a b c & $!@#$%^&*( )`, `ds=~!@ \# $% ^ & * ( ) _ - = +` ) values(1,2,3); +CREATE TABLE t4(ËÏÌÏÎËÁ1 INT); +insert into t4 values(1); +--exec $MYSQL_DUMP --compact d + +--echo #Check side effect on --complete insert +--exec $MYSQL_DUMP --compact --complete-insert d +--echo #Check xml +--exec $MYSQL_DUMP --skip-create-options --skip-comments -X d + +#import data +--exec $MYSQL_DUMP --skip-comments d > $MYSQLTEST_VARDIR/tmp/invisible_dump.sql +DROP table t1,t2,t3; + +--exec $MYSQL d < $MYSQLTEST_VARDIR/tmp/invisible_dump.sql + +select * from t1; +select a,b from t1; +select * from t2; +select * from t3; +desc t3; +drop database d; diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index d84226460f2..a24fa632ea5 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -890,62 +890,62 @@ DROP FUNCTION f1; # Part 2: check that table with non-latin1 characters are dumped/restored # correctly. # - +# See MDEV-14651 for details # Ensure that all needed objects are dropped. -set names koi8r; +#set names koi8r; ---disable_warnings -DROP DATABASE IF EXISTS mysqltest1; ---enable_warnings +#--disable_warnings +#DROP DATABASE IF EXISTS mysqltest1; +#--enable_warnings # Create objects. -CREATE DATABASE mysqltest1; +#CREATE DATABASE mysqltest1; -use mysqltest1; +#use mysqltest1; -CREATE TABLE t1(1 INT); +#CREATE TABLE t1(1 INT); # Check: # - Dump mysqltest1; ---let $outfile1=$MYSQLTEST_VARDIR/tmp/show_check.mysqltest1.sql +#--let $outfile1=$MYSQLTEST_VARDIR/tmp/show_check.mysqltest1.sql ---source include/count_sessions.inc ---echo ---echo ---> Dumping mysqltest1 to outfile1 ---exec $MYSQL_DUMP --default-character-set=latin1 --character-sets-dir=$MYSQL_SHAREDIR/charsets --databases mysqltest1 > $outfile1 +#--source include/count_sessions.inc +#--echo +#--echo ---> Dumping mysqltest1 to outfile1 +#--exec $MYSQL_DUMP --default-character-set=latin1 --character-sets-dir=$MYSQL_SHAREDIR/charsets --databases mysqltest1 > $outfile1 # Take care that the additional session caused by MYSQL_DUMP has disappeared. ---source include/wait_until_count_sessions.inc +#--source include/wait_until_count_sessions.inc # - Clean mysqltest1; ---echo ---echo +#--echo +#--echo -DROP DATABASE mysqltest1; +#DROP DATABASE mysqltest1; # - Restore mysqltest1; ---echo ---echo +#--echo +#--echo ---source include/count_sessions.inc ---echo ---> Restoring mysqltest1... ---exec $MYSQL test < $outfile1 ---remove_file $outfile1 +#--source include/count_sessions.inc +#--echo ---> Restoring mysqltest1... +#--exec $MYSQL test < $outfile1 +#--remove_file $outfile1 # Take care that the additional session caused by MYSQL has disappeared. ---source include/wait_until_count_sessions.inc +#--source include/wait_until_count_sessions.inc # - Check definition of the table. -SHOW CREATE TABLE mysqltest1.t1; +#SHOW CREATE TABLE mysqltest1.t1; # Cleanup. -DROP DATABASE mysqltest1; -use test; +#DROP DATABASE mysqltest1; +#use test; # # Bug#28808 log_queries_not_using_indexes variable dynamic change is ignored |