diff options
author | Sergei Golubchik <serg@mariadb.org> | 2021-02-22 18:43:03 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2021-02-22 18:43:03 +0100 |
commit | a638f1577a356350c8e7cb6021a0b3d2a087755d (patch) | |
tree | 9079f0ff8e913391cde16cf3d190719bc3903127 | |
parent | 6aa909745dac87585ad3d2ebf73b8a274759102d (diff) | |
parent | ce3a2a688db556d8d077a409fd9bf5cc013d13dd (diff) | |
download | mariadb-git-a638f1577a356350c8e7cb6021a0b3d2a087755d.tar.gz |
Merge branch 'bb-10.2-release' into 10.2
33 files changed, 533 insertions, 625 deletions
diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 054bb7b7693..40445c5b62b 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -30,4 +30,5 @@ partition : MDEV-19958 Galera test failure on galera.partition query_cache: MDEV-15805 Test failure on galera.query_cache sql_log_bin : MDEV-21491 galera.sql_log_bin versioning_trx_id: MDEV-18590: galera.versioning_trx_id: Test failure: mysqltest: Result content mismatch - +galera_wsrep_provider_unset_set: wsrep_provider is read-only for security reasons +pxc-421: wsrep_provider is read-only for security reasons diff --git a/mysql-test/suite/galera/include/galera_load_provider.inc b/mysql-test/suite/galera/include/galera_load_provider.inc index aeab7e6ea19..e6ce6411193 100644 --- a/mysql-test/suite/galera/include/galera_load_provider.inc +++ b/mysql-test/suite/galera/include/galera_load_provider.inc @@ -1,7 +1,6 @@ --echo Loading wsrep provider ... --disable_query_log ---eval SET GLOBAL wsrep_provider = '$wsrep_provider_orig'; --eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_orig'; --enable_query_log diff --git a/mysql-test/suite/galera/include/galera_unload_provider.inc b/mysql-test/suite/galera/include/galera_unload_provider.inc index edc7eb31e0e..83438a947f0 100644 --- a/mysql-test/suite/galera/include/galera_unload_provider.inc +++ b/mysql-test/suite/galera/include/galera_unload_provider.inc @@ -1,7 +1,6 @@ --echo Unloading wsrep provider ... --let $wsrep_cluster_address_orig = `SELECT @@wsrep_cluster_address` ---let $wsrep_provider_orig = `SELECT @@wsrep_provider` --let $wsrep_provider_options_orig = `SELECT @@wsrep_provider_options` -SET GLOBAL wsrep_provider = 'none'; +SET GLOBAL wsrep_cluster_address = ''; diff --git a/mysql-test/suite/galera/r/galera_ist_mariabackup.result b/mysql-test/suite/galera/r/galera_ist_mariabackup.result index 8a7c02ab1b6..80a28d349ba 100644 --- a/mysql-test/suite/galera/r/galera_ist_mariabackup.result +++ b/mysql-test/suite/galera/r/galera_ist_mariabackup.result @@ -21,7 +21,7 @@ INSERT INTO t1 VALUES ('node2_committed_before'); INSERT INTO t1 VALUES ('node2_committed_before'); COMMIT; Unloading wsrep provider ... -SET GLOBAL wsrep_provider = 'none'; +SET GLOBAL wsrep_cluster_address = ''; connection node_1; SET AUTOCOMMIT=OFF; START TRANSACTION; diff --git a/mysql-test/suite/galera/r/galera_ist_rsync.result b/mysql-test/suite/galera/r/galera_ist_rsync.result index 8a7c02ab1b6..80a28d349ba 100644 --- a/mysql-test/suite/galera/r/galera_ist_rsync.result +++ b/mysql-test/suite/galera/r/galera_ist_rsync.result @@ -21,7 +21,7 @@ INSERT INTO t1 VALUES ('node2_committed_before'); INSERT INTO t1 VALUES ('node2_committed_before'); COMMIT; Unloading wsrep provider ... -SET GLOBAL wsrep_provider = 'none'; +SET GLOBAL wsrep_cluster_address = ''; connection node_1; SET AUTOCOMMIT=OFF; START TRANSACTION; diff --git a/mysql-test/suite/galera/r/galera_sst_mysqldump.result b/mysql-test/suite/galera/r/galera_sst_mysqldump.result index 5c530c32ce6..6bdc933a9fc 100644 --- a/mysql-test/suite/galera/r/galera_sst_mysqldump.result +++ b/mysql-test/suite/galera/r/galera_sst_mysqldump.result @@ -30,7 +30,7 @@ INSERT INTO t1 VALUES ('node2_committed_before'); INSERT INTO t1 VALUES ('node2_committed_before'); COMMIT; Unloading wsrep provider ... -SET GLOBAL wsrep_provider = 'none'; +SET GLOBAL wsrep_cluster_address = ''; connection node_1; SET AUTOCOMMIT=OFF; START TRANSACTION; diff --git a/mysql-test/suite/galera/r/mysql-wsrep#33.result b/mysql-test/suite/galera/r/mysql-wsrep#33.result index 6a5251204b9..4cc49c0cf07 100644 --- a/mysql-test/suite/galera/r/mysql-wsrep#33.result +++ b/mysql-test/suite/galera/r/mysql-wsrep#33.result @@ -30,7 +30,7 @@ INSERT INTO t1 VALUES ('node2_committed_before'); INSERT INTO t1 VALUES ('node2_committed_before'); COMMIT; Unloading wsrep provider ... -SET GLOBAL wsrep_provider = 'none'; +SET GLOBAL wsrep_cluster_address = ''; connection node_1; SET AUTOCOMMIT=OFF; START TRANSACTION; diff --git a/mysql-test/suite/sys_vars/r/sysvars_wsrep.result b/mysql-test/suite/sys_vars/r/sysvars_wsrep.result index e54afd2d64a..67e15405313 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_wsrep.result +++ b/mysql-test/suite/sys_vars/r/sysvars_wsrep.result @@ -349,7 +349,7 @@ NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL ENUM_VALUE_LIST NULL -READ_ONLY NO +READ_ONLY YES COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME WSREP_ON SESSION_VALUE OFF @@ -405,7 +405,7 @@ NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL ENUM_VALUE_LIST NULL -READ_ONLY NO +READ_ONLY YES COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME WSREP_PROVIDER_OPTIONS SESSION_VALUE NULL diff --git a/mysql-test/suite/sys_vars/r/wsrep_notify_cmd_basic.result b/mysql-test/suite/sys_vars/r/wsrep_notify_cmd_basic.result deleted file mode 100644 index 056ff8c817b..00000000000 --- a/mysql-test/suite/sys_vars/r/wsrep_notify_cmd_basic.result +++ /dev/null @@ -1,47 +0,0 @@ -# -# wsrep_notify_cmd -# -call mtr.add_suppression("WSREP: Failed to get provider options"); -# save the initial value -SET @wsrep_notify_cmd_global_saved = @@global.wsrep_notify_cmd; -# default -SELECT @@global.wsrep_notify_cmd; -@@global.wsrep_notify_cmd - - -# scope -SELECT @@session.wsrep_notify_cmd; -ERROR HY000: Variable 'wsrep_notify_cmd' is a GLOBAL variable -SET @@global.wsrep_notify_cmd='notify_cmd'; -SELECT @@global.wsrep_notify_cmd; -@@global.wsrep_notify_cmd -notify_cmd - -# valid values -SET @@global.wsrep_notify_cmd='command'; -SELECT @@global.wsrep_notify_cmd; -@@global.wsrep_notify_cmd -command -SET @@global.wsrep_notify_cmd='hyphenated-command'; -SELECT @@global.wsrep_notify_cmd; -@@global.wsrep_notify_cmd -hyphenated-command -SET @@global.wsrep_notify_cmd=default; -SELECT @@global.wsrep_notify_cmd; -@@global.wsrep_notify_cmd - -SET @@global.wsrep_notify_cmd=NULL; -SELECT @@global.wsrep_notify_cmd; -@@global.wsrep_notify_cmd -NULL - -# invalid values -SET @@global.wsrep_notify_cmd=1; -ERROR 42000: Incorrect argument type to variable 'wsrep_notify_cmd' -SELECT @@global.wsrep_notify_cmd; -@@global.wsrep_notify_cmd -NULL - -# restore the initial value -SET @@global.wsrep_notify_cmd = @wsrep_notify_cmd_global_saved; -# End of test diff --git a/mysql-test/suite/sys_vars/r/wsrep_provider_basic.result b/mysql-test/suite/sys_vars/r/wsrep_provider_basic.result deleted file mode 100644 index 3e4ac8ca883..00000000000 --- a/mysql-test/suite/sys_vars/r/wsrep_provider_basic.result +++ /dev/null @@ -1,40 +0,0 @@ -# -# wsrep_provider -# -# save the initial value -SET @wsrep_provider_global_saved = @@global.wsrep_provider; -# default -SELECT @@global.wsrep_provider; -@@global.wsrep_provider -none - -# scope -SELECT @@session.wsrep_provider; -ERROR HY000: Variable 'wsrep_provider' is a GLOBAL variable -SELECT @@global.wsrep_provider; -@@global.wsrep_provider -none - -# valid values -SET @@global.wsrep_provider=default; -SELECT @@global.wsrep_provider; -@@global.wsrep_provider -none - -# invalid values -SET @@global.wsrep_provider='/invalid/libgalera_smm.so'; -ERROR 42000: Variable 'wsrep_provider' can't be set to the value of '/invalid/libgalera_smm.so' -SET @@global.wsrep_provider=NULL; -ERROR 42000: Variable 'wsrep_provider' can't be set to the value of 'NULL' -SELECT @@global.wsrep_provider; -@@global.wsrep_provider -none -SET @@global.wsrep_provider=1; -ERROR 42000: Incorrect argument type to variable 'wsrep_provider' -SELECT @@global.wsrep_provider; -@@global.wsrep_provider -none - -# restore the initial value -SET @@global.wsrep_provider = @wsrep_provider_global_saved; -# End of test diff --git a/mysql-test/suite/sys_vars/r/wsrep_provider_options_basic.result b/mysql-test/suite/sys_vars/r/wsrep_provider_options_basic.result deleted file mode 100644 index b2e07c55b38..00000000000 --- a/mysql-test/suite/sys_vars/r/wsrep_provider_options_basic.result +++ /dev/null @@ -1,49 +0,0 @@ -# -# wsrep_provider_options -# -call mtr.add_suppression("WSREP: Failed to get provider options"); -SET @@global.wsrep_provider = @@global.wsrep_provider; -# save the initial value -SET @wsrep_provider_options_global_saved = @@global.wsrep_provider_options; -# default -SELECT @@global.wsrep_provider_options; -@@global.wsrep_provider_options - - -# scope -SELECT @@session.wsrep_provider_options; -ERROR HY000: Variable 'wsrep_provider_options' is a GLOBAL variable -SET @@global.wsrep_provider_options='option1'; -SELECT @@global.wsrep_provider_options; -@@global.wsrep_provider_options -option1 - -# valid values -SET @@global.wsrep_provider_options='name1=value1;name2=value2'; -SELECT @@global.wsrep_provider_options; -@@global.wsrep_provider_options -name1=value1;name2=value2 -SET @@global.wsrep_provider_options='hyphenated-name:value'; -SELECT @@global.wsrep_provider_options; -@@global.wsrep_provider_options -hyphenated-name:value -SET @@global.wsrep_provider_options=default; -SELECT @@global.wsrep_provider_options; -@@global.wsrep_provider_options - - -# invalid values -SET @@global.wsrep_provider_options=1; -ERROR 42000: Incorrect argument type to variable 'wsrep_provider_options' -SELECT @@global.wsrep_provider_options; -@@global.wsrep_provider_options - -SET @@global.wsrep_provider_options=NULL; -Got one of the listed errors -SELECT @@global.wsrep_provider_options; -@@global.wsrep_provider_options -NULL - -# restore the initial value -SET @@global.wsrep_provider_options = @wsrep_provider_options_global_saved; -# End of test diff --git a/mysql-test/suite/sys_vars/t/wsrep_notify_cmd_basic.test b/mysql-test/suite/sys_vars/t/wsrep_notify_cmd_basic.test deleted file mode 100644 index 6d1535ba148..00000000000 --- a/mysql-test/suite/sys_vars/t/wsrep_notify_cmd_basic.test +++ /dev/null @@ -1,43 +0,0 @@ ---source include/have_wsrep.inc - ---echo # ---echo # wsrep_notify_cmd ---echo # - -call mtr.add_suppression("WSREP: Failed to get provider options"); - ---echo # save the initial value -SET @wsrep_notify_cmd_global_saved = @@global.wsrep_notify_cmd; - ---echo # default -SELECT @@global.wsrep_notify_cmd; - ---echo ---echo # scope ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -SELECT @@session.wsrep_notify_cmd; -SET @@global.wsrep_notify_cmd='notify_cmd'; -SELECT @@global.wsrep_notify_cmd; - ---echo ---echo # valid values -SET @@global.wsrep_notify_cmd='command'; -SELECT @@global.wsrep_notify_cmd; -SET @@global.wsrep_notify_cmd='hyphenated-command'; -SELECT @@global.wsrep_notify_cmd; -SET @@global.wsrep_notify_cmd=default; -SELECT @@global.wsrep_notify_cmd; -SET @@global.wsrep_notify_cmd=NULL; -SELECT @@global.wsrep_notify_cmd; - ---echo ---echo # invalid values ---error ER_WRONG_TYPE_FOR_VAR -SET @@global.wsrep_notify_cmd=1; -SELECT @@global.wsrep_notify_cmd; - ---echo ---echo # restore the initial value -SET @@global.wsrep_notify_cmd = @wsrep_notify_cmd_global_saved; - ---echo # End of test diff --git a/mysql-test/suite/sys_vars/t/wsrep_provider_basic.test b/mysql-test/suite/sys_vars/t/wsrep_provider_basic.test deleted file mode 100644 index 1190ab41bb0..00000000000 --- a/mysql-test/suite/sys_vars/t/wsrep_provider_basic.test +++ /dev/null @@ -1,39 +0,0 @@ ---source include/have_wsrep.inc - ---echo # ---echo # wsrep_provider ---echo # - ---echo # save the initial value -SET @wsrep_provider_global_saved = @@global.wsrep_provider; - ---echo # default -SELECT @@global.wsrep_provider; - ---echo ---echo # scope ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -SELECT @@session.wsrep_provider; -SELECT @@global.wsrep_provider; - ---echo ---echo # valid values -SET @@global.wsrep_provider=default; -SELECT @@global.wsrep_provider; - ---echo ---echo # invalid values ---error ER_WRONG_VALUE_FOR_VAR -SET @@global.wsrep_provider='/invalid/libgalera_smm.so'; ---error ER_WRONG_VALUE_FOR_VAR -SET @@global.wsrep_provider=NULL; -SELECT @@global.wsrep_provider; ---error ER_WRONG_TYPE_FOR_VAR -SET @@global.wsrep_provider=1; -SELECT @@global.wsrep_provider; - ---echo ---echo # restore the initial value -SET @@global.wsrep_provider = @wsrep_provider_global_saved; - ---echo # End of test diff --git a/mysql-test/suite/sys_vars/t/wsrep_provider_options_basic.test b/mysql-test/suite/sys_vars/t/wsrep_provider_options_basic.test deleted file mode 100644 index d2ea32a0637..00000000000 --- a/mysql-test/suite/sys_vars/t/wsrep_provider_options_basic.test +++ /dev/null @@ -1,51 +0,0 @@ ---source include/have_wsrep.inc - ---echo # ---echo # wsrep_provider_options ---echo # - -call mtr.add_suppression("WSREP: Failed to get provider options"); - -SET @@global.wsrep_provider = @@global.wsrep_provider; - ---echo # save the initial value -SET @wsrep_provider_options_global_saved = @@global.wsrep_provider_options; - ---echo # default -SELECT @@global.wsrep_provider_options; - ---echo ---echo # scope ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -SELECT @@session.wsrep_provider_options; ---error 0,ER_WRONG_ARGUMENTS -SET @@global.wsrep_provider_options='option1'; -SELECT @@global.wsrep_provider_options; - ---echo ---echo # valid values ---error 0,ER_WRONG_ARGUMENTS -SET @@global.wsrep_provider_options='name1=value1;name2=value2'; -SELECT @@global.wsrep_provider_options; ---error 0,ER_WRONG_ARGUMENTS -SET @@global.wsrep_provider_options='hyphenated-name:value'; -SELECT @@global.wsrep_provider_options; ---error 0,ER_WRONG_ARGUMENTS -SET @@global.wsrep_provider_options=default; -SELECT @@global.wsrep_provider_options; - ---echo ---echo # invalid values ---error ER_WRONG_TYPE_FOR_VAR -SET @@global.wsrep_provider_options=1; -SELECT @@global.wsrep_provider_options; ---error ER_WRONG_ARGUMENTS,ER_WRONG_ARGUMENTS -SET @@global.wsrep_provider_options=NULL; -SELECT @@global.wsrep_provider_options; - ---echo ---echo # restore the initial value ---error 0,ER_WRONG_ARGUMENTS -SET @@global.wsrep_provider_options = @wsrep_provider_options_global_saved; - ---echo # End of test diff --git a/mysql-test/suite/wsrep/disabled.def b/mysql-test/suite/wsrep/disabled.def index 11577bfe8b0..3d204db6945 100644 --- a/mysql-test/suite/wsrep/disabled.def +++ b/mysql-test/suite/wsrep/disabled.def @@ -10,3 +10,5 @@ # ############################################################################## + +mdev_6832: wsrep_provider is read-only for security reasons diff --git a/mysql-test/suite/wsrep/r/variables.result b/mysql-test/suite/wsrep/r/variables.result index 01f5355cbad..df7ca3787aa 100644 --- a/mysql-test/suite/wsrep/r/variables.result +++ b/mysql-test/suite/wsrep/r/variables.result @@ -14,7 +14,6 @@ SET SESSION wsrep_replicate_myisam= ON; ERROR HY000: Variable 'wsrep_replicate_myisam' is a GLOBAL variable and should be set with SET GLOBAL SET GLOBAL wsrep_replicate_myisam= ON; SET GLOBAL wsrep_replicate_myisam= OFF; -SET GLOBAL wsrep_provider=none; # # MDEV#5790: SHOW GLOBAL STATUS LIKE does not show the correct list of # variables when using "_" @@ -26,7 +25,6 @@ wsrep_local_state_comment # # Should show nothing. SHOW STATUS LIKE 'x'; Variable_name Value -SET GLOBAL wsrep_provider=none; SHOW STATUS LIKE 'wsrep_local_state_uuid'; Variable_name Value @@ -35,7 +33,6 @@ wsrep_local_state_uuid # SHOW STATUS LIKE 'wsrep_last_committed'; Variable_name Value wsrep_last_committed # -SET GLOBAL wsrep_provider=none; # # MDEV#6206: wsrep_slave_threads subtracts from max_connections @@ -49,7 +46,7 @@ SELECT @@global.wsrep_slave_threads; 1 SELECT @@global.wsrep_cluster_address; @@global.wsrep_cluster_address - +gcomm:// SELECT @@global.wsrep_on; @@global.wsrep_on 1 @@ -58,14 +55,14 @@ Variable_name Value Threads_connected 1 SHOW STATUS LIKE 'wsrep_thread_count'; Variable_name Value -wsrep_thread_count 0 +wsrep_thread_count 2 SELECT @@global.wsrep_provider; @@global.wsrep_provider libgalera_smm.so SELECT @@global.wsrep_cluster_address; @@global.wsrep_cluster_address - +gcomm:// SELECT @@global.wsrep_on; @@global.wsrep_on 1 @@ -74,11 +71,10 @@ Variable_name Value Threads_connected 1 SHOW STATUS LIKE 'wsrep_thread_count'; Variable_name Value -wsrep_thread_count 0 +wsrep_thread_count 2 # Setting wsrep_cluster_address triggers the creation of # applier/rollbacker threads. -SET GLOBAL wsrep_cluster_address= 'gcomm://'; # Wait for applier thread to get created 1. # Wait for applier thread to get created 2. SELECT VARIABLE_VALUE AS EXPECT_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count'; @@ -138,4 +134,5 @@ SET @wsrep_sst_auth_saved= @@global.wsrep_sst_auth; SET @@global.wsrep_sst_auth= 'user:pass'; SET @@global.wsrep_sst_auth= ''; SET @@global.wsrep_sst_auth= NULL; +SET @@global.wsrep_sst_auth= @wsrep_sst_auth_saved; # End of test. diff --git a/mysql-test/suite/wsrep/t/variables.test b/mysql-test/suite/wsrep/t/variables.test index f815c0edf0f..0cf13650ce0 100644 --- a/mysql-test/suite/wsrep/t/variables.test +++ b/mysql-test/suite/wsrep/t/variables.test @@ -22,7 +22,7 @@ SET GLOBAL wsrep_replicate_myisam= ON; # Reset it back. SET GLOBAL wsrep_replicate_myisam= OFF; -SET GLOBAL wsrep_provider=none; +#SET GLOBAL wsrep_provider=none; --echo # --echo # MDEV#5790: SHOW GLOBAL STATUS LIKE does not show the correct list of @@ -31,13 +31,9 @@ SET GLOBAL wsrep_provider=none; CALL mtr.add_suppression("WSREP: Could not open saved state file for reading.*"); ---disable_result_log ---disable_query_log -eval SET GLOBAL wsrep_provider= '$WSREP_PROVIDER'; +#evalp SET GLOBAL wsrep_provider= '$WSREP_PROVIDER'; --let $galera_version=25.3.24 source include/check_galera_version.inc; ---enable_result_log ---enable_query_log --replace_column 2 # SHOW GLOBAL STATUS LIKE 'wsrep_local_state_comment'; @@ -46,11 +42,9 @@ SHOW GLOBAL STATUS LIKE 'wsrep_local_state_comment'; SHOW STATUS LIKE 'x'; # Reset it back. -SET GLOBAL wsrep_provider=none; +#SET GLOBAL wsrep_provider=none; ---disable_query_log -eval SET GLOBAL wsrep_provider= '$WSREP_PROVIDER'; ---enable_query_log +#evalp SET GLOBAL wsrep_provider= '$WSREP_PROVIDER'; # The following 2 variables are used by mariabackup # SST. @@ -62,7 +56,7 @@ SHOW STATUS LIKE 'wsrep_local_state_uuid'; SHOW STATUS LIKE 'wsrep_last_committed'; # Reset it back. -SET GLOBAL wsrep_provider=none; +#SET GLOBAL wsrep_provider=none; --echo --echo # @@ -70,9 +64,7 @@ SET GLOBAL wsrep_provider=none; --echo # call mtr.add_suppression("WSREP: Failed to get provider options"); ---disable_query_log -eval SET GLOBAL wsrep_provider= '$WSREP_PROVIDER'; ---enable_query_log +#evalp SET GLOBAL wsrep_provider= '$WSREP_PROVIDER'; --replace_regex /.*libgalera_smm.*/libgalera_smm.so/ SELECT @@global.wsrep_provider; @@ -83,9 +75,7 @@ SHOW STATUS LIKE 'threads_connected'; SHOW STATUS LIKE 'wsrep_thread_count'; --echo ---disable_query_log -eval SET GLOBAL wsrep_provider= '$WSREP_PROVIDER'; ---enable_query_log +#evalp SET GLOBAL wsrep_provider= '$WSREP_PROVIDER'; --replace_regex /.*libgalera_smm.*/libgalera_smm.so/ SELECT @@global.wsrep_provider; @@ -97,7 +87,7 @@ SHOW STATUS LIKE 'wsrep_thread_count'; --echo # Setting wsrep_cluster_address triggers the creation of --echo # applier/rollbacker threads. -SET GLOBAL wsrep_cluster_address= 'gcomm://'; +#SET GLOBAL wsrep_cluster_address= 'gcomm://'; --echo # Wait for applier thread to get created 1. --let $wait_timeout=600 @@ -154,16 +144,7 @@ SET @wsrep_sst_auth_saved= @@global.wsrep_sst_auth; SET @@global.wsrep_sst_auth= 'user:pass'; SET @@global.wsrep_sst_auth= ''; SET @@global.wsrep_sst_auth= NULL; - -# Reset (for mtr internal checks) ---disable_query_log - SET @@global.wsrep_sst_auth= @wsrep_sst_auth_saved; -SET GLOBAL wsrep_slave_threads= @wsrep_slave_threads_saved; -eval SET GLOBAL wsrep_provider= '$WSREP_PROVIDER'; -SET GLOBAL wsrep_cluster_address= @wsrep_cluster_address_saved; -SET GLOBAL wsrep_provider_options= @wsrep_provider_options_saved; ---enable_query_log --source include/galera_wait_ready.inc diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index baf27a7d0af..e4de3d8d0aa 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -4958,7 +4958,7 @@ static Sys_var_tz Sys_time_zone( static Sys_var_charptr Sys_wsrep_provider( "wsrep_provider", "Path to replication provider library", - PREALLOCATED GLOBAL_VAR(wsrep_provider), CMD_LINE(REQUIRED_ARG), + PREALLOCATED READ_ONLY GLOBAL_VAR(wsrep_provider), CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT(WSREP_NONE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(wsrep_provider_check), ON_UPDATE(wsrep_provider_update)); @@ -5171,7 +5171,7 @@ static Sys_var_ulong Sys_wsrep_max_ws_rows ( static Sys_var_charptr Sys_wsrep_notify_cmd( "wsrep_notify_cmd", "", - GLOBAL_VAR(wsrep_notify_cmd),CMD_LINE(REQUIRED_ARG), + READ_ONLY GLOBAL_VAR(wsrep_notify_cmd), CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET, DEFAULT("")); static Sys_var_mybool Sys_wsrep_certify_nonPK( diff --git a/sql/wsrep_notify.cc b/sql/wsrep_notify.cc index fb04d7be7c1..3683d70a980 100644 --- a/sql/wsrep_notify.cc +++ b/sql/wsrep_notify.cc @@ -40,11 +40,13 @@ void wsrep_notify_status (wsrep_member_status_t status, return; } - char cmd_buf[1 << 16]; // this can be long - long cmd_len = sizeof(cmd_buf) - 1; - char* cmd_ptr = cmd_buf; + const long cmd_len = (1 << 16) - 1; + char* cmd_ptr = (char*) my_malloc(cmd_len + 1, MYF(MY_WME)); long cmd_off = 0; + if (!cmd_ptr) + return; // the warning is in the log + cmd_off += snprintf (cmd_ptr + cmd_off, cmd_len - cmd_off, "%s", wsrep_notify_cmd); @@ -93,6 +95,7 @@ void wsrep_notify_status (wsrep_member_status_t status, { WSREP_ERROR("Notification buffer too short (%ld). Aborting notification.", cmd_len); + my_free(cmd_ptr); return; } @@ -106,5 +109,6 @@ void wsrep_notify_status (wsrep_member_status_t status, WSREP_ERROR("Notification command failed: %d (%s): \"%s\"", err, strerror(err), cmd_ptr); } + my_free(cmd_ptr); } diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index f6a8db67d42..3c33551cb68 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -37,6 +37,8 @@ #undef SE_CATCH // Does not work for Linux #endif +int GetJsonDefPrec(void); + #if defined(SE_CATCH) /**************************************************************************/ /* This is the support of catching C interrupts to prevent crashes. */ @@ -80,7 +82,7 @@ BDOC::BDOC(PGLOBAL G) : BJSON(G, NULL) /***********************************************************************/ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng) { - int i; + size_t i; bool b = false, ptyp = (bool *)pty; PBVAL bvp = NULL; @@ -183,7 +185,7 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng) /***********************************************************************/ /* Parse several items as being in an array. */ /***********************************************************************/ -OFFSET BDOC::ParseAsArray(int& i) { +OFFSET BDOC::ParseAsArray(size_t& i) { if (pty[0] && (!pretty || pretty > 2)) { OFFSET jsp; @@ -200,7 +202,7 @@ OFFSET BDOC::ParseAsArray(int& i) { /***********************************************************************/ /* Parse a JSON Array. */ /***********************************************************************/ -OFFSET BDOC::ParseArray(int& i) +OFFSET BDOC::ParseArray(size_t& i) { int level = 0; bool b = (!i); @@ -212,7 +214,7 @@ OFFSET BDOC::ParseArray(int& i) switch (s[i]) { case ',': if (level < 2) { - sprintf(G->Message, "Unexpected ',' near %.*s", ARGS); + sprintf(G->Message, "Unexpected ',' near %.*s", (int) ARGS); throw 1; } else level = 1; @@ -220,7 +222,7 @@ OFFSET BDOC::ParseArray(int& i) break; case ']': if (level == 1) { - sprintf(G->Message, "Unexpected ',]' near %.*s", ARGS); + sprintf(G->Message, "Unexpected ',]' near %.*s", (int) ARGS); throw 1; } // endif level @@ -234,7 +236,7 @@ OFFSET BDOC::ParseArray(int& i) break; default: if (level == 2) { - sprintf(G->Message, "Unexpected value near %.*s", ARGS); + sprintf(G->Message, "Unexpected value near %.*s", (int) ARGS); throw 1; } else if (lastvlp) { vlp = ParseValue(i, NewVal()); @@ -258,7 +260,7 @@ OFFSET BDOC::ParseArray(int& i) /***********************************************************************/ /* Parse a JSON Object. */ /***********************************************************************/ -OFFSET BDOC::ParseObject(int& i) +OFFSET BDOC::ParseObject(size_t& i) { OFFSET key; int level = 0; @@ -281,7 +283,7 @@ OFFSET BDOC::ParseObject(int& i) level = 2; } else { - sprintf(G->Message, "misplaced string near %.*s", ARGS); + sprintf(G->Message, "misplaced string near %.*s", (int) ARGS); throw 2; } // endif level @@ -291,14 +293,14 @@ OFFSET BDOC::ParseObject(int& i) ParseValue(++i, GetVlp(lastbpp)); level = 3; } else { - sprintf(G->Message, "Unexpected ':' near %.*s", ARGS); + sprintf(G->Message, "Unexpected ':' near %.*s", (int) ARGS); throw 2; } // endif level break; case ',': if (level < 3) { - sprintf(G->Message, "Unexpected ',' near %.*s", ARGS); + sprintf(G->Message, "Unexpected ',' near %.*s", (int) ARGS); throw 2; } else level = 1; @@ -306,7 +308,7 @@ OFFSET BDOC::ParseObject(int& i) break; case '}': if (!(level == 0 || level == 3)) { - sprintf(G->Message, "Unexpected '}' near %.*s", ARGS); + sprintf(G->Message, "Unexpected '}' near %.*s", (int) ARGS); throw 2; } // endif level @@ -319,7 +321,7 @@ OFFSET BDOC::ParseObject(int& i) break; default: sprintf(G->Message, "Unexpected character '%c' near %.*s", - s[i], ARGS); + s[i], (int) ARGS); throw 2; }; // endswitch s[i] @@ -330,7 +332,7 @@ OFFSET BDOC::ParseObject(int& i) /***********************************************************************/ /* Parse a JSON Value. */ /***********************************************************************/ -PBVAL BDOC::ParseValue(int& i, PBVAL bvp) +PBVAL BDOC::ParseValue(size_t& i, PBVAL bvp) { for (; i < len; i++) switch (s[i]) { @@ -396,14 +398,14 @@ suite: return bvp; err: - sprintf(G->Message, "Unexpected character '%c' near %.*s", s[i], ARGS); + sprintf(G->Message, "Unexpected character '%c' near %.*s", s[i], (int) ARGS); throw 3; } // end of ParseValue /***********************************************************************/ /* Unescape and parse a JSON string. */ /***********************************************************************/ -OFFSET BDOC::ParseString(int& i) +OFFSET BDOC::ParseString(size_t& i) { uchar* p; int n = 0; @@ -490,7 +492,7 @@ throw("Unexpected EOF in String"); /***********************************************************************/ /* Parse a JSON numeric value. */ /***********************************************************************/ -void BDOC::ParseNumeric(int& i, PBVAL vlp) +void BDOC::ParseNumeric(size_t& i, PBVAL vlp) { char buf[50]; int n = 0; @@ -767,7 +769,7 @@ bool BDOC::SerializeValue(PBVAL jvp, bool b) case TYPE_DBL: sprintf(buf, "%.*lf", jvp->Nd, *(double*)MakePtr(Base, jvp->To_Val)); return jp->WriteStr(buf); - case (char)TYPE_NULL: + case TYPE_NULL: return jp->WriteStr("null"); case TYPE_JVAL: return SerializeValue(MVP(jvp->To_Val)); @@ -884,7 +886,6 @@ PBPR BJSON::NewPair(OFFSET key, int type) PBPR bpp = (PBPR)BsonSubAlloc(sizeof(BPAIR)); bpp->Key = key; - bpp->Vlp.Ktp = TYPE_STRG; bpp->Vlp.Type = type; bpp->Vlp.To_Val = 0; bpp->Vlp.Nd = 0; @@ -1498,31 +1499,27 @@ double BJSON::GetDouble(PBVAL vp) PBVAL vlp = (vp->Type == TYPE_JVAL) ? MVP(vp->To_Val) : vp; switch (vlp->Type) { - case TYPE_DBL: - d = *(double*)MP(vlp->To_Val); - break; - case TYPE_BINT: - d = (double)*(longlong*)MP(vlp->To_Val); - break; - case TYPE_INTG: - d = (double)vlp->N; - break; - case TYPE_FLOAT: - { char buf[32]; - int n = (vlp->Nd) ? vlp->Nd : 5; - - sprintf(buf, "%.*f", n, vlp->F); - d = atof(buf); - } break; - case TYPE_DTM: - case TYPE_STRG: - d = atof(MZP(vlp->To_Val)); - break; - case TYPE_BOOL: - d = (vlp->B) ? 1.0 : 0.0; - break; - default: - d = 0.0; + case TYPE_DBL: + d = *(double*)MP(vlp->To_Val); + break; + case TYPE_BINT: + d = (double)*(longlong*)MP(vlp->To_Val); + break; + case TYPE_INTG: + d = (double)vlp->N; + break; + case TYPE_FLOAT: + d = (double)vlp->F; + break; + case TYPE_DTM: + case TYPE_STRG: + d = atof(MZP(vlp->To_Val)); + break; + case TYPE_BOOL: + d = (vlp->B) ? 1.0 : 0.0; + break; + default: + d = 0.0; } // endswitch Type return d; @@ -1557,7 +1554,7 @@ PSZ BJSON::GetString(PBVAL vp, char* buff) case TYPE_BOOL: p = (PSZ)((vlp->B) ? "true" : "false"); break; - case (char)TYPE_NULL: + case TYPE_NULL: p = (PSZ)"null"; break; default: @@ -1721,14 +1718,22 @@ void BJSON::SetBigint(PBVAL vlp, longlong ll) /***********************************************************************/ /* Set the Value's value as the given DOUBLE. */ /***********************************************************************/ -void BJSON::SetFloat(PBVAL vlp, double d, int nd) +void BJSON::SetFloat(PBVAL vlp, double d, int prec) { - double* dp = (double*)BsonSubAlloc(sizeof(double)); + int nd = MY_MIN((prec < 0) ? GetJsonDefPrec() : prec, 16); + + if (nd < 6 && d >= FLT_MIN && d <= FLT_MAX) { + vlp->F = (float)d; + vlp->Type = TYPE_FLOAT; + } else { + double* dp = (double*)BsonSubAlloc(sizeof(double)); + + *dp = d; + vlp->To_Val = MOF(dp); + vlp->Type = TYPE_DBL; + } // endif nd - *dp = d; - vlp->To_Val = MOF(dp); - vlp->Nd = MY_MIN(nd, 16); - vlp->Type = TYPE_DBL; + vlp->Nd = nd; } // end of SetFloat /***********************************************************************/ @@ -1745,13 +1750,7 @@ void BJSON::SetFloat(PBVAL vlp, PSZ s) for (--p; *p == '0'; nd--, p--); } // endif p - if (nd < 6 && d >= FLT_MIN && d <= FLT_MAX) { - vlp->F = (float)d; - vlp->Nd = nd; - vlp->Type = TYPE_FLOAT; - } else - SetFloat(vlp, d, nd); - + SetFloat(vlp, d, nd); } // end of SetFloat /***********************************************************************/ @@ -1772,7 +1771,7 @@ bool BJSON::IsValueNull(PBVAL vlp) bool b; switch (vlp->Type) { - case (char)TYPE_NULL: + case TYPE_NULL: b = true; break; case TYPE_JOB: diff --git a/storage/connect/bson.h b/storage/connect/bson.h index 5420c6f2f36..acc36e8e0ed 100644 --- a/storage/connect/bson.h +++ b/storage/connect/bson.h @@ -37,8 +37,7 @@ typedef struct _jvalue { bool B; // A boolean value True or false (0) }; short Nd; // Number of decimals - char Type; // The value type - char Ktp; // The key type + short Type; // The value type OFFSET Next; // Offset to the next value in array } BVAL, *PBVAL; // end of struct BVALUE @@ -149,7 +148,7 @@ public: void SetString(PBVAL vlp, PSZ s, int ci = 0); void SetInteger(PBVAL vlp, int n); void SetBigint(PBVAL vlp, longlong ll); - void SetFloat(PBVAL vlp, double f, int nd = 16); + void SetFloat(PBVAL vlp, double f, int nd = -1); void SetFloat(PBVAL vlp, PSZ s); void SetBool(PBVAL vlp, bool b); void Clear(PBVAL vlp) { vlp->N = 0; vlp->Nd = 0; vlp->Next = 0; } @@ -185,12 +184,12 @@ public: PSZ Serialize(PGLOBAL g, PBVAL bvp, char* fn, int pretty); protected: - OFFSET ParseArray(int& i); - OFFSET ParseObject(int& i); - PBVAL ParseValue(int& i, PBVAL bvp); - OFFSET ParseString(int& i); - void ParseNumeric(int& i, PBVAL bvp); - OFFSET ParseAsArray(int& i); + OFFSET ParseArray(size_t& i); + OFFSET ParseObject(size_t& i); + PBVAL ParseValue(size_t& i, PBVAL bvp); + OFFSET ParseString(size_t& i); + void ParseNumeric(size_t& i, PBVAL bvp); + OFFSET ParseAsArray(size_t& i); bool SerializeArray(OFFSET arp, bool b); bool SerializeObject(OFFSET obp); bool SerializeValue(PBVAL vp, bool b = false); @@ -198,7 +197,7 @@ protected: // Members used when parsing and serializing JOUT* jp; // Used with serialize char* s; // The Json string to parse - int len; // The Json string length + size_t len; // The Json string length int pretty; // The pretty style of the file to parse bool pty[3]; // Used to guess what pretty is bool comma; // True if Pretty = 1 diff --git a/storage/connect/bsonudf.cpp b/storage/connect/bsonudf.cpp index 4145e21deb5..29fe0a6bf22 100644 --- a/storage/connect/bsonudf.cpp +++ b/storage/connect/bsonudf.cpp @@ -27,14 +27,24 @@ #endif #define M 6 +int JsonDefPrec = -1; +int GetDefaultPrec(void); int IsArgJson(UDF_ARGS* args, uint i); void SetChanged(PBSON bsp); +int GetJsonDefPrec(void); static PBSON BbinAlloc(PGLOBAL g, ulong len, PBVAL jsp); /* --------------------------------- JSON UDF ---------------------------------- */ /*********************************************************************************/ +/* Replaces GetJsonGrpSize not usable when CONNECT is not installed. */ +/*********************************************************************************/ +int GetJsonDefPrec(void) { + return (JsonDefPrec < 0) ? GetDefaultPrec() : JsonDefPrec; +} /* end of GetJsonDefPrec */ + +/*********************************************************************************/ /* Program for saving the status of the memory pools. */ /*********************************************************************************/ inline void JsonMemSave(PGLOBAL g) { @@ -109,7 +119,7 @@ BJNX::BJNX(PGLOBAL g) : BDOC(g) Value = NULL; MulVal = NULL; Jpath = NULL; - Buf_Type = TYPE_NULL; + Buf_Type = TYPE_STRING; Long = len; Prec = 0; Nod = 0; @@ -164,10 +174,9 @@ BJNX::BJNX(PGLOBAL g, PBVAL row, int type, int len, int prec, my_bool wr) : BDOC my_bool BJNX::SetJpath(PGLOBAL g, char* path, my_bool jb) { // Check Value was allocated - if (!Value) - return true; + if (Value) + Value->SetNullable(true); - Value->SetNullable(true); Jpath = path; // Parse the json path @@ -264,6 +273,7 @@ my_bool BJNX::SetArrayOptions(PGLOBAL g, char* p, int i, PSZ nm) return true; } // endif's +#if 0 // For calculated arrays, a local Value must be used switch (jnp->Op) { case OP_NUM: @@ -295,6 +305,7 @@ my_bool BJNX::SetArrayOptions(PGLOBAL g, char* p, int i, PSZ nm) if (jnp->Valp) MulVal = AllocateValue(g, jnp->Valp); +#endif // 0 return false; } // end of SetArrayOptions @@ -378,7 +389,7 @@ my_bool BJNX::ParseJpath(PGLOBAL g) } // endfor i, p Nod = i; - MulVal = AllocateValue(g, Value); +//MulVal = AllocateValue(g, Value); if (trace(1)) for (i = 0; i < Nod; i++) @@ -435,20 +446,42 @@ PSZ BJNX::MakeKey(UDF_ARGS *args, int i) } // end of MakeKey /*********************************************************************************/ -/* MakeJson: Serialize the json item and set value to it. */ +/* MakeJson: Make the Json tree to serialize. */ /*********************************************************************************/ -PVAL BJNX::MakeJson(PGLOBAL g, PBVAL bvp) +PBVAL BJNX::MakeJson(PGLOBAL g, PBVAL bvp, int n) { - if (Value->IsTypeNum()) { - strcpy(g->Message, "Cannot make Json for a numeric value"); - Value->Reset(); - } else if (bvp->Type != TYPE_JAR && bvp->Type != TYPE_JOB) { - strcpy(g->Message, "Target is not an array or object"); - Value->Reset(); - } else - Value->SetValue_psz(Serialize(g, bvp, NULL, 0)); + PBVAL vlp, jvp = bvp; - return Value; + if (n < Nod -1) { + if (bvp->Type == TYPE_JAR) { + int ars = GetArraySize(bvp); + PJNODE jnp = &Nodes[n]; + + jvp = NewVal(TYPE_JAR); + jnp->Op = OP_EQ; + + for (int i = 0; i < ars; i++) { + jnp->Rank = i; + vlp = GetRowValue(g, bvp, n); + AddArrayValue(jvp, DupVal(vlp)); + } // endfor i + + jnp->Op = OP_XX; + jnp->Rank = 0; + } else if(bvp->Type == TYPE_JOB) { + jvp = NewVal(TYPE_JOB); + + for (PBPR prp = GetObject(bvp); prp; prp = GetNext(prp)) { + vlp = GetRowValue(g, GetVlp(prp), n + 1); + SetKeyValue(jvp, vlp, MZP(prp->Key)); + } // endfor prp + + } // endif Type + + } // endif n + + Jb = true; + return jvp; } // end of MakeJson /*********************************************************************************/ @@ -461,15 +494,18 @@ void BJNX::SetJsonValue(PGLOBAL g, PVAL vp, PBVAL vlp) if (Jb) { vp->SetValue_psz(Serialize(g, vlp, NULL, 0)); + Jb = false; } else switch (vlp->Type) { case TYPE_DTM: case TYPE_STRG: vp->SetValue_psz(GetString(vlp)); break; case TYPE_INTG: - case TYPE_BINT: vp->SetValue(GetInteger(vlp)); break; + case TYPE_BINT: + vp->SetValue(GetBigint(vlp)); + break; case TYPE_DBL: case TYPE_FLOAT: if (vp->IsTypeNum()) @@ -491,7 +527,7 @@ void BJNX::SetJsonValue(PGLOBAL g, PVAL vp, PBVAL vlp) case TYPE_JOB: vp->SetValue_psz(GetObjectText(g, vlp, NULL)); break; - case (char)TYPE_NULL: + case TYPE_NULL: vp->SetNull(true); default: vp->Reset(); @@ -534,7 +570,7 @@ PVAL BJNX::GetColumnValue(PGLOBAL g, PBVAL row, int i) /*********************************************************************************/ /* GetRowValue: */ /*********************************************************************************/ -PBVAL BJNX::GetRowValue(PGLOBAL g, PBVAL row, int i, my_bool b) +PBVAL BJNX::GetRowValue(PGLOBAL g, PBVAL row, int i) { my_bool expd = false; PBVAL bap; @@ -546,9 +582,7 @@ PBVAL BJNX::GetRowValue(PGLOBAL g, PBVAL row, int i, my_bool b) vlp = NewVal(Value); return vlp; } else if (Nodes[i].Op == OP_XX) { - Jb = b; - // return DupVal(g, row); - return row; // or last line ??? + return MakeJson(g, row, i); } else if (Nodes[i].Op == OP_EXP) { PUSH_WARNING("Expand not supported by this function"); return NULL; @@ -613,93 +647,184 @@ PVAL BJNX::ExpandArray(PGLOBAL g, PBVAL arp, int n) } // end of ExpandArray /*********************************************************************************/ -/* CalculateArray: NIY */ +/* Get the value used for calculating the array. */ +/*********************************************************************************/ +PVAL BJNX::GetCalcValue(PGLOBAL g, PBVAL bap, int n) +{ + // For calculated arrays, a local Value must be used + int lng = 0; + short type, prec = 0; + bool b = n < Nod - 1; + PVAL valp; + PBVAL vlp, vp; + OPVAL op = Nodes[n].Op; + + switch (op) { + case OP_NUM: + type = TYPE_INT; + break; + case OP_ADD: + case OP_MULT: + if (!IsTypeNum(Buf_Type)) { + type = TYPE_INT; + prec = 0; + + for (vlp = GetArray(bap); vlp; vlp = GetNext(vlp)) { + vp = (b && IsJson(vlp)) ? GetRowValue(g, vlp, n + 1) : vlp; + + switch (vp->Type) { + case TYPE_BINT: + if (type == TYPE_INT) + type = TYPE_BIGINT; + + break; + case TYPE_DBL: + case TYPE_FLOAT: + type = TYPE_DOUBLE; + prec = MY_MAX(prec, vp->Nd); + break; + default: + break; + } // endswitch Type + + } // endfor vlp + + } else { + type = Buf_Type; + prec = GetPrecision(); + } // endif Buf_Type + + break; + case OP_SEP: + if (IsTypeChar(Buf_Type)) { + type = TYPE_DOUBLE; + prec = 2; + } else { + type = Buf_Type; + prec = GetPrecision(); + } // endif Buf_Type + + break; + case OP_MIN: + case OP_MAX: + type = Buf_Type; + lng = Long; + prec = GetPrecision(); + break; + case OP_CNC: + type = TYPE_STRING; + + if (IsTypeChar(Buf_Type)) { + lng = (Long) ? Long : 512; + prec = GetPrecision(); + } else + lng = 512; + + break; + default: + break; + } // endswitch Op + + return valp = AllocateValue(g, type, lng, prec); +} // end of GetCalcValue + +/*********************************************************************************/ +/* CalculateArray */ /*********************************************************************************/ PVAL BJNX::CalculateArray(PGLOBAL g, PBVAL bap, int n) { int i, ars = GetArraySize(bap), nv = 0; bool err; OPVAL op = Nodes[n].Op; - PVAL val[2], vp = Nodes[n].Valp; + PVAL val[2], vp = GetCalcValue(g, bap, n); + PVAL mulval = AllocateValue(g, vp); PBVAL bvrp, bvp; BVAL bval; vp->Reset(); xtrc(1, "CalculateArray size=%d op=%d\n", ars, op); - for (i = 0; i < ars; i++) { - bvrp = GetArrayValue(bap, i); - xtrc(1, "i=%d nv=%d\n", i, nv); - - if (!IsValueNull(bvrp) || (op == OP_CNC && GetJsonNull())) { - if (IsValueNull(bvrp)) { - SetString(bvrp, NewStr(GetJsonNull()), 0); - bvp = bvrp; - } else if (n < Nod - 1 && IsJson(bvrp)) { - SetValue(&bval, GetColumnValue(g, bvrp, n + 1)); - bvp = &bval; - } else - bvp = bvrp; + try { + for (i = 0; i < ars; i++) { + bvrp = GetArrayValue(bap, i); + xtrc(1, "i=%d nv=%d\n", i, nv); + + if (!IsValueNull(bvrp) || (op == OP_CNC && GetJsonNull())) { + if (IsValueNull(bvrp)) { + SetString(bvrp, NewStr(GetJsonNull()), 0); + bvp = bvrp; + } else if (n < Nod - 1 && IsJson(bvrp)) { + SetValue(&bval, GetColumnValue(g, bvrp, n + 1)); + bvp = &bval; + } else + bvp = bvrp; - if (trace(1)) - htrc("bvp=%s null=%d\n", - GetString(bvp), IsValueNull(bvp) ? 1 : 0); + if (trace(1)) + htrc("bvp=%s null=%d\n", + GetString(bvp), IsValueNull(bvp) ? 1 : 0); - if (!nv++) { - SetJsonValue(g, vp, bvp); - continue; - } else - SetJsonValue(g, MulVal, bvp); + if (!nv++) { + SetJsonValue(g, vp, bvp); + continue; + } else + SetJsonValue(g, mulval, bvp); + + if (!mulval->IsNull()) { + switch (op) { + case OP_CNC: + if (Nodes[n].CncVal) { + val[0] = Nodes[n].CncVal; + err = vp->Compute(g, val, 1, op); + } // endif CncVal - if (!MulVal->IsNull()) { - switch (op) { - case OP_CNC: - if (Nodes[n].CncVal) { - val[0] = Nodes[n].CncVal; + val[0] = mulval; err = vp->Compute(g, val, 1, op); - } // endif CncVal + break; + // case OP_NUM: + case OP_SEP: + val[0] = vp; + val[1] = mulval; + err = vp->Compute(g, val, 2, OP_ADD); + break; + default: + val[0] = vp; + val[1] = mulval; + err = vp->Compute(g, val, 2, op); + } // endswitch Op - val[0] = MulVal; - err = vp->Compute(g, val, 1, op); - break; - // case OP_NUM: - case OP_SEP: - val[0] = Nodes[n].Valp; - val[1] = MulVal; - err = vp->Compute(g, val, 2, OP_ADD); - break; - default: - val[0] = Nodes[n].Valp; - val[1] = MulVal; - err = vp->Compute(g, val, 2, op); - } // endswitch Op + if (err) + vp->Reset(); - if (err) - vp->Reset(); + if (trace(1)) { + char buf(32); - if (trace(1)) { - char buf(32); + htrc("vp='%s' err=%d\n", + vp->GetCharString(&buf), err ? 1 : 0); + } // endif trace - htrc("vp='%s' err=%d\n", - vp->GetCharString(&buf), err ? 1 : 0); - } // endif trace + } // endif Zero - } // endif Zero + } // endif jvrp - } // endif jvrp + } // endfor i - } // endfor i + if (op == OP_SEP) { + // Calculate average + mulval->SetValue(nv); + val[0] = vp; + val[1] = mulval; - if (op == OP_SEP) { - // Calculate average - MulVal->SetValue(nv); - val[0] = vp; - val[1] = MulVal; + if (vp->Compute(g, val, 2, OP_DIV)) + vp->Reset(); - if (vp->Compute(g, val, 2, OP_DIV)) - vp->Reset(); + } // endif Op - } // endif Op + } catch (int n) { + xtrc(1, "Exception %d: %s\n", n, g->Message); + PUSH_WARNING(g->Message); + } catch (const char* msg) { + strcpy(g->Message, msg); + } // end catch return vp; } // end of CalculateArray @@ -1320,7 +1445,7 @@ my_bool BJNX::CompareValues(PGLOBAL g, PBVAL v1, PBVAL v2) b = (v1->B == v2->B); break; - case (char)TYPE_NULL: + case TYPE_NULL: b = (v2->Type == TYPE_NULL); break; default: @@ -1545,7 +1670,7 @@ PBVAL BJNX::ParseJsonFile(PGLOBAL g, char *fn, int& pty, size_t& len) len = (size_t)mm.lenL; if (mm.lenH) - len += ((size_t)mm.lenH * 0x000000001LL); + len += mm.lenH; memory = (char *)mm.memory; @@ -2703,6 +2828,45 @@ void bson_object_values_deinit(UDF_INIT* initid) /*********************************************************************************/ /* Set the value of JsonGrpSize. */ /*********************************************************************************/ +my_bool bsonset_def_prec_init(UDF_INIT *initid, UDF_ARGS *args, char *message) +{ + if (args->arg_count != 1 || args->arg_type[0] != INT_RESULT) { + strcpy(message, "This function must have 1 integer argument"); + return true; + } else + return false; + +} // end of bsonset_def_prec_init + +long long bsonset_def_prec(UDF_INIT *initid, UDF_ARGS *args, char *, char *) +{ + long long n = *(long long*)args->args[0]; + + JsonDefPrec = (int)n; + return (long long)GetJsonDefPrec(); +} // end of bsonset_def_prec + +/*********************************************************************************/ +/* Get the value of JsonGrpSize. */ +/*********************************************************************************/ +my_bool bsonget_def_prec_init(UDF_INIT *initid, UDF_ARGS *args, char *message) +{ + if (args->arg_count != 0) { + strcpy(message, "This function must have no arguments"); + return true; + } else + return false; + +} // end of bsonget_def_prec_init + +long long bsonget_def_prec(UDF_INIT *initid, UDF_ARGS *args, char *, char *) +{ + return (long long)GetJsonDefPrec(); +} // end of bsonget_def_prec + +/*********************************************************************************/ +/* Set the value of JsonGrpSize. */ +/*********************************************************************************/ my_bool bsonset_grp_size_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { if (args->arg_count != 1 || args->arg_type[0] != INT_RESULT) { @@ -2858,7 +3022,7 @@ void bson_object_grp_add(UDF_INIT *initid, UDF_ARGS *args, char*, char*) PBVAL bop = (PBVAL)g->Activityp; if (g->N-- > 0) - bxp->SetKeyValue(bop, bxp->MakeValue(args, 0), MakePSZ(g, args, 1)); + bxp->SetKeyValue(bop, bxp->MakeValue(args, 1), MakePSZ(g, args, 0)); } // end of bson_object_grp_add @@ -3532,8 +3696,8 @@ char *bson_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result, { char *path, *str = NULL; PBVAL jvp; - PBJNX bxp = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; + BJNX bnx(g, NULL, TYPE_STRING, initid->max_length); if (g->N) { str = (char*)g->Activityp; @@ -3546,8 +3710,7 @@ char *bson_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result, PUSH_WARNING("CheckMemory error"); goto fin; } else { - BJNX bnx(g); - + bnx.Reset(); jvp = bnx.MakeValue(args, 0, true); if (g->Mrr) { // First argument is a constant @@ -3561,16 +3724,16 @@ char *bson_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result, jvp = (PBVAL)g->Xchk; path = MakePSZ(g, args, 1); - bxp = new(g) BJNX(g, jvp, TYPE_STRING, initid->max_length); - if (bxp->SetJpath(g, path, true)) { - PUSH_WARNING(g->Message); + if (bnx.SetJpath(g, path, true)) { goto fin; } else - bxp->ReadValue(g); + jvp = bnx.GetRowValue(g, jvp, 0); - if (!bxp->GetValue()->IsNull()) - str = bxp->GetValue()->GetCharValue(); + if (!bnx.IsJson(jvp)) { + strcpy(g->Message, "Not a Json item"); + } else + str = bnx.Serialize(g, jvp, NULL, 0); if (initid->const_item) // Keep result of constant function @@ -3578,6 +3741,7 @@ char *bson_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result, fin: if (!str) { + PUSH_WARNING(g->Message); *is_null = 1; *res_length = 0; } else @@ -3872,8 +4036,8 @@ double bsonget_real(UDF_INIT *initid, UDF_ARGS *args, char *p, *path; double d; PBVAL jsp, jvp; - PBJNX bxp = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; + BJNX bnx(g); if (g->N) { if (!g->Activityp) { @@ -3892,8 +4056,7 @@ double bsonget_real(UDF_INIT *initid, UDF_ARGS *args, *is_null = 1; return 0.0; } else { - BJNX bnx(g); - + bnx.Reset(); jvp = bnx.MakeValue(args, 0); if ((p = bnx.GetString(jvp))) { @@ -3916,21 +4079,22 @@ double bsonget_real(UDF_INIT *initid, UDF_ARGS *args, jsp = (PBVAL)g->Xchk; path = MakePSZ(g, args, 1); - bxp = new(g) BJNX(g, jsp, TYPE_DOUBLE); +//bxp = new(g) BJNX(g, jsp, TYPE_DOUBLE, 32, jsp->Nd); - if (bxp->SetJpath(g, path)) { + if (bnx.SetJpath(g, path)) { PUSH_WARNING(g->Message); *is_null = 1; return 0.0; } else - bxp->ReadValue(g); + jvp = bnx.GetRowValue(g, jsp, 0); - if (bxp->GetValue()->IsNull()) { + if (!jvp || bnx.IsValueNull(jvp)) { *is_null = 1; return 0.0; - } // endif IsNull - - d = bxp->GetValue()->GetFloatValue(); + } else if (args->arg_count == 2) { + d = atof(bnx.GetString(jvp)); + } else + d = bnx.GetDouble(jvp); if (initid->const_item) { // Keep result of constant function @@ -4716,7 +4880,8 @@ char *bson_serialize(UDF_INIT *initid, UDF_ARGS *args, char *result, BJNX bnx(bsp->G); PBVAL bvp = (args->arg_count == 1) ? (PBVAL)bsp->Jsp : (PBVAL)bsp->Top; - if (!(str = bnx.Serialize(g, bvp, bsp->Filename, bsp->Pretty))) +// if (!(str = bnx.Serialize(g, bvp, bsp->Filename, bsp->Pretty))) + if (!(str = bnx.Serialize(g, bvp, NULL, 0))) str = strcpy(result, g->Message); // Keep result of constant function @@ -5515,7 +5680,7 @@ void bbin_object_values_deinit(UDF_INIT* initid) my_bool bbin_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { return bson_get_item_init(initid, args, message); -} // end of bbin_get_item_init +} // end of bbin_get_item_init char *bbin_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) diff --git a/storage/connect/bsonudf.h b/storage/connect/bsonudf.h index 01b9b9d55d5..bbfd1ceed80 100644 --- a/storage/connect/bsonudf.h +++ b/storage/connect/bsonudf.h @@ -81,6 +81,7 @@ typedef struct _jpn { extern uint JsonGrpSize; uint GetJsonGroupSize(void); + typedef class BJNX* PBJNX; /*********************************************************************************/ @@ -102,7 +103,7 @@ public: my_bool SetJpath(PGLOBAL g, char* path, my_bool jb = false); my_bool ParseJpath(PGLOBAL g); void ReadValue(PGLOBAL g); - PBVAL GetRowValue(PGLOBAL g, PBVAL row, int i, my_bool b = true); + PBVAL GetRowValue(PGLOBAL g, PBVAL row, int i); PBVAL GetJson(PGLOBAL g); my_bool CheckPath(PGLOBAL g); my_bool CheckPath(PGLOBAL g, UDF_ARGS* args, PBVAL jsp, PBVAL& jvp, int n); @@ -123,7 +124,8 @@ protected: PVAL GetColumnValue(PGLOBAL g, PBVAL row, int i); PVAL ExpandArray(PGLOBAL g, PBVAL arp, int n); PVAL CalculateArray(PGLOBAL g, PBVAL arp, int n); - PVAL MakeJson(PGLOBAL g, PBVAL bvp); + PVAL GetCalcValue(PGLOBAL g, PBVAL bap, int n); + PBVAL MakeJson(PGLOBAL g, PBVAL bvp, int n); void SetJsonValue(PGLOBAL g, PVAL vp, PBVAL vlp); PBVAL GetRow(PGLOBAL g); PBVAL MoveVal(PBVAL vlp); @@ -259,6 +261,12 @@ extern "C" { DllExport double bsonget_real(UDF_INIT*, UDF_ARGS*, char*, char*); DllExport void bsonget_real_deinit(UDF_INIT*); + DllExport my_bool bsonset_def_prec_init(UDF_INIT*, UDF_ARGS*, char*); + DllExport long long bsonset_def_prec(UDF_INIT*, UDF_ARGS*, char*, char*); + + DllExport my_bool bsonget_def_prec_init(UDF_INIT*, UDF_ARGS*, char*); + DllExport long long bsonget_def_prec(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport my_bool bsonset_grp_size_init(UDF_INIT*, UDF_ARGS*, char*); DllExport long long bsonset_grp_size(UDF_INIT*, UDF_ARGS*, char*, char*); diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 9f62dbfe2f9..1ef5345fd68 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -170,7 +170,7 @@ #define JSONMAX 10 // JSON Default max grp size extern "C" { - char version[]= "Version 1.07.0002 December 25, 2020"; + char version[]= "Version 1.07.0002 January 27, 2021"; #if defined(__WIN__) char compver[]= "Version 1.07.0002 " __DATE__ " " __TIME__; char slash= '\\'; @@ -255,6 +255,7 @@ USETEMP UseTemp(void); int GetConvSize(void); TYPCONV GetTypeConv(void); int GetDefaultDepth(void); +int GetDefaultPrec(void); bool JsonAllPath(void); char *GetJsonNull(void); uint GetJsonGrpSize(void); @@ -420,9 +421,15 @@ static MYSQL_THDVAR_INT(default_depth, "Default depth used by Json, XML and Mongo discovery", NULL, NULL, 5, -1, 16, 1); // Defaults to 5 +// Default precision for doubles +static MYSQL_THDVAR_INT(default_prec, + PLUGIN_VAR_RQCMDARG, + "Default precision used for doubles", + NULL, NULL, 6, 0, 16, 1); // Defaults to 6 + // Estimate max number of rows for JSON aggregate functions static MYSQL_THDVAR_UINT(json_grp_size, - PLUGIN_VAR_RQCMDARG, // opt + PLUGIN_VAR_RQCMDARG, // opt "max number of rows for JSON aggregate functions.", NULL, NULL, JSONMAX, 1, INT_MAX, 1); @@ -495,6 +502,7 @@ TYPCONV GetTypeConv(void) {return (TYPCONV)THDVAR(current_thd, type_conv);} char *GetJsonNull(void) {return connect_hton ? THDVAR(current_thd, json_null) : NULL;} int GetDefaultDepth(void) {return THDVAR(current_thd, default_depth);} +int GetDefaultPrec(void) {return THDVAR(current_thd, default_prec);} uint GetJsonGrpSize(void) {return connect_hton ? THDVAR(current_thd, json_grp_size) : 10;} size_t GetWorkSize(void) {return (size_t)THDVAR(current_thd, work_size);} @@ -4833,6 +4841,7 @@ int ha_connect::start_stmt(THD *thd, thr_lock_type lock_type) lock.cc by lock_external() and unlock_external() in lock.cc; the section "locking functions for mysql" in lock.cc; copy_data_between_tables() in sql_table.cc. + */ int ha_connect::external_lock(THD *thd, int lock_type) { @@ -7444,7 +7453,8 @@ static struct st_mysql_sys_var* connect_system_variables[]= { MYSQL_SYSVAR(json_null), MYSQL_SYSVAR(json_all_path), MYSQL_SYSVAR(default_depth), - MYSQL_SYSVAR(json_grp_size), + MYSQL_SYSVAR(default_prec), + MYSQL_SYSVAR(json_grp_size), #if defined(JAVA_SUPPORT) MYSQL_SYSVAR(jvm_path), MYSQL_SYSVAR(class_path), diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index 6669b7af5d8..abc70a0f93a 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -356,9 +356,11 @@ void JSNX::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val) vp->SetValue_psz(val->GetString(g)); break; case TYPE_INTG: - case TYPE_BINT: vp->SetValue(val->GetInteger()); break; + case TYPE_BINT: + vp->SetValue(val->GetBigint()); + break; case TYPE_DBL: if (vp->IsTypeNum()) vp->SetValue(val->GetFloat()); diff --git a/storage/connect/mysql-test/connect/r/bson_udf.result b/storage/connect/mysql-test/connect/r/bson_udf.result index a0b93f2e547..fef55f7d3d9 100644 --- a/storage/connect/mysql-test/connect/r/bson_udf.result +++ b/storage/connect/mysql-test/connect/r/bson_udf.result @@ -176,6 +176,9 @@ Value List # # Test UDF's with column arguments # +SELECT Bsonset_Def_Prec(2); +Bsonset_Def_Prec(2) +2 CREATE TABLE t2 ( ISBN CHAR(15), @@ -213,7 +216,7 @@ SALARY DOUBLE(8,2) NOT NULL FLAG=52 ) ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=8 FILE_NAME='employee.dat' ENDING=1; SELECT Bson_Make_Object(SERIALNO, NAME, TITLE, SALARY) FROM t3 WHERE NAME = 'MERCHANT'; Bson_Make_Object(SERIALNO, NAME, TITLE, SALARY) -{"SERIALNO":"78943","NAME":"MERCHANT","TITLE":"SALESMAN","SALARY":8700.0000000000000000} +{"SERIALNO":"78943","NAME":"MERCHANT","TITLE":"SALESMAN","SALARY":8700.00} SELECT DEPARTMENT, Bson_Array_Grp(NAME) FROM t3 GROUP BY DEPARTMENT; DEPARTMENT Bson_Array_Grp(NAME) 0021 ["STRONG","SHORTSIGHT"] @@ -249,41 +252,41 @@ Bson_Make_Object(DEPARTMENT, Bson_Array_Grp(NAME) json_NAMES) {"DEPARTMENT":"2452","NAMES":["BIGHEAD","ORELLY","BIGHORN","SMITH","CHERRY"]} SELECT Bson_Make_Object(DEPARTMENT, Bson_Array_Grp(Bson_Make_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT; Bson_Make_Object(DEPARTMENT, Bson_Array_Grp(Bson_Make_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) -{"DEPARTMENT":"0021","EMPLOYES":[{"SERIALNO":"87777","NAME":"STRONG","TITLE":"DIRECTOR","SALARY":23000.0000000000000000},{"SERIALNO":"22222","NAME":"SHORTSIGHT","TITLE":"SECRETARY","SALARY":5500.0000000000000000}]} -{"DEPARTMENT":"0318","EMPLOYES":[{"SERIALNO":"74200","NAME":"BANCROFT","TITLE":"SALESMAN","SALARY":9600.0000000000000000},{"SERIALNO":"24888","NAME":"PLUMHEAD","TITLE":"TYPIST","SALARY":2800.0000000000000000},{"SERIALNO":"27845","NAME":"HONEY","TITLE":"SECRETARY","SALARY":4900.0000000000000000},{"SERIALNO":"73452","NAME":"TONGHO","TITLE":"ENGINEER","SALARY":6800.0000000000000000},{"SERIALNO":"74234","NAME":"WALTER","TITLE":"ENGINEER","SALARY":7400.0000000000000000},{"SERIALNO":"77777","NAME":"SHRINKY","TITLE":"ADMINISTRATOR","SALARY":7500.0000000000000000},{"SERIALNO":"70012","NAME":"WERTHER","TITLE":"DIRECTOR","SALARY":14500.0000000000000000},{"SERIALNO":"78943","NAME":"MERCHANT","TITLE":"SALESMAN","SALARY":8700.0000000000000000},{"SERIALNO":"73111","NAME":"WHEELFOR","TITLE":"SALESMAN","SALARY":10030.0000000000000000}]} -{"DEPARTMENT":"0319","EMPLOYES":[{"SERIALNO":"76543","NAME":"BULLOZER","TITLE":"SALESMAN","SALARY":14800.0000000000000000},{"SERIALNO":"40567","NAME":"QUINN","TITLE":"DIRECTOR","SALARY":14000.0000000000000000},{"SERIALNO":"00137","NAME":"BROWNY","TITLE":"ENGINEER","SALARY":10500.0000000000000000},{"SERIALNO":"12345","NAME":"KITTY","TITLE":"TYPIST","SALARY":3000.4499999999998181},{"SERIALNO":"33333","NAME":"MONAPENNY","TITLE":"SECRETARY","SALARY":3800.0000000000000000},{"SERIALNO":"00023","NAME":"MARTIN","TITLE":"ENGINEER","SALARY":10000.0000000000000000},{"SERIALNO":"07654","NAME":"FUNNIGUY","TITLE":"ADMINISTRATOR","SALARY":8500.0000000000000000},{"SERIALNO":"45678","NAME":"BUGHAPPY","TITLE":"PROGRAMMER","SALARY":8500.0000000000000000},{"SERIALNO":"56789","NAME":"FODDERMAN","TITLE":"SALESMAN","SALARY":7000.0000000000000000},{"SERIALNO":"55555","NAME":"MESSIFUL","TITLE":"SECRETARY","SALARY":5000.5000000000000000},{"SERIALNO":"98765","NAME":"GOOSEPEN","TITLE":"ADMINISTRATOR","SALARY":4700.0000000000000000}]} -{"DEPARTMENT":"2452","EMPLOYES":[{"SERIALNO":"34567","NAME":"BIGHEAD","TITLE":"SCIENTIST","SALARY":8000.0000000000000000},{"SERIALNO":"31416","NAME":"ORELLY","TITLE":"ENGINEER","SALARY":13400.0000000000000000},{"SERIALNO":"36666","NAME":"BIGHORN","TITLE":"SCIENTIST","SALARY":11000.0000000000000000},{"SERIALNO":"02345","NAME":"SMITH","TITLE":"ENGINEER","SALARY":9000.0000000000000000},{"SERIALNO":"11111","NAME":"CHERRY","TITLE":"SECRETARY","SALARY":4500.0000000000000000}]} +{"DEPARTMENT":"0021","EMPLOYES":[{"SERIALNO":"87777","NAME":"STRONG","TITLE":"DIRECTOR","SALARY":23000.00},{"SERIALNO":"22222","NAME":"SHORTSIGHT","TITLE":"SECRETARY","SALARY":5500.00}]} +{"DEPARTMENT":"0318","EMPLOYES":[{"SERIALNO":"74200","NAME":"BANCROFT","TITLE":"SALESMAN","SALARY":9600.00},{"SERIALNO":"24888","NAME":"PLUMHEAD","TITLE":"TYPIST","SALARY":2800.00},{"SERIALNO":"27845","NAME":"HONEY","TITLE":"SECRETARY","SALARY":4900.00},{"SERIALNO":"73452","NAME":"TONGHO","TITLE":"ENGINEER","SALARY":6800.00},{"SERIALNO":"74234","NAME":"WALTER","TITLE":"ENGINEER","SALARY":7400.00},{"SERIALNO":"77777","NAME":"SHRINKY","TITLE":"ADMINISTRATOR","SALARY":7500.00},{"SERIALNO":"70012","NAME":"WERTHER","TITLE":"DIRECTOR","SALARY":14500.00},{"SERIALNO":"78943","NAME":"MERCHANT","TITLE":"SALESMAN","SALARY":8700.00},{"SERIALNO":"73111","NAME":"WHEELFOR","TITLE":"SALESMAN","SALARY":10030.00}]} +{"DEPARTMENT":"0319","EMPLOYES":[{"SERIALNO":"76543","NAME":"BULLOZER","TITLE":"SALESMAN","SALARY":14800.00},{"SERIALNO":"40567","NAME":"QUINN","TITLE":"DIRECTOR","SALARY":14000.00},{"SERIALNO":"00137","NAME":"BROWNY","TITLE":"ENGINEER","SALARY":10500.00},{"SERIALNO":"12345","NAME":"KITTY","TITLE":"TYPIST","SALARY":3000.45},{"SERIALNO":"33333","NAME":"MONAPENNY","TITLE":"SECRETARY","SALARY":3800.00},{"SERIALNO":"00023","NAME":"MARTIN","TITLE":"ENGINEER","SALARY":10000.00},{"SERIALNO":"07654","NAME":"FUNNIGUY","TITLE":"ADMINISTRATOR","SALARY":8500.00},{"SERIALNO":"45678","NAME":"BUGHAPPY","TITLE":"PROGRAMMER","SALARY":8500.00},{"SERIALNO":"56789","NAME":"FODDERMAN","TITLE":"SALESMAN","SALARY":7000.00},{"SERIALNO":"55555","NAME":"MESSIFUL","TITLE":"SECRETARY","SALARY":5000.50},{"SERIALNO":"98765","NAME":"GOOSEPEN","TITLE":"ADMINISTRATOR","SALARY":4700.00}]} +{"DEPARTMENT":"2452","EMPLOYES":[{"SERIALNO":"34567","NAME":"BIGHEAD","TITLE":"SCIENTIST","SALARY":8000.00},{"SERIALNO":"31416","NAME":"ORELLY","TITLE":"ENGINEER","SALARY":13400.00},{"SERIALNO":"36666","NAME":"BIGHORN","TITLE":"SCIENTIST","SALARY":11000.00},{"SERIALNO":"02345","NAME":"SMITH","TITLE":"ENGINEER","SALARY":9000.00},{"SERIALNO":"11111","NAME":"CHERRY","TITLE":"SECRETARY","SALARY":4500.00}]} SELECT Bson_Make_Object(DEPARTMENT, TITLE, Bson_Array_Grp(Bson_Make_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT, TITLE; Bson_Make_Object(DEPARTMENT, TITLE, Bson_Array_Grp(Bson_Make_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) -{"DEPARTMENT":"0021","TITLE":"DIRECTOR","EMPLOYES":[{"SERIALNO":"87777","NAME":"STRONG","SALARY":23000.0000000000000000}]} -{"DEPARTMENT":"0021","TITLE":"SECRETARY","EMPLOYES":[{"SERIALNO":"22222","NAME":"SHORTSIGHT","SALARY":5500.0000000000000000}]} -{"DEPARTMENT":"0318","TITLE":"ADMINISTRATOR","EMPLOYES":[{"SERIALNO":"77777","NAME":"SHRINKY","SALARY":7500.0000000000000000}]} -{"DEPARTMENT":"0318","TITLE":"DIRECTOR","EMPLOYES":[{"SERIALNO":"70012","NAME":"WERTHER","SALARY":14500.0000000000000000}]} -{"DEPARTMENT":"0318","TITLE":"ENGINEER","EMPLOYES":[{"SERIALNO":"73452","NAME":"TONGHO","SALARY":6800.0000000000000000},{"SERIALNO":"74234","NAME":"WALTER","SALARY":7400.0000000000000000}]} -{"DEPARTMENT":"0318","TITLE":"SALESMAN","EMPLOYES":[{"SERIALNO":"74200","NAME":"BANCROFT","SALARY":9600.0000000000000000},{"SERIALNO":"78943","NAME":"MERCHANT","SALARY":8700.0000000000000000},{"SERIALNO":"73111","NAME":"WHEELFOR","SALARY":10030.0000000000000000}]} -{"DEPARTMENT":"0318","TITLE":"SECRETARY","EMPLOYES":[{"SERIALNO":"27845","NAME":"HONEY","SALARY":4900.0000000000000000}]} -{"DEPARTMENT":"0318","TITLE":"TYPIST","EMPLOYES":[{"SERIALNO":"24888","NAME":"PLUMHEAD","SALARY":2800.0000000000000000}]} -{"DEPARTMENT":"0319","TITLE":"ADMINISTRATOR","EMPLOYES":[{"SERIALNO":"98765","NAME":"GOOSEPEN","SALARY":4700.0000000000000000},{"SERIALNO":"07654","NAME":"FUNNIGUY","SALARY":8500.0000000000000000}]} -{"DEPARTMENT":"0319","TITLE":"DIRECTOR","EMPLOYES":[{"SERIALNO":"40567","NAME":"QUINN","SALARY":14000.0000000000000000}]} -{"DEPARTMENT":"0319","TITLE":"ENGINEER","EMPLOYES":[{"SERIALNO":"00023","NAME":"MARTIN","SALARY":10000.0000000000000000},{"SERIALNO":"00137","NAME":"BROWNY","SALARY":10500.0000000000000000}]} -{"DEPARTMENT":"0319","TITLE":"PROGRAMMER","EMPLOYES":[{"SERIALNO":"45678","NAME":"BUGHAPPY","SALARY":8500.0000000000000000}]} -{"DEPARTMENT":"0319","TITLE":"SALESMAN","EMPLOYES":[{"SERIALNO":"76543","NAME":"BULLOZER","SALARY":14800.0000000000000000},{"SERIALNO":"56789","NAME":"FODDERMAN","SALARY":7000.0000000000000000}]} -{"DEPARTMENT":"0319","TITLE":"SECRETARY","EMPLOYES":[{"SERIALNO":"33333","NAME":"MONAPENNY","SALARY":3800.0000000000000000},{"SERIALNO":"55555","NAME":"MESSIFUL","SALARY":5000.5000000000000000}]} -{"DEPARTMENT":"0319","TITLE":"TYPIST","EMPLOYES":[{"SERIALNO":"12345","NAME":"KITTY","SALARY":3000.4499999999998181}]} -{"DEPARTMENT":"2452","TITLE":"ENGINEER","EMPLOYES":[{"SERIALNO":"31416","NAME":"ORELLY","SALARY":13400.0000000000000000},{"SERIALNO":"02345","NAME":"SMITH","SALARY":9000.0000000000000000}]} -{"DEPARTMENT":"2452","TITLE":"SCIENTIST","EMPLOYES":[{"SERIALNO":"34567","NAME":"BIGHEAD","SALARY":8000.0000000000000000},{"SERIALNO":"36666","NAME":"BIGHORN","SALARY":11000.0000000000000000}]} -{"DEPARTMENT":"2452","TITLE":"SECRETARY","EMPLOYES":[{"SERIALNO":"11111","NAME":"CHERRY","SALARY":4500.0000000000000000}]} +{"DEPARTMENT":"0021","TITLE":"DIRECTOR","EMPLOYES":[{"SERIALNO":"87777","NAME":"STRONG","SALARY":23000.00}]} +{"DEPARTMENT":"0021","TITLE":"SECRETARY","EMPLOYES":[{"SERIALNO":"22222","NAME":"SHORTSIGHT","SALARY":5500.00}]} +{"DEPARTMENT":"0318","TITLE":"ADMINISTRATOR","EMPLOYES":[{"SERIALNO":"77777","NAME":"SHRINKY","SALARY":7500.00}]} +{"DEPARTMENT":"0318","TITLE":"DIRECTOR","EMPLOYES":[{"SERIALNO":"70012","NAME":"WERTHER","SALARY":14500.00}]} +{"DEPARTMENT":"0318","TITLE":"ENGINEER","EMPLOYES":[{"SERIALNO":"73452","NAME":"TONGHO","SALARY":6800.00},{"SERIALNO":"74234","NAME":"WALTER","SALARY":7400.00}]} +{"DEPARTMENT":"0318","TITLE":"SALESMAN","EMPLOYES":[{"SERIALNO":"74200","NAME":"BANCROFT","SALARY":9600.00},{"SERIALNO":"78943","NAME":"MERCHANT","SALARY":8700.00},{"SERIALNO":"73111","NAME":"WHEELFOR","SALARY":10030.00}]} +{"DEPARTMENT":"0318","TITLE":"SECRETARY","EMPLOYES":[{"SERIALNO":"27845","NAME":"HONEY","SALARY":4900.00}]} +{"DEPARTMENT":"0318","TITLE":"TYPIST","EMPLOYES":[{"SERIALNO":"24888","NAME":"PLUMHEAD","SALARY":2800.00}]} +{"DEPARTMENT":"0319","TITLE":"ADMINISTRATOR","EMPLOYES":[{"SERIALNO":"98765","NAME":"GOOSEPEN","SALARY":4700.00},{"SERIALNO":"07654","NAME":"FUNNIGUY","SALARY":8500.00}]} +{"DEPARTMENT":"0319","TITLE":"DIRECTOR","EMPLOYES":[{"SERIALNO":"40567","NAME":"QUINN","SALARY":14000.00}]} +{"DEPARTMENT":"0319","TITLE":"ENGINEER","EMPLOYES":[{"SERIALNO":"00023","NAME":"MARTIN","SALARY":10000.00},{"SERIALNO":"00137","NAME":"BROWNY","SALARY":10500.00}]} +{"DEPARTMENT":"0319","TITLE":"PROGRAMMER","EMPLOYES":[{"SERIALNO":"45678","NAME":"BUGHAPPY","SALARY":8500.00}]} +{"DEPARTMENT":"0319","TITLE":"SALESMAN","EMPLOYES":[{"SERIALNO":"76543","NAME":"BULLOZER","SALARY":14800.00},{"SERIALNO":"56789","NAME":"FODDERMAN","SALARY":7000.00}]} +{"DEPARTMENT":"0319","TITLE":"SECRETARY","EMPLOYES":[{"SERIALNO":"33333","NAME":"MONAPENNY","SALARY":3800.00},{"SERIALNO":"55555","NAME":"MESSIFUL","SALARY":5000.50}]} +{"DEPARTMENT":"0319","TITLE":"TYPIST","EMPLOYES":[{"SERIALNO":"12345","NAME":"KITTY","SALARY":3000.45}]} +{"DEPARTMENT":"2452","TITLE":"ENGINEER","EMPLOYES":[{"SERIALNO":"31416","NAME":"ORELLY","SALARY":13400.00},{"SERIALNO":"02345","NAME":"SMITH","SALARY":9000.00}]} +{"DEPARTMENT":"2452","TITLE":"SCIENTIST","EMPLOYES":[{"SERIALNO":"34567","NAME":"BIGHEAD","SALARY":8000.00},{"SERIALNO":"36666","NAME":"BIGHORN","SALARY":11000.00}]} +{"DEPARTMENT":"2452","TITLE":"SECRETARY","EMPLOYES":[{"SERIALNO":"11111","NAME":"CHERRY","SALARY":4500.00}]} SELECT Bson_Object_Grp(SALARY) FROM t3; ERROR HY000: Can't initialize function 'bson_object_grp'; This function requires 2 arguments (key, value) SELECT Bson_Object_Grp(NAME, SALARY) FROM t3; Bson_Object_Grp(NAME, SALARY) -{"":"MARTIN","ffffęp§@":"KITTY"} +{"BANCROFT":9600.00,"SMITH":9000.00,"MERCHANT":8700.00,"FUNNIGUY":8500.00,"BUGHAPPY":8500.00,"BIGHEAD":8000.00,"SHRINKY":7500.00,"WALTER":7400.00,"FODDERMAN":7000.00,"TONGHO":6800.00,"SHORTSIGHT":5500.00,"MESSIFUL":5000.50,"HONEY":4900.00,"GOOSEPEN":4700.00,"CHERRY":4500.00,"MONAPENNY":3800.00,"KITTY":3000.45,"PLUMHEAD":2800.00,"STRONG":23000.00,"BULLOZER":14800.00,"WERTHER":14500.00,"QUINN":14000.00,"ORELLY":13400.00,"BIGHORN":11000.00,"BROWNY":10500.00,"WHEELFOR":10030.00,"MARTIN":10000.00} SELECT Bson_Make_Object(DEPARTMENT, Bson_Object_Grp(NAME, SALARY) "Json_SALARIES") FROM t3 GROUP BY DEPARTMENT; Bson_Make_Object(DEPARTMENT, Bson_Object_Grp(NAME, SALARY) "Json_SALARIES") -{"DEPARTMENT":"0021","SALARIES":{"":"SHORTSIGHT"}} -{"DEPARTMENT":"0318","SALARIES":{"":"WHEELFOR"}} -{"DEPARTMENT":"0319","SALARIES":{"":"GOOSEPEN","ffffęp§@":"KITTY"}} -{"DEPARTMENT":"2452","SALARIES":{"":"CHERRY"}} +{"DEPARTMENT":"0021","SALARIES":{"STRONG":23000.00,"SHORTSIGHT":5500.00}} +{"DEPARTMENT":"0318","SALARIES":{"BANCROFT":9600.00,"PLUMHEAD":2800.00,"HONEY":4900.00,"TONGHO":6800.00,"WALTER":7400.00,"SHRINKY":7500.00,"WERTHER":14500.00,"MERCHANT":8700.00,"WHEELFOR":10030.00}} +{"DEPARTMENT":"0319","SALARIES":{"BULLOZER":14800.00,"QUINN":14000.00,"BROWNY":10500.00,"KITTY":3000.45,"MONAPENNY":3800.00,"MARTIN":10000.00,"FUNNIGUY":8500.00,"BUGHAPPY":8500.00,"FODDERMAN":7000.00,"MESSIFUL":5000.50,"GOOSEPEN":4700.00}} +{"DEPARTMENT":"2452","SALARIES":{"BIGHEAD":8000.00,"ORELLY":13400.00,"BIGHORN":11000.00,"SMITH":9000.00,"CHERRY":4500.00}} SELECT Bson_Array_Grp(NAME) FROM t3; Bson_Array_Grp(NAME) ["BANCROFT","SMITH","MERCHANT","FUNNIGUY","BUGHAPPY","BIGHEAD","SHRINKY","WALTER","FODDERMAN","TONGHO","SHORTSIGHT","MESSIFUL","HONEY","GOOSEPEN","CHERRY","MONAPENNY","KITTY","PLUMHEAD","STRONG","BULLOZER","WERTHER","QUINN","ORELLY","BIGHORN","BROWNY","WHEELFOR","MARTIN"] @@ -300,7 +303,7 @@ Bson_Object_Key(name, title) {"WHEELFOR":"SALESMAN"} SELECT Bson_Object_Grp(name, title) FROM t3 WHERE DEPARTMENT = 318; Bson_Object_Grp(name, title) -{"SALESMAN":"WHEELFOR","ADMINISTRATOR":"SHRINKY","ENGINEER":"TONGHO","SECRETARY":"HONEY","TYPIST":"PLUMHEAD","DIRECTOR":"WERTHER"} +{"BANCROFT":"SALESMAN","MERCHANT":"SALESMAN","SHRINKY":"ADMINISTRATOR","WALTER":"ENGINEER","TONGHO":"ENGINEER","HONEY":"SECRETARY","PLUMHEAD":"TYPIST","WERTHER":"DIRECTOR","WHEELFOR":"SALESMAN"} # # Test value getting UDF's # @@ -325,7 +328,7 @@ BsonGet_String(Bson_Make_Array(45,28,36,45,89),'3') 45 SELECT BsonGet_String(Bson_Make_Array(45,28,36,45,89),'["+"]') "list",'=' as "egal",BsonGet_String(Bson_Make_Array(45,28,36,45,89),'[+]') "sum"; list egal sum -45+28+36+45+89 = 243.00 +45+28+36+45+89 = 243 SELECT BsonGet_String(Bson_Make_Array(Bson_Make_Array(45,28),Bson_Make_Array(36,45,89)),'1.0'); BsonGet_String(Bson_Make_Array(Bson_Make_Array(45,28),Bson_Make_Array(36,45,89)),'1.0') 36 @@ -603,14 +606,12 @@ Bson_File('test/fx.json', 0) [{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]},{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]},{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]},{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":40},"ratings":[5,8,7]}] SELECT Bson_File('test/fx.json', '0'); Bson_File('test/fx.json', '0') -NULL -Warnings: -Warning 1105 +{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]} SELECT Bson_File('test/fx.json', '[?]'); Bson_File('test/fx.json', '[?]') NULL Warnings: -Warning 1105 +Warning 1105 Invalid function specification ? SELECT BsonGet_String(Bson_File('test/fx.json'), '1.*'); BsonGet_String(Bson_File('test/fx.json'), '1.*') {"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]} @@ -625,57 +626,33 @@ Price 5.65 SELECT Bson_Array_Add(Bson_File('test/fx.json', '2'), 6, 'ratings'); Bson_Array_Add(Bson_File('test/fx.json', '2'), 6, 'ratings') -NULL -Warnings: -Warning 1105 -Warning 1105 No sub-item at 'ratings' +{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4,6]} SELECT Bson_Array_Add(Bson_File('test/fx.json', '2'), 6, 1, 'ratings'); Bson_Array_Add(Bson_File('test/fx.json', '2'), 6, 1, 'ratings') -NULL -Warnings: -Warning 1105 -Warning 1105 No sub-item at 'ratings' +{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,6,4]} SELECT Bson_Array_Add(Bson_File('test/fx.json', '2'), 6, 'ratings', 1); Bson_Array_Add(Bson_File('test/fx.json', '2'), 6, 'ratings', 1) -NULL -Warnings: -Warning 1105 -Warning 1105 No sub-item at 'ratings' +{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,6,4]} SELECT Bson_Array_Add(Bson_File('test/fx.json', '2.ratings'), 6, 0); Bson_Array_Add(Bson_File('test/fx.json', '2.ratings'), 6, 0) -[6,null] -Warnings: -Warning 1105 +[6,2,4] SELECT Bson_Array_Delete(Bson_File('test/fx.json', '2'), 'ratings', 1); Bson_Array_Delete(Bson_File('test/fx.json', '2'), 'ratings', 1) -NULL -Warnings: -Warning 1105 -Warning 1105 No sub-item at 'ratings' +{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2]} SELECT Bson_Object_Add(Bson_File('test/fx.json', '2'), 'france' origin); Bson_Object_Add(Bson_File('test/fx.json', '2'), 'france' origin) -NULL -Warnings: -Warning 1105 -Warning 1105 First argument target is not an object +{"_id":7,"type":"food","item":"meat","origin":"france","ratings":[2,4]} SELECT Bson_Object_Add(Bson_File('test/fx.json', '2'), 70 H, 'size'); Bson_Object_Add(Bson_File('test/fx.json', '2'), 70 H, 'size') -NULL +{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]} Warnings: -Warning 1105 Warning 1105 No sub-item at 'size' SELECT Bson_Object_Add(Bson_File('test/fx.json', '3'), 70 H, 'size'); Bson_Object_Add(Bson_File('test/fx.json', '3'), 70 H, 'size') -NULL -Warnings: -Warning 1105 -Warning 1105 No sub-item at 'size' +{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":70},"ratings":[5,8,7]} SELECT Bson_Object_List(Bson_File('test/fx.json', '3.size')); Bson_Object_List(Bson_File('test/fx.json', '3.size')) -NULL -Warnings: -Warning 1105 -Warning 1105 First argument is not an object +["W","L","H"] # # Testing new functions # diff --git a/storage/connect/mysql-test/connect/t/bson_udf.inc b/storage/connect/mysql-test/connect/t/bson_udf.inc index 366f48e5861..c4722722ef7 100644 --- a/storage/connect/mysql-test/connect/t/bson_udf.inc +++ b/storage/connect/mysql-test/connect/t/bson_udf.inc @@ -22,6 +22,8 @@ if (!$HA_CONNECT_SO) { --eval CREATE FUNCTION bson_object_delete RETURNS STRING SONAME '$HA_CONNECT_SO'; --eval CREATE FUNCTION bson_object_list RETURNS STRING SONAME '$HA_CONNECT_SO'; --eval CREATE FUNCTION bson_object_values RETURNS STRING SONAME '$HA_CONNECT_SO'; +--eval CREATE FUNCTION bsonset_def_prec RETURNS INTEGER SONAME '$HA_CONNECT_SO'; +--eval CREATE FUNCTION bsonget_def_prec RETURNS INTEGER SONAME '$HA_CONNECT_SO'; --eval CREATE FUNCTION bsonset_grp_size RETURNS INTEGER SONAME '$HA_CONNECT_SO'; --eval CREATE FUNCTION bsonget_grp_size RETURNS INTEGER SONAME '$HA_CONNECT_SO'; --eval CREATE AGGREGATE FUNCTION bson_array_grp RETURNS STRING SONAME '$HA_CONNECT_SO'; diff --git a/storage/connect/mysql-test/connect/t/bson_udf.test b/storage/connect/mysql-test/connect/t/bson_udf.test index 84a3db6d061..0da2de38864 100644 --- a/storage/connect/mysql-test/connect/t/bson_udf.test +++ b/storage/connect/mysql-test/connect/t/bson_udf.test @@ -77,6 +77,7 @@ SELECT Bson_Object_Values('{"One":1,"Two":2,"Three":3}') "Value List"; --echo # --echo # Test UDF's with column arguments --echo # +SELECT Bsonset_Def_Prec(2); CREATE TABLE t2 ( ISBN CHAR(15), diff --git a/storage/connect/mysql-test/connect/t/bson_udf2.inc b/storage/connect/mysql-test/connect/t/bson_udf2.inc index ceddf8b0632..d06d7fac435 100644 --- a/storage/connect/mysql-test/connect/t/bson_udf2.inc +++ b/storage/connect/mysql-test/connect/t/bson_udf2.inc @@ -13,6 +13,8 @@ DROP FUNCTION bson_object_add; DROP FUNCTION bson_object_delete; DROP FUNCTION bson_object_list; DROP FUNCTION bson_object_values; +DROP FUNCTION bsonset_def_prec; +DROP FUNCTION bsonget_def_prec; DROP FUNCTION bsonset_grp_size; DROP FUNCTION bsonget_grp_size; DROP FUNCTION bson_array_grp; diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp index 389613351bb..9e1f006d605 100644 --- a/storage/connect/plugutil.cpp +++ b/storage/connect/plugutil.cpp @@ -628,7 +628,7 @@ size_t MakeOff(void* memp, void* ptr) DoThrow(999); } // endif ptr #endif // _DEBUG || DEVELOPMENT - return (size_t)((char*)ptr - (size_t)memp); + return (size_t)(((char*)ptr) - ((char*)memp)); } else return 0; diff --git a/storage/connect/tabbson.cpp b/storage/connect/tabbson.cpp index ba4380c5f89..db63b8e78db 100644 --- a/storage/connect/tabbson.cpp +++ b/storage/connect/tabbson.cpp @@ -719,7 +719,10 @@ void BCUTIL::SetJsonValue(PGLOBAL g, PVAL vp, PBVAL jvp) if (jvp) { vp->SetNull(false); - switch (jvp->Type) { + if (Jb) { + vp->SetValue_psz(Serialize(g, jvp, NULL, 0)); + Jb = false; + } else switch (jvp->Type) { case TYPE_STRG: case TYPE_INTG: case TYPE_BINT: @@ -727,29 +730,29 @@ void BCUTIL::SetJsonValue(PGLOBAL g, PVAL vp, PBVAL jvp) case TYPE_DTM: case TYPE_FLOAT: switch (vp->GetType()) { - case TYPE_STRING: - case TYPE_DATE: - case TYPE_DECIM: - vp->SetValue_psz(GetString(jvp)); - break; - case TYPE_INT: - case TYPE_SHORT: - case TYPE_TINY: - vp->SetValue(GetInteger(jvp)); - break; - case TYPE_BIGINT: - vp->SetValue(GetBigint(jvp)); - break; - case TYPE_DOUBLE: - vp->SetValue(GetDouble(jvp)); + case TYPE_STRING: + case TYPE_DATE: + case TYPE_DECIM: + vp->SetValue_psz(GetString(jvp)); + break; + case TYPE_INT: + case TYPE_SHORT: + case TYPE_TINY: + vp->SetValue(GetInteger(jvp)); + break; + case TYPE_BIGINT: + vp->SetValue(GetBigint(jvp)); + break; + case TYPE_DOUBLE: + vp->SetValue(GetDouble(jvp)); - if (jvp->Type == TYPE_DBL || jvp->Type == TYPE_FLOAT) - vp->SetPrec(jvp->Nd); + if (jvp->Type == TYPE_DBL || jvp->Type == TYPE_FLOAT) + vp->SetPrec(jvp->Nd); - break; - default: - sprintf(G->Message, "Unsupported column type %d", vp->GetType()); - throw 888; + break; + default: + sprintf(G->Message, "Unsupported column type %d", vp->GetType()); + throw 888; } // endswitch Type break; @@ -780,53 +783,59 @@ void BCUTIL::SetJsonValue(PGLOBAL g, PVAL vp, PBVAL jvp) /***********************************************************************/ /* MakeJson: Serialize the json item and set value to it. */ /***********************************************************************/ -PVAL BCUTIL::MakeBson(PGLOBAL g, PBVAL jsp) +PBVAL BCUTIL::MakeBson(PGLOBAL g, PBVAL jsp, int n) { - if (Cp->Value->IsTypeNum()) { - strcpy(g->Message, "Cannot make Json for a numeric column"); + PBVAL vlp, jvp = jsp; - if (!Cp->Warned) { - PushWarning(g, Tp); - Cp->Warned = true; - } // endif Warned + if (n < Cp->Nod - 1) { + if (jsp->Type == TYPE_JAR) { + int ars = GetArraySize(jsp); + PJNODE jnp = &Cp->Nodes[n]; - Cp->Value->Reset(); -#if 0 - } else if (Value->GetType() == TYPE_BIN) { - if ((unsigned)Value->GetClen() >= sizeof(BSON)) { - ulong len = Tjp->Lrecl ? Tjp->Lrecl : 500; - PBSON bsp = JbinAlloc(g, NULL, len, jsp); + jvp = NewVal(TYPE_JAR); + jnp->Op = OP_EQ; - strcat(bsp->Msg, " column"); - ((BINVAL*)Value)->SetBinValue(bsp, sizeof(BSON)); - } else { - strcpy(g->Message, "Column size too small"); - Value->SetValue_char(NULL, 0); - } // endif Clen -#endif // 0 - } else - Cp->Value->SetValue_psz(Serialize(g, jsp, NULL, 0)); + for (int i = 0; i < ars; i++) { + jnp->Rank = i; + vlp = GetRowValue(g, jsp, n); + AddArrayValue(jvp,DupVal(vlp)); + } // endfor i + + jnp->Op = OP_XX; + jnp->Rank = 0; + } else if (jsp->Type == TYPE_JOB) { + jvp = NewVal(TYPE_JOB); - return Cp->Value; -} // end of MakeJson + for (PBPR prp = GetObject(jsp); prp; prp = GetNext(prp)) { + vlp = GetRowValue(g, GetVlp(prp), n + 1); + SetKeyValue(jvp, vlp, MZP(prp->Key)); + } // endfor prp + + } // endif Type + + } // endif's + + Jb = true; + return jvp; +} // end of MakeBson /***********************************************************************/ -/* GetColumnValue: */ +/* GetRowValue: */ /***********************************************************************/ -PVAL BCUTIL::GetColumnValue(PGLOBAL g, PBVAL row, int i) +PBVAL BCUTIL::GetRowValue(PGLOBAL g, PBVAL row, int i) { int nod = Cp->Nod, n = nod - 1; JNODE *nodes = Cp->Nodes; - PVAL value = Cp->Value; PBVAL arp; PBVAL bvp = NULL; for (; i < nod && row; i++) { if (nodes[i].Op == OP_NUM) { - value->SetValue(row->Type == TYPE_JAR ? GetSize(row) : 1); - return(value); + bvp = NewVal(TYPE_INT); + bvp->N = (row->Type == TYPE_JAR) ? GetSize(row) : 1; + return(bvp); } else if (nodes[i].Op == OP_XX) { - return MakeBson(g, row); + return MakeBson(g, row, i); } else switch (row->Type) { case TYPE_JOB: if (!nodes[i].Key) { @@ -847,9 +856,9 @@ PVAL BCUTIL::GetColumnValue(PGLOBAL g, PBVAL row, int i) if (nodes[i].Op == OP_EQ) bvp = GetArrayValue(arp, nodes[i].Rank); else if (nodes[i].Op == OP_EXP) - return ExpandArray(g, arp, i); + return NewVal(ExpandArray(g, arp, i)); else - return CalculateArray(g, arp, i); + return NewVal(CalculateArray(g, arp, i)); } else { // Unexpected array, unwrap it as [0] @@ -871,6 +880,17 @@ PVAL BCUTIL::GetColumnValue(PGLOBAL g, PBVAL row, int i) } // endfor i + return bvp; +} // end of GetColumnValue + +/***********************************************************************/ +/* GetColumnValue: */ +/***********************************************************************/ +PVAL BCUTIL::GetColumnValue(PGLOBAL g, PBVAL row, int i) +{ + PVAL value = Cp->Value; + PBVAL bvp = GetRowValue(g, row, i); + SetJsonValue(g, value, bvp); return value; } // end of GetColumnValue diff --git a/storage/connect/tabbson.h b/storage/connect/tabbson.h index bb3f32bd945..adb02dd28e4 100644 --- a/storage/connect/tabbson.h +++ b/storage/connect/tabbson.h @@ -127,11 +127,13 @@ protected: class BCUTIL : public BTUTIL { public: // Constructor - BCUTIL(PGLOBAL G, PBSCOL cp, TDBBSN* tp) : BTUTIL(G, tp) { Cp = cp; } + BCUTIL(PGLOBAL G, PBSCOL cp, TDBBSN* tp) : BTUTIL(G, tp) + { Cp = cp; Jb = false; } // Utility functions void SetJsonValue(PGLOBAL g, PVAL vp, PBVAL jvp); - PVAL MakeBson(PGLOBAL g, PBVAL jsp); + PBVAL MakeBson(PGLOBAL g, PBVAL jsp, int n); + PBVAL GetRowValue(PGLOBAL g, PBVAL row, int i); PVAL GetColumnValue(PGLOBAL g, PBVAL row, int i); PVAL ExpandArray(PGLOBAL g, PBVAL arp, int n); PVAL CalculateArray(PGLOBAL g, PBVAL arp, int n); @@ -140,6 +142,7 @@ public: protected: // Member PBSCOL Cp; + bool Jb; }; // end of class BCUTIL /* -------------------------- TDBBSN class --------------------------- */ diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp index 19f721f692b..fb5a64c7d55 100644 --- a/storage/connect/tabjson.cpp +++ b/storage/connect/tabjson.cpp @@ -1024,8 +1024,14 @@ bool TDBJSN::OpenDB(PGLOBAL g) /* Lrecl is Ok. */ /*********************************************************************/ size_t linelen = Lrecl; + MODE mode = Mode; - //To_Line = (char*)PlugSubAlloc(g, NULL, linelen); + // Buffer must be allocated in g->Sarea + Mode = MODE_ANY; + Txfp->AllocateBuffer(g); + Mode = mode; + + //To_Line = (char*)PlugSubAlloc(g, NULL, linelen); //memset(To_Line, 0, linelen); To_Line = Txfp->GetBuf(); xtrc(1, "OpenJSN: R%hd mode=%d To_Line=%p\n", Tdb_No, Mode, To_Line); |