Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 75 additions & 40 deletions client/mysqldump.cc
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
#define DUMP_TABLE_SEQUENCE 1

/* until MDEV-35831 is implemented, we'll have to detect VECTOR by name */
#define MYSQL_TYPE_VECTOR "V"
#define MYSQL_TYPE_VECTOR 1

static my_bool ignore_table_data(const uchar *hash_key, size_t len);
static void add_load_option(DYNAMIC_STRING *str, const char *option,
Expand Down Expand Up @@ -3168,6 +3168,7 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
char *ignore_flag, my_bool *versioned)
{
my_bool init=0, delayed, write_data, complete_insert;
my_bool is_generated=0, is_vector=0;
my_ulonglong num_fields;
char *result_table, *opt_quoted_table;
const char *insert_option;
Expand Down Expand Up @@ -3486,8 +3487,20 @@ static uint get_table_structure(const char *table, const char *db, char *table_t

while ((row= mysql_fetch_row(result)))
{
if (strstr(row[1],"INVISIBLE"))
complete_insert= 1;
is_generated= 0;
if (row[1])
{
if (strstr(row[1], "GENERATED") &&
!(row[2] && (strcmp(row[2], "ROW START") == 0 ||
strcmp(row[2], "ROW END") == 0)))
{
complete_insert= 1;
is_generated= 1;
}
if (strstr(row[1], "INVISIBLE"))
complete_insert= 1;
}

if (vers_hidden && row[2] && strcmp(row[2], "ROW START") == 0)
{
vers_hidden= 0;
Expand All @@ -3498,6 +3511,14 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
*versioned= 0;
}
}

if (is_generated && !path && !opt_dir)
continue;

dynstr_append_mem_checked(&field_flags, "", 1);
if (row[3] && strcmp(row[3], "vector") == 0)
field_flags.str[field_flags.length-1]|= MYSQL_TYPE_VECTOR;

if (init)
{
dynstr_append_checked(&select_field_names, ", ");
Expand Down Expand Up @@ -3526,11 +3547,6 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
if (opt_header)
dynstr_append_checked(&select_field_names_for_header,
quote_for_equal(row[0], name_buff));
/* VECTOR doesn't have a type code yet, must be detected by name */
if (row[3] && strcmp(row[3], "vector") == 0)
dynstr_append_checked(&field_flags, MYSQL_TYPE_VECTOR);
else
dynstr_append_checked(&field_flags, " ");
}

if (vers_hidden)
Expand All @@ -3544,7 +3560,7 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
"row_end" :
"row_end");
dynstr_append_checked(&insert_field_names, ", row_start, row_end");
dynstr_append_checked(&field_flags, " ");
dynstr_append_mem_checked(&field_flags, "", 2);
}

/*
Expand All @@ -3563,9 +3579,7 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
dynstr_append_checked(&insert_pat, "INTO ");
dynstr_append_checked(&insert_pat, opt_quoted_table);
if (complete_insert)
{
dynstr_append_checked(&insert_pat, " (");
}
else
{
if (extended_insert)
Expand All @@ -3577,7 +3591,7 @@ static uint get_table_structure(const char *table, const char *db, char *table_t

if (complete_insert)
dynstr_append_checked(&insert_pat, insert_field_names.str);
num_fields= mysql_num_rows(result) + (vers_hidden ? 2 : 0);
num_fields= field_flags.length;
mysql_free_result(result);
}
else
Expand Down Expand Up @@ -3629,33 +3643,35 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
check_io(sql_file);
}

if (write_data)
{
if (opt_replace_into)
dynstr_append_checked(&insert_pat, "REPLACE ");
else
dynstr_append_checked(&insert_pat, "INSERT ");
dynstr_append_checked(&insert_pat, insert_option);
dynstr_append_checked(&insert_pat, "INTO ");
dynstr_append_checked(&insert_pat, result_table);
if (complete_insert)
dynstr_append_checked(&insert_pat, " (");
else
{
dynstr_append_checked(&insert_pat, " VALUES ");
if (!extended_insert)
dynstr_append_checked(&insert_pat, "(");
}
}

while ((row= mysql_fetch_row(result)))
{
ulong *lengths= mysql_fetch_lengths(result);
is_generated= 0;
is_vector= 0;

/* VECTOR doesn't have a type code yet, must be detected by name */
if (strncmp(row[SHOW_TYPE], STRING_WITH_LEN("vector(")) == 0)
dynstr_append_checked(&field_flags, MYSQL_TYPE_VECTOR);
else
dynstr_append_checked(&field_flags, " ");
is_vector= 1;
else if (row[SHOW_EXTRA])
{
if (strstr(row[SHOW_EXTRA], "GENERATED") &&
!strstr(row[SHOW_EXTRA], "ROW START") &&
!strstr(row[SHOW_EXTRA], "ROW END"))
{
complete_insert= 1;
is_generated= 1;
}
}
if (row[SHOW_EXTRA] && strstr(row[SHOW_EXTRA], "INVISIBLE"))
complete_insert= 1;

if (is_generated && !path && !opt_dir)
continue;

dynstr_append_mem_checked(&field_flags, "", 1);
if (is_vector)
field_flags.str[field_flags.length-1]|= MYSQL_TYPE_VECTOR;

if (init)
{
if (!opt_xml && !opt_no_create_info)
Expand All @@ -3668,11 +3684,12 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
dynstr_append_checked(&select_field_names_for_header, ", ");
}
dynstr_append_checked(&select_field_names,
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
if (opt_header)
dynstr_append_checked(&select_field_names_for_header,
quote_for_equal(row[SHOW_FIELDNAME], name_buff));
init=1;

if (!opt_no_create_info)
{
if (opt_xml)
Expand All @@ -3686,7 +3703,7 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
quote_name(row[SHOW_FIELDNAME],name_buff, 0), row[SHOW_TYPE]);
else
fprintf(sql_file, " %s %s",
quote_name(row[SHOW_FIELDNAME], name_buff, 0), row[SHOW_TYPE]);
quote_name(row[SHOW_FIELDNAME], name_buff, 0), row[SHOW_TYPE]);
if (row[SHOW_DEFAULT])
{
fputs(" DEFAULT ", sql_file);
Expand All @@ -3699,9 +3716,29 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
check_io(sql_file);
}
}

if (write_data)
{
if (opt_replace_into)
dynstr_append_checked(&insert_pat, "REPLACE ");
else
dynstr_append_checked(&insert_pat, "INSERT ");
dynstr_append_checked(&insert_pat, insert_option);
dynstr_append_checked(&insert_pat, "INTO ");
dynstr_append_checked(&insert_pat, result_table);
if (complete_insert)
dynstr_append_checked(&insert_pat, " (");
else
{
dynstr_append_checked(&insert_pat, " VALUES ");
if (!extended_insert)
dynstr_append_checked(&insert_pat, "(");
}
}

if (complete_insert)
dynstr_append_checked(&insert_pat, select_field_names.str);
num_fields= mysql_num_rows(result);
num_fields= field_flags.length;
mysql_free_result(result);
if (!opt_no_create_info)
{
Expand Down Expand Up @@ -4240,7 +4277,6 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key,
uint num_fields;
size_t total_length, init_length;
my_bool versioned= 0;

MYSQL_RES *res= NULL;
MYSQL_FIELD *field;
MYSQL_ROW row;
Expand All @@ -4251,7 +4287,6 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key,
--no-data flag below. Otherwise, the create table info won't be printed.
*/
num_fields= get_table_structure(table, db, table_type, &ignore_flag, &versioned);

/*
The "table" could be a view. If so, we don't do anything here.
*/
Expand Down Expand Up @@ -4544,7 +4579,7 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key,
*/
is_blob= field->type == MYSQL_TYPE_GEOMETRY ||
field->type == MYSQL_TYPE_BIT ||
field_flags.str[i] == MYSQL_TYPE_VECTOR[0] ||
field_flags.str[i] & MYSQL_TYPE_VECTOR ||
(opt_hex_blob && field->charsetnr == 63 &&
(field->type == MYSQL_TYPE_STRING ||
field->type == MYSQL_TYPE_VAR_STRING ||
Expand Down
55 changes: 55 additions & 0 deletions mysql-test/main/mysqldump.result
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,61 @@ INSERT INTO t1 VALUES (1), (2);
</mysqldump>
DROP TABLE t1;
#
# MDEV-32362 Remove generated columns from INSERT statements in dump
# Include list of non-generated columns in INSERT statements for tables
# with one or more generated columns
#
CREATE DATABASE dump_generated;
USE dump_generated;
CREATE TABLE t1 (pk INTEGER, a INTEGER, b INTEGER, c VARCHAR(16),
sum INTEGER GENERATED ALWAYS AS (a+b),
sub VARCHAR(4) GENERATED ALWAYS AS (SUBSTRING(c, 1, 4)),
key k1(sum),
key k2(sub)
) engine=innodb;
INSERT INTO t1(pk, a, b, c) VALUES (1, 11, 12, 'oneone'), (2, 21, 22, 'twotwo');
SELECT * FROM t1;
pk a b c sum sub
1 11 12 oneone 23 oneo
2 21 22 twotwo 43 twot
DELETE FROM t1;
SELECT * FROM t1;
pk a b c sum sub
1 11 12 oneone 23 oneo
2 21 22 twotwo 43 twot
DELETE FROM t1;
LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' INTO TABLE t1;
SELECT * FROM t1;
pk a b c sum sub
1 11 12 oneone 23 oneo
2 21 22 twotwo 43 twot
DROP TABLE t1;
# A table with regular columns after generated
CREATE TABLE t2 (pk INTEGER, a INTEGER, b INTEGER,
sum INTEGER GENERATED ALWAYS AS (a+b),
c VARCHAR(16),
key k1(sum)
) engine=innodb;
INSERT INTO t2(pk, a, b, c) VALUES (1, 11, 12, 'oneone'), (2, 21, 22, 'twotwo');
SELECT * FROM t2;
pk a b sum c
1 11 12 23 oneone
2 21 22 43 twotwo
DELETE FROM t2;
SELECT * FROM t2;
pk a b sum c
1 11 12 23 oneone
2 21 22 43 twotwo
DELETE FROM t2;
LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/t2.txt' INTO TABLE t2;
SELECT * FROM t2;
pk a b sum c
1 11 12 23 oneone
2 21 22 43 twotwo
DROP TABLE t2;
DROP DATABASE dump_generated;
USE test;
#
# Bug#2005 Long decimal comparison bug.
#
CREATE TABLE t1 (a decimal(64, 20));
Expand Down
50 changes: 50 additions & 0 deletions mysql-test/main/mysqldump.test
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,56 @@ INSERT INTO t1 VALUES (1), (2);
--exec $MYSQL_DUMP --skip-create-options --skip-comments -X test t1
DROP TABLE t1;

--echo #
--echo # MDEV-32362 Remove generated columns from INSERT statements in dump
--echo # Include list of non-generated columns in INSERT statements for tables
--echo # with one or more generated columns
--echo #

CREATE DATABASE dump_generated;
USE dump_generated;
CREATE TABLE t1 (pk INTEGER, a INTEGER, b INTEGER, c VARCHAR(16),
sum INTEGER GENERATED ALWAYS AS (a+b),
sub VARCHAR(4) GENERATED ALWAYS AS (SUBSTRING(c, 1, 4)),
key k1(sum),
key k2(sub)
) engine=innodb;
INSERT INTO t1(pk, a, b, c) VALUES (1, 11, 12, 'oneone'), (2, 21, 22, 'twotwo');
SELECT * FROM t1;
--exec $MYSQL_DUMP dump_generated t1 > $MYSQLTEST_VARDIR/tmp/t1.sql
DELETE FROM t1;
--exec $MYSQL dump_generated < $MYSQLTEST_VARDIR/tmp/t1.sql
SELECT * FROM t1;
--exec $MYSQL_DUMP dump_generated t1 --tab=$MYSQLTEST_VARDIR/tmp/
DELETE FROM t1;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t1.txt' INTO TABLE t1
SELECT * FROM t1;
DROP TABLE t1;

--echo # A table with regular columns after generated

CREATE TABLE t2 (pk INTEGER, a INTEGER, b INTEGER,
sum INTEGER GENERATED ALWAYS AS (a+b),
c VARCHAR(16),
key k1(sum)
) engine=innodb;
INSERT INTO t2(pk, a, b, c) VALUES (1, 11, 12, 'oneone'), (2, 21, 22, 'twotwo');
SELECT * FROM t2;
--exec $MYSQL_DUMP dump_generated t2 > $MYSQLTEST_VARDIR/tmp/t2.sql
DELETE FROM t2;
--exec $MYSQL dump_generated < $MYSQLTEST_VARDIR/tmp/t2.sql
SELECT * FROM t2;
--exec $MYSQL_DUMP dump_generated t2 --tab=$MYSQLTEST_VARDIR/tmp/
DELETE FROM t2;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t2.txt' INTO TABLE t2
SELECT * FROM t2;
DROP TABLE t2;

DROP DATABASE dump_generated;
USE test;

--echo #
--echo # Bug#2005 Long decimal comparison bug.
--echo #
Expand Down