# ==== 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