!4383 【MYSQL兼容性】修复自增列多条INSERT INTO ON DUPLICATE KEY UPDATE结果问题

Merge pull request !4383 from 李居东/fix_autoinc_upsert
This commit is contained in:
opengauss_bot
2023-11-07 08:30:43 +00:00
committed by Gitee
8 changed files with 558 additions and 25 deletions

View File

@ -203,6 +203,8 @@ EState* CreateExecutorState()
estate->pruningResult = NULL;
estate->first_autoinc = 0;
estate->cur_insert_autoinc = 0;
estate->next_autoinc = 0;
estate->es_is_flt_frame = (u_sess->attr.attr_common.enable_expr_fusion && u_sess->attr.attr_sql.query_dop_tmp == 1);
/*
* Return the executor state structure
@ -1553,8 +1555,15 @@ Tuple ExecAutoIncrement(Relation rel, EState* estate, TupleTableSlot* slot, Tupl
if (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP) {
autoinc = tmptable_autoinc_nextval(rel->rd_rel->relfilenode, cons_autoinc->next);
} else {
autoinc = nextval_internal(cons_autoinc->seqoid);
if (estate->next_autoinc > 0) {
autoinc = estate->next_autoinc;
estate->next_autoinc = 0;
} else {
autoinc = nextval_internal(cons_autoinc->seqoid);
}
}
estate->cur_insert_autoinc = autoinc;
if (estate->first_autoinc == 0) {
estate->first_autoinc = autoinc;
}
@ -1589,6 +1598,26 @@ static void UpdateAutoIncrement(Relation rel, Tuple tuple, EState* estate)
}
}
void RestoreAutoIncrement(Relation rel, EState* estate, Tuple tuple)
{
bool isnull = false;
ConstrAutoInc* cons_autoinc = rel->rd_att->constr->cons_autoinc;
Datum datum = tableam_tops_tuple_fast_getattr(tuple, cons_autoinc->attnum, rel->rd_att, &isnull);
if (!isnull) {
int128 autoinc = datum2autoinc(cons_autoinc, datum);
if (autoinc >= estate->cur_insert_autoinc) {
return;
}
}
if (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP) {
*cons_autoinc->next = estate->cur_insert_autoinc;
} else {
estate->next_autoinc = estate->cur_insert_autoinc;
}
}
/* purely for reducing cyclomatic complexity */
static inline bool GetPartiionIndexOidList(List **oidlist_ptr, Partition part)
{

View File

@ -2255,6 +2255,17 @@ lreplace:
slot = ExecProcNodeDMLInXC(estate, planSlot, slot);
} else {
#endif
/* restore auto_increment value for multi-rows upsert-update */
if (node->mt_upsert != NULL && node->mt_upsert->us_action != UPSERT_NONE &&
RelHasAutoInc(result_relation_desc) &&
estate->cur_insert_autoinc > 0) {
RestoreAutoIncrement(result_relation_desc, estate, tuple);
/* avoid set last_insert_id */
if (estate->first_autoinc == estate->cur_insert_autoinc) {
estate->first_autoinc = 0;
}
}
/*
* replace the heap tuple
*

View File

@ -691,6 +691,7 @@ extern void ExecCopyDataFromDatum(PLpgSQL_datum** datums, int dno, Cursor_Data*
extern void ExecCopyDataToDatum(PLpgSQL_datum** datums, int dno, Cursor_Data* target_cursor);
extern Tuple ExecAutoIncrement(Relation rel, EState* estate, TupleTableSlot* slot, Tuple tuple);
extern void RestoreAutoIncrement(Relation rel, EState* estate, Tuple tuple);
/*
* prototypes from functions in execReplication.cpp

View File

@ -722,6 +722,8 @@ typedef struct EState {
bool have_current_xact_date; /* Check whether dirty reads exist in the cursor rollback scenario. */
int128 first_autoinc; /* autoinc has increased during this execution */
int result_rel_index; /* which result_rel_info to be excuted when multiple-relation modified. */
int128 cur_insert_autoinc;
int128 next_autoinc;
#ifdef USE_SPQ
List *es_sharenode;
#endif

View File

@ -982,13 +982,13 @@ SELECT CONCAT(_utf8mb4'楂樻柉DB楂樻柉DB' COLLATE utf8mb4_bin, CONCAT(_gbk'
SELECT CONCAT('高斯DB', opengauss_version()) result, collation for(result);
result | pg_collation_for
---------------+------------------
高斯DB5.1.0 | utf8_general_ci
高斯DB5.1.1 | utf8_general_ci
(1 row)
SELECT CONCAT(opengauss_version(), '高斯DB') result, collation for(result);
result | pg_collation_for
---------------+------------------
5.1.0高斯DB | utf8_general_ci
5.1.1高斯DB | utf8_general_ci
(1 row)
SELECT CONCAT('高斯DB', 123) result, collation for(result);
@ -1031,13 +1031,13 @@ SELECT CONCAT(NULL, '高斯DB') result, collation for(result);
SELECT CONCAT(_utf8mb4'高斯DB', opengauss_version()) result, collation for(result);
result | pg_collation_for
-------------+------------------
��˹DB5.1.0 | utf8_general_ci
��˹DB5.1.1 | utf8_general_ci
(1 row)
SELECT CONCAT(opengauss_version(), _utf8mb4'高斯DB') result, collation for(result);
result | pg_collation_for
-------------+------------------
5.1.0��˹DB | utf8_general_ci
5.1.1��˹DB | utf8_general_ci
(1 row)
SELECT CONCAT(_utf8mb4'高斯DB', 123) result, collation for(result);
@ -1081,13 +1081,13 @@ SELECT CONCAT(NULL, _utf8mb4'高斯DB') result, collation for(result);
SELECT CONCAT(CONCAT('高斯DB'), opengauss_version()) result, collation for(result);
result | pg_collation_for
---------------+------------------
高斯DB5.1.0 | utf8_general_ci
高斯DB5.1.1 | utf8_general_ci
(1 row)
SELECT CONCAT(opengauss_version(), CONCAT('高斯DB')) result, collation for(result);
result | pg_collation_for
---------------+------------------
5.1.0高斯DB | utf8_general_ci
5.1.1高斯DB | utf8_general_ci
(1 row)
SELECT CONCAT(CONCAT('高斯DB'), 123) result, collation for(result);
@ -1130,13 +1130,13 @@ SELECT CONCAT(NULL, CONCAT('高斯DB')) result, collation for(result);
SELECT CONCAT(CONCAT(_utf8mb4'高斯DB'), opengauss_version()) result, collation for(result);
result | pg_collation_for
-------------+------------------
��˹DB5.1.0 | utf8_general_ci
��˹DB5.1.1 | utf8_general_ci
(1 row)
SELECT CONCAT(opengauss_version(), CONCAT(_utf8mb4'高斯DB')) result, collation for(result);
result | pg_collation_for
-------------+------------------
5.1.0��˹DB | utf8_general_ci
5.1.1��˹DB | utf8_general_ci
(1 row)
SELECT CONCAT(CONCAT(_utf8mb4'高斯DB'), 123) result, collation for(result);
@ -2102,13 +2102,13 @@ LINE 1: ...) result, collation for(result) FROM t_diff_charset_columns;
SELECT CONCAT(futf8_uni, opengauss_version()) result, collation for(result) FROM t_diff_charset_columns;
result | pg_collation_for
---------------+--------------------
高斯db5.1.0 | utf8mb4_unicode_ci
高斯db5.1.1 | utf8mb4_unicode_ci
(1 row)
SELECT CONCAT(opengauss_version(), futf8_uni) result, collation for(result) FROM t_diff_charset_columns;
result | pg_collation_for
---------------+--------------------
5.1.0高斯db | utf8mb4_unicode_ci
5.1.1高斯db | utf8mb4_unicode_ci
(1 row)
SELECT CONCAT(fgbk_chi, '高斯DB') result, collation for(result) FROM t_diff_charset_columns;
@ -2195,13 +2195,13 @@ LINE 1: ...) result, collation for(result) FROM t_diff_charset_columns;
SELECT CONCAT(fgbk_chi, opengauss_version()) result, collation for(result) FROM t_diff_charset_columns;
result | pg_collation_for
---------------+------------------
高斯db5.1.0 | gbk_chinese_ci
高斯db5.1.1 | gbk_chinese_ci
(1 row)
SELECT CONCAT(opengauss_version(), fgbk_bin) result, collation for(result) FROM t_diff_charset_columns;
result | pg_collation_for
---------------+------------------
5.1.0高斯DB | gbk_bin
5.1.1高斯DB | gbk_bin
(1 row)
SELECT CONCAT(futf8_uni, '高斯DB') result, collation for(result) FROM t_diff_charset_columns;

View File

@ -1368,13 +1368,13 @@ SELECT CONCAT(_utf8mb4'楂樻柉DB楂樻柉DB' COLLATE utf8mb4_bin, CONCAT(_gbk'
SELECT CONCAT('高斯DB', opengauss_version()) result, collation for(result);
result | pg_collation_for
-------------+------------------
高斯DB5.1.0 | utf8_general_ci
高斯DB5.1.1 | utf8_general_ci
(1 row)
SELECT CONCAT(opengauss_version(), '高斯DB') result, collation for(result);
result | pg_collation_for
-------------+------------------
5.1.0高斯DB | utf8_general_ci
5.1.1高斯DB | utf8_general_ci
(1 row)
SELECT CONCAT('高斯DB', 123) result, collation for(result);
@ -1417,13 +1417,13 @@ SELECT CONCAT(NULL, '高斯DB') result, collation for(result);
SELECT CONCAT(_gbk'高斯DB', opengauss_version()) result, collation for(result);
result | pg_collation_for
---------------+------------------
楂樻柉DB5.1.0 | utf8_general_ci
楂樻柉DB5.1.1 | utf8_general_ci
(1 row)
SELECT CONCAT(opengauss_version(), _gbk'高斯DB') result, collation for(result);
result | pg_collation_for
---------------+------------------
5.1.0楂樻柉DB | utf8_general_ci
5.1.1楂樻柉DB | utf8_general_ci
(1 row)
SELECT CONCAT(_gbk'高斯DB', 123) result, collation for(result);
@ -1467,13 +1467,13 @@ SELECT CONCAT(NULL, _gbk'高斯DB') result, collation for(result);
SELECT CONCAT(CONCAT('高斯DB'), opengauss_version()) result, collation for(result);
result | pg_collation_for
-------------+------------------
高斯DB5.1.0 | utf8_general_ci
高斯DB5.1.1 | utf8_general_ci
(1 row)
SELECT CONCAT(opengauss_version(), CONCAT('高斯DB')) result, collation for(result);
result | pg_collation_for
-------------+------------------
5.1.0高斯DB | utf8_general_ci
5.1.1高斯DB | utf8_general_ci
(1 row)
SELECT CONCAT(CONCAT('高斯DB'), 123) result, collation for(result);
@ -1516,13 +1516,13 @@ SELECT CONCAT(NULL, CONCAT('高斯DB')) result, collation for(result);
SELECT CONCAT(CONCAT(_gbk'高斯DB'), opengauss_version()) result, collation for(result);
result | pg_collation_for
---------------+------------------
楂樻柉DB5.1.0 | utf8_general_ci
楂樻柉DB5.1.1 | utf8_general_ci
(1 row)
SELECT CONCAT(opengauss_version(), CONCAT(_gbk'高斯DB')) result, collation for(result);
result | pg_collation_for
---------------+------------------
5.1.0楂樻柉DB | utf8_general_ci
5.1.1楂樻柉DB | utf8_general_ci
(1 row)
SELECT CONCAT(CONCAT(_gbk'高斯DB'), 123) result, collation for(result);
@ -2952,13 +2952,13 @@ SELECT CONCAT(futf8_uni, CONCAT(futf8_gen)) result, collation for(result) FROM t
SELECT CONCAT(futf8_uni, opengauss_version()) result, collation for(result) FROM t_diff_charset_columns;
result | pg_collation_for
-------------+--------------------
高斯db5.1.0 | utf8mb4_unicode_ci
高斯db5.1.1 | utf8mb4_unicode_ci
(1 row)
SELECT CONCAT(opengauss_version(), futf8_uni) result, collation for(result) FROM t_diff_charset_columns;
result | pg_collation_for
-------------+--------------------
5.1.0高斯db | utf8mb4_unicode_ci
5.1.1高斯db | utf8mb4_unicode_ci
(1 row)
SELECT CONCAT(futf8_uni, '高斯DB') result, collation for(result) FROM t_diff_charset_columns;
@ -3065,13 +3065,13 @@ LINE 1: ...) result, collation for(result) FROM t_diff_charset_columns;
SELECT CONCAT(fgbk_chi, opengauss_version()) result, collation for(result) FROM t_diff_charset_columns;
result | pg_collation_for
-------------+------------------
高斯db5.1.0 | gbk_chinese_ci
高斯db5.1.1 | gbk_chinese_ci
(1 row)
SELECT CONCAT(opengauss_version(), fgbk_bin) result, collation for(result) FROM t_diff_charset_columns;
result | pg_collation_for
-------------+------------------
5.1.0高斯DB | gbk_bin
5.1.1高斯DB | gbk_bin
(1 row)
SELECT CONCAT(fgbk_chi, '高斯DB') result, collation for(result) FROM t_diff_charset_columns;

View File

@ -5356,6 +5356,366 @@ SELECT col1,col2 FROM test_autoinc_batch_copy ORDER BY 1;
(7 rows)
drop table test_autoinc_batch_copy;
-- upsert not auto_increment column
CREATE TABLE test_autoinc_upsert ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( ID ),
val INT NOT NULL, UNIQUE( val ),
test_autoinc_upsert INT DEFAULT 1,
action varchar( 10 ) DEFAULT 'insert',
comment varchar( 30 ) );
NOTICE: CREATE TABLE will create implicit sequence "test_autoinc_upsert_id_seq" for serial column "test_autoinc_upsert.id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_autoinc_upsert_pkey" for table "test_autoinc_upsert"
NOTICE: CREATE TABLE / UNIQUE will create implicit index "test_autoinc_upsert_val_key" for table "test_autoinc_upsert"
INSERT INTO test_autoinc_upsert ( val ) VALUES ( 1 ), ( 2 ) ON DUPLICATE KEY UPDATE action = 'update';
SELECT * FROM test_autoinc_upsert ORDER BY 2;
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
2 | 2 | 1 | insert |
(2 rows)
INSERT INTO test_autoinc_upsert (val )
VALUES ( 1 ), ( 2 ), ( 3 )
ON DUPLICATE KEY UPDATE action = 'update';
SELECT LAST_INSERT_ID(); -- 3
last_insert_id
----------------
3
(1 row)
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 2 3
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | update |
2 | 2 | 1 | update |
3 | 3 | 1 | insert |
(3 rows)
INSERT INTO test_autoinc_upsert (val ) VALUES ( 4 );
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 2 3 4
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | update |
2 | 2 | 1 | update |
3 | 3 | 1 | insert |
4 | 4 | 1 | insert |
(4 rows)
drop table test_autoinc_upsert;
-- upsert auto_increment 3
CREATE TABLE test_autoinc_upsert ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( ID ),
val INT NOT NULL, UNIQUE( val ),
test_autoinc_upsert INT DEFAULT 1,
action varchar( 10 ) DEFAULT 'insert',
comment varchar( 30 ) );
NOTICE: CREATE TABLE will create implicit sequence "test_autoinc_upsert_id_seq" for serial column "test_autoinc_upsert.id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_autoinc_upsert_pkey" for table "test_autoinc_upsert"
NOTICE: CREATE TABLE / UNIQUE will create implicit index "test_autoinc_upsert_val_key" for table "test_autoinc_upsert"
INSERT INTO test_autoinc_upsert ( val ) VALUES ( 1 ), ( 2 ) ON DUPLICATE KEY UPDATE action = 'update';
SELECT * FROM test_autoinc_upsert ORDER BY 2;
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
2 | 2 | 1 | insert |
(2 rows)
INSERT INTO test_autoinc_upsert (val )
VALUES ( 2 ), ( 3 )
ON DUPLICATE KEY UPDATE id = '3';
SELECT LAST_INSERT_ID(); -- 4
last_insert_id
----------------
4
(1 row)
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 3 4
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
3 | 2 | 1 | insert |
4 | 3 | 1 | insert |
(3 rows)
INSERT INTO test_autoinc_upsert (val ) VALUES ( 4 );
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 3 4 5
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
3 | 2 | 1 | insert |
4 | 3 | 1 | insert |
5 | 4 | 1 | insert |
(4 rows)
drop table test_autoinc_upsert;
-- upsert auto_increment 2
CREATE TABLE test_autoinc_upsert ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( ID ),
val INT NOT NULL, UNIQUE( val ),
test_autoinc_upsert INT DEFAULT 1,
action varchar( 10 ) DEFAULT 'insert',
comment varchar( 30 ) );
NOTICE: CREATE TABLE will create implicit sequence "test_autoinc_upsert_id_seq" for serial column "test_autoinc_upsert.id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_autoinc_upsert_pkey" for table "test_autoinc_upsert"
NOTICE: CREATE TABLE / UNIQUE will create implicit index "test_autoinc_upsert_val_key" for table "test_autoinc_upsert"
INSERT INTO test_autoinc_upsert ( val ) VALUES ( 1 ), ( 2 ) ON DUPLICATE KEY UPDATE action = 'update';
SELECT * FROM test_autoinc_upsert ORDER BY 2;
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
2 | 2 | 1 | insert |
(2 rows)
INSERT INTO test_autoinc_upsert (val )
VALUES ( 2 ), ( 3 )
ON DUPLICATE KEY UPDATE id = '2';
SELECT LAST_INSERT_ID(); -- 3
last_insert_id
----------------
3
(1 row)
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 2 3
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
2 | 2 | 1 | insert |
3 | 3 | 1 | insert |
(3 rows)
INSERT INTO test_autoinc_upsert (val ) VALUES ( 4 );
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 2 3 4
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
2 | 2 | 1 | insert |
3 | 3 | 1 | insert |
4 | 4 | 1 | insert |
(4 rows)
drop table test_autoinc_upsert;
-- upsert auto_increment 5
CREATE TABLE test_autoinc_upsert ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( ID ),
val INT NOT NULL, UNIQUE( val ),
test_autoinc_upsert INT DEFAULT 1,
action varchar( 10 ) DEFAULT 'insert',
comment varchar( 30 ) );
NOTICE: CREATE TABLE will create implicit sequence "test_autoinc_upsert_id_seq" for serial column "test_autoinc_upsert.id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_autoinc_upsert_pkey" for table "test_autoinc_upsert"
NOTICE: CREATE TABLE / UNIQUE will create implicit index "test_autoinc_upsert_val_key" for table "test_autoinc_upsert"
INSERT INTO test_autoinc_upsert ( val ) VALUES ( 1 ), ( 2 ) ON DUPLICATE KEY UPDATE action = 'update';
SELECT * FROM test_autoinc_upsert ORDER BY 2;
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
2 | 2 | 1 | insert |
(2 rows)
INSERT INTO test_autoinc_upsert (val )
VALUES ( 2 ), ( 3 ), ( 4 )
ON DUPLICATE KEY UPDATE id = '5';
SELECT LAST_INSERT_ID(); -- 6
last_insert_id
----------------
6
(1 row)
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 5 6 7
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
5 | 2 | 1 | insert |
6 | 3 | 1 | insert |
7 | 4 | 1 | insert |
(4 rows)
INSERT INTO test_autoinc_upsert (val ) VALUES ( 5 );
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 5 6 7 8
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
5 | 2 | 1 | insert |
6 | 3 | 1 | insert |
7 | 4 | 1 | insert |
8 | 5 | 1 | insert |
(5 rows)
drop table test_autoinc_upsert;
-- temp table upsert not auto_increment column
CREATE TEMPORARY TABLE test_autoinc_upsert ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( ID ),
val INT NOT NULL, UNIQUE( val ),
test_autoinc_upsert INT DEFAULT 1,
action varchar( 10 ) DEFAULT 'insert',
comment varchar( 30 ) );
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_autoinc_upsert_pkey" for table "test_autoinc_upsert"
NOTICE: CREATE TABLE / UNIQUE will create implicit index "test_autoinc_upsert_val_key" for table "test_autoinc_upsert"
INSERT INTO test_autoinc_upsert ( val ) VALUES ( 1 ), ( 2 ) ON DUPLICATE KEY UPDATE action = 'update';
SELECT * FROM test_autoinc_upsert ORDER BY 2;
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
2 | 2 | 1 | insert |
(2 rows)
INSERT INTO test_autoinc_upsert (val )
VALUES ( 1 ), ( 2 ), ( 3 )
ON DUPLICATE KEY UPDATE action = 'update';
SELECT LAST_INSERT_ID(); -- 3
last_insert_id
----------------
3
(1 row)
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 2 3
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | update |
2 | 2 | 1 | update |
3 | 3 | 1 | insert |
(3 rows)
INSERT INTO test_autoinc_upsert (val ) VALUES ( 4 );
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 2 3 4
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | update |
2 | 2 | 1 | update |
3 | 3 | 1 | insert |
4 | 4 | 1 | insert |
(4 rows)
drop table test_autoinc_upsert;
-- upsert auto_increment 3
CREATE TEMPORARY TABLE test_autoinc_upsert ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( ID ),
val INT NOT NULL, UNIQUE( val ),
test_autoinc_upsert INT DEFAULT 1,
action varchar( 10 ) DEFAULT 'insert',
comment varchar( 30 ) );
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_autoinc_upsert_pkey" for table "test_autoinc_upsert"
NOTICE: CREATE TABLE / UNIQUE will create implicit index "test_autoinc_upsert_val_key" for table "test_autoinc_upsert"
INSERT INTO test_autoinc_upsert ( val ) VALUES ( 1 ), ( 2 ) ON DUPLICATE KEY UPDATE action = 'update';
SELECT * FROM test_autoinc_upsert ORDER BY 2;
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
2 | 2 | 1 | insert |
(2 rows)
INSERT INTO test_autoinc_upsert (val )
VALUES ( 2 ), ( 3 )
ON DUPLICATE KEY UPDATE id = '3';
SELECT LAST_INSERT_ID(); -- 4
last_insert_id
----------------
4
(1 row)
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 3 4
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
3 | 2 | 1 | insert |
4 | 3 | 1 | insert |
(3 rows)
INSERT INTO test_autoinc_upsert (val ) VALUES ( 4 );
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 3 4 5
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
3 | 2 | 1 | insert |
4 | 3 | 1 | insert |
5 | 4 | 1 | insert |
(4 rows)
drop table test_autoinc_upsert;
-- upsert auto_increment 2
CREATE TEMPORARY TABLE test_autoinc_upsert ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( ID ),
val INT NOT NULL, UNIQUE( val ),
test_autoinc_upsert INT DEFAULT 1,
action varchar( 10 ) DEFAULT 'insert',
comment varchar( 30 ) );
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_autoinc_upsert_pkey" for table "test_autoinc_upsert"
NOTICE: CREATE TABLE / UNIQUE will create implicit index "test_autoinc_upsert_val_key" for table "test_autoinc_upsert"
INSERT INTO test_autoinc_upsert ( val ) VALUES ( 1 ), ( 2 ) ON DUPLICATE KEY UPDATE action = 'update';
SELECT * FROM test_autoinc_upsert ORDER BY 2;
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
2 | 2 | 1 | insert |
(2 rows)
INSERT INTO test_autoinc_upsert (val )
VALUES ( 2 ), ( 3 )
ON DUPLICATE KEY UPDATE id = '2';
SELECT LAST_INSERT_ID(); -- 3
last_insert_id
----------------
3
(1 row)
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 2 3
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
2 | 2 | 1 | insert |
3 | 3 | 1 | insert |
(3 rows)
INSERT INTO test_autoinc_upsert (val ) VALUES ( 4 );
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 2 3 4
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
2 | 2 | 1 | insert |
3 | 3 | 1 | insert |
4 | 4 | 1 | insert |
(4 rows)
drop table test_autoinc_upsert;
-- upsert auto_increment 5
CREATE TEMPORARY TABLE test_autoinc_upsert ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( ID ),
val INT NOT NULL, UNIQUE( val ),
test_autoinc_upsert INT DEFAULT 1,
action varchar( 10 ) DEFAULT 'insert',
comment varchar( 30 ) );
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_autoinc_upsert_pkey" for table "test_autoinc_upsert"
NOTICE: CREATE TABLE / UNIQUE will create implicit index "test_autoinc_upsert_val_key" for table "test_autoinc_upsert"
INSERT INTO test_autoinc_upsert ( val ) VALUES ( 1 ), ( 2 ) ON DUPLICATE KEY UPDATE action = 'update';
SELECT * FROM test_autoinc_upsert ORDER BY 2;
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
2 | 2 | 1 | insert |
(2 rows)
INSERT INTO test_autoinc_upsert (val )
VALUES ( 2 ), ( 3 ), ( 4 )
ON DUPLICATE KEY UPDATE id = '5';
SELECT LAST_INSERT_ID(); -- 6
last_insert_id
----------------
6
(1 row)
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 5 6 7
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
5 | 2 | 1 | insert |
6 | 3 | 1 | insert |
7 | 4 | 1 | insert |
(4 rows)
INSERT INTO test_autoinc_upsert (val ) VALUES ( 5 );
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 5 6 7 8
id | val | test_autoinc_upsert | action | comment
----+-----+---------------------+--------+---------
1 | 1 | 1 | insert |
5 | 2 | 1 | insert |
6 | 3 | 1 | insert |
7 | 4 | 1 | insert |
8 | 5 | 1 | insert |
(5 rows)
drop table test_autoinc_upsert;
\c regression
clean connection to all force for database autoinc_b_db;
drop database if exists autoinc_b_db;

View File

@ -1568,6 +1568,136 @@ INSERT INTO test_autoinc_batch_copy VALUES(DEFAULT, 1);
SELECT col1,col2 FROM test_autoinc_batch_copy ORDER BY 1;
drop table test_autoinc_batch_copy;
-- upsert not auto_increment column
CREATE TABLE test_autoinc_upsert ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( ID ),
val INT NOT NULL, UNIQUE( val ),
test_autoinc_upsert INT DEFAULT 1,
action varchar( 10 ) DEFAULT 'insert',
comment varchar( 30 ) );
INSERT INTO test_autoinc_upsert ( val ) VALUES ( 1 ), ( 2 ) ON DUPLICATE KEY UPDATE action = 'update';
SELECT * FROM test_autoinc_upsert ORDER BY 2;
INSERT INTO test_autoinc_upsert (val )
VALUES ( 1 ), ( 2 ), ( 3 )
ON DUPLICATE KEY UPDATE action = 'update';
SELECT LAST_INSERT_ID(); -- 3
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 2 3
INSERT INTO test_autoinc_upsert (val ) VALUES ( 4 );
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 2 3 4
drop table test_autoinc_upsert;
-- upsert auto_increment 3
CREATE TABLE test_autoinc_upsert ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( ID ),
val INT NOT NULL, UNIQUE( val ),
test_autoinc_upsert INT DEFAULT 1,
action varchar( 10 ) DEFAULT 'insert',
comment varchar( 30 ) );
INSERT INTO test_autoinc_upsert ( val ) VALUES ( 1 ), ( 2 ) ON DUPLICATE KEY UPDATE action = 'update';
SELECT * FROM test_autoinc_upsert ORDER BY 2;
INSERT INTO test_autoinc_upsert (val )
VALUES ( 2 ), ( 3 )
ON DUPLICATE KEY UPDATE id = '3';
SELECT LAST_INSERT_ID(); -- 4
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 3 4
INSERT INTO test_autoinc_upsert (val ) VALUES ( 4 );
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 3 4 5
drop table test_autoinc_upsert;
-- upsert auto_increment 2
CREATE TABLE test_autoinc_upsert ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( ID ),
val INT NOT NULL, UNIQUE( val ),
test_autoinc_upsert INT DEFAULT 1,
action varchar( 10 ) DEFAULT 'insert',
comment varchar( 30 ) );
INSERT INTO test_autoinc_upsert ( val ) VALUES ( 1 ), ( 2 ) ON DUPLICATE KEY UPDATE action = 'update';
SELECT * FROM test_autoinc_upsert ORDER BY 2;
INSERT INTO test_autoinc_upsert (val )
VALUES ( 2 ), ( 3 )
ON DUPLICATE KEY UPDATE id = '2';
SELECT LAST_INSERT_ID(); -- 3
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 2 3
INSERT INTO test_autoinc_upsert (val ) VALUES ( 4 );
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 2 3 4
drop table test_autoinc_upsert;
-- upsert auto_increment 5
CREATE TABLE test_autoinc_upsert ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( ID ),
val INT NOT NULL, UNIQUE( val ),
test_autoinc_upsert INT DEFAULT 1,
action varchar( 10 ) DEFAULT 'insert',
comment varchar( 30 ) );
INSERT INTO test_autoinc_upsert ( val ) VALUES ( 1 ), ( 2 ) ON DUPLICATE KEY UPDATE action = 'update';
SELECT * FROM test_autoinc_upsert ORDER BY 2;
INSERT INTO test_autoinc_upsert (val )
VALUES ( 2 ), ( 3 ), ( 4 )
ON DUPLICATE KEY UPDATE id = '5';
SELECT LAST_INSERT_ID(); -- 6
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 5 6 7
INSERT INTO test_autoinc_upsert (val ) VALUES ( 5 );
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 5 6 7 8
drop table test_autoinc_upsert;
-- temp table upsert not auto_increment column
CREATE TEMPORARY TABLE test_autoinc_upsert ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( ID ),
val INT NOT NULL, UNIQUE( val ),
test_autoinc_upsert INT DEFAULT 1,
action varchar( 10 ) DEFAULT 'insert',
comment varchar( 30 ) );
INSERT INTO test_autoinc_upsert ( val ) VALUES ( 1 ), ( 2 ) ON DUPLICATE KEY UPDATE action = 'update';
SELECT * FROM test_autoinc_upsert ORDER BY 2;
INSERT INTO test_autoinc_upsert (val )
VALUES ( 1 ), ( 2 ), ( 3 )
ON DUPLICATE KEY UPDATE action = 'update';
SELECT LAST_INSERT_ID(); -- 3
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 2 3
INSERT INTO test_autoinc_upsert (val ) VALUES ( 4 );
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 2 3 4
drop table test_autoinc_upsert;
-- upsert auto_increment 3
CREATE TEMPORARY TABLE test_autoinc_upsert ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( ID ),
val INT NOT NULL, UNIQUE( val ),
test_autoinc_upsert INT DEFAULT 1,
action varchar( 10 ) DEFAULT 'insert',
comment varchar( 30 ) );
INSERT INTO test_autoinc_upsert ( val ) VALUES ( 1 ), ( 2 ) ON DUPLICATE KEY UPDATE action = 'update';
SELECT * FROM test_autoinc_upsert ORDER BY 2;
INSERT INTO test_autoinc_upsert (val )
VALUES ( 2 ), ( 3 )
ON DUPLICATE KEY UPDATE id = '3';
SELECT LAST_INSERT_ID(); -- 4
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 3 4
INSERT INTO test_autoinc_upsert (val ) VALUES ( 4 );
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 3 4 5
drop table test_autoinc_upsert;
-- upsert auto_increment 2
CREATE TEMPORARY TABLE test_autoinc_upsert ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( ID ),
val INT NOT NULL, UNIQUE( val ),
test_autoinc_upsert INT DEFAULT 1,
action varchar( 10 ) DEFAULT 'insert',
comment varchar( 30 ) );
INSERT INTO test_autoinc_upsert ( val ) VALUES ( 1 ), ( 2 ) ON DUPLICATE KEY UPDATE action = 'update';
SELECT * FROM test_autoinc_upsert ORDER BY 2;
INSERT INTO test_autoinc_upsert (val )
VALUES ( 2 ), ( 3 )
ON DUPLICATE KEY UPDATE id = '2';
SELECT LAST_INSERT_ID(); -- 3
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 2 3
INSERT INTO test_autoinc_upsert (val ) VALUES ( 4 );
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 2 3 4
drop table test_autoinc_upsert;
-- upsert auto_increment 5
CREATE TEMPORARY TABLE test_autoinc_upsert ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( ID ),
val INT NOT NULL, UNIQUE( val ),
test_autoinc_upsert INT DEFAULT 1,
action varchar( 10 ) DEFAULT 'insert',
comment varchar( 30 ) );
INSERT INTO test_autoinc_upsert ( val ) VALUES ( 1 ), ( 2 ) ON DUPLICATE KEY UPDATE action = 'update';
SELECT * FROM test_autoinc_upsert ORDER BY 2;
INSERT INTO test_autoinc_upsert (val )
VALUES ( 2 ), ( 3 ), ( 4 )
ON DUPLICATE KEY UPDATE id = '5';
SELECT LAST_INSERT_ID(); -- 6
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 5 6 7
INSERT INTO test_autoinc_upsert (val ) VALUES ( 5 );
SELECT * FROM test_autoinc_upsert ORDER BY 2; -- 1 5 6 7 8
drop table test_autoinc_upsert;
\c regression
clean connection to all force for database autoinc_b_db;
drop database if exists autoinc_b_db;