################################################################################
#
# INSERT
#
# INSERT and commit new rows, using the constants "40" for most values.
# For each new transaction, the constant is increased by 1.
#
# This test runs a number of consecutive transactions to generate high 
# concurrency:
#
# Tx 1:
#  - multi-statemement insert, inserting first positive then negative number (0-sum).
#
# Tx 2:
#  - insert multiple rows using a single statement.
#
# Tx 3:
#  - INSERT IGNORE using both known duplicate values and non-duplicates.
#
# Net effect: 6 more rows
#
# In this test we need some kind of valid unique integer value for the columns
# with unique indexes.
#
# Alternatively: 
#  - Set unique value as 0 and rollback if ERR_DUP_KEY (see 
#    check_error_rollback.inc), then make sure to UPDATE where unique value is 0
#    in other tests.
#  - OR: insert NULL (requires special handling when calculating row sums in 
#    other tests).
#  - OR: skip unique indexes entirely (except `pk`) (remove from t1 in init).
#
# Using CONNECTION_ID (swithcing sign and doing +/- 3) as unique value, meaning 
# that some of the INSERTs will fail with duplicate key until this is high 
# enough (should not take long with a relatively high number of threads and some
# duration, given that the number of initial rows is relatively low, ~1000). 
# Let's just say this is a warm-up period.
#
# Alternatively, add some random integer to the value or use UNIX_TIMESTAMP()
# (the latter requires that some care is taken in subsequent updates etc. For
# example, simply doubling the value will cause overflow/truncation).
# 
# No need to ROLLBACK if all statements in a transaction by themselves are
# consistent.
#
#
################################################################################
SET autocommit = 0;
START TRANSACTION;
--echo
--echo *** multi-statemement insert, inserting first positive then negative number:
--echo

--error 0, ER_LOCK_DEADLOCK, ER_LOCK_WAIT_TIMEOUT, ER_DUP_ENTRY
INSERT INTO t1 (`id`, `int1`, `int1_key`, `int1_unique`,
                `int2`, `int2_key`, `int2_unique`,
                `for_update`, `connection_id`, `thread_id`, `is_uncommitted`, `is_consistent`)
        VALUES (40, 40, 40, CONNECTION_ID(),
                -40, -40, -CONNECTION_ID(),
                0, CONNECTION_ID(), 0, 0, 1);


--error 0, ER_LOCK_DEADLOCK, ER_LOCK_WAIT_TIMEOUT, ER_DUP_ENTRY
INSERT INTO t1 (`id`, `int1`, `int1_key`, `int1_unique`,
                `int2`, `int2_key`, `int2_unique`,
                `for_update`, `connection_id`, `thread_id`, `is_uncommitted`, `is_consistent`)
        VALUES (-40, -40, -40, -CONNECTION_ID(),
                40, 40, CONNECTION_ID(),
                0, CONNECTION_ID(), 0, 0, 1);

COMMIT;

START TRANSACTION;
--echo
--echo *** insert multiple rows using a single statement:
--echo

# First row is by itself consistent (sum = 0). Row 3 zero-sums row 2, so the 
# statement itself is consistent.
--error 0, ER_LOCK_DEADLOCK, ER_LOCK_WAIT_TIMEOUT, ER_DUP_ENTRY
INSERT INTO t1 (`id`, `int1`, `int1_key`, `int1_unique`,
                `int2`, `int2_key`, `int2_unique`,
                `for_update`, `connection_id`, `thread_id`, `is_uncommitted`, `is_consistent`)
        VALUES (41, 41, 41, CONNECTION_ID()+1,
                -41, -41, -(CONNECTION_ID()+1),
                0, CONNECTION_ID(), 0, 0, 1),
               (41, 41, 41, CONNECTION_ID()+2,
                41, 41, CONNECTION_ID()+2,
                0, CONNECTION_ID(), 0, 0, 0),
               (41, -41, -41, -(CONNECTION_ID()+2),
                -41, -41, -(CONNECTION_ID()+2),
                0, CONNECTION_ID(), 0, 0, 0);

COMMIT;

START TRANSACTION;
--echo
--echo *** INSERT IGNORE using both known duplicate values and non-duplicates:
--echo

# This MAY be discarded (duplicate entry in UNIQUE index) - should succeed if CONNECTION_ID is high enough (int*_unique).
--error 0, ER_LOCK_DEADLOCK, ER_LOCK_WAIT_TIMEOUT, ER_DUP_ENTRY
INSERT IGNORE INTO t1 (`id`, `int1`, `int1_key`, `int1_unique`,
                       `int2`, `int2_key`, `int2_unique`,
                       `for_update`, `connection_id`, `thread_id`, `is_uncommitted`, `is_consistent`)
               VALUES (42, 42, 42, CONNECTION_ID()+3,
                       -42, -42, -(CONNECTION_ID()+3),
                       0, CONNECTION_ID(), 0, 0, 1);

--error 0, ER_LOCK_DEADLOCK, ER_LOCK_WAIT_TIMEOUT
# This WILL (SHOULD) be discarded (duplicate entry as primary key).
# pk's that are 1000 or less AND divisible by 5 should all be present (i.e. never deleted), so we pick pk 5.
# Note that we insert an inconsistent row, so it will show up as a sum anomaly if it succeeds.
INSERT IGNORE INTO t1 (`pk`, `id`, `int1`, `int1_key`, `int1_unique`,
                       `int2`, `int2_key`, `int2_unique`,
                       `for_update`, `connection_id`, `thread_id`, `is_uncommitted`, `is_consistent`)
               VALUES (5, 43, 42, 42, CONNECTION_ID(),
                       -42, -42, CONNECTION_ID(),
                       0, CONNECTION_ID(), 0, 0, 0);

--error 0, ER_LOCK_DEADLOCK, ER_LOCK_WAIT_TIMEOUT
# This MAY be discarded (duplicate entry in UNIQUE index).
INSERT IGNORE INTO t1 (`id`, `int1`, `int1_key`, `int1_unique`,
                       `int2`, `int2_key`, `int2_unique`,
                       `for_update`, `connection_id`, `thread_id`, `is_uncommitted`, `is_consistent`)
               VALUES (44, 42, 42, (CONNECTION_ID() + 1000) MOD 5000,
                       -42, -42, -((CONNECTION_ID() + 1000) MOD 5000),
                       0, CONNECTION_ID(), 0, 0, 1);

--source suite/engines/rr_trx/include/check_for_error_rollback.inc

COMMIT;

