!4383 【MYSQL兼容性】修复自增列多条INSERT INTO ON DUPLICATE KEY UPDATE结果问题
Merge pull request !4383 from 李居东/fix_autoinc_upsert
This commit is contained in:
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
Reference in New Issue
Block a user