Commit a638f157 authored by Sergei Golubchik's avatar Sergei Golubchik

Merge branch 'bb-10.2-release' into 10.2

parents 6aa90974 ce3a2a68
......@@ -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
--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
......
--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 = '';
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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
......
#
# 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
#
# 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
#
# 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
--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
--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
--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
......@@ -10,3 +10,5 @@
#
##############################################################################
mdev_6832: wsrep_provider is read-only for security reasons
......@@ -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.
......@@ -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
......
......@@ -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(
......
......@@ -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);
}
......@@ -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 @@ PBVAL BDOC::ParseValue(int& i, PBVAL bvp)
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:
......
......@@ -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 @@ class BJSON : public BLOCK {
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 @@ class BDOC : public BJSON {
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 @@ class BDOC : public BJSON {
// 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
......
This diff is collapsed.
......@@ -81,6 +81,7 @@ typedef struct _jpn {
extern uint JsonGrpSize;
uint GetJsonGroupSize(void);
typedef class BJNX* PBJNX;
/*********************************************************************************/
......@@ -102,7 +103,7 @@ class BJNX : public BDOC {
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 @@ class BJNX : public BDOC {
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*);
......
......@@ -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),
......
......@@ -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());
......
......@@ -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';
......
......@@ -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),
......
......@@ -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;
......
......@@ -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;
......
......@@ -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
......
......@@ -127,11 +127,13 @@ class BTUTIL : public BDOC {
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 @@ class BCUTIL : public BTUTIL {
protected:
// Member
PBSCOL Cp;
bool Jb;
}; // end of class BCUTIL
/* -------------------------- TDBBSN class --------------------------- */
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment