337 lines
11 KiB
PHP
337 lines
11 KiB
PHP
# ==== Requirements ====
|
|
#
|
|
# See rpl_row_jsondiff_init.inc for an overview.
|
|
#
|
|
# This script sets up the following scenarios:
|
|
# - updates using all supported JSON functions: JSON_SET, JSON_INSERT,
|
|
# JSON_REMOVE
|
|
# - updates that generate different diff 'operations' (see
|
|
# enum_json_diff_operation in json_diff.h)
|
|
# - updates that are logged in full format
|
|
# - updates that generate multiple diffs
|
|
# - updates componsed of several function calls
|
|
# - updates from non-NULL to NULL or NULL to non-NULL
|
|
# - updates that result in a no-op
|
|
# - updates that result in auto-wrapping (see the manual for JSON_SET)
|
|
# - updates where multiple rows are updated and:
|
|
# - all are partial
|
|
# - full appears before partial
|
|
# - partial appears before full
|
|
# - all are full
|
|
#
|
|
# ==== Usage ====
|
|
#
|
|
# Before using this script, setup the servers using like in
|
|
# rpl_row_jsondiff_basic.test:
|
|
# - setup replication
|
|
# - setup connections
|
|
# - set BINLOG_ROW_IMAGE and BINLOG_ROW_VALUE_OPTIONS as in rpl_row_jsondiff
|
|
# Then use this script like:
|
|
#
|
|
# [--let $key= KEY DEFINITION]
|
|
# --source include/rpl_row_jsondiff_basic.inc
|
|
#
|
|
# Parameters:
|
|
#
|
|
# $key
|
|
# This can be set to a key definition. It will be inserted verbatim
|
|
# after the first INT column in the table definition.
|
|
#
|
|
# ==== See also ====
|
|
#
|
|
# rpl_row_jsondiff.test
|
|
|
|
|
|
--echo ******** Single JSON column ********
|
|
|
|
--echo ==== Full format ====
|
|
|
|
--let $stmt_pre= UPDATE t SET j =
|
|
--let $stmt_post= WHERE i = 1
|
|
|
|
--let $column_def= i INT $key, j JSON, k JSON
|
|
--let $rows= (1, '[1, 2]', '[3, 4]')
|
|
--let $echo_select= i, j, k
|
|
--let $compare_size_columns= j, k
|
|
|
|
--let $desc= Update one row using full format (wrong column used)
|
|
--let $stmt= JSON_SET(k, '$dollar[0]', 'a')
|
|
--source $scenario_inc
|
|
|
|
--let $column_def= i INT $key, j JSON
|
|
--let $rows= (1, '[1, 2]')
|
|
--let $echo_select= i, j
|
|
--let $compare_size_columns= j
|
|
|
|
--let $desc= Update one row using full format (no JSON function used)
|
|
--let $stmt= CAST(7 AS JSON)
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Update one row using full format (wrong JSON function used (1))
|
|
--let $stmt= JSON_MERGE(j, '[8]')
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Update one row using full format (wrong JSON function used (2))
|
|
--let $stmt= JSON_MERGE(JSON_REPLACE(j, '$dollar[0]', 3), '[8]')
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Update one row using full format (wrong JSON function used (3))
|
|
--let $stmt= JSON_REPLACE(JSON_MERGE(j, '[8]'), '$dollar[0]', 3)
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Update one row using full format (full smaller than partial)
|
|
--let $stmt= JSON_SET(j, '$dollar[0]', 'abcdefghijklmnopqrstuvwxyz', '$dollar[0]', 3)
|
|
--source $scenario_inc
|
|
|
|
--echo ==== Single diffs ====
|
|
|
|
--let $rows= (1, '[1, {"a": 2}]')
|
|
|
|
--let $desc= Update one row (REPLACE using JSON_REPLACE in array)
|
|
--let $stmt= JSON_REPLACE(j, '$dollar[0]', 7)
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Update one row (REPLACE using JSON_SET in array)
|
|
--let $stmt= JSON_SET(j, '$dollar[0]', "7")
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Update one row (REPLACE using JSON_REPLACE in object)
|
|
--let $stmt= JSON_REPLACE(j, '$dollar[1].a', CAST('[7]' AS JSON))
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Update one row (REPLACE using JSON_SET in object)
|
|
--let $stmt= JSON_SET(j, '$dollar[1].a', CAST('{"a":7}' AS JSON))
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Update one row (INSERT using JSON_SET in array)
|
|
--let $stmt= JSON_SET(j, '$dollar[2]', 3)
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Update one row (INSERT using JSON_SET in object)
|
|
# decoder will output the number as int even if it is decimal, and this
|
|
# results in different sizes. so we skip the size comparison
|
|
--let $compare_size_columns=
|
|
--let $stmt= JSON_SET(j, '$dollar[1].b', CAST(4 AS DECIMAL))
|
|
--source $scenario_inc
|
|
--let $compare_size_columns= j
|
|
|
|
--let $desc= Update one row (REMOVE using JSON_REMOVE in array)
|
|
--let $stmt= JSON_REMOVE(j, '$dollar[1]')
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Update one row (REMOVE using JSON_REMOVE in object)
|
|
--let $stmt= JSON_REMOVE(j, '$dollar[1].a')
|
|
--source $scenario_inc
|
|
|
|
--echo ==== Multiple diffs from one function call ====
|
|
|
|
--let $rows= (1, '[1, 2, {"a long string that ensures that the diff format is smaller than the full format": "", "a": 3, "b": 4}]')
|
|
|
|
--let $desc= Update one row (many different update types, using JSON_SET)
|
|
--let $stmt= JSON_SET(j, '$dollar[0]', 'one', '$dollar[1]', 'two', '$dollar[2].a', 'three', '$dollar[2].b', 'four', '$dollar[2].c', 'five', '$dollar[2].d', 'six', '$dollar[3]', 'seven', '$dollar[4]', 'eight')
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Update one row (many different update types, using JSON_REPLACE)
|
|
--let $stmt= JSON_REPLACE(j, '$dollar[0]', 'one', '$dollar[1]', 'two', '$dollar[3].a', 'three', '$dollar[3].b', 'four', '$dollar[0]', 'ONE', '$dollar[1]', 'TWO', '$dollar[3].a', 'THREE', '$dollar[3].b', 'FOUR')
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Update one row (using JSON_REMOVE)
|
|
--let $stmt= JSON_REMOVE(j, '$dollar[1]', '$dollar[2].b', '$dollar[2].a', '$dollar[0]')
|
|
--source $scenario_inc
|
|
|
|
--echo ==== Multiple diffs from multiple function calls ====
|
|
|
|
--let $rows= (1, '[1, 2, 3, "a long string that ensures that the diff format is smaller than the full format"]')
|
|
|
|
--let $desc= Update one row (using JSON_SET, JSON_REPLACE, and JSON_REMOVE)
|
|
--let $stmt= JSON_REMOVE(JSON_SET(JSON_REPLACE(JSON_SET(j, '$dollar[0]', 'one'), '$dollar[1]', 'two', '$dollar[2]', CAST('{"a": 1}' AS JSON)), '$dollar[2].b', 2, '$dollar[2].c', 3), '$dollar[0]', '$dollar[0]')
|
|
--source $scenario_inc
|
|
|
|
--echo ==== NULL values ====
|
|
|
|
--let $rows= (1, '[1, 2, 3, 4]')
|
|
|
|
--let $desc= Updating from non-NULL to NULL using JSON_SET
|
|
--let $stmt= JSON_SET(j, NULL, 'a')
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Updating from non-NULL to NULL using JSON_REPLACE
|
|
--let $stmt= JSON_REPLACE(j, NULL, 'a')
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Updating from non-NULL to NULL using JSON_REMOVE
|
|
--let $stmt= JSON_REMOVE(j, NULL)
|
|
--source $scenario_inc
|
|
|
|
--let $rows= (1, NULL)
|
|
|
|
--let $desc= Updating from NULL to non-NULL using JSON_SET
|
|
--let $stmt= JSON_SET('{"a": "a"}', '$dollar.b', j)
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Updating from NULL to non-NULL using JSON_REPLACE
|
|
--let $stmt= JSON_REPLACE('{"a": "a"}', '$dollar.a', j)
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Updating from NULL to non-NULL using JSON_REMOVE
|
|
--let $stmt= JSON_REPLACE('{"a": "a", "b": "b"}', '$dollar.b', 'BB')
|
|
--source $scenario_inc
|
|
|
|
--echo ==== No-op updates ====
|
|
|
|
--let $column_def= i INT $key, j JSON, x INT
|
|
--let $echo_select= i, j, x
|
|
--let $compare_size_columns= j
|
|
--let $rows= (1, '["a", {"b": "c"}]', 1)
|
|
|
|
# Change value of 'x' so that the row is not omitted
|
|
--let $stmt_pre= UPDATE t SET x = 2
|
|
|
|
--let $desc= Making a no-op not mentioning the column
|
|
--let $stmt=
|
|
--source $scenario_inc
|
|
|
|
# In the following tests set j to itself (expressed in different ways)
|
|
--let $stmt_pre= UPDATE t SET x = 2, j =
|
|
|
|
--let $desc= Making a no-op setting the column to itself
|
|
--let $stmt= j
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Making a no-op setting the column to its own value (1)
|
|
--let $stmt= CONCAT(j, '')
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Making a no-op setting the column to its own value (2)
|
|
--let $stmt= '["a", {"b": "c"}]'
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Making a no-op using JSON_SET inserting object in non-object or array element in non-array
|
|
--let $stmt= JSON_SET(j, '$dollar.a', 0, '$dollar[1][2]', 1, '$dollar[1].b.x', 2)
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Making a no-op using JSON_REPLACE with non-existing paths
|
|
--let $stmt= JSON_REPLACE(j, '$dollar[9]', 0, '$dollar.x', 1, '$dollar[1].x', 2)
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Making a no-op removing a non-existing path, using JSON_REMOVE
|
|
--let $stmt= JSON_REMOVE(j, '$dollar[9]', '$dollar[1].x', '$dollar.foo', '$dollar[1][0]')
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Making a no-op replacing a JSON value by itself, using JSON_SET
|
|
--let $stmt= JSON_SET(j, '$dollar[0]', 'a', '$dollar[1].b', 'c', '$dollar[0]', 'a')
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Making a no-op replacing a JSON value by itself, using JSON_REPLACE
|
|
--let $stmt= JSON_REPLACE(j, '$dollar[0]', 'a', '$dollar[1].b', 'c', '$dollar[0]', 'a')
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Making a no-op update using JSON_SET, JSON_REPLACE, and JSON_REMOVE
|
|
let $stmt=
|
|
JSON_SET(JSON_REMOVE(JSON_REPLACE(j,
|
|
'$dollar[0]', 'a', '$dollar[1].b', 'c', '$dollar[0]', 'a'),
|
|
'$dollar[9]', '$dollar[1].x', '$dollar.foo'),
|
|
'$dollar[0]', 'a', '$dollar[1].b', 'c', '$dollar[0]', 'a');
|
|
--source $scenario_inc
|
|
|
|
--echo ==== Long paths ====
|
|
|
|
--let $column_def= i INT $key, j JSON
|
|
--let $echo_select= i, j
|
|
--let $compare_size_columns= j
|
|
--let $stmt_pre= UPDATE t SET j =
|
|
|
|
--let $short_text= short text
|
|
--let $long_text= `SELECT REPEAT('a', 260)`
|
|
--let $very_long_text= `SELECT REPEAT('a', 66000)`
|
|
|
|
--let $desc= Update using long path
|
|
--let $rows= (1, '{"abc" : "def"}')
|
|
--let $stmt= JSON_SET(j, '$dollar.$long_text', 'ghi')
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Update using long document
|
|
--let $rows= (1, '{"abc" : "def"}')
|
|
--let $stmt= JSON_SET(j, '$dollar.ghi', '$long_text')
|
|
--source $scenario_inc
|
|
|
|
--let $echo_stmt= 0
|
|
--let $echo_decoded_rows= 0
|
|
--let $echo_select=
|
|
|
|
--let $desc= Update using very long document
|
|
--let $rows= (1, '{"abc" : "def"}')
|
|
--let $stmt= JSON_SET(j, '$dollar.ghi', '$very_long_text')
|
|
--source $scenario_inc
|
|
|
|
--let $echo_stmt= 1
|
|
--let $echo_decoded_rows= 1
|
|
|
|
--echo ==== Auto-wrapping ====
|
|
|
|
--let $column_def= i INT $key, j JSON
|
|
--let $echo_select= i, j
|
|
--let $compare_size_columns= j
|
|
--let $rows= (1, '{"a" : 1}')
|
|
--let $stmt_pre= UPDATE t SET j =
|
|
|
|
--let $desc= Auto-wrap using JSON_SET
|
|
--let $stmt= JSON_SET(j, '$dollar[1]', 4711)
|
|
--source $scenario_inc
|
|
|
|
--echo ==== Multi-row updates ====
|
|
|
|
let $rows=
|
|
(1, '[1, 2, 3]'),
|
|
(2, '[4, 5, 6, "a long string that ensures that the diff format is smaller than the full format"]'),
|
|
(3, '[7, 8, 9]'),
|
|
(4, '[10, 11, 12, "a long string that ensures that the diff format is smaller than the full format"]');
|
|
|
|
--let $stmt_pre= UPDATE t SET j = JSON_SET(j, '$dollar[0]', 'abcdefghijklmnopqrstuvxyz', '$dollar[0]', 0) WHERE
|
|
--let $stmt_post=
|
|
|
|
--let $desc= Update two rows: both partial
|
|
--let $stmt= i = 2 OR i = 4
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Update two rows: first partial, then full
|
|
--let $stmt= i = 2 OR i = 3
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Update two rows: first full, then partial
|
|
--let $stmt= i = 1 OR i = 2
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Update two rows: both full
|
|
--let $stmt= i = 1 OR i = 3
|
|
--source $scenario_inc
|
|
|
|
--let $desc= Update four rows: full, partial, full, partial
|
|
--let $stmt= i IN (1, 2, 3, 4)
|
|
--source $scenario_inc
|
|
|
|
--echo ==== Invalid paths ====
|
|
|
|
--echo TODO
|
|
|
|
--echo ******** Multiple JSON columns ********
|
|
|
|
--let $column_def= i INT $key, j JSON, k JSON, l JSON, m JSON
|
|
let $rows=
|
|
(1,
|
|
'[1, 2, 3, 4]',
|
|
'[5, 6, 7, 8]',
|
|
'{"a": 1, "b": 2, "c": 3, "d": 4}',
|
|
'{"e": 5, "f": 6, "g": 7, "e": 8}');
|
|
--let $echo_select= i, j, k, l, m
|
|
--let $compare_size_columns= j, k, l, m
|
|
--let $stmt_pre= UPDATE t SET
|
|
|
|
--let $desc= Update after null and after non-modified column
|
|
--let $stmt= j = NULL, l = JSON_SET(l, '$dollar.d', "DDD")
|
|
--source $scenario_inc
|
|
|
|
--echo ******** Differences between master and slave ********
|
|
|
|
--echo TODO: applies ok, does not apply, and mix
|