summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2018-05-05 14:01:59 +0200
committerSergei Golubchik <serg@mariadb.org>2018-05-05 14:01:59 +0200
commit9989c26bc99c90d3047a7b3e20e0800b62f62300 (patch)
tree0a2b04288168bf08530568c94c326f2e9a98a397
parent39d248fa555350756a569d766f11eec4c65c5b16 (diff)
parent3c07ed141c2ed885dea13fbce8603afce6250590 (diff)
downloadmariadb-git-9989c26bc99c90d3047a7b3e20e0800b62f62300.tar.gz
Merge branch '10.0' into 10.1
-rw-r--r--.gitattributes1
-rw-r--r--mysql-test/lib/My/SafeProcess/safe_process.cc14
-rw-r--r--mysql-test/r/connect_debug.result5
-rw-r--r--mysql-test/r/sp-innodb.result34
-rw-r--r--mysql-test/r/subselect_sj.result26
-rw-r--r--mysql-test/r/subselect_sj_jcl6.result26
-rw-r--r--mysql-test/suite/parts/inc/part_alter_values.inc2
-rw-r--r--mysql-test/suite/parts/r/partition_alter_innodb.result2
-rw-r--r--mysql-test/suite/parts/r/partition_alter_maria.result2
-rw-r--r--mysql-test/suite/parts/r/partition_alter_myisam.result2
-rw-r--r--mysql-test/t/connect_debug.test12
-rw-r--r--mysql-test/t/sp-innodb.test42
-rw-r--r--mysql-test/t/subselect_sj.test30
-rw-r--r--pcre/AUTHORS6
-rw-r--r--pcre/ChangeLog53
-rw-r--r--pcre/INSTALL320
-rw-r--r--pcre/LICENCE6
-rw-r--r--pcre/NEWS6
-rw-r--r--pcre/NON-AUTOTOOLS-BUILD15
-rw-r--r--pcre/configure.ac26
-rw-r--r--pcre/doc/html/NON-AUTOTOOLS-BUILD.txt15
-rw-r--r--pcre/pcre.h.in8
-rw-r--r--pcre/pcre_compile.c2
-rw-r--r--pcre/pcre_dfa_exec.c4
-rw-r--r--pcre/pcre_exec.c8
-rw-r--r--pcre/pcre_jit_compile.c407
-rw-r--r--pcre/pcregrep.c55
-rw-r--r--pcre/pcreposix.c6
-rw-r--r--pcre/testdata/testinput28
-rw-r--r--pcre/testdata/testinput56
-rw-r--r--pcre/testdata/testoutput216
-rw-r--r--pcre/testdata/testoutput58
-rw-r--r--sql-common/client.c30
-rw-r--r--sql/item.cc10
-rw-r--r--sql/item.h1
-rw-r--r--sql/item_cmpfunc.cc42
-rw-r--r--sql/item_func.cc3
-rw-r--r--sql/item_func.h8
-rw-r--r--sql/item_row.cc1
-rw-r--r--sql/item_sum.cc3
-rw-r--r--sql/opt_subselect.cc26
-rw-r--r--sql/sql_acl.cc1
-rw-r--r--sql/sql_base.cc3
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_select.cc6
-rw-r--r--storage/connect/CMakeLists.txt9
-rw-r--r--storage/connect/Client.java27
-rw-r--r--storage/connect/JavaWrappers.jarbin44053 -> 19192 bytes
-rw-r--r--storage/connect/JdbcInterface.java54
-rw-r--r--storage/connect/PostgresqlInterface.java5
-rw-r--r--storage/connect/array.cpp22
-rw-r--r--storage/connect/blkfil.cpp8
-rw-r--r--storage/connect/block.h4
-rw-r--r--storage/connect/checklvl.h3
-rw-r--r--storage/connect/cmgoconn.cpp18
-rw-r--r--storage/connect/colblk.cpp9
-rw-r--r--storage/connect/connect.cc43
-rw-r--r--storage/connect/csort.cpp16
-rw-r--r--storage/connect/domdoc.cpp3
-rw-r--r--storage/connect/filamap.cpp32
-rw-r--r--storage/connect/filamdbf.cpp12
-rw-r--r--storage/connect/filamfix.cpp68
-rw-r--r--storage/connect/filamgz.cpp20
-rw-r--r--storage/connect/filamtxt.cpp71
-rwxr-xr-xstorage/connect/filamvct.cpp162
-rw-r--r--storage/connect/filamzip.cpp8
-rw-r--r--storage/connect/filter.cpp36
-rw-r--r--storage/connect/fmdlex.c8
-rw-r--r--storage/connect/global.h11
-rw-r--r--storage/connect/ha_connect.cc332
-rw-r--r--storage/connect/inihandl.cpp54
-rw-r--r--storage/connect/javaconn.cpp6
-rw-r--r--storage/connect/jdbconn.cpp365
-rw-r--r--storage/connect/jdbconn.h11
-rw-r--r--storage/connect/jmgfam.cpp2
-rw-r--r--storage/connect/jmgoconn.cpp14
-rw-r--r--storage/connect/json.cpp41
-rw-r--r--storage/connect/json.h8
-rw-r--r--storage/connect/jsonudf.cpp862
-rw-r--r--storage/connect/jsonudf.h4
-rw-r--r--storage/connect/libdoc.cpp98
-rw-r--r--storage/connect/macutil.cpp4
-rw-r--r--storage/connect/mongo.cpp4
-rw-r--r--storage/connect/mycat.cc34
-rw-r--r--storage/connect/myconn.cpp10
-rw-r--r--storage/connect/mysql-test/connect/r/jdbc_postgresql.result35
-rw-r--r--storage/connect/mysql-test/connect/r/json_java_2.result7
-rw-r--r--storage/connect/mysql-test/connect/r/json_java_3.result4
-rw-r--r--storage/connect/mysql-test/connect/r/json_mongo_c.result2
-rw-r--r--storage/connect/mysql-test/connect/r/json_udf.result10
-rw-r--r--storage/connect/mysql-test/connect/r/json_udf_bin.result3
-rw-r--r--storage/connect/mysql-test/connect/r/mongo_c.result2
-rw-r--r--storage/connect/mysql-test/connect/r/mongo_java_2.result4
-rw-r--r--storage/connect/mysql-test/connect/r/mongo_java_3.result4
-rw-r--r--storage/connect/mysql-test/connect/r/tbl_thread.result6
-rw-r--r--storage/connect/mysql-test/connect/r/vcol.result29
-rw-r--r--storage/connect/mysql-test/connect/std_data/JavaWrappers.jarbin0 -> 19192 bytes
-rw-r--r--storage/connect/mysql-test/connect/std_data/Mongo2.jarbin3461358 -> 623907 bytes
-rw-r--r--storage/connect/mysql-test/connect/std_data/Mongo3.jarbin1705776 -> 1705776 bytes
-rw-r--r--storage/connect/mysql-test/connect/t/jdbc_postgresql.test33
-rw-r--r--storage/connect/mysql-test/connect/t/jdbconn.inc7
-rw-r--r--storage/connect/mysql-test/connect/t/json_udf.test6
-rw-r--r--storage/connect/mysql-test/connect/t/mongo.inc4
-rw-r--r--storage/connect/mysql-test/connect/t/mongo_test.inc8
-rw-r--r--storage/connect/mysql-test/connect/t/tbl_thread.test6
-rw-r--r--storage/connect/mysql-test/connect/t/vcol.test31
-rw-r--r--storage/connect/odbconn.cpp103
-rw-r--r--storage/connect/plgdbsem.h3
-rw-r--r--storage/connect/plgdbutl.cpp143
-rw-r--r--storage/connect/plugutil.cpp28
-rw-r--r--storage/connect/preparse.h2
-rw-r--r--storage/connect/reldef.cpp2
-rw-r--r--storage/connect/tabcol.cpp8
-rw-r--r--storage/connect/tabdos.cpp59
-rw-r--r--storage/connect/tabdos.h1
-rw-r--r--storage/connect/tabext.cpp6
-rw-r--r--storage/connect/tabfix.cpp8
-rw-r--r--storage/connect/tabfmt.cpp36
-rw-r--r--storage/connect/tabjdbc.cpp35
-rw-r--r--storage/connect/tabjdbc.h2
-rw-r--r--storage/connect/tabjson.cpp607
-rw-r--r--storage/connect/tabjson.h44
-rw-r--r--storage/connect/table.cpp16
-rw-r--r--storage/connect/tabmac.cpp4
-rw-r--r--storage/connect/tabmul.cpp22
-rw-r--r--storage/connect/tabmysql.cpp28
-rw-r--r--storage/connect/tabodbc.cpp20
-rw-r--r--storage/connect/tabpivot.cpp2
-rw-r--r--storage/connect/tabsys.cpp12
-rw-r--r--storage/connect/tabtbl.cpp41
-rw-r--r--storage/connect/tabutil.cpp8
-rw-r--r--storage/connect/tabvct.cpp8
-rw-r--r--storage/connect/tabwmi.cpp4
-rw-r--r--storage/connect/tabxml.cpp26
-rw-r--r--storage/connect/user_connect.cc2
-rw-r--r--storage/connect/valblk.cpp2
-rw-r--r--storage/connect/value.cpp50
-rwxr-xr-xstorage/connect/xindex.cpp88
-rw-r--r--storage/connect/xobject.cpp5
-rw-r--r--storage/innobase/handler/handler0alter.cc51
-rw-r--r--storage/innobase/include/univ.i2
-rw-r--r--storage/innobase/row/row0import.cc7
-rw-r--r--storage/innobase/row/row0log.cc138
-rw-r--r--storage/innobase/row/row0mysql.cc8
-rw-r--r--storage/perfschema/ha_perfschema.cc2
-rw-r--r--storage/tokudb/CMakeLists.txt2
-rw-r--r--storage/tokudb/PerconaFT/.clang-format36
-rw-r--r--storage/tokudb/PerconaFT/CMakeLists.txt6
-rw-r--r--storage/tokudb/PerconaFT/README.md29
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-ops.cc91
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/ft-clock-test.cc4
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/log-test4.cc2
-rw-r--r--storage/tokudb/PerconaFT/portability/tests/test-max-data.cc2
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_instrumentation.h2
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_portability.h2
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_pthread.h6
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_race_tools.h2
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_time.h5
-rw-r--r--storage/tokudb/PerconaFT/src/tests/checkpoint_stress.cc2
-rw-r--r--storage/tokudb/PerconaFT/src/tests/directory_lock.cc2
-rw-r--r--storage/tokudb/PerconaFT/src/tests/loader-cleanup-test.cc18
-rw-r--r--storage/tokudb/PerconaFT/src/tests/recover-del-multiple-abort.cc6
-rw-r--r--storage/tokudb/PerconaFT/src/tests/recover-del-multiple-srcdb-fdelete-all.cc6
-rw-r--r--storage/tokudb/PerconaFT/src/tests/recover-del-multiple.cc6
-rw-r--r--storage/tokudb/PerconaFT/src/tests/recover-put-multiple-abort.cc6
-rw-r--r--storage/tokudb/PerconaFT/src/tests/recovery_fileops_unit.cc4
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test-prepare3.cc1
-rw-r--r--storage/tokudb/hatoku_hton.cc20
-rw-r--r--storage/xtradb/CMakeLists.txt10
-rw-r--r--storage/xtradb/dict/dict0dict.cc47
-rw-r--r--storage/xtradb/dict/dict0mem.cc2
-rw-r--r--storage/xtradb/fts/fts0fts.cc14
-rw-r--r--storage/xtradb/fts/fts0que.cc17
-rw-r--r--storage/xtradb/handler/ha_innodb.cc8
-rw-r--r--storage/xtradb/include/univ.i4
-rw-r--r--storage/xtradb/include/ut0ut.h11
-rw-r--r--storage/xtradb/row/row0log.cc126
-rw-r--r--storage/xtradb/ut/ut0ut.cc30
178 files changed, 3763 insertions, 2409 deletions
diff --git a/.gitattributes b/.gitattributes
index 852eec4d638..9d638481a84 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -25,6 +25,7 @@ pcre/testdata/greppatN4 -text
*.MYD binary
*.MYI binary
*.class binary
+*.jar binary
*.c diff=cpp
*.h diff=cpp
diff --git a/mysql-test/lib/My/SafeProcess/safe_process.cc b/mysql-test/lib/My/SafeProcess/safe_process.cc
index 8f18b137b87..f8bed800114 100644
--- a/mysql-test/lib/My/SafeProcess/safe_process.cc
+++ b/mysql-test/lib/My/SafeProcess/safe_process.cc
@@ -89,7 +89,7 @@ static void die(const char* fmt, ...)
}
-static void kill_child(bool was_killed)
+static int kill_child(bool was_killed)
{
int status= 0;
@@ -108,15 +108,15 @@ static void kill_child(bool was_killed)
exit_code= WEXITSTATUS(status);
message("Child exit: %d", exit_code);
// Exit with exit status of the child
- exit(exit_code);
+ return exit_code;
}
if (WIFSIGNALED(status))
message("Child killed by signal: %d", WTERMSIG(status));
- exit(exit_code);
+ return exit_code;
}
- exit(5);
+ return 5;
}
@@ -136,7 +136,7 @@ extern "C" void handle_signal(int sig)
terminated= 1;
if (child_pid > 0)
- kill_child(sig == SIGCHLD);
+ _exit(kill_child(sig == SIGCHLD));
// Ignore further signals
signal(SIGTERM, SIG_IGN);
@@ -300,8 +300,6 @@ int main(int argc, char* const argv[] )
/* Wait for parent or child to die */
sleep(1);
}
- kill_child(0);
-
- return 4;
+ return kill_child(0);
}
diff --git a/mysql-test/r/connect_debug.result b/mysql-test/r/connect_debug.result
new file mode 100644
index 00000000000..0452b238db9
--- /dev/null
+++ b/mysql-test/r/connect_debug.result
@@ -0,0 +1,5 @@
+set @old_dbug=@@global.debug_dbug;
+set global debug_dbug='+d,auth_disconnect';
+create user 'bad' identified by 'worse';
+set global debug_dbug=@old_dbug;
+drop user bad;
diff --git a/mysql-test/r/sp-innodb.result b/mysql-test/r/sp-innodb.result
index b3405705698..8dee74040b3 100644
--- a/mysql-test/r/sp-innodb.result
+++ b/mysql-test/r/sp-innodb.result
@@ -130,3 +130,37 @@ SET @@innodb_lock_wait_timeout= @innodb_lock_wait_timeout_saved;
#
# BUG 16041903: End of test case
#
+#
+# MDEV-15035: SP using query with outer join and a parameter
+# in ON expression
+#
+CREATE TABLE t1 (
+id int NOT NULL,
+PRIMARY KEY (id)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 (
+id int NOT NULL,
+id_foo int NOT NULL,
+PRIMARY KEY (id)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1, 1);
+DROP PROCEDURE IF EXISTS test_proc;
+CREATE PROCEDURE test_proc(IN param int)
+LANGUAGE SQL
+READS SQL DATA
+BEGIN
+SELECT DISTINCT f.id
+FROM t1 f
+LEFT OUTER JOIN t2 b ON b.id_foo = f.id
+WHERE (param <> 0 OR b.id IS NOT NULL);
+END|
+CALL test_proc(0);
+id
+1
+CALL test_proc(1);
+id
+1
+2
+DROP PROCEDURE IF EXISTS test_proc;
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result
index 643034f452d..77dea34e2ab 100644
--- a/mysql-test/r/subselect_sj.result
+++ b/mysql-test/r/subselect_sj.result
@@ -3161,4 +3161,30 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2`,`test`.`t4`.`c4` AS `c4` from `test`.`t1` left join (`test`.`t2` join `test`.`t4`) on(((`test`.`t2`.`c2` = `test`.`t1`.`c1`) and <in_optimizer>(`test`.`t1`.`c1`,<exists>(select `test`.`t3`.`c3` from `test`.`t3` where (<cache>(`test`.`t2`.`c2`) = `test`.`t3`.`c3`))))) where 1
DROP TABLE t1,t2,t3,t4;
+#
+# MDEV-13699: Assertion `!new_field->field_name.str ||
+# strlen(new_field->field_name.str) == new_field->field_name.length'
+# failed in create_tmp_table on 2nd execution of PS with semijoin
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (c INT);
+CREATE ALGORITHM=MERGE VIEW v3 AS SELECT * FROM t3;
+INSERT INTO t3 VALUES (5),(6);
+PREPARE stmt FROM
+"SELECT * FROM t1
+ WHERE EXISTS (
+ SELECT * FROM t2 WHERE t1.a IN ( SELECT c AS fld FROM v3 )
+ )";
+EXECUTE stmt;
+a
+EXECUTE stmt;
+a
+EXECUTE stmt;
+a
+drop view v3;
+drop table t1,t2,t3;
+# End of 5.5 test
set optimizer_switch=@subselect_sj_tmp;
diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result
index 6d9dc37345a..0741eb236ea 100644
--- a/mysql-test/r/subselect_sj_jcl6.result
+++ b/mysql-test/r/subselect_sj_jcl6.result
@@ -3175,6 +3175,32 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2`,`test`.`t4`.`c4` AS `c4` from `test`.`t1` left join (`test`.`t2` join `test`.`t4`) on(((`test`.`t2`.`c2` = `test`.`t1`.`c1`) and <in_optimizer>(`test`.`t1`.`c1`,<exists>(select `test`.`t3`.`c3` from `test`.`t3` where (<cache>(`test`.`t2`.`c2`) = `test`.`t3`.`c3`))))) where 1
DROP TABLE t1,t2,t3,t4;
+#
+# MDEV-13699: Assertion `!new_field->field_name.str ||
+# strlen(new_field->field_name.str) == new_field->field_name.length'
+# failed in create_tmp_table on 2nd execution of PS with semijoin
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (c INT);
+CREATE ALGORITHM=MERGE VIEW v3 AS SELECT * FROM t3;
+INSERT INTO t3 VALUES (5),(6);
+PREPARE stmt FROM
+"SELECT * FROM t1
+ WHERE EXISTS (
+ SELECT * FROM t2 WHERE t1.a IN ( SELECT c AS fld FROM v3 )
+ )";
+EXECUTE stmt;
+a
+EXECUTE stmt;
+a
+EXECUTE stmt;
+a
+drop view v3;
+drop table t1,t2,t3;
+# End of 5.5 test
set optimizer_switch=@subselect_sj_tmp;
#
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
diff --git a/mysql-test/suite/parts/inc/part_alter_values.inc b/mysql-test/suite/parts/inc/part_alter_values.inc
index 1b0605ff57b..ac69169a9ca 100644
--- a/mysql-test/suite/parts/inc/part_alter_values.inc
+++ b/mysql-test/suite/parts/inc/part_alter_values.inc
@@ -39,7 +39,7 @@ DROP TABLE t1;
#
# MDEV-15456 Server crashes upon adding or dropping a partition in ALTER under LOCK TABLE after ER_SAME_NAME_PARTITION
#
-create table t1 (i int) partition by range(i) (partition p0 values less than (10));
+--eval create table t1 (i int) engine=$engine partition by range(i) (partition p0 values less than (10))
lock table t1 write;
--error ER_SAME_NAME_PARTITION
alter table t1 add partition (partition p0 values less than (20));
diff --git a/mysql-test/suite/parts/r/partition_alter_innodb.result b/mysql-test/suite/parts/r/partition_alter_innodb.result
index 08f0c321119..87c113a2720 100644
--- a/mysql-test/suite/parts/r/partition_alter_innodb.result
+++ b/mysql-test/suite/parts/r/partition_alter_innodb.result
@@ -47,7 +47,7 @@ PARTITION p3 VALUES IN (4,5,6)
);
ERROR HY000: Syntax error: LIST PARTITIONING requires definition of VALUES IN for each partition
DROP TABLE t1;
-create table t1 (i int) partition by range(i) (partition p0 values less than (10));
+create table t1 (i int) engine=InnoDB partition by range(i) (partition p0 values less than (10));
lock table t1 write;
alter table t1 add partition (partition p0 values less than (20));
ERROR HY000: Duplicate partition name p0
diff --git a/mysql-test/suite/parts/r/partition_alter_maria.result b/mysql-test/suite/parts/r/partition_alter_maria.result
index 5e53dc99db8..5f1f882d2ea 100644
--- a/mysql-test/suite/parts/r/partition_alter_maria.result
+++ b/mysql-test/suite/parts/r/partition_alter_maria.result
@@ -69,7 +69,7 @@ PARTITION p3 VALUES IN (4,5,6)
);
ERROR HY000: Syntax error: LIST PARTITIONING requires definition of VALUES IN for each partition
DROP TABLE t1;
-create table t1 (i int) partition by range(i) (partition p0 values less than (10));
+create table t1 (i int) engine=Aria partition by range(i) (partition p0 values less than (10));
lock table t1 write;
alter table t1 add partition (partition p0 values less than (20));
ERROR HY000: Duplicate partition name p0
diff --git a/mysql-test/suite/parts/r/partition_alter_myisam.result b/mysql-test/suite/parts/r/partition_alter_myisam.result
index 490d4af2cb5..4098ebba473 100644
--- a/mysql-test/suite/parts/r/partition_alter_myisam.result
+++ b/mysql-test/suite/parts/r/partition_alter_myisam.result
@@ -42,7 +42,7 @@ PARTITION p3 VALUES IN (4,5,6)
);
ERROR HY000: Syntax error: LIST PARTITIONING requires definition of VALUES IN for each partition
DROP TABLE t1;
-create table t1 (i int) partition by range(i) (partition p0 values less than (10));
+create table t1 (i int) engine=MyISAM partition by range(i) (partition p0 values less than (10));
lock table t1 write;
alter table t1 add partition (partition p0 values less than (20));
ERROR HY000: Duplicate partition name p0
diff --git a/mysql-test/t/connect_debug.test b/mysql-test/t/connect_debug.test
new file mode 100644
index 00000000000..299b605b2cd
--- /dev/null
+++ b/mysql-test/t/connect_debug.test
@@ -0,0 +1,12 @@
+source include/have_debug.inc;
+set @old_dbug=@@global.debug_dbug;
+
+#
+# use after free if need plugin change and auth aborted
+#
+set global debug_dbug='+d,auth_disconnect';
+create user 'bad' identified by 'worse';
+--error 1
+--exec $MYSQL --default-auth=mysql_old_password --user=bad --password=worse
+set global debug_dbug=@old_dbug;
+drop user bad;
diff --git a/mysql-test/t/sp-innodb.test b/mysql-test/t/sp-innodb.test
index 23715166a02..e44a853e713 100644
--- a/mysql-test/t/sp-innodb.test
+++ b/mysql-test/t/sp-innodb.test
@@ -158,5 +158,47 @@ SET @@innodb_lock_wait_timeout= @innodb_lock_wait_timeout_saved;
--echo # BUG 16041903: End of test case
--echo #
+--echo #
+--echo # MDEV-15035: SP using query with outer join and a parameter
+--echo # in ON expression
+--echo #
+
+CREATE TABLE t1 (
+ id int NOT NULL,
+ PRIMARY KEY (id)
+) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES (1), (2);
+
+CREATE TABLE t2 (
+ id int NOT NULL,
+ id_foo int NOT NULL,
+ PRIMARY KEY (id)
+) ENGINE=InnoDB;
+
+INSERT INTO t2 VALUES (1, 1);
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS test_proc;
+--enable_warnings
+
+DELIMITER |;
+CREATE PROCEDURE test_proc(IN param int)
+LANGUAGE SQL
+READS SQL DATA
+BEGIN
+ SELECT DISTINCT f.id
+ FROM t1 f
+ LEFT OUTER JOIN t2 b ON b.id_foo = f.id
+ WHERE (param <> 0 OR b.id IS NOT NULL);
+END|
+DELIMITER ;|
+
+CALL test_proc(0);
+CALL test_proc(1);
+
+DROP PROCEDURE IF EXISTS test_proc;
+DROP TABLE t1, t2;
+
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test
index f90f1e2e927..623e414310a 100644
--- a/mysql-test/t/subselect_sj.test
+++ b/mysql-test/t/subselect_sj.test
@@ -2845,5 +2845,35 @@ eval EXPLAIN EXTENDED $q2;
DROP TABLE t1,t2,t3,t4;
+--echo #
+--echo # MDEV-13699: Assertion `!new_field->field_name.str ||
+--echo # strlen(new_field->field_name.str) == new_field->field_name.length'
+--echo # failed in create_tmp_table on 2nd execution of PS with semijoin
+--echo #
+
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (3),(4);
+
+CREATE TABLE t3 (c INT);
+CREATE ALGORITHM=MERGE VIEW v3 AS SELECT * FROM t3;
+INSERT INTO t3 VALUES (5),(6);
+
+PREPARE stmt FROM
+ "SELECT * FROM t1
+ WHERE EXISTS (
+ SELECT * FROM t2 WHERE t1.a IN ( SELECT c AS fld FROM v3 )
+ )";
+EXECUTE stmt;
+EXECUTE stmt;
+EXECUTE stmt;
+
+drop view v3;
+drop table t1,t2,t3;
+
+--echo # End of 5.5 test
+
# The following command must be the last one the file
set optimizer_switch=@subselect_sj_tmp;
diff --git a/pcre/AUTHORS b/pcre/AUTHORS
index 291657caef1..eb9b1a44b34 100644
--- a/pcre/AUTHORS
+++ b/pcre/AUTHORS
@@ -8,7 +8,7 @@ Email domain: cam.ac.uk
University of Cambridge Computing Service,
Cambridge, England.
-Copyright (c) 1997-2017 University of Cambridge
+Copyright (c) 1997-2018 University of Cambridge
All rights reserved
@@ -19,7 +19,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2010-2017 Zoltan Herczeg
+Copyright(c) 2010-2018 Zoltan Herczeg
All rights reserved.
@@ -30,7 +30,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2009-2017 Zoltan Herczeg
+Copyright(c) 2009-2018 Zoltan Herczeg
All rights reserved.
diff --git a/pcre/ChangeLog b/pcre/ChangeLog
index 590a7542885..7b53195f6a6 100644
--- a/pcre/ChangeLog
+++ b/pcre/ChangeLog
@@ -4,6 +4,59 @@ ChangeLog for PCRE
Note that the PCRE 8.xx series (PCRE1) is now in a bugfix-only state. All
development is happening in the PCRE2 10.xx series.
+
+Version 8.42 20-March-2018
+--------------------------
+
+1. Fixed a MIPS issue in the JIT compiler reported by Joshua Kinard.
+
+2. Fixed outdated real_pcre definitions in pcre.h.in (patch by Evgeny Kotkov).
+
+3. pcregrep was truncating components of file names to 128 characters when
+processing files with the -r option, and also (some very odd code) truncating
+path names to 512 characters. There is now a check on the absolute length of
+full path file names, which may be up to 2047 characters long.
+
+4. Using pcre_dfa_exec(), in UTF mode when UCP support was not defined, there
+was the possibility of a false positive match when caselessly matching a "not
+this character" item such as [^\x{1234}] (with a code point greater than 127)
+because the "other case" variable was not being initialized.
+
+5. Although pcre_jit_exec checks whether the pattern is compiled
+in a given mode, it was also expected that at least one mode is available.
+This is fixed and pcre_jit_exec returns with PCRE_ERROR_JIT_BADOPTION
+when the pattern is not optimized by JIT at all.
+
+6. The line number and related variables such as match counts in pcregrep
+were all int variables, causing overflow when files with more than 2147483647
+lines were processed (assuming 32-bit ints). They have all been changed to
+unsigned long ints.
+
+7. If a backreference with a minimum repeat count of zero was first in a
+pattern, apart from assertions, an incorrect first matching character could be
+recorded. For example, for the pattern /(?=(a))\1?b/, "b" was incorrectly set
+as the first character of a match.
+
+8. Fix out-of-bounds read for partial matching of /./ against an empty string
+when the newline type is CRLF.
+
+9. When matching using the the REG_STARTEND feature of the POSIX API with a
+non-zero starting offset, unset capturing groups with lower numbers than a
+group that did capture something were not being correctly returned as "unset"
+(that is, with offset values of -1).
+
+10. Matching the pattern /(*UTF)\C[^\v]+\x80/ against an 8-bit string
+containing multi-code-unit characters caused bad behaviour and possibly a
+crash. This issue was fixed for other kinds of repeat in release 8.37 by change
+38, but repeating character classes were overlooked.
+
+11. A small fix to pcregrep to avoid compiler warnings for -Wformat-overflow=2.
+
+12. Added --enable-jit=auto support to configure.ac.
+
+13. Fix misleading error message in configure.ac.
+
+
Version 8.41 05-July-2017
-------------------------
diff --git a/pcre/INSTALL b/pcre/INSTALL
index 2099840756e..8865734f81b 100644
--- a/pcre/INSTALL
+++ b/pcre/INSTALL
@@ -1,8 +1,8 @@
Installation Instructions
*************************
-Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
-Inc.
+ Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software
+Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
@@ -12,97 +12,96 @@ without warranty of any kind.
Basic Installation
==================
- Briefly, the shell command `./configure && make && make install'
+ Briefly, the shell command './configure && make && make install'
should configure, build, and install this package. The following
-more-detailed instructions are generic; see the `README' file for
+more-detailed instructions are generic; see the 'README' file for
instructions specific to this package. Some packages provide this
-`INSTALL' file but do not implement all of the features documented
+'INSTALL' file but do not implement all of the features documented
below. The lack of an optional feature in a given package is not
necessarily a bug. More recommendations for GNU packages can be found
in *note Makefile Conventions: (standards)Makefile Conventions.
- The `configure' shell script attempts to guess correct values for
+ The 'configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions. Finally, it creates a shell script `config.status' that
+those values to create a 'Makefile' in each directory of the package.
+It may also create one or more '.h' files containing system-dependent
+definitions. Finally, it creates a shell script 'config.status' that
you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
+file 'config.log' containing compiler output (useful mainly for
+debugging 'configure').
- It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring. Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.
+ It can also use an optional file (typically called 'config.cache' and
+enabled with '--cache-file=config.cache' or simply '-C') that saves the
+results of its tests to speed up reconfiguring. Caching is disabled by
+default to prevent problems with accidental use of stale cache files.
If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
+to figure out how 'configure' could check whether to do them, and mail
+diffs or instructions to the address given in the 'README' so they can
be considered for the next release. If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
+some point 'config.cache' contains results you don't want to keep, you
may remove or edit it.
- The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'. You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
+ The file 'configure.ac' (or 'configure.in') is used to create
+'configure' by a program called 'autoconf'. You need 'configure.ac' if
+you want to change it or regenerate 'configure' using a newer version of
+'autoconf'.
The simplest way to compile this package is:
- 1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system.
+ 1. 'cd' to the directory containing the package's source code and type
+ './configure' to configure the package for your system.
- Running `configure' might take a while. While running, it prints
+ Running 'configure' might take a while. While running, it prints
some messages telling which features it is checking for.
- 2. Type `make' to compile the package.
+ 2. Type 'make' to compile the package.
- 3. Optionally, type `make check' to run any self-tests that come with
+ 3. Optionally, type 'make check' to run any self-tests that come with
the package, generally using the just-built uninstalled binaries.
- 4. Type `make install' to install the programs and any data files and
+ 4. Type 'make install' to install the programs and any data files and
documentation. When installing into a prefix owned by root, it is
recommended that the package be configured and built as a regular
- user, and only the `make install' phase executed with root
+ user, and only the 'make install' phase executed with root
privileges.
- 5. Optionally, type `make installcheck' to repeat any self-tests, but
+ 5. Optionally, type 'make installcheck' to repeat any self-tests, but
this time using the binaries in their final installed location.
This target does not install anything. Running this target as a
- regular user, particularly if the prior `make install' required
+ regular user, particularly if the prior 'make install' required
root privileges, verifies that the installation completed
correctly.
6. You can remove the program binaries and object files from the
- source code directory by typing `make clean'. To also remove the
- files that `configure' created (so you can compile the package for
- a different kind of computer), type `make distclean'. There is
- also a `make maintainer-clean' target, but that is intended mainly
+ source code directory by typing 'make clean'. To also remove the
+ files that 'configure' created (so you can compile the package for
+ a different kind of computer), type 'make distclean'. There is
+ also a 'make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
- 7. Often, you can also type `make uninstall' to remove the installed
+ 7. Often, you can also type 'make uninstall' to remove the installed
files again. In practice, not all packages have tested that
uninstallation works correctly, even though it is required by the
GNU Coding Standards.
- 8. Some packages, particularly those that use Automake, provide `make
+ 8. Some packages, particularly those that use Automake, provide 'make
distcheck', which can by used by developers to test that all other
- targets like `make install' and `make uninstall' work correctly.
+ targets like 'make install' and 'make uninstall' work correctly.
This target is generally not run by end users.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
-the `configure' script does not know about. Run `./configure --help'
+the 'configure' script does not know about. Run './configure --help'
for details on some of the pertinent environment variables.
- You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment. Here
-is an example:
+ You can give 'configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here is
+an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
@@ -113,21 +112,21 @@ Compiling For Multiple Architectures
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
-own directory. To do this, you can use GNU `make'. `cd' to the
+own directory. To do this, you can use GNU 'make'. 'cd' to the
directory where you want the object files and executables to go and run
-the `configure' script. `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'. This
-is known as a "VPATH" build.
+the 'configure' script. 'configure' automatically checks for the source
+code in the directory that 'configure' is in and in '..'. This is known
+as a "VPATH" build.
- With a non-GNU `make', it is safer to compile the package for one
+ With a non-GNU 'make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
-installed the package for one architecture, use `make distclean' before
+installed the package for one architecture, use 'make distclean' before
reconfiguring for another architecture.
On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
-"universal" binaries--by specifying multiple `-arch' options to the
-compiler but only a single `-arch' option to the preprocessor. Like
+"universal" binaries--by specifying multiple '-arch' options to the
+compiler but only a single '-arch' option to the preprocessor. Like
this:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
@@ -136,105 +135,104 @@ this:
This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
-using the `lipo' tool if you have problems.
+using the 'lipo' tool if you have problems.
Installation Names
==================
- By default, `make install' installs the package's commands under
-`/usr/local/bin', include files under `/usr/local/include', etc. You
-can specify an installation prefix other than `/usr/local' by giving
-`configure' the option `--prefix=PREFIX', where PREFIX must be an
+ By default, 'make install' installs the package's commands under
+'/usr/local/bin', include files under '/usr/local/include', etc. You
+can specify an installation prefix other than '/usr/local' by giving
+'configure' the option '--prefix=PREFIX', where PREFIX must be an
absolute file name.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
-pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+pass the option '--exec-prefix=PREFIX' to 'configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
-options like `--bindir=DIR' to specify different values for particular
-kinds of files. Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them. In general, the
-default for these options is expressed in terms of `${prefix}', so that
-specifying just `--prefix' will affect all of the other directory
+options like '--bindir=DIR' to specify different values for particular
+kinds of files. Run 'configure --help' for a list of the directories
+you can set and what kinds of files go in them. In general, the default
+for these options is expressed in terms of '${prefix}', so that
+specifying just '--prefix' will affect all of the other directory
specifications that were not explicitly provided.
The most portable way to affect installation locations is to pass the
-correct locations to `configure'; however, many packages provide one or
+correct locations to 'configure'; however, many packages provide one or
both of the following shortcuts of passing variable assignments to the
-`make install' command line to change installation locations without
+'make install' command line to change installation locations without
having to reconfigure or recompile.
The first method involves providing an override variable for each
-affected directory. For example, `make install
+affected directory. For example, 'make install
prefix=/alternate/directory' will choose an alternate location for all
directory configuration variables that were expressed in terms of
-`${prefix}'. Any directories that were specified during `configure',
-but not in terms of `${prefix}', must each be overridden at install
-time for the entire installation to be relocated. The approach of
-makefile variable overrides for each directory variable is required by
-the GNU Coding Standards, and ideally causes no recompilation.
-However, some platforms have known limitations with the semantics of
-shared libraries that end up requiring recompilation when using this
-method, particularly noticeable in packages that use GNU Libtool.
-
- The second method involves providing the `DESTDIR' variable. For
-example, `make install DESTDIR=/alternate/directory' will prepend
-`/alternate/directory' before all installation names. The approach of
-`DESTDIR' overrides is not required by the GNU Coding Standards, and
+'${prefix}'. Any directories that were specified during 'configure',
+but not in terms of '${prefix}', must each be overridden at install time
+for the entire installation to be relocated. The approach of makefile
+variable overrides for each directory variable is required by the GNU
+Coding Standards, and ideally causes no recompilation. However, some
+platforms have known limitations with the semantics of shared libraries
+that end up requiring recompilation when using this method, particularly
+noticeable in packages that use GNU Libtool.
+
+ The second method involves providing the 'DESTDIR' variable. For
+example, 'make install DESTDIR=/alternate/directory' will prepend
+'/alternate/directory' before all installation names. The approach of
+'DESTDIR' overrides is not required by the GNU Coding Standards, and
does not work on platforms that have drive letters. On the other hand,
it does better at avoiding recompilation issues, and works well even
-when some directory options were not specified in terms of `${prefix}'
-at `configure' time.
+when some directory options were not specified in terms of '${prefix}'
+at 'configure' time.
Optional Features
=================
If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
- Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System). The
-`README' should mention any `--enable-' and `--with-' options that the
+with an extra prefix or suffix on their names by giving 'configure' the
+option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'.
+
+ Some packages pay attention to '--enable-FEATURE' options to
+'configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to '--with-PACKAGE' options, where PACKAGE
+is something like 'gnu-as' or 'x' (for the X Window System). The
+'README' should mention any '--enable-' and '--with-' options that the
package recognizes.
- For packages that use the X Window System, `configure' can usually
+ For packages that use the X Window System, 'configure' can usually
find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
+you can use the 'configure' options '--x-includes=DIR' and
+'--x-libraries=DIR' to specify their locations.
Some packages offer the ability to configure how verbose the
-execution of `make' will be. For these packages, running `./configure
+execution of 'make' will be. For these packages, running './configure
--enable-silent-rules' sets the default to minimal output, which can be
-overridden with `make V=1'; while running `./configure
+overridden with 'make V=1'; while running './configure
--disable-silent-rules' sets the default to verbose, which can be
-overridden with `make V=0'.
+overridden with 'make V=0'.
Particular systems
==================
- On HP-UX, the default C compiler is not ANSI C compatible. If GNU
-CC is not installed, it is recommended to use the following options in
+ On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC
+is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
- HP-UX `make' updates targets which have the same time stamps as
-their prerequisites, which makes it generally unusable when shipped
-generated files such as `configure' are involved. Use GNU `make'
-instead.
+ HP-UX 'make' updates targets which have the same time stamps as their
+prerequisites, which makes it generally unusable when shipped generated
+files such as 'configure' are involved. Use GNU 'make' instead.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
-parse its `<wchar.h>' header file. The option `-nodtk' can be used as
-a workaround. If GNU CC is not installed, it is therefore recommended
-to try
+parse its '<wchar.h>' header file. The option '-nodtk' can be used as a
+workaround. If GNU CC is not installed, it is therefore recommended to
+try
./configure CC="cc"
@@ -242,26 +240,26 @@ and if that doesn't work, try
./configure CC="cc -nodtk"
- On Solaris, don't put `/usr/ucb' early in your `PATH'. This
+ On Solaris, don't put '/usr/ucb' early in your 'PATH'. This
directory contains several dysfunctional programs; working variants of
-these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
-in your `PATH', put it _after_ `/usr/bin'.
+these programs are available in '/usr/bin'. So, if you need '/usr/ucb'
+in your 'PATH', put it _after_ '/usr/bin'.
- On Haiku, software installed for all users goes in `/boot/common',
-not `/usr/local'. It is recommended to use the following options:
+ On Haiku, software installed for all users goes in '/boot/common',
+not '/usr/local'. It is recommended to use the following options:
./configure --prefix=/boot/common
Specifying the System Type
==========================
- There may be some features `configure' cannot figure out
+ There may be some features 'configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
-_same_ architectures, `configure' can figure that out, but if it prints
+_same_ architectures, 'configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
-`--build=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
+'--build=TYPE' option. TYPE can either be a short name for the system
+type, such as 'sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
@@ -270,101 +268,101 @@ where SYSTEM can have one of these forms:
OS
KERNEL-OS
- See the file `config.sub' for the possible values of each field. If
-`config.sub' isn't included in this package, then this package doesn't
+ See the file 'config.sub' for the possible values of each field. If
+'config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
-use the option `--target=TYPE' to select the type of system they will
+use the option '--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
+eventually be run) with '--host=TYPE'.
Sharing Defaults
================
- If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists. Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
+ If you want to set default values for 'configure' scripts to share,
+you can create a site shell script called 'config.site' that gives
+default values for variables like 'CC', 'cache_file', and 'prefix'.
+'configure' looks for 'PREFIX/share/config.site' if it exists, then
+'PREFIX/etc/config.site' if it exists. Or, you can set the
+'CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all 'configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
-environment passed to `configure'. However, some packages may run
+environment passed to 'configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'. For example:
+them in the 'configure' command line, using 'VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
-causes the specified `gcc' to be used as the C compiler (unless it is
+causes the specified 'gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf limitation. Until the limitation is lifted, you can use
-this workaround:
+Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an
+Autoconf limitation. Until the limitation is lifted, you can use this
+workaround:
CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
-`configure' Invocation
+'configure' Invocation
======================
- `configure' recognizes the following options to control how it
+ 'configure' recognizes the following options to control how it
operates.
-`--help'
-`-h'
- Print a summary of all of the options to `configure', and exit.
+'--help'
+'-h'
+ Print a summary of all of the options to 'configure', and exit.
-`--help=short'
-`--help=recursive'
+'--help=short'
+'--help=recursive'
Print a summary of the options unique to this package's
- `configure', and exit. The `short' variant lists options used
- only in the top level, while the `recursive' variant lists options
- also present in any nested packages.
+ 'configure', and exit. The 'short' variant lists options used only
+ in the top level, while the 'recursive' variant lists options also
+ present in any nested packages.
-`--version'
-`-V'
- Print the version of Autoconf used to generate the `configure'
+'--version'
+'-V'
+ Print the version of Autoconf used to generate the 'configure'
script, and exit.
-`--cache-file=FILE'
+'--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
- traditionally `config.cache'. FILE defaults to `/dev/null' to
+ traditionally 'config.cache'. FILE defaults to '/dev/null' to
disable caching.
-`--config-cache'
-`-C'
- Alias for `--cache-file=config.cache'.
+'--config-cache'
+'-C'
+ Alias for '--cache-file=config.cache'.
-`--quiet'
-`--silent'
-`-q'
+'--quiet'
+'--silent'
+'-q'
Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to `/dev/null' (any error
+ suppress all normal output, redirect it to '/dev/null' (any error
messages will still be shown).
-`--srcdir=DIR'
+'--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
- `configure' can determine that directory automatically.
+ 'configure' can determine that directory automatically.
-`--prefix=DIR'
- Use DIR as the installation prefix. *note Installation Names::
- for more details, including other options available for fine-tuning
- the installation locations.
+'--prefix=DIR'
+ Use DIR as the installation prefix. *note Installation Names:: for
+ more details, including other options available for fine-tuning the
+ installation locations.
-`--no-create'
-`-n'
+'--no-create'
+'-n'
Run the configure checks, but stop before creating any output
files.
-`configure' also accepts some other, not widely useful, options. Run
-`configure --help' for more details.
+'configure' also accepts some other, not widely useful, options. Run
+'configure --help' for more details.
diff --git a/pcre/LICENCE b/pcre/LICENCE
index dd9071a8dd8..f6ef7fd7664 100644
--- a/pcre/LICENCE
+++ b/pcre/LICENCE
@@ -25,7 +25,7 @@ Email domain: cam.ac.uk
University of Cambridge Computing Service,
Cambridge, England.
-Copyright (c) 1997-2017 University of Cambridge
+Copyright (c) 1997-2018 University of Cambridge
All rights reserved.
@@ -36,7 +36,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2010-2017 Zoltan Herczeg
+Copyright(c) 2010-2018 Zoltan Herczeg
All rights reserved.
@@ -47,7 +47,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2009-2017 Zoltan Herczeg
+Copyright(c) 2009-2018 Zoltan Herczeg
All rights reserved.
diff --git a/pcre/NEWS b/pcre/NEWS
index 36be07cb880..09b4ad36003 100644
--- a/pcre/NEWS
+++ b/pcre/NEWS
@@ -1,6 +1,12 @@
News about PCRE releases
------------------------
+Release 8.42 20-March-2018
+--------------------------
+
+This is a bug-fix release.
+
+
Release 8.41 13-June-2017
-------------------------
diff --git a/pcre/NON-AUTOTOOLS-BUILD b/pcre/NON-AUTOTOOLS-BUILD
index 3910059106b..37f6164475b 100644
--- a/pcre/NON-AUTOTOOLS-BUILD
+++ b/pcre/NON-AUTOTOOLS-BUILD
@@ -760,13 +760,14 @@ The character code used is EBCDIC, not ASCII or Unicode. In z/OS, UNIX APIs and
applications can be supported through UNIX System Services, and in such an
environment PCRE can be built in the same way as in other systems. However, in
native z/OS (without UNIX System Services) and in z/VM, special ports are
-required. For details, please see this web site:
+required. PCRE1 version 8.39 is available in file 882 on this site:
- http://www.zaconsultants.net
+ http://www.cbttape.org
-You may download PCRE from WWW.CBTTAPE.ORG, file 882.  Everything, source and
-executable, is in EBCDIC and native z/OS file formats and this is the
-recommended download site.
+Everything, source and executable, is in EBCDIC and native z/OS file formats.
+However, this software is not maintained and will not be upgraded. If you are
+new to PCRE you should be looking at PCRE2 (version 10.30 or later).
-==========================
-Last Updated: 25 June 2015
+===============================
+Last Updated: 13 September 2017
+===============================
diff --git a/pcre/configure.ac b/pcre/configure.ac
index 718a18508c9..dcdef6a9427 100644
--- a/pcre/configure.ac
+++ b/pcre/configure.ac
@@ -9,18 +9,18 @@ dnl The PCRE_PRERELEASE feature is for identifying release candidates. It might
dnl be defined as -RC2, for example. For real releases, it should be empty.
m4_define(pcre_major, [8])
-m4_define(pcre_minor, [41])
+m4_define(pcre_minor, [42])
m4_define(pcre_prerelease, [])
-m4_define(pcre_date, [2017-07-05])
+m4_define(pcre_date, [2018-03-20])
# NOTE: The CMakeLists.txt file searches for the above variables in the first
# 50 lines of this file. Please update that if the variables above are moved.
# Libtool shared library interface versions (current:revision:age)
-m4_define(libpcre_version, [3:9:2])
-m4_define(libpcre16_version, [2:9:2])
-m4_define(libpcre32_version, [0:9:0])
-m4_define(libpcreposix_version, [0:5:0])
+m4_define(libpcre_version, [3:10:2])
+m4_define(libpcre16_version, [2:10:2])
+m4_define(libpcre32_version, [0:10:0])
+m4_define(libpcreposix_version, [0:6:0])
m4_define(libpcrecpp_version, [0:1:0])
AC_PREREQ(2.57)
@@ -155,6 +155,18 @@ AC_ARG_ENABLE(jit,
[enable Just-In-Time compiling support]),
, enable_jit=no)
+# This code enables JIT if the hardware supports it.
+
+if test "$enable_jit" = "auto"; then
+ AC_LANG(C)
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+ #define SLJIT_CONFIG_AUTO 1
+ #include "sljit/sljitConfigInternal.h"
+ #if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
+ #error unsupported
+ #endif]])], enable_jit=yes, enable_jit=no)
+fi
+
# Handle --disable-pcregrep-jit (enabled by default)
AC_ARG_ENABLE(pcregrep-jit,
AS_HELP_STRING([--disable-pcregrep-jit],
@@ -469,7 +481,7 @@ pcre_have_type_traits="0"
pcre_have_bits_type_traits="0"
if test "x$enable_cpp" = "xyes" -a -z "$CXX"; then
- AC_MSG_ERROR([You need a C++ compiler for C++ support.])
+ AC_MSG_ERROR([Invalid C++ compiler or C++ compiler flags])
fi
if test "x$enable_cpp" = "xyes" -a -n "$CXX"
diff --git a/pcre/doc/html/NON-AUTOTOOLS-BUILD.txt b/pcre/doc/html/NON-AUTOTOOLS-BUILD.txt
index 3910059106b..37f6164475b 100644
--- a/pcre/doc/html/NON-AUTOTOOLS-BUILD.txt
+++ b/pcre/doc/html/NON-AUTOTOOLS-BUILD.txt
@@ -760,13 +760,14 @@ The character code used is EBCDIC, not ASCII or Unicode. In z/OS, UNIX APIs and
applications can be supported through UNIX System Services, and in such an
environment PCRE can be built in the same way as in other systems. However, in
native z/OS (without UNIX System Services) and in z/VM, special ports are
-required. For details, please see this web site:
+required. PCRE1 version 8.39 is available in file 882 on this site:
- http://www.zaconsultants.net
+ http://www.cbttape.org
-You may download PCRE from WWW.CBTTAPE.ORG, file 882.  Everything, source and
-executable, is in EBCDIC and native z/OS file formats and this is the
-recommended download site.
+Everything, source and executable, is in EBCDIC and native z/OS file formats.
+However, this software is not maintained and will not be upgraded. If you are
+new to PCRE you should be looking at PCRE2 (version 10.30 or later).
-==========================
-Last Updated: 25 June 2015
+===============================
+Last Updated: 13 September 2017
+===============================
diff --git a/pcre/pcre.h.in b/pcre/pcre.h.in
index 667a45ed575..d4d78926984 100644
--- a/pcre/pcre.h.in
+++ b/pcre/pcre.h.in
@@ -321,11 +321,11 @@ these bits, just add new ones on the end, in order to remain compatible. */
/* Types */
-struct real_pcre; /* declaration; the definition is private */
-typedef struct real_pcre pcre;
+struct real_pcre8_or_16; /* declaration; the definition is private */
+typedef struct real_pcre8_or_16 pcre;
-struct real_pcre16; /* declaration; the definition is private */
-typedef struct real_pcre16 pcre16;
+struct real_pcre8_or_16; /* declaration; the definition is private */
+typedef struct real_pcre8_or_16 pcre16;
struct real_pcre32; /* declaration; the definition is private */
typedef struct real_pcre32 pcre32;
diff --git a/pcre/pcre_compile.c b/pcre/pcre_compile.c
index 1a916693e69..9b9da46f0d0 100644
--- a/pcre/pcre_compile.c
+++ b/pcre/pcre_compile.c
@@ -8063,7 +8063,7 @@ for (;; ptr++)
single group (i.e. not to a duplicated name. */
HANDLE_REFERENCE:
- if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
+ if (firstcharflags == REQ_UNSET) zerofirstcharflags = firstcharflags = REQ_NONE;
previous = code;
item_hwm_offset = cd->hwm - cd->start_workspace;
*code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF;
diff --git a/pcre/pcre_dfa_exec.c b/pcre/pcre_dfa_exec.c
index bc09ced3a7c..f333381d088 100644
--- a/pcre/pcre_dfa_exec.c
+++ b/pcre/pcre_dfa_exec.c
@@ -2287,12 +2287,14 @@ for (;;)
case OP_NOTI:
if (clen > 0)
{
- unsigned int otherd;
+ pcre_uint32 otherd;
#ifdef SUPPORT_UTF
if (utf && d >= 128)
{
#ifdef SUPPORT_UCP
otherd = UCD_OTHERCASE(d);
+#else
+ otherd = d;
#endif /* SUPPORT_UCP */
}
else
diff --git a/pcre/pcre_exec.c b/pcre/pcre_exec.c
index fa84d924a4c..93256d32455 100644
--- a/pcre/pcre_exec.c
+++ b/pcre/pcre_exec.c
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2014 University of Cambridge
+ Copyright (c) 1997-2018 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -2313,7 +2313,7 @@ for (;;)
case OP_ANY:
if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
if (md->partial != 0 &&
- eptr + 1 >= md->end_subject &&
+ eptr == md->end_subject - 1 &&
NLBLOCK->nltype == NLTYPE_FIXED &&
NLBLOCK->nllen == 2 &&
UCHAR21TEST(eptr) == NLBLOCK->nl[0])
@@ -3061,7 +3061,7 @@ for (;;)
{
RMATCH(eptr, ecode, offset_top, md, eptrb, RM18);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
+ if (eptr-- <= pp) break; /* Stop if tried at original pos */
BACKCHAR(eptr);
}
}
@@ -3218,7 +3218,7 @@ for (;;)
{
RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
+ if (eptr-- <= pp) break; /* Stop if tried at original pos */
#ifdef SUPPORT_UTF
if (utf) BACKCHAR(eptr);
#endif
diff --git a/pcre/pcre_jit_compile.c b/pcre/pcre_jit_compile.c
index 249edbe8e7f..2bad74b0231 100644
--- a/pcre/pcre_jit_compile.c
+++ b/pcre/pcre_jit_compile.c
@@ -164,7 +164,6 @@ typedef struct jit_arguments {
const pcre_uchar *begin;
const pcre_uchar *end;
int *offsets;
- pcre_uchar *uchar_ptr;
pcre_uchar *mark_ptr;
void *callout_data;
/* Everything else after. */
@@ -214,7 +213,7 @@ enum control_types {
type_then_trap = 1
};
-typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
+typedef int (SLJIT_FUNC *jit_function)(jit_arguments *args);
/* The following structure is the key data type for the recursive
code generator. It is allocated by compile_matchingpath, and contains
@@ -489,9 +488,24 @@ typedef struct compare_context {
/* Used for accessing the elements of the stack. */
#define STACK(i) ((i) * (int)sizeof(sljit_sw))
+#ifdef SLJIT_PREF_SHIFT_REG
+#if SLJIT_PREF_SHIFT_REG == SLJIT_R2
+/* Nothing. */
+#elif SLJIT_PREF_SHIFT_REG == SLJIT_R3
+#define SHIFT_REG_IS_R3
+#else
+#error "Unsupported shift register"
+#endif
+#endif
+
#define TMP1 SLJIT_R0
+#ifdef SHIFT_REG_IS_R3
+#define TMP2 SLJIT_R3
+#define TMP3 SLJIT_R2
+#else
#define TMP2 SLJIT_R2
#define TMP3 SLJIT_R3
+#endif
#define STR_PTR SLJIT_S0
#define STR_END SLJIT_S1
#define STACK_TOP SLJIT_R1
@@ -520,13 +534,10 @@ the start pointers when the end of the capturing group has not yet reached. */
#if defined COMPILE_PCRE8
#define MOV_UCHAR SLJIT_MOV_U8
-#define MOVU_UCHAR SLJIT_MOVU_U8
#elif defined COMPILE_PCRE16
#define MOV_UCHAR SLJIT_MOV_U16
-#define MOVU_UCHAR SLJIT_MOVU_U16
#elif defined COMPILE_PCRE32
#define MOV_UCHAR SLJIT_MOV_U32
-#define MOVU_UCHAR SLJIT_MOVU_U32
#else
#error Unsupported compiling mode
#endif
@@ -2383,12 +2394,25 @@ if (length < 8)
}
else
{
- GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START);
- OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
- loop = LABEL();
- OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw), SLJIT_R0, 0);
- OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
- JUMPTO(SLJIT_NOT_ZERO, loop);
+ if (sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_STORE | SLJIT_MEM_PRE, SLJIT_R0, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw)) == SLJIT_SUCCESS)
+ {
+ GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START);
+ OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
+ loop = LABEL();
+ sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_STORE | SLJIT_MEM_PRE, SLJIT_R0, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw));
+ OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_NOT_ZERO, loop);
+ }
+ else
+ {
+ GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START + sizeof(sljit_sw));
+ OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
+ loop = LABEL();
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), 0, SLJIT_R0, 0);
+ OP2(SLJIT_ADD, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, sizeof(sljit_sw));
+ OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_NOT_ZERO, loop);
+ }
}
}
@@ -2421,12 +2445,25 @@ if (length < 8)
}
else
{
- GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
- loop = LABEL();
- OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
- OP2(SLJIT_SUB | SLJIT_SET_Z, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
- JUMPTO(SLJIT_NOT_ZERO, loop);
+ if (sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_STORE | SLJIT_MEM_PRE, TMP1, SLJIT_MEM1(TMP2), sizeof(sljit_sw)) == SLJIT_SUCCESS)
+ {
+ GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
+ loop = LABEL();
+ sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_STORE | SLJIT_MEM_PRE, TMP1, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
+ OP2(SLJIT_SUB | SLJIT_SET_Z, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_NOT_ZERO, loop);
+ }
+ else
+ {
+ GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + 2 * sizeof(sljit_sw));
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
+ loop = LABEL();
+ OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, TMP1, 0);
+ OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, sizeof(sljit_sw));
+ OP2(SLJIT_SUB | SLJIT_SET_Z, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_NOT_ZERO, loop);
+ }
}
OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
@@ -2436,10 +2473,10 @@ if (common->control_head_ptr != 0)
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, end));
}
-static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
+static sljit_sw SLJIT_FUNC do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
{
while (current != NULL)
{
@@ -2460,7 +2497,7 @@ while (current != NULL)
SLJIT_ASSERT(current[0] == 0 || current < (sljit_sw*)current[0]);
current = (sljit_sw*)current[0];
}
-return -1;
+return 0;
}
static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
@@ -2468,6 +2505,7 @@ static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
DEFINE_COMPILER;
struct sljit_label *loop;
struct sljit_jump *early_quit;
+BOOL has_pre;
/* At this point we can freely use all registers. */
OP1(SLJIT_MOV, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
@@ -2481,17 +2519,30 @@ if (common->mark_ptr != 0)
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0);
OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, begin));
-GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START);
+
+has_pre = sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, SLJIT_S1, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw)) == SLJIT_SUCCESS;
+GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START - (has_pre ? sizeof(sljit_sw) : 0));
+
/* Unlikely, but possible */
early_quit = CMP(SLJIT_EQUAL, SLJIT_R1, 0, SLJIT_IMM, 0);
loop = LABEL();
-OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_R0, 0);
-OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw));
+
+if (has_pre)
+ sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_PRE, SLJIT_S1, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw));
+else
+ {
+ OP1(SLJIT_MOV, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0);
+ OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw));
+ }
+
+OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, sizeof(int));
+OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_R0, 0);
/* Copy the integer value to the output buffer */
#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT);
#endif
-OP1(SLJIT_MOVU_S32, SLJIT_MEM1(SLJIT_R2), sizeof(int), SLJIT_S1, 0);
+
+OP1(SLJIT_MOV_S32, SLJIT_MEM1(SLJIT_R2), 0, SLJIT_S1, 0);
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
JUMPTO(SLJIT_NOT_ZERO, loop);
JUMPHERE(early_quit);
@@ -2499,14 +2550,29 @@ JUMPHERE(early_quit);
/* Calculate the return value, which is the maximum ovector value. */
if (topbracket > 1)
{
- GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
- OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
+ if (sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, SLJIT_R2, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw))) == SLJIT_SUCCESS)
+ {
+ GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
+ OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
- /* OVECTOR(0) is never equal to SLJIT_S2. */
- loop = LABEL();
- OP1(SLJIT_MOVU, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw)));
- OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
- CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
+ /* OVECTOR(0) is never equal to SLJIT_S2. */
+ loop = LABEL();
+ sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_PRE, SLJIT_R2, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw)));
+ OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
+ CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
+ }
+ else
+ {
+ GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + (topbracket - 1) * 2 * sizeof(sljit_sw));
+ OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
+
+ /* OVECTOR(0) is never equal to SLJIT_S2. */
+ loop = LABEL();
+ OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), 0);
+ OP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, 2 * (sljit_sw)sizeof(sljit_sw));
+ OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
+ CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
+ }
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0);
}
else
@@ -5167,93 +5233,190 @@ OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
}
-#define CHAR1 STR_END
-#define CHAR2 STACK_TOP
-
static void do_casefulcmp(compiler_common *common)
{
DEFINE_COMPILER;
struct sljit_jump *jump;
struct sljit_label *label;
+int char1_reg;
+int char2_reg;
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+if (sljit_get_register_index(TMP3) < 0)
+ {
+ char1_reg = STR_END;
+ char2_reg = STACK_TOP;
+ }
+else
+ {
+ char1_reg = TMP3;
+ char2_reg = RETURN_ADDR;
+ }
+
+sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR2, 0);
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-label = LABEL();
-OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
-OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
-jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
-OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
-JUMPTO(SLJIT_NOT_ZERO, label);
+if (char1_reg == STR_END)
+ {
+ OP1(SLJIT_MOV, TMP3, 0, char1_reg, 0);
+ OP1(SLJIT_MOV, RETURN_ADDR, 0, char2_reg, 0);
+ }
-JUMPHERE(jump);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
-OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-}
+if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
+ {
+ label = LABEL();
+ sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
+ sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
+ OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+ JUMPTO(SLJIT_NOT_ZERO, label);
+
+ JUMPHERE(jump);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+ }
+else if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
+ {
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+ label = LABEL();
+ sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
+ sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
+ OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+ JUMPTO(SLJIT_NOT_ZERO, label);
-#define LCC_TABLE STACK_LIMIT
+ JUMPHERE(jump);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ }
+else
+ {
+ label = LABEL();
+ OP1(MOV_UCHAR, char1_reg, 0, SLJIT_MEM1(TMP1), 0);
+ OP1(MOV_UCHAR, char2_reg, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
+ OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+ JUMPTO(SLJIT_NOT_ZERO, label);
+
+ JUMPHERE(jump);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+ }
+
+if (char1_reg == STR_END)
+ {
+ OP1(SLJIT_MOV, char1_reg, 0, TMP3, 0);
+ OP1(SLJIT_MOV, char2_reg, 0, RETURN_ADDR, 0);
+ }
+
+sljit_emit_fast_return(compiler, TMP1, 0);
+}
static void do_caselesscmp(compiler_common *common)
{
DEFINE_COMPILER;
struct sljit_jump *jump;
struct sljit_label *label;
+int char1_reg = STR_END;
+int char2_reg;
+int lcc_table;
+int opt_type = 0;
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+if (sljit_get_register_index(TMP3) < 0)
+ {
+ char2_reg = STACK_TOP;
+ lcc_table = STACK_LIMIT;
+ }
+else
+ {
+ char2_reg = RETURN_ADDR;
+ lcc_table = TMP3;
+ }
+
+if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
+ opt_type = 1;
+else if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
+ opt_type = 2;
+
+sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR1, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, CHAR2, 0);
-OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, char1_reg, 0);
+
+if (char2_reg == STACK_TOP)
+ {
+ OP1(SLJIT_MOV, TMP3, 0, char2_reg, 0);
+ OP1(SLJIT_MOV, RETURN_ADDR, 0, lcc_table, 0);
+ }
+
+OP1(SLJIT_MOV, lcc_table, 0, SLJIT_IMM, common->lcc);
+
+if (opt_type == 1)
+ {
+ label = LABEL();
+ sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
+ sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ }
+else if (opt_type == 2)
+ {
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+ label = LABEL();
+ sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
+ sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ }
+else
+ {
+ label = LABEL();
+ OP1(MOV_UCHAR, char1_reg, 0, SLJIT_MEM1(TMP1), 0);
+ OP1(MOV_UCHAR, char2_reg, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+ }
-label = LABEL();
-OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
-OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
#ifndef COMPILE_PCRE8
-jump = CMP(SLJIT_GREATER, CHAR1, 0, SLJIT_IMM, 255);
+jump = CMP(SLJIT_GREATER, char1_reg, 0, SLJIT_IMM, 255);
#endif
-OP1(SLJIT_MOV_U8, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
+OP1(SLJIT_MOV_U8, char1_reg, 0, SLJIT_MEM2(lcc_table, char1_reg), 0);
#ifndef COMPILE_PCRE8
JUMPHERE(jump);
-jump = CMP(SLJIT_GREATER, CHAR2, 0, SLJIT_IMM, 255);
+jump = CMP(SLJIT_GREATER, char2_reg, 0, SLJIT_IMM, 255);
#endif
-OP1(SLJIT_MOV_U8, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
+OP1(SLJIT_MOV_U8, char2_reg, 0, SLJIT_MEM2(lcc_table, char2_reg), 0);
#ifndef COMPILE_PCRE8
JUMPHERE(jump);
#endif
-jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
+
+if (opt_type == 0)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
JUMPTO(SLJIT_NOT_ZERO, label);
JUMPHERE(jump);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
-OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
-OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-}
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+
+if (opt_type == 2)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-#undef LCC_TABLE
-#undef CHAR1
-#undef CHAR2
+if (char2_reg == STACK_TOP)
+ {
+ OP1(SLJIT_MOV, char2_reg, 0, TMP3, 0);
+ OP1(SLJIT_MOV, lcc_table, 0, RETURN_ADDR, 0);
+ }
+
+OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
+sljit_emit_fast_return(compiler, TMP1, 0);
+}
#if defined SUPPORT_UTF && defined SUPPORT_UCP
-static const pcre_uchar * SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
+static const pcre_uchar * SLJIT_FUNC do_utf_caselesscmp(pcre_uchar *src1, pcre_uchar *src2, pcre_uchar *end1, pcre_uchar *end2)
{
/* This function would be ineffective to do in JIT level. */
sljit_u32 c1, c2;
-const pcre_uchar *src2 = args->uchar_ptr;
-const pcre_uchar *end2 = args->end;
const ucd_record *ur;
const sljit_u32 *pp;
@@ -6776,32 +6939,37 @@ else
#if defined SUPPORT_UTF && defined SUPPORT_UCP
if (common->utf && *cc == OP_REFI)
{
- SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1 && TMP2 == SLJIT_R2);
+ SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1);
if (ref)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
+ OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
else
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
+ OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
if (withchecks)
- jump = CMP(SLJIT_EQUAL, TMP1, 0, TMP2, 0);
+ jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_R2, 0);
- /* Needed to save important temporary registers. */
+ /* No free saved registers so save data on stack. */
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
- OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
- sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
+ OP1(SLJIT_MOV, SLJIT_R1, 0, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_R3, 0, STR_END, 0);
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
+
if (common->mode == JIT_COMPILE)
add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
else
{
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
- nopartial = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_LESS, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
+
+ add_jump(compiler, backtracks, JUMP(SLJIT_LESS));
+
+ nopartial = JUMP(SLJIT_NOT_EQUAL);
+ OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
check_partial(common, FALSE);
add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
JUMPHERE(nopartial);
}
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
}
else
#endif /* SUPPORT_UTF && SUPPORT_UCP */
@@ -7125,7 +7293,7 @@ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IM
return cc + 1 + LINK_SIZE;
}
-static int SLJIT_CALL do_callout(struct jit_arguments *arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector)
+static sljit_s32 SLJIT_FUNC do_callout(struct jit_arguments *arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector)
{
const pcre_uchar *begin = arguments->begin;
int *offset_vector = arguments->offsets;
@@ -7207,18 +7375,17 @@ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
/* SLJIT_R0 = arguments */
OP1(SLJIT_MOV, SLJIT_R1, 0, STACK_TOP, 0);
GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START);
-sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
-OP1(SLJIT_MOV_S32, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0);
+sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(S32) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
/* Check return value. */
-OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_SIG_GREATER, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
-add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER));
+OP2(SLJIT_SUB32 | SLJIT_SET_Z | SLJIT_SET_SIG_GREATER, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
+add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER32));
if (common->forced_quit_label == NULL)
- add_jump(compiler, &common->forced_quit, JUMP(SLJIT_NOT_EQUAL) /* SIG_LESS */);
+ add_jump(compiler, &common->forced_quit, JUMP(SLJIT_NOT_EQUAL32) /* SIG_LESS */);
else
- JUMPTO(SLJIT_NOT_EQUAL /* SIG_LESS */, common->forced_quit_label);
+ JUMPTO(SLJIT_NOT_EQUAL32 /* SIG_LESS */, common->forced_quit_label);
return cc + 2 + 2 * LINK_SIZE;
}
@@ -10439,11 +10606,11 @@ if (opcode == OP_SKIP_ARG)
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
- sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
- add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
+ add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0));
return;
}
@@ -11031,7 +11198,7 @@ if (!compiler)
common->compiler = compiler;
/* Main pcre_jit_exec entry. */
-sljit_emit_enter(compiler, 0, 1, 5, 5, 0, 0, private_data_size);
+sljit_emit_enter(compiler, 0, SLJIT_ARG1(SW), 5, 5, 0, 0, private_data_size);
/* Register init. */
reset_ovector(common, (re->top_bracket + 1) * 2);
@@ -11044,8 +11211,8 @@ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str))
OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
-OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, end));
+OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, start));
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
@@ -11251,20 +11418,22 @@ common->quit_label = quit_label;
set_jumps(common->stackalloc, LABEL());
/* RETURN_ADDR is not a saved register. */
sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0);
-OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
-OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0);
-OP2(SLJIT_SUB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);
-sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
-jump = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
-OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));
-OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit));
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
-sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1);
+
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STACK_TOP, 0);
+OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
+OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_LIMIT, 0, SLJIT_IMM, STACK_GROWTH_RATE);
+OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, stack));
+OP1(SLJIT_MOV, STACK_LIMIT, 0, TMP2, 0);
+
+sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
+jump = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
+OP1(SLJIT_MOV, TMP2, 0, STACK_LIMIT, 0);
+OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_RETURN_REG, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
+sljit_emit_fast_return(compiler, TMP1, 0);
/* Allocation failed. */
JUMPHERE(jump);
@@ -11409,9 +11578,9 @@ union {
sljit_u8 local_space[MACHINE_STACK_SIZE];
struct sljit_stack local_stack;
-local_stack.max_limit = local_space;
-local_stack.limit = local_space;
-local_stack.base = local_space + MACHINE_STACK_SIZE;
+local_stack.min_start = local_space;
+local_stack.start = local_space;
+local_stack.end = local_space + MACHINE_STACK_SIZE;
local_stack.top = local_space + MACHINE_STACK_SIZE;
arguments->stack = &local_stack;
convert_executable_func.executable_func = executable_func;
@@ -11529,7 +11698,7 @@ if ((options & PCRE_PARTIAL_HARD) != 0)
else if ((options & PCRE_PARTIAL_SOFT) != 0)
mode = JIT_PARTIAL_SOFT_COMPILE;
-if (functions->executable_funcs[mode] == NULL)
+if (functions == NULL || functions->executable_funcs[mode] == NULL)
return PCRE_ERROR_JIT_BADOPTION;
/* Sanity checks should be handled by pcre_exec. */
diff --git a/pcre/pcregrep.c b/pcre/pcregrep.c
index 317f7454e13..a406be962d7 100644
--- a/pcre/pcregrep.c
+++ b/pcre/pcregrep.c
@@ -1387,8 +1387,8 @@ Returns: nothing
*/
static void
-do_after_lines(int lastmatchnumber, char *lastmatchrestart, char *endptr,
- char *printname)
+do_after_lines(unsigned long int lastmatchnumber, char *lastmatchrestart,
+ char *endptr, char *printname)
{
if (after_context > 0 && lastmatchnumber > 0)
{
@@ -1398,7 +1398,7 @@ if (after_context > 0 && lastmatchnumber > 0)
int ellength;
char *pp = lastmatchrestart;
if (printname != NULL) fprintf(stdout, "%s-", printname);
- if (number) fprintf(stdout, "%d-", lastmatchnumber++);
+ if (number) fprintf(stdout, "%lu-", lastmatchnumber++);
pp = end_of_line(pp, endptr, &ellength);
FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout);
lastmatchrestart = pp;
@@ -1502,11 +1502,11 @@ static int
pcregrep(void *handle, int frtype, char *filename, char *printname)
{
int rc = 1;
-int linenumber = 1;
-int lastmatchnumber = 0;
-int count = 0;
int filepos = 0;
int offsets[OFFSET_SIZE];
+unsigned long int linenumber = 1;
+unsigned long int lastmatchnumber = 0;
+unsigned long int count = 0;
char *lastmatchrestart = NULL;
char *ptr = main_buffer;
char *endptr;
@@ -1609,7 +1609,7 @@ while (ptr < endptr)
if (endlinelength == 0 && t == main_buffer + bufsize)
{
- fprintf(stderr, "pcregrep: line %d%s%s is too long for the internal buffer\n"
+ fprintf(stderr, "pcregrep: line %lu%s%s is too long for the internal buffer\n"
"pcregrep: check the --buffer-size option\n",
linenumber,
(filename == NULL)? "" : " of file ",
@@ -1747,7 +1747,7 @@ while (ptr < endptr)
prevoffsets[1] = offsets[1];
if (printname != NULL) fprintf(stdout, "%s:", printname);
- if (number) fprintf(stdout, "%d:", linenumber);
+ if (number) fprintf(stdout, "%lu:", linenumber);
/* Handle --line-offsets */
@@ -1862,7 +1862,7 @@ while (ptr < endptr)
{
char *pp = lastmatchrestart;
if (printname != NULL) fprintf(stdout, "%s-", printname);
- if (number) fprintf(stdout, "%d-", lastmatchnumber++);
+ if (number) fprintf(stdout, "%lu-", lastmatchnumber++);
pp = end_of_line(pp, endptr, &ellength);
FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout);
lastmatchrestart = pp;
@@ -1902,7 +1902,7 @@ while (ptr < endptr)
int ellength;
char *pp = p;
if (printname != NULL) fprintf(stdout, "%s-", printname);
- if (number) fprintf(stdout, "%d-", linenumber - linecount--);
+ if (number) fprintf(stdout, "%lu-", linenumber - linecount--);
pp = end_of_line(pp, endptr, &ellength);
FWRITE(p, 1, pp - p, stdout);
p = pp;
@@ -1916,7 +1916,7 @@ while (ptr < endptr)
endhyphenpending = TRUE;
if (printname != NULL) fprintf(stdout, "%s:", printname);
- if (number) fprintf(stdout, "%d:", linenumber);
+ if (number) fprintf(stdout, "%lu:", linenumber);
/* In multiline mode, we want to print to the end of the line in which
the end of the matched string is found, so we adjust linelength and the
@@ -2112,7 +2112,7 @@ if (count_only && !quiet)
{
if (printname != NULL && filenames != FN_NONE)
fprintf(stdout, "%s:", printname);
- fprintf(stdout, "%d\n", count);
+ fprintf(stdout, "%lu\n", count);
}
}
@@ -2234,7 +2234,7 @@ if (isdirectory(pathname))
if (dee_action == dee_RECURSE)
{
- char buffer[1024];
+ char buffer[2048];
char *nextfile;
directory_type *dir = opendirectory(pathname);
@@ -2249,7 +2249,14 @@ if (isdirectory(pathname))
while ((nextfile = readdirectory(dir)) != NULL)
{
int frc;
- sprintf(buffer, "%.512s%c%.128s", pathname, FILESEP, nextfile);
+ int fnlength = strlen(pathname) + strlen(nextfile) + 2;
+ if (fnlength > 2048)
+ {
+ fprintf(stderr, "pcre2grep: recursive filename is too long\n");
+ rc = 2;
+ break;
+ }
+ sprintf(buffer, "%s%c%s", pathname, FILESEP, nextfile);
frc = grep_or_recurse(buffer, dir_recurse, FALSE);
if (frc > 1) rc = frc;
else if (frc == 0 && rc == 1) rc = 0;
@@ -2520,7 +2527,14 @@ if ((popts & PO_FIXED_STRINGS) != 0)
}
}
-sprintf(buffer, "%s%.*s%s", prefix[popts], patlen, ps, suffix[popts]);
+if (snprintf(buffer, PATBUFSIZE, "%s%.*s%s", prefix[popts], patlen, ps,
+ suffix[popts]) > PATBUFSIZE)
+ {
+ fprintf(stderr, "pcregrep: Buffer overflow while compiling \"%s\"\n",
+ ps);
+ return FALSE;
+ }
+
p->compiled = pcre_compile(buffer, options, &error, &errptr, pcretables);
if (p->compiled != NULL) return TRUE;
@@ -2756,8 +2770,15 @@ for (i = 1; i < argc; i++)
int arglen = (argequals == NULL || equals == NULL)?
(int)strlen(arg) : (int)(argequals - arg);
- sprintf(buff1, "%.*s", baselen, op->long_name);
- sprintf(buff2, "%s%.*s", buff1, fulllen - baselen - 2, opbra + 1);
+ if (snprintf(buff1, sizeof(buff1), "%.*s", baselen, op->long_name) >
+ (int)sizeof(buff1) ||
+ snprintf(buff2, sizeof(buff2), "%s%.*s", buff1,
+ fulllen - baselen - 2, opbra + 1) > (int)sizeof(buff2))
+ {
+ fprintf(stderr, "pcregrep: Buffer overflow when parsing %s option\n",
+ op->long_name);
+ pcregrep_exit(2);
+ }
if (strncmp(arg, buff1, arglen) == 0 ||
strncmp(arg, buff2, arglen) == 0)
diff --git a/pcre/pcreposix.c b/pcre/pcreposix.c
index 7b404a71100..a76d6bfca45 100644
--- a/pcre/pcreposix.c
+++ b/pcre/pcreposix.c
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2017 University of Cambridge
+ Copyright (c) 1997-2018 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -389,8 +389,8 @@ if (rc >= 0)
{
for (i = 0; i < (size_t)rc; i++)
{
- pmatch[i].rm_so = ovector[i*2] + so;
- pmatch[i].rm_eo = ovector[i*2+1] + so;
+ pmatch[i].rm_so = (ovector[i*2] < 0)? -1 : ovector[i*2] + so;
+ pmatch[i].rm_eo = (ovector[i*2+1] < 0)? -1: ovector[i*2+1] + so;
}
if (allocated_ovector) free(ovector);
for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;
diff --git a/pcre/testdata/testinput2 b/pcre/testdata/testinput2
index 08c6f39a565..8ba4dc4ddab 100644
--- a/pcre/testdata/testinput2
+++ b/pcre/testdata/testinput2
@@ -4249,4 +4249,12 @@ backtracking verbs. --/
/(?=.*[A-Z])/I
+"(?<=(a))\1?b"
+ ab
+ aaab
+
+"(?=(a))\1?b"
+ ab
+ aaab
+
/-- End of testinput2 --/
diff --git a/pcre/testdata/testinput5 b/pcre/testdata/testinput5
index 28561a93572..c94008c3f29 100644
--- a/pcre/testdata/testinput5
+++ b/pcre/testdata/testinput5
@@ -798,4 +798,10 @@
/(?<=\K\x{17f})/8G+
\x{17f}\x{17f}\x{17f}\x{17f}\x{17f}
+/\C[^\v]+\x80/8
+ [Aá¿»BÅ€C]
+
+/\C[^\d]+\x80/8
+ [Aá¿»BÅ€C]
+
/-- End of testinput5 --/
diff --git a/pcre/testdata/testoutput2 b/pcre/testdata/testoutput2
index 811bbefc84c..61ed8d9d4e4 100644
--- a/pcre/testdata/testoutput2
+++ b/pcre/testdata/testoutput2
@@ -14705,4 +14705,20 @@ No options
No first char
No need char
+"(?<=(a))\1?b"
+ ab
+ 0: b
+ 1: a
+ aaab
+ 0: ab
+ 1: a
+
+"(?=(a))\1?b"
+ ab
+ 0: ab
+ 1: a
+ aaab
+ 0: ab
+ 1: a
+
/-- End of testinput2 --/
diff --git a/pcre/testdata/testoutput5 b/pcre/testdata/testoutput5
index bab989ca7e5..090e1e1c85f 100644
--- a/pcre/testdata/testoutput5
+++ b/pcre/testdata/testoutput5
@@ -1942,4 +1942,12 @@ Need char = 'z'
0: \x{17f}
0+
+/\C[^\v]+\x80/8
+ [Aá¿»BÅ€C]
+No match
+
+/\C[^\d]+\x80/8
+ [Aá¿»BÅ€C]
+No match
+
/-- End of testinput5 --/
diff --git a/sql-common/client.c b/sql-common/client.c
index d9b81324c4d..fe43b593b1c 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1348,7 +1348,9 @@ unpack_fields(MYSQL *mysql, MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
{
uchar *pos;
/* fields count may be wrong */
- DBUG_ASSERT((uint) (field - result) < fields);
+ if (field - result >= fields)
+ goto err;
+
cli_fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7);
field->catalog= strmake_root(alloc,(char*) row->data[0], lengths[0]);
field->db= strmake_root(alloc,(char*) row->data[1], lengths[1]);
@@ -1366,12 +1368,7 @@ unpack_fields(MYSQL *mysql, MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
/* Unpack fixed length parts */
if (lengths[6] != 12)
- {
- /* malformed packet. signal an error. */
- free_rows(data); /* Free old data */
- set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
- DBUG_RETURN(0);
- }
+ goto err;
pos= (uchar*) row->data[6];
field->charsetnr= uint2korr(pos);
@@ -1398,6 +1395,8 @@ unpack_fields(MYSQL *mysql, MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
/* old protocol, for backward compatibility */
for (row=data->data; row ; row = row->next,field++)
{
+ if (field - result >= fields)
+ goto err;
cli_fetch_lengths(&lengths[0], row->data, default_value ? 6 : 5);
field->org_table= field->table= strdup_root(alloc,(char*) row->data[0]);
field->name= strdup_root(alloc,(char*) row->data[1]);
@@ -1434,8 +1433,17 @@ unpack_fields(MYSQL *mysql, MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
}
}
#endif /* DELETE_SUPPORT_OF_4_0_PROTOCOL */
+ if (field - result < fields)
+ goto err;
free_rows(data); /* Free old data */
DBUG_RETURN(result);
+
+err:
+ /* malformed packet. signal an error. */
+ free_rows(data);
+ free_root(alloc, MYF(0));
+ set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
+ DBUG_RETURN(0);
}
/* Read all rows (fields or data) from server */
@@ -1504,7 +1512,7 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
else
{
cur->data[field] = to;
- if (len > (ulong) (end_to - to))
+ if (unlikely(len > (ulong)(end_to-to) || to > end_to))
{
free_rows(result);
set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
@@ -1576,7 +1584,7 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
}
else
{
- if (pos + len > end_pos)
+ if (unlikely(len > (ulong)(end_pos - pos) || pos > end_pos))
{
set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
return -1;
@@ -2738,7 +2746,7 @@ static int client_mpvio_read_packet(struct st_plugin_vio *mpv, uchar **buf)
*buf= mysql->net.read_pos;
/* was it a request to change plugins ? */
- if (**buf == 254)
+ if (pkt_len == packet_error || **buf == 254)
return (int)packet_error; /* if yes, this plugin shan't continue */
/*
@@ -2923,7 +2931,7 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
compile_time_assert(CR_OK == -1);
compile_time_assert(CR_ERROR == 0);
- if (res > CR_OK && mysql->net.read_pos[0] != 254)
+ if (res > CR_OK && (mysql->net.last_errno || mysql->net.read_pos[0] != 254))
{
/*
the plugin returned an error. write it down in mysql,
diff --git a/sql/item.cc b/sql/item.cc
index 1d0ed6a6ea5..00d812cb3d7 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -472,7 +472,9 @@ Item::Item(THD *thd):
maybe_null=null_value=with_sum_func=with_field=0;
in_rollup= 0;
with_subselect= 0;
- /* Initially this item is not attached to any JOIN_TAB. */
+ with_param= 0;
+
+ /* Initially this item is not attached to any JOIN_TAB. */
join_tab_idx= MAX_TABLES;
/* Put item in free list so that we can free all items at end */
@@ -514,6 +516,7 @@ Item::Item(THD *thd, Item *item):
in_rollup(item->in_rollup),
null_value(item->null_value),
with_sum_func(item->with_sum_func),
+ with_param(item->with_param),
with_field(item->with_field),
fixed(item->fixed),
is_autogenerated_name(item->is_autogenerated_name),
@@ -1423,6 +1426,9 @@ bool Item_sp_variable::fix_fields(THD *thd, Item **)
max_length= it->max_length;
decimals= it->decimals;
unsigned_flag= it->unsigned_flag;
+ with_param= 1;
+ if (thd->lex->current_select->master_unit()->item)
+ thd->lex->current_select->master_unit()->item->with_param= 1;
fixed= 1;
collation.set(it->collation.collation, it->collation.derivation);
@@ -7178,6 +7184,7 @@ void Item_ref::set_properties()
split_sum_func() doesn't try to change the reference.
*/
with_sum_func= (*ref)->with_sum_func;
+ with_param= (*ref)->with_param;
with_field= (*ref)->with_field;
fixed= 1;
if (alias_name_used)
@@ -7603,6 +7610,7 @@ Item_cache_wrapper::Item_cache_wrapper(THD *thd, Item *item_arg):
Type_std_attributes::set(orig_item);
maybe_null= orig_item->maybe_null;
with_sum_func= orig_item->with_sum_func;
+ with_param= orig_item->with_param;
with_field= orig_item->with_field;
name= item_arg->name;
name_length= item_arg->name_length;
diff --git a/sql/item.h b/sql/item.h
index a9b8006cdf3..60073f054c9 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -694,6 +694,7 @@ public:
of a query with ROLLUP */
bool null_value; /* if item is null */
bool with_sum_func; /* True if item contains a sum func */
+ bool with_param; /* True if contains an SP parameter */
/**
True if any item except Item_sum contains a field. Set during parsing.
*/
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 4e2e5bd4cac..6ffd582c133 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1358,6 +1358,7 @@ bool Item_in_optimizer::fix_left(THD *thd)
}
eval_not_null_tables(NULL);
with_sum_func= args[0]->with_sum_func;
+ with_param= args[0]->with_param || args[1]->with_param;
with_field= args[0]->with_field;
if ((const_item_cache= args[0]->const_item()))
{
@@ -1406,6 +1407,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
with_subselect= 1;
with_sum_func= with_sum_func || args[1]->with_sum_func;
with_field= with_field || args[1]->with_field;
+ with_param= args[0]->with_param || args[1]->with_param;
used_tables_and_const_cache_join(args[1]);
fixed= 1;
return FALSE;
@@ -1955,6 +1957,7 @@ void Item_func_interval::fix_length_and_dec()
used_tables_and_const_cache_join(row);
not_null_tables_cache= row->not_null_tables();
with_sum_func= with_sum_func || row->with_sum_func;
+ with_param= with_param || row->with_param;
with_field= with_field || row->with_field;
}
@@ -4573,6 +4576,7 @@ Item_cond::fix_fields(THD *thd, Item **ref)
List_iterator<Item> li(list);
Item *item;
uchar buff[sizeof(char*)]; // Max local vars in function
+ bool is_and_cond= functype() == Item_func::COND_AND_FUNC;
not_null_tables_cache= 0;
used_tables_and_const_cache_init();
@@ -4635,26 +4639,33 @@ Item_cond::fix_fields(THD *thd, Item **ref)
(item= *li.ref())->check_cols(1))
return TRUE; /* purecov: inspected */
used_tables_cache|= item->used_tables();
- if (item->const_item())
+ if (item->const_item() && !item->with_param &&
+ !item->is_expensive() && !cond_has_datetime_is_null(item))
{
- if (!item->is_expensive() && !cond_has_datetime_is_null(item) &&
- item->val_int() == 0)
+ if (item->val_int() == is_and_cond && top_level())
{
/*
- This is "... OR false_cond OR ..."
+ a. This is "... AND true_cond AND ..."
+ In this case, true_cond has no effect on cond_and->not_null_tables()
+ b. This is "... OR false_cond/null cond OR ..."
In this case, false_cond has no effect on cond_or->not_null_tables()
*/
}
else
{
/*
- This is "... OR const_cond OR ..."
+ a. This is "... AND false_cond/null_cond AND ..."
+ The whole condition is FALSE/UNKNOWN.
+ b. This is "... OR const_cond OR ..."
In this case, cond_or->not_null_tables()=0, because the condition
const_cond might evaluate to true (regardless of whether some tables
were NULL-complemented).
*/
+ not_null_tables_cache= (table_map) 0;
and_tables_cache= (table_map) 0;
}
+ if (thd->is_error())
+ return TRUE;
}
else
{
@@ -4666,6 +4677,7 @@ Item_cond::fix_fields(THD *thd, Item **ref)
}
with_sum_func= with_sum_func || item->with_sum_func;
+ with_param= with_param || item->with_param;
with_field= with_field || item->with_field;
with_subselect|= item->has_subquery();
if (item->maybe_null)
@@ -4681,30 +4693,36 @@ bool
Item_cond::eval_not_null_tables(uchar *opt_arg)
{
Item *item;
+ bool is_and_cond= functype() == Item_func::COND_AND_FUNC;
List_iterator<Item> li(list);
not_null_tables_cache= (table_map) 0;
and_tables_cache= ~(table_map) 0;
while ((item=li++))
{
table_map tmp_table_map;
- if (item->const_item())
+ if (item->const_item() && !item->with_param &&
+ !item->is_expensive() && !cond_has_datetime_is_null(item))
{
- if (!item->is_expensive() && !cond_has_datetime_is_null(item) &&
- item->val_int() == 0)
+ if (item->val_int() == is_and_cond && top_level())
{
/*
- This is "... OR false_cond OR ..."
+ a. This is "... AND true_cond AND ..."
+ In this case, true_cond has no effect on cond_and->not_null_tables()
+ b. This is "... OR false_cond/null cond OR ..."
In this case, false_cond has no effect on cond_or->not_null_tables()
*/
}
else
{
/*
- This is "... OR const_cond OR ..."
+ a. This is "... AND false_cond/null_cond AND ..."
+ The whole condition is FALSE/UNKNOWN.
+ b. This is "... OR const_cond OR ..."
In this case, cond_or->not_null_tables()=0, because the condition
- some_cond_or might be true regardless of what tables are
- NULL-complemented.
+ const_cond might evaluate to true (regardless of whether some tables
+ were NULL-complemented).
*/
+ not_null_tables_cache= (table_map) 0;
and_tables_cache= (table_map) 0;
}
}
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 0700d71a396..05a34a9a24a 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -133,6 +133,7 @@ void Item_func::sync_with_sum_func_and_with_field(List<Item> &list)
{
with_sum_func|= item->with_sum_func;
with_field|= item->with_field;
+ with_param|= item->with_param;
}
}
@@ -226,6 +227,7 @@ Item_func::fix_fields(THD *thd, Item **ref)
maybe_null=1;
with_sum_func= with_sum_func || item->with_sum_func;
+ with_param= with_param || item->with_param;
with_field= with_field || item->with_field;
used_tables_and_const_cache_join(item);
with_subselect|= item->has_subquery();
@@ -3506,6 +3508,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
func->maybe_null=1;
func->with_sum_func= func->with_sum_func || item->with_sum_func;
func->with_field= func->with_field || item->with_field;
+ func->with_param= func->with_param || item->with_param;
func->with_subselect|= item->with_subselect;
func->used_tables_and_const_cache_join(item);
f_args.arg_type[i]=item->result_type();
diff --git a/sql/item_func.h b/sql/item_func.h
index 25f96be7962..3219c813821 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -74,16 +74,19 @@ public:
{
with_sum_func= 0;
with_field= 0;
+ with_param= 0;
}
Item_func(THD *thd, Item *a): Item_func_or_sum(thd, a), allowed_arg_cols(1)
{
with_sum_func= a->with_sum_func;
+ with_param= a->with_param;
with_field= a->with_field;
}
Item_func(THD *thd, Item *a, Item *b):
Item_func_or_sum(thd, a, b), allowed_arg_cols(1)
{
with_sum_func= a->with_sum_func || b->with_sum_func;
+ with_param= a->with_param || b->with_param;
with_field= a->with_field || b->with_field;
}
Item_func(THD *thd, Item *a, Item *b, Item *c):
@@ -91,6 +94,7 @@ public:
{
with_sum_func= a->with_sum_func || b->with_sum_func || c->with_sum_func;
with_field= a->with_field || b->with_field || c->with_field;
+ with_param= a->with_param || b->with_param || c->with_param;
}
Item_func(THD *thd, Item *a, Item *b, Item *c, Item *d):
Item_func_or_sum(thd, a, b, c, d), allowed_arg_cols(1)
@@ -99,6 +103,8 @@ public:
c->with_sum_func || d->with_sum_func;
with_field= a->with_field || b->with_field ||
c->with_field || d->with_field;
+ with_param= a->with_param || b->with_param ||
+ c->with_param || d->with_param;
}
Item_func(THD *thd, Item *a, Item *b, Item *c, Item *d, Item* e):
Item_func_or_sum(thd, a, b, c, d, e), allowed_arg_cols(1)
@@ -107,6 +113,8 @@ public:
c->with_sum_func || d->with_sum_func || e->with_sum_func;
with_field= a->with_field || b->with_field ||
c->with_field || d->with_field || e->with_field;
+ with_param= a->with_param || b->with_param ||
+ c->with_param || d->with_param || e->with_param;
}
Item_func(THD *thd, List<Item> &list):
Item_func_or_sum(thd, list), allowed_arg_cols(1)
diff --git a/sql/item_row.cc b/sql/item_row.cc
index 97f75c4b4cf..8c6edacad7f 100644
--- a/sql/item_row.cc
+++ b/sql/item_row.cc
@@ -64,6 +64,7 @@ bool Item_row::fix_fields(THD *thd, Item **ref)
with_sum_func= with_sum_func || item->with_sum_func;
with_field= with_field || item->with_field;
with_subselect|= item->with_subselect;
+ with_param|= item->with_param;
}
fixed= 1;
return FALSE;
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 0e2e9f0795d..b4e31ba012f 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1159,6 +1159,7 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
return TRUE;
set_if_bigger(decimals, args[i]->decimals);
with_subselect|= args[i]->with_subselect;
+ with_param|= args[i]->with_param;
}
result_field=0;
max_length=float_length(decimals);
@@ -1190,6 +1191,7 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
return TRUE;
Type_std_attributes::set(args[0]);
with_subselect= args[0]->with_subselect;
+ with_param= args[0]->with_param;
Item *item2= item->real_item();
if (item2->type() == Item::FIELD_ITEM)
@@ -3361,6 +3363,7 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref)
args[i]->check_cols(1))
return TRUE;
with_subselect|= args[i]->with_subselect;
+ with_param|= args[i]->with_param;
}
/* skip charset aggregation for order columns */
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 05cc8db057a..89338928cb5 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -3744,22 +3744,30 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab)
sjm= emb_sj_nest->sj_mat_info;
thd= tab->join->thd;
/* First the calls come to the materialization function */
- //List<Item> &item_list= emb_sj_nest->sj_subq_pred->unit->first_select()->item_list;
-
+
DBUG_ASSERT(sjm->is_used);
/*
Set up the table to write to, do as select_union::create_result_table does
*/
sjm->sjm_table_param.init();
sjm->sjm_table_param.bit_fields_as_long= TRUE;
- //List_iterator<Item> it(item_list);
SELECT_LEX *subq_select= emb_sj_nest->sj_subq_pred->unit->first_select();
- Item **p_item= subq_select->ref_pointer_array;
- Item **p_end= p_item + subq_select->item_list.elements;
- //while((right_expr= it++))
- for(;p_item != p_end; p_item++)
- sjm->sjm_table_cols.push_back(*p_item, thd->mem_root);
-
+ List_iterator<Item> it(subq_select->item_list);
+ Item *item;
+ while((item= it++))
+ {
+ /*
+ This semi-join replaced the subquery (subq_select) and so on
+ re-executing it will not be prepared. To use the Items from its
+ select list we have to prepare (fix_fields) them
+ */
+ if (!item->fixed && item->fix_fields(thd, it.ref()))
+ DBUG_RETURN(TRUE);
+ item= *(it.ref()); // it can be changed by fix_fields
+ DBUG_ASSERT(!item->name_length || item->name_length == strlen(item->name));
+ sjm->sjm_table_cols.push_back(item, thd->mem_root);
+ }
+
sjm->sjm_table_param.field_count= subq_select->item_list.elements;
sjm->sjm_table_param.force_not_null_cols= TRUE;
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index ce139280c5d..a5c91b49951 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -11475,6 +11475,7 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio,
const char *client_auth_plugin=
((st_mysql_auth *) (plugin_decl(mpvio->plugin)->info))->client_auth_plugin;
+ DBUG_EXECUTE_IF("auth_disconnect", { vio_close(net->vio); DBUG_RETURN(1); });
DBUG_ASSERT(client_auth_plugin);
/*
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index a5208ef29a5..8472117510b 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -995,10 +995,7 @@ void close_thread_tables(THD *thd)
we will exit this function a few lines below.
*/
if (! thd->lex->requires_prelocking())
- {
- thd->locked_tables_list.reopen_tables(thd, true);
DBUG_VOID_RETURN;
- }
/*
We are in the top-level statement of a prelocked statement,
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 5c03999c9ac..3d40f8e4245 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5722,6 +5722,10 @@ finish:
lex->unit.cleanup();
+ /* close/reopen tables that were marked to need reopen under LOCK TABLES */
+ if (! thd->lex->requires_prelocking())
+ thd->locked_tables_list.reopen_tables(thd, true);
+
if (! thd->in_sub_stmt)
{
if (thd->killed != NOT_KILLED)
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 067c71205d0..e56f301af86 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1148,9 +1148,6 @@ JOIN::optimize_inner()
eval_select_list_used_tables();
- if (optimize_constant_subqueries())
- DBUG_RETURN(1);
-
table_count= select_lex->leaf_tables.elements;
if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */
@@ -1212,6 +1209,9 @@ JOIN::optimize_inner()
thd->restore_active_arena(arena, &backup);
}
+ if (optimize_constant_subqueries())
+ DBUG_RETURN(1);
+
if (setup_jtbm_semi_joins(this, join_list, &conds))
DBUG_RETURN(1);
diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt
index e283da97c4b..6e8c8baf90e 100644
--- a/storage/connect/CMakeLists.txt
+++ b/storage/connect/CMakeLists.txt
@@ -230,7 +230,7 @@ ENDIF(CONNECT_WITH_ODBC)
#
# JDBC with MongoDB Java Driver included but disabled if without MONGO
#
-# OPTION(CONNECT_WITH_MONGO "Compile CONNECT storage engine with MONGO support" ON)
+#OPTION(CONNECT_WITH_MONGO "Compile CONNECT storage engine with MONGO support" ON)
OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON)
IF(CONNECT_WITH_JDBC)
@@ -326,6 +326,13 @@ IF(NOT TARGET connect)
RETURN()
ENDIF()
+IF(WIN32)
+ IF (libmongoc-1.0_FOUND)
+ SET_TARGET_PROPERTIES(connect PROPERTIES LINK_FLAGS
+ "/DELAYLOAD:libbson-1.0.dll /DELAYLOAD:libmongoc-1.0.dll")
+ ENDIF(libmongoc-1.0_FOUND)
+ENDIF(WIN32)
+
# Install some extra files that belong to connect engine
IF(WIN32)
# install ha_connect.lib
diff --git a/storage/connect/Client.java b/storage/connect/Client.java
index aaf1b7bf2f8..afa54fa4256 100644
--- a/storage/connect/Client.java
+++ b/storage/connect/Client.java
@@ -1,9 +1,13 @@
+
package wrappers;
import java.io.BufferedReader;
import java.io.Console;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
public class Client {
static boolean DEBUG = true;
@@ -58,6 +62,9 @@ public class Client {
String query;
System.out.println("Successfully connected to " + parms[1]);
+ s = jdi.GetQuoteString();
+ System.out.println("Qstr = '" + s + "'");
+
while ((query = getLine("Query: ", false)) != null) {
n = jdi.Execute(query);
System.out.println("Returned n = " + n);
@@ -79,7 +86,11 @@ public class Client {
private static void PrintResult(int ncol) {
// Get result set meta data
int i;
+ Date date = new Date(0);
+ Time time = new Time(0);
+ Timestamp tsp = new Timestamp(0);
String columnName;
+ Object job;
// Get the column names; column indices start from 1
for (i = 1; i <= ncol; i++) {
@@ -112,6 +123,7 @@ public class Client {
case java.sql.Types.VARCHAR:
case java.sql.Types.LONGVARCHAR:
case java.sql.Types.CHAR:
+ case 1111:
System.out.print(jdi.StringField(i, null));
break;
case java.sql.Types.INTEGER:
@@ -120,14 +132,17 @@ public class Client {
case java.sql.Types.BIGINT:
System.out.print(jdi.BigintField(i, null));
break;
- case java.sql.Types.TIMESTAMP:
- System.out.print(jdi.TimestampField(i, null));
- break;
case java.sql.Types.TIME:
- System.out.print(jdi.TimeField(i, null));
+ time.setTime((long)jdi.TimeField(i, null) * 1000);
+ System.out.print(time);
break;
case java.sql.Types.DATE:
- System.out.print(jdi.DateField(i, null));
+ date.setTime((long)jdi.DateField(i, null) * 1000);
+ System.out.print(date);
+ break;
+ case java.sql.Types.TIMESTAMP:
+ tsp.setTime((long)jdi.TimestampField(i, null) * 1000);
+ System.out.print(tsp);
break;
case java.sql.Types.SMALLINT:
System.out.print(jdi.IntField(i, null));
@@ -141,6 +156,8 @@ public class Client {
case java.sql.Types.BOOLEAN:
System.out.print(jdi.BooleanField(i, null));
default:
+ job = jdi.ObjectField(i, null);
+ System.out.print(job.toString());
break;
} // endswitch Type
diff --git a/storage/connect/JavaWrappers.jar b/storage/connect/JavaWrappers.jar
index ef407f6a9c2..33b29e7685b 100644
--- a/storage/connect/JavaWrappers.jar
+++ b/storage/connect/JavaWrappers.jar
Binary files differ
diff --git a/storage/connect/JdbcInterface.java b/storage/connect/JdbcInterface.java
index a1b1360e6ea..72ee4ab0d39 100644
--- a/storage/connect/JdbcInterface.java
+++ b/storage/connect/JdbcInterface.java
@@ -1,10 +1,22 @@
package wrappers;
-import java.math.*;
-import java.sql.*;
+import java.math.BigDecimal;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.Date;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
+import java.util.UUID;
import javax.sql.DataSource;
@@ -223,6 +235,24 @@ public class JdbcInterface {
} // end of SetTimestampParm
+ public void SetUuidParm(int i, String s) {
+ try {
+ UUID uuid;
+
+ if (s == null)
+ uuid = null;
+ else if (s.isEmpty())
+ uuid = UUID.randomUUID();
+ else
+ uuid = UUID.fromString(s);
+
+ pstmt.setObject(i, uuid);
+ } catch (Exception e) {
+ SetErrmsg(e);
+ } // end try/catch
+
+ } // end of SetUuidParm
+
public int SetNullParm(int i, int typ) {
int rc = 0;
@@ -481,6 +511,8 @@ public class JdbcInterface {
System.out.println("Executing query '" + query + "'");
try {
+ if (rs != null)
+ rs.close();
rs = stmt.executeQuery(query);
rsmd = rs.getMetaData();
ncol = rsmd.getColumnCount();
@@ -708,7 +740,7 @@ public class JdbcInterface {
return 0;
} // end of TimestampField
- public Object ObjectField(int n, String name) {
+ public Object ObjectField(int n, String name) {
if (rs == null) {
System.out.println("No result set");
} else try {
@@ -720,6 +752,22 @@ public class JdbcInterface {
return null;
} // end of ObjectField
+ public String UuidField(int n, String name) {
+ Object job;
+
+ if (rs == null) {
+ System.out.println("No result set");
+ } else
+ try {
+ job = (n > 0) ? rs.getObject(n) : rs.getObject(name);
+ return job.toString();
+ } catch (SQLException se) {
+ SetErrmsg(se);
+ } // end try/catch
+
+ return null;
+ } // end of UuidField
+
public int GetDrivers(String[] s, int mxs) {
int n = 0;
List<Driver> drivers = Collections.list(DriverManager.getDrivers());
diff --git a/storage/connect/PostgresqlInterface.java b/storage/connect/PostgresqlInterface.java
index adce0616a1b..9f611eeb23b 100644
--- a/storage/connect/PostgresqlInterface.java
+++ b/storage/connect/PostgresqlInterface.java
@@ -1,9 +1,10 @@
package wrappers;
-import java.sql.*;
+import java.sql.SQLException;
import java.util.Hashtable;
import javax.sql.DataSource;
+
import org.postgresql.jdbc2.optional.PoolingDataSource;
public class PostgresqlInterface extends JdbcInterface {
@@ -19,7 +20,7 @@ public class PostgresqlInterface extends JdbcInterface {
} // end of constructor
- @Override
+ @Override
public int JdbcConnect(String[] parms, int fsize, boolean scrollable) {
int rc = 0;
String url = parms[1];
diff --git a/storage/connect/array.cpp b/storage/connect/array.cpp
index 639edf63a1a..cd1785b48ac 100644
--- a/storage/connect/array.cpp
+++ b/storage/connect/array.cpp
@@ -82,7 +82,7 @@ PARRAY MakeValueArray(PGLOBAL g, PPARM pp)
if ((valtyp = pp->Type) != TYPE_STRING)
len = 1;
- if (trace)
+ if (trace(1))
htrc("valtyp=%d len=%d\n", valtyp, len);
/*********************************************************************/
@@ -287,7 +287,7 @@ bool ARRAY::AddValue(PGLOBAL g, PSZ strp)
return true;
} // endif Type
- if (trace)
+ if (trace(1))
htrc(" adding string(%d): '%s'\n", Nval, strp);
//Value->SetValue_psz(strp);
@@ -306,7 +306,7 @@ bool ARRAY::AddValue(PGLOBAL g, void *p)
return true;
} // endif Type
- if (trace)
+ if (trace(1))
htrc(" adding pointer(%d): %p\n", Nval, p);
Vblp->SetValue((PSZ)p, Nval++);
@@ -323,7 +323,7 @@ bool ARRAY::AddValue(PGLOBAL g, short n)
return true;
} // endif Type
- if (trace)
+ if (trace(1))
htrc(" adding SHORT(%d): %hd\n", Nval, n);
//Value->SetValue(n);
@@ -342,7 +342,7 @@ bool ARRAY::AddValue(PGLOBAL g, int n)
return true;
} // endif Type
- if (trace)
+ if (trace(1))
htrc(" adding int(%d): %d\n", Nval, n);
//Value->SetValue(n);
@@ -361,7 +361,7 @@ bool ARRAY::AddValue(PGLOBAL g, double d)
return true;
} // endif Type
- if (trace)
+ if (trace(1))
htrc(" adding float(%d): %lf\n", Nval, d);
Value->SetValue(d);
@@ -380,7 +380,7 @@ bool ARRAY::AddValue(PGLOBAL g, PXOB xp)
return true;
} // endif Type
- if (trace)
+ if (trace(1))
htrc(" adding (%d) from xp=%p\n", Nval, xp);
//AddValue(xp->GetValue());
@@ -399,7 +399,7 @@ bool ARRAY::AddValue(PGLOBAL g, PVAL vp)
return true;
} // endif Type
- if (trace)
+ if (trace(1))
htrc(" adding (%d) from vp=%p\n", Nval, vp);
Vblp->SetValue(vp, Nval++);
@@ -520,7 +520,7 @@ bool ARRAY::FilTest(PGLOBAL g, PVAL valp, OPVAL opc, int opm)
} else if (opc != OP_EXIST) {
sprintf(g->Message, MSG(MISSING_ARG), opc);
- throw (int)TYPE_ARRAY;
+ throw (int)TYPE_ARRAY;
} else // OP_EXIST
return Nval > 0;
@@ -990,7 +990,7 @@ PSZ ARRAY::MakeArrayList(PGLOBAL g)
len += strlen(tp);
} // enfor i
- if (trace)
+ if (trace(1))
htrc("Arraylist: len=%d\n", len);
p = (char *)PlugSubAlloc(g, NULL, len);
@@ -1003,7 +1003,7 @@ PSZ ARRAY::MakeArrayList(PGLOBAL g)
strcat(p, (++i == Nval) ? ")" : ",");
} // enfor i
- if (trace)
+ if (trace(1))
htrc("Arraylist: newlen=%d\n", strlen(p));
return p;
diff --git a/storage/connect/blkfil.cpp b/storage/connect/blkfil.cpp
index 802095f2f82..76c9d09ac93 100644
--- a/storage/connect/blkfil.cpp
+++ b/storage/connect/blkfil.cpp
@@ -241,7 +241,7 @@ int BLKFILARI::BlockEval(PGLOBAL)
break;
} // endswitch Opc
- if (trace)
+ if (trace(1))
htrc("BlockEval: op=%d n=%d rc=%d\n", Opc, n, Result);
return Result;
@@ -338,7 +338,7 @@ int BLKFILAR2::BlockEval(PGLOBAL)
break;
} // endswitch Opc
- if (trace)
+ if (trace(1))
htrc("BlockEval2: op=%d n=%d rc=%d\n", Opc, n, Result);
return Result;
@@ -474,7 +474,7 @@ int BLKFILMR2::BlockEval(PGLOBAL)
break;
} // endswitch Opc
- if (trace)
+ if (trace(1))
htrc("BlockEval2: op=%d n=%d rc=%d\n", Opc, n, Result);
return Result;
@@ -567,7 +567,7 @@ int BLKSPCARI::BlockEval(PGLOBAL)
break;
} // endswitch Opc
- if (trace)
+ if (trace(1))
htrc("BlockEval: op=%d n=%d rc=%d\n", Opc, n, Result);
return Result;
diff --git a/storage/connect/block.h b/storage/connect/block.h
index 8ac7be80988..737c74c1293 100644
--- a/storage/connect/block.h
+++ b/storage/connect/block.h
@@ -38,8 +38,8 @@ typedef class BLOCK *PBLOCK;
class DllExport BLOCK {
public:
void * operator new(size_t size, PGLOBAL g, void *p = NULL) {
-// if (trace > 3)
-// htrc("New BLOCK: size=%d g=%p p=%p\n", size, g, p);
+ if (trace(256))
+ htrc("New BLOCK: size=%d g=%p p=%p\n", size, g, p);
return (PlugSubAlloc(g, p, size));
} // end of new
diff --git a/storage/connect/checklvl.h b/storage/connect/checklvl.h
index 0c234dfb8b8..9029e616bb6 100644
--- a/storage/connect/checklvl.h
+++ b/storage/connect/checklvl.h
@@ -45,6 +45,7 @@ enum USETEMP {TMP_NO = 0, /* Never */
/***********************************************************************/
enum TYPCONV {TPC_NO = 0, /* Never */
TPC_YES = 1, /* Always */
- TPC_SKIP = 2}; /* Skip TEXT columns */
+ TPC_FORCE = 2, /* Also convert BLOBs */
+ TPC_SKIP = 3}; /* Skip TEXT columns */
#endif // _CHKLVL_DEFINED_
diff --git a/storage/connect/cmgoconn.cpp b/storage/connect/cmgoconn.cpp
index 44fac56137f..edee1874b97 100644
--- a/storage/connect/cmgoconn.cpp
+++ b/storage/connect/cmgoconn.cpp
@@ -280,7 +280,7 @@ bool CMgoConn::MakeCursor(PGLOBAL g)
all = true;
if (Pcg->Pipe) {
- if (trace)
+ if (trace(1))
htrc("Pipeline: %s\n", options);
p = strrchr(options, ']');
@@ -330,7 +330,7 @@ bool CMgoConn::MakeCursor(PGLOBAL g)
*(char*)p = ']'; // Restore Colist for discovery
p = s->GetStr();
- if (trace)
+ if (trace(33))
htrc("New Pipeline: %s\n", p);
Query = bson_new_from_json((const uint8_t *)p, -1, &Error);
@@ -350,7 +350,7 @@ bool CMgoConn::MakeCursor(PGLOBAL g)
} else {
if (Pcg->Filter || filp) {
- if (trace) {
+ if (trace(1)) {
if (Pcg->Filter)
htrc("Filter: %s\n", Pcg->Filter);
@@ -377,7 +377,7 @@ bool CMgoConn::MakeCursor(PGLOBAL g)
tp->SetFilter(NULL); // Not needed anymore
} // endif To_Filter
- if (trace)
+ if (trace(33))
htrc("selector: %s\n", s->GetStr());
s->Resize(s->GetLength() + 1);
@@ -393,7 +393,7 @@ bool CMgoConn::MakeCursor(PGLOBAL g)
if (!all) {
if (options && *options) {
- if (trace)
+ if (trace(1))
htrc("options=%s\n", options);
p = options;
@@ -450,10 +450,10 @@ int CMgoConn::ReadNext(PGLOBAL g)
if (!Cursor && MakeCursor(g)) {
rc = RC_FX;
} else if (mongoc_cursor_next(Cursor, &Document)) {
- if (trace > 1) {
+ if (trace(512)) {
bson_iter_t iter;
ShowDocument(&iter, Document, "");
- } else if (trace == 1)
+ } else if (trace(1))
htrc("%s\n", GetDocument(g));
} else if (mongoc_cursor_error(Cursor, &Error)) {
@@ -589,7 +589,7 @@ int CMgoConn::Write(PGLOBAL g)
if (DocWrite(g, Fpc))
return RC_FX;
- if (trace) {
+ if (trace(2)) {
char *str = bson_as_json(Fpc->Child, NULL);
htrc("Inserting: %s\n", str);
bson_free(str);
@@ -623,7 +623,7 @@ int CMgoConn::Write(PGLOBAL g)
} // endif iter
if (b) {
- if (trace) {
+ if (trace(2)) {
char *str = bson_as_json(query, NULL);
htrc("update query: %s\n", str);
bson_free(str);
diff --git a/storage/connect/colblk.cpp b/storage/connect/colblk.cpp
index 2ffe51d2009..a9cf43f3d96 100644
--- a/storage/connect/colblk.cpp
+++ b/storage/connect/colblk.cpp
@@ -76,7 +76,7 @@ COLBLK::COLBLK(PCOL col1, PTDB tdbp)
//To_Orig = col1;
To_Tdb = tdbp;
- if (trace > 1)
+ if (trace(2))
htrc(" copying COLBLK %s from %p to %p\n", Name, col1, this);
if (tdbp)
@@ -115,7 +115,7 @@ bool COLBLK::SetFormat(PGLOBAL, FORMAT& fmt)
{
fmt = Format;
- if (trace > 1)
+ if (trace(2))
htrc("COLBLK: %p format=%c(%d,%d)\n",
this, *fmt.Type, fmt.Length, fmt.Prec);
@@ -128,7 +128,7 @@ bool COLBLK::SetFormat(PGLOBAL, FORMAT& fmt)
/***********************************************************************/
bool COLBLK::Eval(PGLOBAL g)
{
- if (trace > 1)
+ if (trace(2))
htrc("Col Eval: %s status=%.4X\n", Name, Status);
if (!GetStatus(BUF_READ)) {
@@ -165,7 +165,7 @@ bool COLBLK::InitValue(PGLOBAL g)
AddStatus(BUF_READY);
Value->SetNullable(Nullable);
- if (trace > 1)
+ if (trace(2))
htrc(" colp=%p type=%d value=%p coluse=%.4X status=%.4X\n",
this, Buf_Type, Value, ColUse, Status);
@@ -412,4 +412,3 @@ void SIDBLK::ReadColumn(PGLOBAL)
// } // endif Sname
} // end of ReadColumn
-
diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc
index 5e80201fccf..39123b18c59 100644
--- a/storage/connect/connect.cc
+++ b/storage/connect/connect.cc
@@ -92,7 +92,7 @@ void CntEndDB(PGLOBAL g)
free(dbuserp);
- if (trace)
+ if (trace(1))
htrc("CntEndDB: Freeing Dup\n");
g->Activityp->Aptr = NULL;
@@ -112,14 +112,14 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname)
bool rc= false;
PDBUSER dbuserp= PlgGetUser(g);
- if (trace) {
+ if (trace(1)) {
printf("CntCheckDB: dbuserp=%p\n", dbuserp);
} // endif trace
if (!dbuserp || !handler)
return true;
- if (trace)
+ if (trace(1))
printf("cat=%p oldhandler=%p newhandler=%p\n", dbuserp->Catalog,
(dbuserp->Catalog) ? ((MYCAT*)dbuserp->Catalog)->GetHandler() : NULL,
handler);
@@ -150,7 +150,7 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname)
/*********************************************************************/
sprintf(g->Message, MSG(DATABASE_LOADED), "???");
- if (trace)
+ if (trace(1))
printf("msg=%s\n", g->Message);
return rc;
@@ -198,7 +198,7 @@ PTDB CntGetTDB(PGLOBAL g, LPCSTR name, MODE mode, PHC h)
PDBUSER dup = PlgGetUser(g);
volatile PCATLG cat = (dup) ? dup->Catalog : NULL; // Safe over throw
- if (trace)
+ if (trace(1))
printf("CntGetTDB: name=%s mode=%d cat=%p\n", name, mode, cat);
if (!cat)
@@ -208,7 +208,7 @@ PTDB CntGetTDB(PGLOBAL g, LPCSTR name, MODE mode, PHC h)
// Get table object from the catalog
tabp = new(g) XTAB(name);
- if (trace)
+ if (trace(1))
printf("CntGetTDB: tabp=%p\n", tabp);
// Perhaps this should be made thread safe
@@ -218,13 +218,13 @@ PTDB CntGetTDB(PGLOBAL g, LPCSTR name, MODE mode, PHC h)
printf("CntGetTDB: %s\n", g->Message);
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
} catch (const char *msg) {
strcpy(g->Message, msg);
} // end catch
- if (trace)
+ if (trace(1))
printf("Returning tdbp=%p mode=%d\n", tdbp, mode);
return tdbp;
@@ -243,7 +243,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
//PCOLUMN cp;
PDBUSER dup= PlgGetUser(g);
- if (trace)
+ if (trace(1))
printf("CntOpenTable: tdbp=%p mode=%d\n", tdbp, mode);
if (!tdbp) {
@@ -260,7 +260,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
} else for (p = c1; *p; p += n) {
// Allocate only used column blocks
- if (trace)
+ if (trace(1))
printf("Allocating column %s\n", p);
g->Message[0] = 0; // To check whether ColDB made an error message
@@ -325,7 +325,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
tdbp->SetSetCols(tdbp->GetColumns());
// Now do open the physical table
- if (trace)
+ if (trace(1))
printf("Opening table %s in mode %d tdbp=%p\n",
tdbp->GetName(), mode, tdbp);
@@ -341,7 +341,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
} // endif del
- if (trace)
+ if (trace(1))
printf("About to open the table: tdbp=%p\n", tdbp);
if (mode != MODE_ANY && mode != MODE_ALTER) {
@@ -356,7 +356,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
rcop = false;
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
} catch (const char *msg) {
strcpy(g->Message, msg);
@@ -399,12 +399,13 @@ RCODE EvalColumns(PGLOBAL g, PTDB tdbp, bool reset, bool mrr)
} // endfor colp
} catch (int n) {
- if (trace)
+ if (trace(1))
printf("Error %d reading columns: %s\n", n, g->Message);
rc = RC_FX;
} catch (const char *msg) {
strcpy(g->Message, msg);
+ rc = RC_NF;
} // end catch
return rc;
@@ -549,7 +550,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
return rc;
} // endif !USE_OPEN
- if (trace)
+ if (trace(1))
printf("CntCloseTable: tdbp=%p mode=%d nox=%d abort=%d\n",
tdbp, tdbp->GetMode(), nox, abort);
@@ -579,11 +580,11 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
tdbp->CloseDB(g);
tdbp->SetAbort(false);
- if (trace > 1)
+ if (trace(2))
printf("Table %s closed\n", tdbp->GetName());
if (!nox && tdbp->GetMode() != MODE_READ && tdbp->GetMode() != MODE_ANY) {
- if (trace > 1)
+ if (trace(2))
printf("About to reset opt\n");
if (!tdbp->IsRemote()) {
@@ -603,7 +604,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
rc = RC_FX;
} // end catch
- if (trace > 1)
+ if (trace(2))
htrc("Done rc=%d\n", rc);
return (rc == RC_OK || rc == RC_INFO) ? 0 : rc;
@@ -922,7 +923,7 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
valp->SetBinValue((void*)p);
#endif // !WORDS_BIGENDIAN
- if (trace) {
+ if (trace(1)) {
char bf[32];
printf("i=%d n=%d key=%s\n", i, n, valp->GetCharString(bf));
} // endif trace
@@ -944,7 +945,7 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
xbp->SetNval(n);
- if (trace)
+ if (trace(1))
printf("xbp=%p Nval=%d i=%d incl=%d\n", xbp, n, i, incl[i]);
k[i]= xbp->Range(g, i + 1, incl[i]);
@@ -953,7 +954,7 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
} // endfor i
- if (trace)
+ if (trace(1))
printf("k1=%d k0=%d\n", k[1], k[0]);
return k[1] - k[0];
diff --git a/storage/connect/csort.cpp b/storage/connect/csort.cpp
index 13f325d8f3f..670131b8fd2 100644
--- a/storage/connect/csort.cpp
+++ b/storage/connect/csort.cpp
@@ -351,7 +351,7 @@ void CSORT::Qstx(int *base, int *max)
zlo = zhi = cnm = 0; // Avoid warning message
- lo = max - base; // Number of elements as longs
+ lo = (int)(max - base); // Number of elements as longs
if (Dup)
cnm = Cmpnum(lo);
@@ -472,7 +472,7 @@ void CSORT::Qstx(int *base, int *max)
i = him + 1;
if (Pof)
- Pof[him - Pex] = Pof[mid - Pex] = i - j;
+ Pof[him - Pex] = Pof[mid - Pex] = (int)(i - j);
/*******************************************************************/
/* Look at sizes of the two partitions, do the smaller one first */
@@ -481,8 +481,8 @@ void CSORT::Qstx(int *base, int *max)
/* But only repeat (recursively or by branching) if the partition */
/* is of at least size THRESH. */
/*******************************************************************/
- lo = j - base;
- hi = max - i;
+ lo = (int)(j - base);
+ hi = (int)(max - i);
if (Dup) { // Update progress information
zlo = Cmpnum(lo);
@@ -726,7 +726,7 @@ void CSORT::Qstc(int *base, int *max)
zlo = zhi = cnm = 0; // Avoid warning message
- lo = max - base; // Number of elements as longs
+ lo = (int)(max - base); // Number of elements as longs
if (Dup)
cnm = Cmpnum(lo);
@@ -853,7 +853,7 @@ void CSORT::Qstc(int *base, int *max)
/* the offset array values indicating break point and block size. */
/*******************************************************************/
if (Pof)
- Pof[lt - Pex] = Pof[(jj - 1) - Pex] = jj - lt;
+ Pof[lt - Pex] = Pof[(jj - 1) - Pex] = (int)(jj - lt);
/*******************************************************************/
/* Look at sizes of the two partitions, do the smaller one first */
@@ -862,8 +862,8 @@ void CSORT::Qstc(int *base, int *max)
/* But only repeat (recursively or by branching) if the partition */
/* is of at least size THRESH. */
/*******************************************************************/
- lo = lt - base;
- hi = gt - Swix;
+ lo = (int)(lt - base);
+ hi = (int)(gt - Swix);
if (Dup) { // Update progress information
zlo = Cmpnum(lo);
diff --git a/storage/connect/domdoc.cpp b/storage/connect/domdoc.cpp
index e24e10835c1..ba8eb829abd 100644
--- a/storage/connect/domdoc.cpp
+++ b/storage/connect/domdoc.cpp
@@ -13,6 +13,7 @@
#elif defined(MSX4)
#import "msxml4.dll" //Causes error C2872: DOMNodeType: ambiguous symbol ??
#elif defined(MSX6)
+#pragma warning(suppress : 4192)
#import "msxml6.dll" //Causes error C2872: DOMNodeType: ambiguous symbol ??
#else // MSX4
#error MSX? is not defined
@@ -540,7 +541,7 @@ PXNODE DOMNODE::AddChildNode(PGLOBAL g, PCSZ name, PXNODE np)
// If name has the format m[n] only m is taken as node name
if ((p = strchr(name, '[')))
- pn = BufAlloc(g, name, p - name);
+ pn = BufAlloc(g, name, (int)(p - name));
else
pn = name;
diff --git a/storage/connect/filamap.cpp b/storage/connect/filamap.cpp
index 84dff422db7..6e71e1bf2cd 100644
--- a/storage/connect/filamap.cpp
+++ b/storage/connect/filamap.cpp
@@ -90,7 +90,7 @@ int MAPFAM::GetFileLength(PGLOBAL g)
len = (To_Fb && To_Fb->Count) ? To_Fb->Length : TXTFAM::GetFileLength(g);
- if (trace)
+ if (trace(1))
htrc("Mapped file length=%d\n", len);
return len;
@@ -128,7 +128,7 @@ bool MAPFAM::OpenTableFile(PGLOBAL g)
&& fp->Count && fp->Mode == mode)
break;
- if (trace)
+ if (trace(1))
htrc("Mapping file, fp=%p\n", fp);
} else
@@ -166,7 +166,7 @@ bool MAPFAM::OpenTableFile(PGLOBAL g)
sprintf(g->Message, MSG(OPEN_MODE_ERROR),
"map", (int) rc, filename);
- if (trace)
+ if (trace(1))
htrc("CreateFileMap: %s\n", g->Message);
return (mode == MODE_READ && rc == ENOENT)
@@ -227,7 +227,7 @@ bool MAPFAM::OpenTableFile(PGLOBAL g)
Fpos = Mempos = Memory;
Top = Memory + len;
- if (trace)
+ if (trace(1))
htrc("fp=%p count=%d MapView=%p len=%d Top=%p\n",
fp, fp->Count, Memory, len, Top);
@@ -247,7 +247,7 @@ int MAPFAM::GetRowID(void)
/***********************************************************************/
int MAPFAM::GetPos(void)
{
- return Fpos - Memory;
+ return (int)(Fpos - Memory);
} // end of GetPos
/***********************************************************************/
@@ -255,7 +255,7 @@ int MAPFAM::GetPos(void)
/***********************************************************************/
int MAPFAM::GetNextPos(void)
{
- return Mempos - Memory;
+ return (int)(Mempos - Memory);
} // end of GetNextPos
/***********************************************************************/
@@ -368,7 +368,7 @@ int MAPFAM::ReadBuffer(PGLOBAL g)
} // endif Mempos
// Set caller line buffer
- len = (Mempos - Fpos) - n;
+ len = (int)(Mempos - Fpos) - n;
// Don't rely on ENDING setting
if (len > 0 && *(Mempos - 2) == '\r')
@@ -407,7 +407,7 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
{
int n;
- if (trace)
+ if (trace(1))
htrc("MAP DeleteDB: irc=%d mempos=%p tobuf=%p Tpos=%p Spos=%p\n",
irc, Mempos, To_Buf, Tpos, Spos);
@@ -417,7 +417,7 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
/*******************************************************************/
Fpos = Top;
- if (trace)
+ if (trace(1))
htrc("Fpos placed at file top=%p\n", Fpos);
} // endif irc
@@ -428,14 +428,14 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
/* not required here, just setting of future Spos and Tpos. */
/*******************************************************************/
Tpos = Spos = Fpos;
- } else if ((n = Fpos - Spos) > 0) {
+ } else if ((n = (int)(Fpos - Spos)) > 0) {
/*******************************************************************/
/* Non consecutive line to delete. Move intermediate lines. */
/*******************************************************************/
memmove(Tpos, Spos, n);
Tpos += n;
- if (trace)
+ if (trace(1))
htrc("move %d bytes\n", n);
} // endif n
@@ -443,7 +443,7 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
if (irc == RC_OK) {
Spos = Mempos; // New start position
- if (trace)
+ if (trace(1))
htrc("after: Tpos=%p Spos=%p\n", Tpos, Spos);
} else if (To_Fb) { // Can be NULL for deleted files
@@ -461,7 +461,7 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
/*****************************************************************/
/* Remove extra records. */
/*****************************************************************/
- n = Tpos - Memory;
+ n = (int)(Tpos - Memory);
#if defined(__WIN__)
DWORD drc = SetFilePointer(fp->Handle, n, NULL, FILE_BEGIN);
@@ -473,7 +473,7 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
return RC_FX;
} // endif
- if (trace)
+ if (trace(1))
htrc("done, Tpos=%p newsize=%d drc=%d\n", Tpos, n, drc);
if (!SetEndOfFile(fp->Handle)) {
@@ -511,7 +511,7 @@ void MAPFAM::CloseTableFile(PGLOBAL g, bool)
PlugCloseFile(g, To_Fb);
//To_Fb = NULL; // To get correct file size in Cardinality
- if (trace)
+ if (trace(1))
htrc("MAP Close: closing %s count=%d\n",
To_File, (To_Fb) ? To_Fb->Count : 0);
@@ -627,7 +627,7 @@ int MBKFAM::ReadBuffer(PGLOBAL g)
break;
// Set caller line buffer
- len = (Mempos - Fpos) - Ending;
+ len = (int)(Mempos - Fpos) - Ending;
memcpy(Tdbp->GetLine(), Fpos, len);
Tdbp->GetLine()[len] = '\0';
return RC_OK;
diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp
index 44abd962c56..893e3da0d46 100644
--- a/storage/connect/filamdbf.cpp
+++ b/storage/connect/filamdbf.cpp
@@ -203,7 +203,7 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info)
PQRYRES qrp;
PCOLRES crp;
- if (trace)
+ if (trace(1))
htrc("DBFColumns: File %s\n", SVP(fn));
if (!info) {
@@ -245,7 +245,7 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info)
return qrp;
} // endif info
- if (trace) {
+ if (trace(1)) {
htrc("Structure of %s\n", filename);
htrc("headlen=%hd reclen=%hd degree=%d\n",
mainhead.Headlen(), mainhead.Reclen(), fields);
@@ -271,7 +271,7 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info)
} else
len = thisfield.Length;
- if (trace)
+ if (trace(1))
htrc("%-11s %c %6ld %3d %2d %3d %3d\n",
thisfield.Name, thisfield.Type, thisfield.Offset, len,
thisfield.Decimals, thisfield.Setfield, thisfield.Mdxfield);
@@ -522,14 +522,14 @@ bool DBFFAM::OpenTableFile(PGLOBAL g)
PlugSetPath(filename, To_File, Tdbp->GetPath());
if (!(Stream = PlugOpenFile(g, filename, opmode))) {
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
return (mode == MODE_READ && errno == ENOENT)
? PushWarning(g, Tdbp) : true;
} // endif Stream
- if (trace)
+ if (trace(1))
htrc("File %s is open in mode %s\n", filename, opmode);
To_Fb = dbuserp->Openlist; // Keep track of File block
@@ -938,7 +938,7 @@ void DBFFAM::CloseTableFile(PGLOBAL g, bool abort)
rc = PlugCloseFile(g, To_Fb);
fin:
- if (trace)
+ if (trace(1))
htrc("DBF CloseTableFile: closing %s mode=%d wrc=%d rc=%d\n",
To_File, mode, wrc, rc);
diff --git a/storage/connect/filamfix.cpp b/storage/connect/filamfix.cpp
index 1d6194b154d..0a98ec5b54a 100644
--- a/storage/connect/filamfix.cpp
+++ b/storage/connect/filamfix.cpp
@@ -322,7 +322,7 @@ int FIXFAM::ReadBuffer(PGLOBAL g)
return RC_FX;
} // endif fseek
- if (trace > 1)
+ if (trace(2))
htrc("File position is now %d\n", ftell(Stream));
if (Padded)
@@ -344,7 +344,7 @@ int FIXFAM::ReadBuffer(PGLOBAL g)
sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno));
#endif
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
return RC_FX;
@@ -361,7 +361,7 @@ int FIXFAM::ReadBuffer(PGLOBAL g)
/***********************************************************************/
int FIXFAM::WriteBuffer(PGLOBAL g)
{
- if (trace > 1)
+ if (trace(2))
htrc("FIX WriteDB: Mode=%d buf=%p line=%p Nrec=%d Rbuf=%d CurNum=%d\n",
Tdbp->GetMode(), To_Buf, Tdbp->GetLine(), Nrec, Rbuf, CurNum);
@@ -374,7 +374,7 @@ int FIXFAM::WriteBuffer(PGLOBAL g)
return RC_OK; // We write only full blocks
} // endif CurNum
- if (trace > 1)
+ if (trace(2))
htrc(" First line is '%.*s'\n", Lrecl - 2, To_Buf);
// Now start the writing process.
@@ -388,7 +388,7 @@ int FIXFAM::WriteBuffer(PGLOBAL g)
CurNum = 0;
Tdbp->SetLine(To_Buf);
- if (trace > 1)
+ if (trace(2))
htrc("write done\n");
} else { // Mode == MODE_UPDATE
@@ -431,7 +431,7 @@ int FIXFAM::DeleteRecords(PGLOBAL g, int irc)
/* file, and at the end erase all trailing records. */
/* This will be experimented. */
/*********************************************************************/
- if (trace > 1)
+ if (trace(2))
htrc("DOS DeleteDB: rc=%d UseTemp=%d Fpos=%d Tpos=%d Spos=%d\n",
irc, UseTemp, Fpos, Tpos, Spos);
@@ -441,7 +441,7 @@ int FIXFAM::DeleteRecords(PGLOBAL g, int irc)
/*******************************************************************/
Fpos = Tdbp->Cardinality(g);
- if (trace > 1)
+ if (trace(2))
htrc("Fpos placed at file end=%d\n", Fpos);
} else // Fpos is the deleted line position
@@ -491,7 +491,7 @@ int FIXFAM::DeleteRecords(PGLOBAL g, int irc)
OldBlk = -2; // To force fseek to be executed on next block
} // endif moved
- if (trace > 1)
+ if (trace(2))
htrc("after: Tpos=%d Spos=%d\n", Tpos, Spos);
} else {
@@ -540,7 +540,7 @@ int FIXFAM::DeleteRecords(PGLOBAL g, int irc)
close(h);
- if (trace > 1)
+ if (trace(2))
htrc("done, h=%d irc=%d\n", h, irc);
} // endif UseTemp
@@ -572,7 +572,7 @@ bool FIXFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
req = (size_t)MY_MIN(n, Dbflen);
len = fread(DelBuf, Lrecl, req, Stream);
- if (trace > 1)
+ if (trace(2))
htrc("after read req=%d len=%d\n", req, len);
if (len != req) {
@@ -591,13 +591,13 @@ bool FIXFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
return true;
} // endif
- if (trace > 1)
+ if (trace(2))
htrc("after write pos=%d\n", ftell(Stream));
Tpos += (int)req;
Spos += (int)req;
- if (trace > 1)
+ if (trace(2))
htrc("loop: Tpos=%d Spos=%d\n", Tpos, Spos);
*b = true;
@@ -648,7 +648,7 @@ void FIXFAM::CloseTableFile(PGLOBAL g, bool abort)
rc = PlugCloseFile(g, To_Fb);
fin:
- if (trace)
+ if (trace(1))
htrc("FIX CloseTableFile: closing %s mode=%d wrc=%d rc=%d\n",
To_File, mode, wrc, rc);
@@ -718,7 +718,7 @@ int BGXFAM::BigRead(PGLOBAL g __attribute__((unused)),
DWORD nbr, drc, len = (DWORD)req;
bool brc = ReadFile(h, inbuf, len, &nbr, NULL);
- if (trace > 1)
+ if (trace(2))
htrc("after read req=%d brc=%d nbr=%d\n", req, brc, nbr);
if (!brc) {
@@ -730,7 +730,7 @@ int BGXFAM::BigRead(PGLOBAL g __attribute__((unused)),
(LPTSTR)buf, sizeof(buf), NULL);
sprintf(g->Message, MSG(READ_ERROR), To_File, buf);
- if (trace > 1)
+ if (trace(2))
htrc("BIGREAD: %s\n", g->Message);
rc = -1;
@@ -757,7 +757,7 @@ bool BGXFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req)
DWORD nbw, drc, len = (DWORD)req;
bool brc = WriteFile(h, inbuf, len, &nbw, NULL);
- if (trace > 1)
+ if (trace(2))
htrc("after write req=%d brc=%d nbw=%d\n", req, brc, nbw);
if (!brc || nbw != len) {
@@ -775,7 +775,7 @@ bool BGXFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req)
sprintf(g->Message, MSG(WRITE_STRERROR), fn, buf);
- if (trace > 1)
+ if (trace(2))
htrc("BIGWRITE: nbw=%d len=%d errno=%d %s\n",
nbw, len, drc, g->Message);
@@ -790,7 +790,7 @@ bool BGXFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req)
sprintf(g->Message, MSG(WRITE_STRERROR), fn, strerror(errno));
- if (trace > 1)
+ if (trace(2))
htrc("BIGWRITE: nbw=%d len=%d errno=%d %s\n",
nbw, len, errno, g->Message);
@@ -828,7 +828,7 @@ bool BGXFAM::OpenTableFile(PGLOBAL g)
PlugSetPath(filename, To_File, Tdbp->GetPath());
- if (trace)
+ if (trace(1))
htrc("OpenTableFile: filename=%s mode=%d\n", filename, mode);
#if defined(__WIN__)
@@ -888,7 +888,7 @@ bool BGXFAM::OpenTableFile(PGLOBAL g)
} else
rc = 0;
- if (trace > 1)
+ if (trace(2))
htrc(" rc=%d access=%p share=%p creation=%d handle=%p fn=%s\n",
rc, access, share, creation, Hfile, filename);
@@ -942,7 +942,7 @@ bool BGXFAM::OpenTableFile(PGLOBAL g)
} else
rc = 0;
- if (trace > 1)
+ if (trace(2))
htrc(" rc=%d oflag=%p tmode=%p handle=%p fn=%s\n",
rc, oflag, tmode, Hfile, filename);
@@ -1026,11 +1026,11 @@ int BGXFAM::Cardinality(PGLOBAL g)
if (Hfile == INVALID_HANDLE_VALUE) {
int h = open64(filename, O_RDONLY, 0);
- if (trace)
+ if (trace(1))
htrc(" h=%d\n", h);
if (h == INVALID_HANDLE_VALUE) {
- if (trace)
+ if (trace(1))
htrc(" errno=%d ENOENT=%d\n", errno, ENOENT);
if (errno != ENOENT) {
@@ -1074,7 +1074,7 @@ int BGXFAM::Cardinality(PGLOBAL g)
} else
card = (int)(fsize / (BIGINT)Lrecl); // Fixed length file
- if (trace)
+ if (trace(1))
htrc(" Computed max_K=%d fsize=%lf lrecl=%d\n",
card, (double)fsize, Lrecl);
@@ -1181,7 +1181,7 @@ int BGXFAM::ReadBuffer(PGLOBAL g)
if (BigSeek(g, Hfile, (BIGINT)Fpos * (BIGINT)Lrecl))
return RC_FX;
- if (trace > 1)
+ if (trace(2))
htrc("File position is now %d\n", Fpos);
nbr = BigRead(g, Hfile, To_Buf, (Padded) ? Blksize : Lrecl * Nrec);
@@ -1205,7 +1205,7 @@ int BGXFAM::ReadBuffer(PGLOBAL g)
/***********************************************************************/
int BGXFAM::WriteBuffer(PGLOBAL g)
{
- if (trace > 1)
+ if (trace(2))
htrc("BIG WriteDB: Mode=%d buf=%p line=%p Nrec=%d Rbuf=%d CurNum=%d\n",
Tdbp->GetMode(), To_Buf, Tdbp->GetLine(), Nrec, Rbuf, CurNum);
@@ -1218,7 +1218,7 @@ int BGXFAM::WriteBuffer(PGLOBAL g)
return RC_OK; // We write only full blocks
} // endif CurNum
- if (trace > 1)
+ if (trace(2))
htrc(" First line is '%.*s'\n", Lrecl - 2, To_Buf);
// Now start the writing process.
@@ -1229,7 +1229,7 @@ int BGXFAM::WriteBuffer(PGLOBAL g)
CurNum = 0;
Tdbp->SetLine(To_Buf);
- if (trace > 1)
+ if (trace(2))
htrc("write done\n");
} else { // Mode == MODE_UPDATE
@@ -1270,7 +1270,7 @@ int BGXFAM::DeleteRecords(PGLOBAL g, int irc)
/* file, and at the end erase all trailing records. */
/* This will be experimented. */
/*********************************************************************/
- if (trace > 1)
+ if (trace(2))
htrc("BGX DeleteDB: rc=%d UseTemp=%d Fpos=%d Tpos=%d Spos=%d\n",
irc, UseTemp, Fpos, Tpos, Spos);
@@ -1280,7 +1280,7 @@ int BGXFAM::DeleteRecords(PGLOBAL g, int irc)
/*******************************************************************/
Fpos = Tdbp->Cardinality(g);
- if (trace > 1)
+ if (trace(2))
htrc("Fpos placed at file end=%d\n", Fpos);
} else // Fpos is the deleted line position
@@ -1318,7 +1318,7 @@ int BGXFAM::DeleteRecords(PGLOBAL g, int irc)
return RC_FX;
if (irc == RC_OK) {
- if (trace)
+ if (trace(1))
assert(Spos == Fpos);
Spos++; // New start position is on next line
@@ -1330,7 +1330,7 @@ int BGXFAM::DeleteRecords(PGLOBAL g, int irc)
OldBlk = -2; // To force fseek to be executed on next block
} // endif moved
- if (trace > 1)
+ if (trace(2))
htrc("after: Tpos=%d Spos=%d\n", Tpos, Spos);
} else if (irc != RC_OK) {
@@ -1459,7 +1459,7 @@ bool BGXFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
Tpos += (int)req;
Spos += (int)req;
- if (trace > 1)
+ if (trace(2))
htrc("loop: Tpos=%d Spos=%d\n", Tpos, Spos);
*b = true;
@@ -1510,7 +1510,7 @@ void BGXFAM::CloseTableFile(PGLOBAL g, bool abort)
rc = PlugCloseFile(g, To_Fb);
fin:
- if (trace)
+ if (trace(1))
htrc("BGX CloseTableFile: closing %s mode=%d wrc=%d rc=%d\n",
To_File, mode, wrc, rc);
diff --git a/storage/connect/filamgz.cpp b/storage/connect/filamgz.cpp
index df366ef15f9..880db54c91d 100644
--- a/storage/connect/filamgz.cpp
+++ b/storage/connect/filamgz.cpp
@@ -203,7 +203,7 @@ bool GZFAM::AllocateBuffer(PGLOBAL g)
Buflen = Lrecl + 2; // Lrecl does not include CRLF
//Buflen *= ((Mode == MODE_DELETE) ? DOS_BUFF_LEN : 1); NIY
- if (trace)
+ if (trace(1))
htrc("SubAllocating a buffer of %d bytes\n", Buflen);
To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);
@@ -347,7 +347,7 @@ int GZFAM::ReadBuffer(PGLOBAL g)
} else
rc = Zerror(g);
- if (trace > 1)
+ if (trace(2))
htrc(" Read: '%s' rc=%d\n", To_Buf, rc);
return rc;
@@ -389,7 +389,7 @@ void GZFAM::CloseTableFile(PGLOBAL, bool)
{
int rc = gzclose(Zfile);
- if (trace)
+ if (trace(1))
htrc("GZ CloseDB: closing %s rc=%d\n", To_File, rc);
Zfile = NULL; // So we can know whether table is open
@@ -537,7 +537,7 @@ int ZBKFAM::ReadBuffer(PGLOBAL g)
while (*NxtLine++ != '\n') ;
// Set caller line buffer
- n = NxtLine - CurLine - Ending;
+ n = (int)(NxtLine - CurLine - Ending);
memcpy(Tdbp->GetLine(), CurLine, n);
Tdbp->GetLine()[n] = '\0';
return RC_OK;
@@ -588,7 +588,7 @@ int ZBKFAM::ReadBuffer(PGLOBAL g)
for (NxtLine = CurLine; *NxtLine++ != '\n';) ;
// Set caller line buffer
- n = NxtLine - CurLine - Ending;
+ n = (int)(NxtLine - CurLine - Ending);
memcpy(Tdbp->GetLine(), CurLine, n);
Tdbp->GetLine()[n] = '\0';
Rbuf = (CurBlk == Block - 1) ? Last : Nrec;
@@ -702,7 +702,7 @@ void ZBKFAM::CloseTableFile(PGLOBAL g, bool)
} else
rc = gzclose(Zfile);
- if (trace)
+ if (trace(1))
htrc("GZ CloseDB: closing %s rc=%d\n", To_File, rc);
Zfile = NULL; // So we can know whether table is open
@@ -1087,7 +1087,7 @@ bool ZLBFAM::SetPos(PGLOBAL g, int pos __attribute__((unused)))
/***********************************************************************/
int ZLBFAM::ReadBuffer(PGLOBAL g)
{
- int n;
+ size_t n;
void *rdbuf;
/*********************************************************************/
@@ -1299,7 +1299,7 @@ int ZLBFAM::WriteBuffer(PGLOBAL g)
else
NxtLine = CurLine + Lrecl;
- BlkLen = NxtLine - To_Buf;
+ BlkLen = (int)(NxtLine - To_Buf);
if (WriteCompressedBuffer(g)) {
Closing = TRUE; // To tell CloseDB about a Write error
@@ -1382,7 +1382,7 @@ void ZLBFAM::CloseTableFile(PGLOBAL g, bool)
} else
rc = fclose(Stream);
- if (trace)
+ if (trace(1))
htrc("ZLB CloseTableFile: closing %s mode=%d rc=%d\n",
To_File, Tdbp->GetMode(), rc);
@@ -1408,7 +1408,7 @@ void ZLBFAM::Rewind(void)
rewind(Stream);
- if (!(st = fread(Zlenp, sizeof(int), 1, Stream)) && trace)
+ if (!(st = fread(Zlenp, sizeof(int), 1, Stream)) && trace(1))
htrc("fread error %d in Rewind", errno);
fseek(Stream, *Zlenp + sizeof(int), SEEK_SET);
diff --git a/storage/connect/filamtxt.cpp b/storage/connect/filamtxt.cpp
index c456ee9e9b7..7c222eb3c80 100644
--- a/storage/connect/filamtxt.cpp
+++ b/storage/connect/filamtxt.cpp
@@ -194,12 +194,12 @@ int TXTFAM::GetFileLength(PGLOBAL g)
PlugSetPath(filename, To_File, Tdbp->GetPath());
h= global_open(g, MSGID_OPEN_MODE_STRERROR, filename, _O_RDONLY);
- if (trace)
+ if (trace(1))
htrc("GetFileLength: fn=%s h=%d\n", filename, h);
if (h == -1) {
if (errno != ENOENT) {
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
len = -1;
@@ -249,7 +249,7 @@ int TXTFAM::Cardinality(PGLOBAL g)
} // endif Padded
- if (trace)
+ if (trace(1))
htrc(" Computed max_K=%d Filen=%d lrecl=%d\n",
card, len, Lrecl);
@@ -390,7 +390,7 @@ int TXTFAM::UpdateSortedRows(PGLOBAL g)
return RC_OK;
err:
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
return RC_FX;
@@ -439,7 +439,7 @@ int TXTFAM::DeleteSortedRows(PGLOBAL g)
return RC_OK;
err:
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
return RC_FX;
@@ -512,7 +512,7 @@ int DOSFAM::GetFileLength(PGLOBAL g)
if ((len = _filelength(_fileno(Stream))) < 0)
sprintf(g->Message, MSG(FILELEN_ERROR), "_filelength", To_File);
- if (trace)
+ if (trace(1))
htrc("File length=%d\n", len);
return len;
@@ -598,14 +598,14 @@ bool DOSFAM::OpenTableFile(PGLOBAL g)
PlugSetPath(filename, To_File, Tdbp->GetPath());
if (!(Stream = PlugOpenFile(g, filename, opmode))) {
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
return (mode == MODE_READ && errno == ENOENT)
? PushWarning(g, Tdbp) : true;
} // endif Stream
- if (trace)
+ if (trace(1))
htrc("File %s open Stream=%p mode=%s\n", filename, Stream, opmode);
To_Fb = dbuserp->Openlist; // Keep track of File block
@@ -628,7 +628,7 @@ bool DOSFAM::AllocateBuffer(PGLOBAL g)
// Lrecl does not include line ending
Buflen = Lrecl + Ending + ((Bin) ? 1 : 0) + 1; // Sergei
- if (trace)
+ if (trace(1))
htrc("SubAllocating a buffer of %d bytes\n", Buflen);
To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);
@@ -768,7 +768,7 @@ int DOSFAM::ReadBuffer(PGLOBAL g)
if (!Stream)
return RC_EF;
- if (trace > 1)
+ if (trace(2))
htrc("ReadBuffer: Tdbp=%p To_Line=%p Placed=%d\n",
Tdbp, Tdbp->To_Line, Placed);
@@ -782,7 +782,7 @@ int DOSFAM::ReadBuffer(PGLOBAL g)
CurBlk = (int)Rows++;
- if (trace > 1)
+ if (trace(2))
htrc("ReadBuffer: CurBlk=%d\n", CurBlk);
/********************************************************************/
@@ -803,14 +803,14 @@ int DOSFAM::ReadBuffer(PGLOBAL g)
} else
Placed = false;
- if (trace > 1)
+ if (trace(2))
htrc(" About to read: stream=%p To_Buf=%p Buflen=%d\n",
Stream, To_Buf, Buflen);
if (fgets(To_Buf, Buflen, Stream)) {
p = To_Buf + strlen(To_Buf) - 1;
- if (trace > 1)
+ if (trace(2))
htrc(" Read: To_Buf=%p p=%c\n", To_Buf, To_Buf, p);
#if defined(__WIN__)
@@ -838,7 +838,7 @@ int DOSFAM::ReadBuffer(PGLOBAL g)
} else if (*p == '\n')
*p = '\0'; // Eliminate ending new-line character
- if (trace > 1)
+ if (trace(2))
htrc(" To_Buf='%s'\n", To_Buf);
strcpy(Tdbp->To_Line, To_Buf);
@@ -853,13 +853,13 @@ int DOSFAM::ReadBuffer(PGLOBAL g)
sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(0));
#endif
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
rc = RC_FX;
} // endif's fgets
- if (trace > 1)
+ if (trace(2))
htrc("ReadBuffer: rc=%d\n", rc);
IsRead = true;
@@ -895,7 +895,7 @@ int DOSFAM::WriteBuffer(PGLOBAL g)
/*******************************************************************/
curpos = ftell(Stream);
- if (trace)
+ if (trace(1))
htrc("Last : %d cur: %d\n", Fpos, curpos);
if (UseTemp) {
@@ -937,7 +937,7 @@ int DOSFAM::WriteBuffer(PGLOBAL g)
return RC_FX;
} // endif
- if (trace)
+ if (trace(1))
htrc("write done\n");
return RC_OK;
@@ -960,7 +960,7 @@ int DOSFAM::DeleteRecords(PGLOBAL g, int irc)
/* file, and at the end erase all trailing records. */
/* This will be experimented. */
/*********************************************************************/
- if (trace)
+ if (trace(1))
htrc(
"DOS DeleteDB: rc=%d UseTemp=%d curpos=%d Fpos=%d Tpos=%d Spos=%d\n",
irc, UseTemp, curpos, Fpos, Tpos, Spos);
@@ -972,7 +972,7 @@ int DOSFAM::DeleteRecords(PGLOBAL g, int irc)
fseek(Stream, 0, SEEK_END);
Fpos = ftell(Stream);
- if (trace)
+ if (trace(1))
htrc("Fpos placed at file end=%d\n", Fpos);
} // endif irc
@@ -1015,7 +1015,7 @@ int DOSFAM::DeleteRecords(PGLOBAL g, int irc)
Spos = GetNextPos(); // New start position
- if (trace)
+ if (trace(1))
htrc("after: Tpos=%d Spos=%d\n", Tpos, Spos);
} else {
@@ -1058,7 +1058,7 @@ int DOSFAM::DeleteRecords(PGLOBAL g, int irc)
close(h);
- if (trace)
+ if (trace(1))
htrc("done, h=%d irc=%d\n", h, irc);
} // endif !UseTemp
@@ -1083,7 +1083,7 @@ bool DOSFAM::OpenTempFile(PGLOBAL g)
strcat(PlugRemoveType(tempname, tempname), ".t");
if (!(T_Stream = PlugOpenFile(g, tempname, "wb"))) {
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
rc = true;
@@ -1112,7 +1112,7 @@ bool DOSFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
req = (size_t)MY_MIN(n, Dbflen);
len = fread(DelBuf, 1, req, Stream);
- if (trace)
+ if (trace(1))
htrc("after read req=%d len=%d\n", req, len);
if (len != req) {
@@ -1131,13 +1131,13 @@ bool DOSFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
return true;
} // endif
- if (trace)
+ if (trace(1))
htrc("after write pos=%d\n", ftell(Stream));
Tpos += (int)req;
Spos += (int)req;
- if (trace)
+ if (trace(1))
htrc("loop: Tpos=%d Spos=%d\n", Tpos, Spos);
*b = true;
@@ -1217,7 +1217,7 @@ void DOSFAM::CloseTableFile(PGLOBAL g, bool abort)
} else {
rc = PlugCloseFile(g, To_Fb);
- if (trace)
+ if (trace(1))
htrc("DOS Close: closing %s rc=%d\n", To_File, rc);
} // endif UseTemp
@@ -1351,7 +1351,7 @@ int BLKFAM::GetPos(void)
/***********************************************************************/
int BLKFAM::GetNextPos(void)
{
- return Fpos + NxtLine - CurLine;
+ return (int)(Fpos + NxtLine - CurLine);
} // end of GetNextPos
/***********************************************************************/
@@ -1396,7 +1396,8 @@ int BLKFAM::SkipRecord(PGLOBAL, bool header)
/***********************************************************************/
int BLKFAM::ReadBuffer(PGLOBAL g)
{
- int i, n, rc = RC_OK;
+ int i, rc = RC_OK;
+ size_t n;
/*********************************************************************/
/* Sequential reading when Placed is not true. */
@@ -1452,13 +1453,13 @@ int BLKFAM::ReadBuffer(PGLOBAL g)
// Calculate the length of block to read
BlkLen = BlkPos[CurBlk + 1] - BlkPos[CurBlk];
- if (trace)
+ if (trace(1))
htrc("File position is now %d\n", ftell(Stream));
// Read the entire next block
n = fread(To_Buf, 1, (size_t)BlkLen, Stream);
- if (n == BlkLen) {
+ if ((size_t) n == (size_t) BlkLen) {
// ReadBlks++;
num_read++;
Rbuf = (CurBlk == Block - 1) ? Last : Nrec;
@@ -1486,7 +1487,7 @@ int BLKFAM::ReadBuffer(PGLOBAL g)
sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno));
#endif
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
return RC_FX;
@@ -1497,7 +1498,7 @@ int BLKFAM::ReadBuffer(PGLOBAL g)
fin:
// Store the current record file position for Delete and Update
- Fpos = BlkPos[CurBlk] + CurLine - To_Buf;
+ Fpos = (int)(BlkPos[CurBlk] + CurLine - To_Buf);
return rc;
} // end of ReadBuffer
@@ -1524,7 +1525,7 @@ int BLKFAM::WriteBuffer(PGLOBAL g)
// Now start the writing process.
NxtLine = CurLine + strlen(CurLine);
- BlkLen = NxtLine - To_Buf;
+ BlkLen = (int)(NxtLine - To_Buf);
if (fwrite(To_Buf, 1, BlkLen, Stream) != (size_t)BlkLen) {
sprintf(g->Message, MSG(FWRITE_ERROR), strerror(errno));
@@ -1636,7 +1637,7 @@ void BLKFAM::CloseTableFile(PGLOBAL g, bool abort)
rc = PlugCloseFile(g, To_Fb);
- if (trace)
+ if (trace(1))
htrc("BLK CloseTableFile: closing %s mode=%d wrc=%d rc=%d\n",
To_File, Tdbp->GetMode(), wrc, rc);
diff --git a/storage/connect/filamvct.cpp b/storage/connect/filamvct.cpp
index 871613cb4b4..244acfdc5c8 100755
--- a/storage/connect/filamvct.cpp
+++ b/storage/connect/filamvct.cpp
@@ -336,7 +336,7 @@ int VCTFAM::Cardinality(PGLOBAL g)
else
sprintf(g->Message, MSG(NOT_FIXED_LEN), To_File, len, clen);
- if (trace)
+ if (trace(1))
htrc(" Computed max_K=%d Filen=%d Clen=%d\n", card, len, clen);
} else
@@ -469,14 +469,14 @@ bool VCTFAM::OpenTableFile(PGLOBAL g)
PlugSetPath(filename, To_File, Tdbp->GetPath());
if (!(Stream = PlugOpenFile(g, filename, opmode))) {
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
return (mode == MODE_READ && errno == ENOENT)
? PushWarning(g, Tdbp) : true;
} // endif Stream
- if (trace)
+ if (trace(1))
htrc("File %s is open in mode %s\n", filename, opmode);
To_Fb = dbuserp->Openlist; // Keep track of File block
@@ -581,7 +581,7 @@ bool VCTFAM::InitInsert(PGLOBAL g)
cp->ReadBlock(g);
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
rc = true;
} catch (const char *msg) {
@@ -652,7 +652,7 @@ int VCTFAM::ReadBuffer(PGLOBAL g)
OldBlk = CurBlk; // Last block actually read
} // endif oldblk
- if (trace)
+ if (trace(1))
htrc(" Read: CurNum=%d CurBlk=%d rc=%d\n", CurNum, CurBlk, RC_OK);
return rc;
@@ -663,7 +663,7 @@ int VCTFAM::ReadBuffer(PGLOBAL g)
/***********************************************************************/
int VCTFAM::WriteBuffer(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("VCT WriteBuffer: R%d Mode=%d CurNum=%d CurBlk=%d\n",
Tdbp->GetTdb_No(), Tdbp->GetMode(), CurNum, CurBlk);
@@ -756,7 +756,7 @@ int VCTFAM::DeleteRecords(PGLOBAL g, int irc)
{
bool eof = false;
- if (trace)
+ if (trace(1))
htrc("VCT DeleteDB: rc=%d UseTemp=%d Fpos=%d Tpos=%d Spos=%d\n",
irc, UseTemp, Fpos, Tpos, Spos);
@@ -766,7 +766,7 @@ int VCTFAM::DeleteRecords(PGLOBAL g, int irc)
/*******************************************************************/
Fpos = (Block - 1) * Nrec + Last;
- if (trace)
+ if (trace(1))
htrc("Fpos placed at file end=%d\n", Fpos);
eof = UseTemp && !MaxBlk;
@@ -807,7 +807,7 @@ int VCTFAM::DeleteRecords(PGLOBAL g, int irc)
#endif
Spos++; // New start position is on next line
- if (trace)
+ if (trace(1))
htrc("after: Tpos=%d Spos=%d\n", Tpos, Spos);
} else {
@@ -856,7 +856,7 @@ int VCTFAM::DeleteRecords(PGLOBAL g, int irc)
close(h);
- if (trace)
+ if (trace(1))
htrc("done, h=%d irc=%d\n", h, irc);
} else
@@ -899,7 +899,7 @@ bool VCTFAM::OpenTempFile(PGLOBAL g)
opmode = "wb";
if (!(T_Stream = PlugOpenFile(g, tempname, opmode))) {
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
rc = true;
@@ -947,7 +947,7 @@ bool VCTFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
len = fread(To_Buf, Clens[i], req, Stream);
- if (trace)
+ if (trace(1))
htrc("after read req=%d len=%d\n", req, len);
if (len != req) {
@@ -976,7 +976,7 @@ bool VCTFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
} // endif UseTemp
- if (trace)
+ if (trace(1))
htrc("after write pos=%d\n", ftell(Stream));
} // endfor i
@@ -1007,7 +1007,7 @@ bool VCTFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
} // endif UseTemp
- if (trace)
+ if (trace(1))
htrc("loop: Tpos=%d Spos=%d\n", Tpos, Spos);
} // endfor n
@@ -1144,7 +1144,7 @@ void VCTFAM::CloseTableFile(PGLOBAL g, bool abort)
if (!(UseTemp && T_Stream))
rc = PlugCloseFile(g, To_Fb);
- if (trace)
+ if (trace(1))
htrc("VCT CloseTableFile: closing %s wrc=%d rc=%d\n",
To_File, wrc, rc);
@@ -1217,7 +1217,7 @@ bool VCTFAM::ReadBlock(PGLOBAL g, PVCTCOL colp)
else // Blocked vector format
len = Nrec * (colp->Deplac + Lrecl * CurBlk);
- if (trace)
+ if (trace(1))
htrc("len=%d Nrec=%d Deplac=%d Lrecl=%d CurBlk=%d maxblk=%d\n",
len, Nrec, colp->Deplac, Lrecl, CurBlk, MaxBlk);
@@ -1236,13 +1236,13 @@ bool VCTFAM::ReadBlock(PGLOBAL g, PVCTCOL colp)
sprintf(g->Message, MSG(READ_ERROR),
To_File, strerror(errno));
- if (trace)
+ if (trace(1))
htrc(" Read error: %s\n", g->Message);
return true;
} // endif
- if (trace)
+ if (trace(1))
num_read++;
return false;
@@ -1268,7 +1268,7 @@ bool VCTFAM::WriteBlock(PGLOBAL g, PVCTCOL colp)
else // Old VCT format
len = Nrec * (colp->Deplac + Lrecl * colp->ColBlk);
- if (trace)
+ if (trace(1))
htrc("modif=%d len=%d Nrec=%d Deplac=%d Lrecl=%d colblk=%d\n",
Modif, len, Nrec, colp->Deplac, Lrecl, colp->ColBlk);
@@ -1287,7 +1287,7 @@ bool VCTFAM::WriteBlock(PGLOBAL g, PVCTCOL colp)
sprintf(g->Message, MSG(WRITE_STRERROR),
(UseTemp) ? To_Fbt->Fname : To_File, strerror(errno));
- if (trace)
+ if (trace(1))
htrc("Write error: %s\n", strerror(errno));
return true;
@@ -1358,7 +1358,7 @@ bool VCMFAM::OpenTableFile(PGLOBAL g)
&& fp->Count && fp->Mode == mode)
break;
- if (trace)
+ if (trace(1))
htrc("Mapping VCM file, fp=%p cnt=%d\n", fp, fp->Count);
} else
@@ -1416,7 +1416,7 @@ bool VCMFAM::OpenTableFile(PGLOBAL g)
sprintf(g->Message, MSG(OPEN_MODE_ERROR),
"map", (int) rc, filename);
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
return (mode == MODE_READ && rc == ENOENT)
@@ -1467,7 +1467,7 @@ bool VCMFAM::OpenTableFile(PGLOBAL g)
To_Fb = fp; // Useful when closing
- if (trace)
+ if (trace(1))
htrc("fp=%p count=%d MapView=%p len=%d Top=%p\n",
fp, fp->Count, Memory, len);
@@ -1551,7 +1551,7 @@ bool VCMFAM::InitInsert(PGLOBAL g)
cp->ReadBlock(g);
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
rc = true;
} catch (const char *msg) {
@@ -1567,7 +1567,7 @@ bool VCMFAM::InitInsert(PGLOBAL g)
/***********************************************************************/
int VCMFAM::WriteBuffer(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("VCM WriteBuffer: R%d Mode=%d CurNum=%d CurBlk=%d\n",
Tdbp->GetTdb_No(), Tdbp->GetMode(), CurNum, CurBlk);
@@ -1608,7 +1608,7 @@ int VCMFAM::WriteBuffer(PGLOBAL g)
/***********************************************************************/
int VCMFAM::DeleteRecords(PGLOBAL g, int irc)
{
- if (trace)
+ if (trace(1))
htrc("VCM DeleteDB: irc=%d tobuf=%p Tpos=%p Spos=%p\n",
irc, To_Buf, Tpos, Spos);
@@ -1618,7 +1618,7 @@ int VCMFAM::DeleteRecords(PGLOBAL g, int irc)
/*******************************************************************/
Fpos = (Block - 1) * Nrec + Last;
- if (trace)
+ if (trace(1))
htrc("Fpos placed at file top=%p\n", Fpos);
} else // Fpos is the Deleted line position
@@ -1636,7 +1636,7 @@ int VCMFAM::DeleteRecords(PGLOBAL g, int irc)
if (irc == RC_OK) {
Spos = Fpos + 1; // New start position
- if (trace)
+ if (trace(1))
htrc("after: Tpos=%p Spos=%p\n", Tpos, Spos);
} else {
@@ -1680,7 +1680,7 @@ int VCMFAM::DeleteRecords(PGLOBAL g, int irc)
return RC_FX;
} // endif
- if (trace)
+ if (trace(1))
htrc("done, Tpos=%p newsize=%d drc=%d\n", Tpos, n, drc);
if (!SetEndOfFile(fp->Handle)) {
@@ -1755,7 +1755,7 @@ bool VCMFAM::MoveIntermediateLines(PGLOBAL, bool *)
Tpos += n;
} // endif MaxBlk
- if (trace)
+ if (trace(1))
htrc("move %d bytes\n", n);
} // endif n
@@ -1812,14 +1812,14 @@ bool VCMFAM::ReadBlock(PGLOBAL, PVCTCOL colp)
/*********************************************************************/
mempos = Memcol[i] + n * CurBlk;
- if (trace)
+ if (trace(1))
htrc("mempos=%p i=%d Nrec=%d Clen=%d CurBlk=%d\n",
mempos, i, Nrec, colp->Clen, CurBlk);
if (colp->GetStatus(BUF_MAPPED))
colp->Blk->SetValPointer(mempos);
- if (trace)
+ if (trace(1))
num_read++;
return false;
@@ -1843,7 +1843,7 @@ bool VCMFAM::WriteBlock(PGLOBAL, PVCTCOL colp __attribute__((unused)))
/*********************************************************************/
mempos = Memcol[i] + n * CurBlk;
- if (trace)
+ if (trace(1))
htrc("modif=%d mempos=%p i=%d Nrec=%d Clen=%d colblk=%d\n",
Modif, mempos, i, Nrec, colp->Clen, colp->ColBlk);
@@ -2008,14 +2008,14 @@ bool VECFAM::OpenColumnFile(PGLOBAL g, PCSZ opmode, int i)
sprintf(filename, Colfn, i+1);
if (!(Streams[i] = PlugOpenFile(g, filename, opmode))) {
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
return (Tdbp->GetMode() == MODE_READ && errno == ENOENT)
? PushWarning(g, Tdbp) : true;
} // endif Streams
- if (trace)
+ if (trace(1))
htrc("File %s is open in mode %s\n", filename, opmode);
To_Fbs[i] = dup->Openlist; // Keep track of File blocks
@@ -2163,7 +2163,7 @@ void VECFAM::ResetBuffer(PGLOBAL g)
/***********************************************************************/
int VECFAM::WriteBuffer(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("VCT WriteBuffer: R%d Mode=%d CurNum=%d CurBlk=%d\n",
Tdbp->GetTdb_No(), Tdbp->GetMode(), CurNum, CurBlk);
@@ -2205,7 +2205,7 @@ int VECFAM::WriteBuffer(PGLOBAL g)
/***********************************************************************/
int VECFAM::DeleteRecords(PGLOBAL g, int irc)
{
- if (trace)
+ if (trace(1))
htrc("VEC DeleteDB: rc=%d UseTemp=%d Fpos=%d Tpos=%d Spos=%d\n",
irc, UseTemp, Fpos, Tpos, Spos);
@@ -2215,7 +2215,7 @@ int VECFAM::DeleteRecords(PGLOBAL g, int irc)
/*******************************************************************/
Fpos = Cardinality(g);
- if (trace)
+ if (trace(1))
htrc("Fpos placed at file end=%d\n", Fpos);
} else // Fpos is the Deleted line position
@@ -2251,7 +2251,7 @@ int VECFAM::DeleteRecords(PGLOBAL g, int irc)
#endif
Spos++; // New start position is on next line
- if (trace)
+ if (trace(1))
htrc("after: Tpos=%d Spos=%d\n", Tpos, Spos);
} else {
@@ -2294,7 +2294,7 @@ int VECFAM::DeleteRecords(PGLOBAL g, int irc)
close(h);
- if (trace)
+ if (trace(1))
htrc("done, h=%d irc=%d\n", h, irc);
} // endfor i
@@ -2332,7 +2332,7 @@ bool VECFAM::OpenTempFile(PGLOBAL g)
sprintf(tempname, Tempat, i+1);
if (!(T_Streams[i] = PlugOpenFile(g, tempname, "wb"))) {
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
return true;
@@ -2391,7 +2391,7 @@ bool VECFAM::MoveIntermediateLines(PGLOBAL g, bool *)
len = fread(To_Buf, Clens[i], req, Streams[i]);
- if (trace)
+ if (trace(1))
htrc("after read req=%d len=%d\n", req, len);
if (len != req) {
@@ -2410,7 +2410,7 @@ bool VECFAM::MoveIntermediateLines(PGLOBAL g, bool *)
return true;
} // endif
- if (trace)
+ if (trace(1))
htrc("after write pos=%d\n", ftell(Streams[i]));
} // endfor i
@@ -2418,7 +2418,7 @@ bool VECFAM::MoveIntermediateLines(PGLOBAL g, bool *)
Tpos += (int)req;
Spos += (int)req;
- if (trace)
+ if (trace(1))
htrc("loop: Tpos=%d Spos=%d\n", Tpos, Spos);
b = true;
@@ -2541,7 +2541,7 @@ void VECFAM::CloseTableFile(PGLOBAL g, bool abort)
To_Fbs[i] = NULL;
} // endif Streams
- if (trace)
+ if (trace(1))
htrc("VCT CloseTableFile: closing %s wrc=%d rc=%d\n", To_File, wrc, rc);
} // end of CloseTableFile
@@ -2560,7 +2560,7 @@ bool VECFAM::ReadBlock(PGLOBAL g, PVCTCOL colp)
len = Nrec * colp->Clen * CurBlk;
i = colp->Index - 1;
- if (trace)
+ if (trace(1))
htrc("len=%d i=%d Nrec=%d Deplac=%d Lrecl=%d CurBlk=%d\n",
len, i, Nrec, colp->Deplac, Lrecl, CurBlk);
@@ -2586,13 +2586,13 @@ bool VECFAM::ReadBlock(PGLOBAL g, PVCTCOL colp)
sprintf(g->Message, MSG(READ_ERROR),
fn, strerror(errno));
- if (trace)
+ if (trace(1))
htrc(" Read error: %s\n", g->Message);
return true;
} // endif
- if (trace)
+ if (trace(1))
num_read++;
return false;
@@ -2615,7 +2615,7 @@ bool VECFAM::WriteBlock(PGLOBAL g, PVCTCOL colp)
len = Nrec * colp->Clen * colp->ColBlk;
i = colp->Index - 1;
- if (trace)
+ if (trace(1))
htrc("modif=%d len=%d i=%d Nrec=%d Deplac=%d Lrecl=%d colblk=%d\n",
Modif, len, i, Nrec, colp->Deplac, Lrecl, colp->ColBlk);
@@ -2638,7 +2638,7 @@ bool VECFAM::WriteBlock(PGLOBAL g, PVCTCOL colp)
sprintf(fn, (UseTemp) ? Tempat : Colfn, colp->Index);
sprintf(g->Message, MSG(WRITE_STRERROR), fn, strerror(errno));
- if (trace)
+ if (trace(1))
htrc("Write error: %s\n", strerror(errno));
return true;
@@ -2782,7 +2782,7 @@ bool VMPFAM::MapColumnFile(PGLOBAL g, MODE mode, int i)
&& fp->Count && fp->Mode == mode)
break;
- if (trace)
+ if (trace(1))
htrc("Mapping file, fp=%p\n", fp);
} else
@@ -2807,7 +2807,7 @@ bool VMPFAM::MapColumnFile(PGLOBAL g, MODE mode, int i)
if (!(*g->Message))
sprintf(g->Message, MSG(OPEN_MODE_ERROR),
"map", (int) rc, filename);
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
return (mode == MODE_READ && rc == ENOENT)
@@ -2858,7 +2858,7 @@ bool VMPFAM::MapColumnFile(PGLOBAL g, MODE mode, int i)
To_Fbs[i] = fp; // Useful when closing
- if (trace)
+ if (trace(1))
htrc("fp=%p count=%d MapView=%p len=%d\n",
fp, fp->Count, Memcol[i], len);
@@ -2903,7 +2903,7 @@ int VMPFAM::DeleteRecords(PGLOBAL g, int irc)
int i;
int m, n;
- if (trace)
+ if (trace(1))
htrc("VMP DeleteDB: irc=%d tobuf=%p Tpos=%p Spos=%p\n",
irc, To_Buf, Tpos, Spos);
@@ -2913,7 +2913,7 @@ int VMPFAM::DeleteRecords(PGLOBAL g, int irc)
/*******************************************************************/
Fpos = (Block - 1) * Nrec + Last;
- if (trace)
+ if (trace(1))
htrc("Fpos placed at file top=%p\n", Fpos);
} else // Fpos is the Deleted line position
@@ -2936,7 +2936,7 @@ int VMPFAM::DeleteRecords(PGLOBAL g, int irc)
Tpos += n;
- if (trace)
+ if (trace(1))
htrc("move %d bytes\n", n);
} // endif n
@@ -2944,7 +2944,7 @@ int VMPFAM::DeleteRecords(PGLOBAL g, int irc)
if (irc == RC_OK) {
Spos = Fpos + 1; // New start position
- if (trace)
+ if (trace(1))
htrc("after: Tpos=%p Spos=%p\n", Tpos, Spos);
} else {
@@ -2981,7 +2981,7 @@ int VMPFAM::DeleteRecords(PGLOBAL g, int irc)
return RC_FX;
} // endif
- if (trace)
+ if (trace(1))
htrc("done, Tpos=%p newsize=%d drc=%d\n", Tpos, n, drc);
if (!SetEndOfFile(fp->Handle)) {
@@ -3088,7 +3088,7 @@ bool BGVFAM::BigRead(PGLOBAL g, HANDLE h, void *inbuf, int req)
DWORD nbr, drc, len = (DWORD)req;
bool brc = ReadFile(h, inbuf, len, &nbr, NULL);
- if (trace)
+ if (trace(1))
htrc("after read req=%d brc=%d nbr=%d\n", req, brc, nbr);
if (!brc || nbr != len) {
@@ -3105,7 +3105,7 @@ bool BGVFAM::BigRead(PGLOBAL g, HANDLE h, void *inbuf, int req)
sprintf(g->Message, MSG(READ_ERROR), To_File, buf);
- if (trace)
+ if (trace(1))
htrc("BIGREAD: %s\n", g->Message);
rc = true;
@@ -3119,7 +3119,7 @@ bool BGVFAM::BigRead(PGLOBAL g, HANDLE h, void *inbuf, int req)
sprintf(g->Message, MSG(READ_ERROR), fn, strerror(errno));
- if (trace)
+ if (trace(1))
htrc("BIGREAD: nbr=%d len=%d errno=%d %s\n",
nbr, len, errno, g->Message);
@@ -3141,7 +3141,7 @@ bool BGVFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req)
DWORD nbw, drc, len = (DWORD)req;
bool brc = WriteFile(h, inbuf, len, &nbw, NULL);
- if (trace)
+ if (trace(1))
htrc("after write req=%d brc=%d nbw=%d\n", req, brc, nbw);
if (!brc || nbw != len) {
@@ -3159,7 +3159,7 @@ bool BGVFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req)
sprintf(g->Message, MSG(WRITE_STRERROR), fn, buf);
- if (trace)
+ if (trace(1))
htrc("BIGWRITE: nbw=%d len=%d errno=%d %s\n",
nbw, len, drc, g->Message);
@@ -3174,7 +3174,7 @@ bool BGVFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req)
sprintf(g->Message, MSG(WRITE_STRERROR), fn, strerror(errno));
- if (trace)
+ if (trace(1))
htrc("BIGWRITE: nbw=%d len=%d errno=%d %s\n",
nbw, len, errno, g->Message);
@@ -3224,7 +3224,7 @@ int BGVFAM::GetBlockInfo(PGLOBAL g)
if (h == INVALID_HANDLE_VALUE || !_filelength(h)) {
#endif // !__WIN__
// Consider this is a void table
- if (trace)
+ if (trace(1))
htrc("Void table h=%d\n", h);
Last = Nrec;
@@ -3248,7 +3248,7 @@ int BGVFAM::GetBlockInfo(PGLOBAL g)
Block = (vh.NumRec > 0) ? (vh.NumRec + Nrec - 1) / Nrec : 0;
Last = (vh.NumRec + Nrec - 1) % Nrec + 1;
- if (trace)
+ if (trace(1))
htrc("Block=%d Last=%d\n", Block, Last);
} // endif's
@@ -3348,7 +3348,7 @@ bool BGVFAM::MakeEmptyFile(PGLOBAL g, PCSZ fn)
of.QuadPart = (BIGINT)n + (BIGINT)MaxBlk * (BIGINT)Blksize - (BIGINT)1;
- if (trace)
+ if (trace(1))
htrc("MEF: of=%lld n=%d maxblk=%d blksize=%d\n",
of.QuadPart, n, MaxBlk, Blksize);
@@ -3394,7 +3394,7 @@ bool BGVFAM::MakeEmptyFile(PGLOBAL g, PCSZ fn)
pos = (BIGINT)n + (BIGINT)MaxBlk * (BIGINT)Blksize - (BIGINT)1;
- if (trace)
+ if (trace(1))
htrc("MEF: pos=%lld n=%d maxblk=%d blksize=%d\n",
pos, n, MaxBlk, Blksize);
@@ -3439,7 +3439,7 @@ bool BGVFAM::OpenTableFile(PGLOBAL g)
PlugSetPath(filename, To_File, Tdbp->GetPath());
- if (trace)
+ if (trace(1))
htrc("OpenTableFile: filename=%s mode=%d Last=%d\n",
filename, mode, Last);
@@ -3516,7 +3516,7 @@ bool BGVFAM::OpenTableFile(PGLOBAL g)
strcat(g->Message, filename);
} // endif Hfile
- if (trace)
+ if (trace(1))
htrc(" rc=%d access=%p share=%p creation=%d handle=%p fn=%s\n",
rc, access, share, creation, Hfile, filename);
@@ -3605,7 +3605,7 @@ bool BGVFAM::OpenTableFile(PGLOBAL g)
strcat(g->Message, strerror(errno));
} // endif Hfile
- if (trace)
+ if (trace(1))
htrc(" rc=%d oflag=%p mode=%p handle=%d fn=%s\n",
rc, oflag, mode, Hfile, filename);
#endif // UNIX
@@ -3626,7 +3626,7 @@ bool BGVFAM::OpenTableFile(PGLOBAL g)
To_Fb->Mode = mode;
To_Fb->Handle = Hfile;
- if (trace)
+ if (trace(1))
htrc("File %s is open in mode %d\n", filename, mode);
if (del)
@@ -3729,7 +3729,7 @@ bool BGVFAM::AllocateBuffer(PGLOBAL g)
/***********************************************************************/
int BGVFAM::WriteBuffer(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("BGV WriteDB: R%d Mode=%d CurNum=%d CurBlk=%d\n",
Tdbp->GetTdb_No(), Tdbp->GetMode(), CurNum, CurBlk);
@@ -3829,7 +3829,7 @@ int BGVFAM::DeleteRecords(PGLOBAL g, int irc)
/* 2 - directly move the not deleted lines inside the original */
/* file, and at the end erase all trailing records. */
/*********************************************************************/
- if (trace)
+ if (trace(1))
htrc("BGV DeleteDB: irc=%d UseTemp=%d Fpos=%d Tpos=%d Spos=%d\n",
irc, UseTemp, Fpos, Tpos, Spos);
@@ -3839,7 +3839,7 @@ int BGVFAM::DeleteRecords(PGLOBAL g, int irc)
/*******************************************************************/
Fpos = (Block - 1) * Nrec + Last;
- if (trace)
+ if (trace(1))
htrc("Fpos placed at file end=%d\n", Fpos);
eof = UseTemp && !MaxBlk;
@@ -3878,7 +3878,7 @@ int BGVFAM::DeleteRecords(PGLOBAL g, int irc)
#endif
Spos++; // New start position is on next line
- if (trace)
+ if (trace(1))
htrc("after: Tpos=%d Spos=%d\n", Tpos, Spos);
} else {
@@ -4065,7 +4065,7 @@ bool BGVFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
} // endif Usetemp...
- if (trace)
+ if (trace(1))
htrc("loop: Tpos=%d Spos=%d\n", Tpos, Spos);
} // endfor n
@@ -4201,7 +4201,7 @@ void BGVFAM::CloseTableFile(PGLOBAL g, bool abort)
if (Hfile != INVALID_HANDLE_VALUE)
rc = PlugCloseFile(g, To_Fb);
- if (trace)
+ if (trace(1))
htrc("BGV CloseTableFile: closing %s wrc=%d rc=%d\n",
To_File, wrc, rc);
@@ -4247,7 +4247,7 @@ bool BGVFAM::ReadBlock(PGLOBAL g, PVCTCOL colp)
pos = (BIGINT)Nrec * ((BIGINT)colp->Deplac
+ (BIGINT)Lrecl * (BIGINT)CurBlk);
- if (trace)
+ if (trace(1))
htrc("RB: offset=%lld Nrec=%d Deplac=%d Lrecl=%d CurBlk=%d MaxBlk=%d\n",
pos, Nrec, colp->Deplac, Lrecl, CurBlk, MaxBlk);
@@ -4257,7 +4257,7 @@ bool BGVFAM::ReadBlock(PGLOBAL g, PVCTCOL colp)
if (BigRead(g, Hfile, colp->Blk->GetValPointer(), colp->Clen * Nrec))
return true;
- if (trace)
+ if (trace(1))
num_read++;
return false;
@@ -4284,7 +4284,7 @@ bool BGVFAM::WriteBlock(PGLOBAL g, PVCTCOL colp)
pos = (BIGINT)Nrec * ((BIGINT)colp->Deplac
+ (BIGINT)Lrecl * (BIGINT)colp->ColBlk);
- if (trace)
+ if (trace(1))
htrc("WB: offset=%lld Nrec=%d Deplac=%d Lrecl=%d ColBlk=%d\n",
pos, Nrec, colp->Deplac, Lrecl, colp->ColBlk);
diff --git a/storage/connect/filamzip.cpp b/storage/connect/filamzip.cpp
index dfd9343af76..e76dc496246 100644
--- a/storage/connect/filamzip.cpp
+++ b/storage/connect/filamzip.cpp
@@ -699,7 +699,7 @@ bool UNZIPUTL::openEntry(PGLOBAL g)
entryopen = true;
} // endif rc
- if (trace)
+ if (trace(1))
htrc("Openning entry%s %s\n", fn, (entryopen) ? "oked" : "failed");
return !entryopen;
@@ -748,10 +748,10 @@ UNZFAM::UNZFAM(PUNZFAM txfp) : MAPFAM(txfp)
/***********************************************************************/
int UNZFAM::GetFileLength(PGLOBAL g)
{
- int len = (zutp && zutp->entryopen) ? Top - Memory
+ int len = (zutp && zutp->entryopen) ? (int)(Top - Memory)
: TXTFAM::GetFileLength(g) * 3;
- if (trace)
+ if (trace(1))
htrc("Zipped file length=%d\n", len);
return len;
@@ -1088,7 +1088,7 @@ int ZIPFAM::WriteBuffer(PGLOBAL g)
// Prepare to write the new line
strcat(strcpy(To_Buf, Tdbp->GetLine()), (Bin) ? CrLf : "\n");
- len = strchr(To_Buf, '\n') - To_Buf + 1;
+ len = (int)(strchr(To_Buf, '\n') - To_Buf + 1);
return zutp->writeEntry(g, To_Buf, len);
} // end of WriteBuffer
diff --git a/storage/connect/filter.cpp b/storage/connect/filter.cpp
index 079128f9aa6..469cd90d1d7 100644
--- a/storage/connect/filter.cpp
+++ b/storage/connect/filter.cpp
@@ -87,7 +87,7 @@ BYTE OpBmp(PGLOBAL g, OPVAL opc)
case OP_EXIST: bt = 0x00; break;
default:
sprintf(g->Message, MSG(BAD_FILTER_OP), opc);
- throw (int)TYPE_ARRAY;
+ throw (int)TYPE_FILTER;
} // endswitch opc
return bt;
@@ -301,7 +301,7 @@ PFIL FILTER::Link(PGLOBAL g, PFIL fil2)
{
PFIL fil1;
- if (trace)
+ if (trace(1))
htrc("Linking filter %p with op=%d... to filter %p with op=%d\n",
this, Opc, fil2, (fil2) ? fil2->Opc : 0);
@@ -355,7 +355,7 @@ int FILTER::CheckColumn(PGLOBAL g, PSQL sqlp, PXOB &p, int &ag)
char errmsg[MAX_STR] = "";
int agg, k, n = 0;
- if (trace)
+ if (trace(1))
htrc("FILTER CheckColumn: sqlp=%p ag=%d\n", sqlp, ag);
switch (Opc) {
@@ -540,7 +540,7 @@ PFIL FILTER::SortJoin(PGLOBAL g)
bool FILTER::FindJoinFilter(POPJOIN opj, PFIL fprec, bool teq, bool tek,
bool tk2, bool tc2, bool tix, bool thx)
{
- if (trace)
+ if (trace(1))
htrc("FindJoinFilter: opj=%p fprec=%p tests=(%d,%d,%d,%d)\n",
opj, fprec, teq, tek, tk2, tc2);
@@ -867,7 +867,7 @@ bool FILTER::CheckLocal(PTDB tdbp)
{
bool local = TRUE;
- if (trace) {
+ if (trace(1)) {
if (tdbp)
htrc("CheckLocal: filp=%p R%d\n", this, tdbp->GetTdb_No());
else
@@ -877,7 +877,7 @@ bool FILTER::CheckLocal(PTDB tdbp)
for (int i = 0; local && i < 2; i++)
local = Arg(i)->CheckLocal(tdbp);
- if (trace)
+ if (trace(1))
htrc("FCL: returning %d\n", local);
return (local);
@@ -983,7 +983,7 @@ bool FILTER::Convert(PGLOBAL g, bool having)
{
int i, comtype = TYPE_ERROR;
- if (trace)
+ if (trace(1))
htrc("converting(?) %s %p opc=%d\n",
(having) ? "having" : "filter", this, Opc);
@@ -1014,7 +1014,7 @@ bool FILTER::Convert(PGLOBAL g, bool having)
return TRUE;
} // endswitch
- if (trace)
+ if (trace(1))
htrc("Filter(%d): Arg type=%d\n", i, GetArgType(i));
// Set default values
@@ -1059,7 +1059,7 @@ bool FILTER::Convert(PGLOBAL g, bool having)
return TRUE;
} // endif
- if (trace)
+ if (trace(1))
htrc(" comtype=%d, B_T(%d)=%d Val(%d)=%p\n",
comtype, i, Test[i].B_T, i, Val(i));
@@ -1067,7 +1067,7 @@ bool FILTER::Convert(PGLOBAL g, bool having)
// Set or allocate the filter argument values and buffers
for (i = 0; i < 2; i++) {
- if (trace)
+ if (trace(1))
htrc(" conv type %d ? i=%d B_T=%d comtype=%d\n",
GetArgType(i), i, Test[i].B_T, comtype);
@@ -1144,7 +1144,7 @@ bool FILTER::Convert(PGLOBAL g, bool having)
TEST: // Test for possible Eval optimization
- if (trace)
+ if (trace(1))
htrc("Filp %p op=%d argtypes=(%d,%d)\n",
this, Opc, GetArgType(0), GetArgType(1));
@@ -1233,7 +1233,7 @@ bool FILTER::Eval(PGLOBAL g)
else if (Test[i].Conv)
Val(i)->SetValue_pval(Arg(i)->GetValue());
- if (trace)
+ if (trace(1))
htrc(" Filter: op=%d type=%d %d B_T=%d %d val=%p %p\n",
Opc, GetArgType(0), GetArgType(1), Test[0].B_T, Test[1].B_T,
Val(0), Val(1));
@@ -1273,7 +1273,7 @@ bool FILTER::Eval(PGLOBAL g)
goto FilterError;
} // endswitch Type
- if (trace) {
+ if (trace(1)) {
htrc(" IN filtering: ap=%p\n", ap);
if (ap)
@@ -1363,7 +1363,7 @@ bool FILTER::Eval(PGLOBAL g)
goto FilterError;
} // endswitch Opc
- if (trace)
+ if (trace(1))
htrc("Eval: filter %p Opc=%d result=%d\n",
this, Opc, Value->GetIntValue());
@@ -1775,7 +1775,7 @@ PFIL PrepareFilter(PGLOBAL g, PFIL fp, bool having)
{
PFIL filp = NULL;
- if (trace)
+ if (trace(1))
htrc("PrepareFilter: fp=%p having=%d\n", fp, having);
while (fp) {
@@ -1790,14 +1790,14 @@ PFIL PrepareFilter(PGLOBAL g, PFIL fp, bool having)
break; // Remove eventual ending separator(s)
// if (fp->Convert(g, having))
-// (int)throw TYPE_ARRAY;
+// throw (int)TYPE_FILTER;
filp = fp;
fp = fp->Next;
filp->Next = NULL;
} // endwhile
- if (trace)
+ if (trace(1))
htrc(" returning filp=%p\n", filp);
return filp;
@@ -1823,7 +1823,7 @@ DllExport bool ApplyFilter(PGLOBAL g, PFIL filp)
if (filp->Eval(g))
throw (int)TYPE_FILTER;
- if (trace > 1)
+ if (trace(2))
htrc("PlugFilter filp=%p result=%d\n",
filp, filp->GetResult());
diff --git a/storage/connect/fmdlex.c b/storage/connect/fmdlex.c
index a8d48a5d3b1..729b1b883c1 100644
--- a/storage/connect/fmdlex.c
+++ b/storage/connect/fmdlex.c
@@ -283,7 +283,7 @@ static void yy_fatal_error YY_PROTO(( const char msg[] ));
*/
#define YY_DO_BEFORE_ACTION \
yytext_ptr = yy_bp; \
- yyleng = yy_cp - yy_bp; \
+ yyleng = (int)(yy_cp - yy_bp); \
yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
yy_c_buf_p = yy_cp;
@@ -695,7 +695,7 @@ case YY_STATE_EOF(dqt):
case YY_END_OF_BUFFER:
{
/* Amount of text matched not including the EOB char. */
- int yy_amount_of_matched_text = yy_cp - yytext_ptr - 1;
+ int yy_amount_of_matched_text = (int)(yy_cp - yytext_ptr - 1);
/* Undo the effects of YY_DO_BEFORE_ACTION. */
*yy_cp = yy_hold_char;
@@ -862,7 +862,7 @@ static int yy_get_next_buffer()
/* Try to read more data. */
/* First move last chars to start of buffer. */
- number_to_move = yy_c_buf_p - yytext_ptr;
+ number_to_move = (int)(yy_c_buf_p - yytext_ptr);
for ( i = 0; i < number_to_move; ++i )
*(dest++) = *(source++);
@@ -888,7 +888,7 @@ static int yy_get_next_buffer()
/* just a shorter name for the current buffer */
YY_BUFFER_STATE b = yy_current_buffer;
- int yy_c_buf_p_offset = yy_c_buf_p - b->yy_ch_buf;
+ int yy_c_buf_p_offset = (int)(yy_c_buf_p - b->yy_ch_buf);
b->yy_buf_size *= 2;
b->yy_ch_buf = (char *)
diff --git a/storage/connect/global.h b/storage/connect/global.h
index e4b00786efa..472d09408c3 100644
--- a/storage/connect/global.h
+++ b/storage/connect/global.h
@@ -52,7 +52,7 @@
/***********************************************************************/
/* Define access to the thread based trace value. */
/***********************************************************************/
-#define trace GetTraceValue()
+#define trace(T) (bool)(GetTraceValue() & (uint)T)
/***********************************************************************/
/* Miscellaneous Constants */
@@ -220,14 +220,19 @@ DllExport BOOL PlugIsAbsolutePath(LPCSTR path);
DllExport bool AllocSarea(PGLOBAL, uint);
DllExport void FreeSarea(PGLOBAL);
DllExport BOOL PlugSubSet(PGLOBAL, void *, uint);
-DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t);
DllExport char *PlugDup(PGLOBAL g, const char *str);
DllExport void *MakePtr(void *, OFFSET);
DllExport void htrc(char const *fmt, ...);
-DllExport int GetTraceValue(void);
+//DllExport int GetTraceValue(void);
+DllExport uint GetTraceValue(void);
#if defined(__cplusplus)
} // extern "C"
#endif
+/***********************************************************************/
+/* Non exported routine declarations. */
+/***********************************************************************/
+void *PlugSubAlloc(PGLOBAL, void *, size_t); // Does throw
+
/*-------------------------- End of Global.H --------------------------*/
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 08a61a75048..e6bfa97f327 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -98,8 +98,8 @@
rnd_next signals that it has reached the end of its data. Calls to
ha_connect::extra() are hints as to what will be occuring to the request.
- Author Olivier Bertrand
-*/
+ Author Olivier Bertrand
+ */
#ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation
@@ -174,9 +174,9 @@
#define JSONMAX 10 // JSON Default max grp size
extern "C" {
- char version[]= "Version 1.06.0005 October 14, 2017";
+ char version[]= "Version 1.06.0007 March 11, 2018";
#if defined(__WIN__)
- char compver[]= "Version 1.06.0005 " __DATE__ " " __TIME__;
+ char compver[]= "Version 1.06.0007 " __DATE__ " " __TIME__;
char slash= '\\';
#else // !__WIN__
char slash= '/';
@@ -266,16 +266,38 @@ static char *strz(PGLOBAL g, LEX_STRING &ls)
/***********************************************************************/
/* CONNECT session variables definitions. */
/***********************************************************************/
-// Tracing: 0 no, 1 yes, >1 more tracing
-static MYSQL_THDVAR_INT(xtrace,
- PLUGIN_VAR_RQCMDARG, "Console trace value.",
- NULL, NULL, 0, 0, INT_MAX, 1);
+// Tracing: 0 no, 1 yes, 2 more, 4 index... 511 all
+const char *xtrace_names[] =
+{
+ "YES", "MORE", "INDEX", "MEMORY", "SUBALLOC",
+ "QUERY", "STMT", "HANDLER", "BLOCK", "MONGO", NullS
+};
+
+TYPELIB xtrace_typelib =
+{
+ array_elements(xtrace_names) - 1, "xtrace_typelib",
+ xtrace_names, NULL
+};
+
+static MYSQL_THDVAR_SET(
+ xtrace, // name
+ PLUGIN_VAR_RQCMDARG, // opt
+ "Trace values.", // comment
+ NULL, // check
+ NULL, // update function
+ 0, // def (NO)
+ &xtrace_typelib); // typelib
// Getting exact info values
static MYSQL_THDVAR_BOOL(exact_info, PLUGIN_VAR_RQCMDARG,
"Getting exact info values",
NULL, NULL, 0);
+// Enabling cond_push
+static MYSQL_THDVAR_BOOL(cond_push, PLUGIN_VAR_RQCMDARG,
+ "Enabling cond_push",
+ NULL, NULL, 1); // YES by default
+
/**
Temporary file usage:
no: Not using temporary file
@@ -314,17 +336,18 @@ static MYSQL_THDVAR_UINT(work_size,
static MYSQL_THDVAR_INT(conv_size,
PLUGIN_VAR_RQCMDARG, // opt
"Size used when converting TEXT columns.",
- NULL, NULL, SZCONV, 0, 65500, 1);
+ NULL, NULL, SZCONV, 0, 65500, 8192);
/**
Type conversion:
no: Unsupported types -> TYPE_ERROR
yes: TEXT -> VARCHAR
+ force: Do it also for ODBC BINARY and BLOBs
skip: skip unsupported type columns in Discovery
*/
const char *xconv_names[]=
{
- "NO", "YES", "SKIP", NullS
+ "NO", "YES", "FORCE", "SKIP", NullS
};
TYPELIB xconv_typelib=
@@ -339,7 +362,7 @@ static MYSQL_THDVAR_ENUM(
"Unsupported types conversion.", // comment
NULL, // check
NULL, // update function
- 0, // def (no)
+ 1, // def (yes)
&xconv_typelib); // typelib
// Null representation for JSON values
@@ -364,12 +387,17 @@ static MYSQL_THDVAR_STR(java_wrapper,
NULL, NULL, "wrappers/JdbcInterface");
#endif // JAVA_SUPPORT
-#if 0 // This is apparently not acceptable for a plugin
+// This is apparently not acceptable for a plugin so it is undocumented
+#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
// Enabling MONGO table type
+#if defined(MONGO_SUPPORT) || (MYSQL_VERSION_ID > 100200)
static MYSQL_THDVAR_BOOL(enable_mongo, PLUGIN_VAR_RQCMDARG,
- "Enabling the MongoDB access",
- NULL, NULL, MONGO_ENABLED);
-#endif // 0
+ "Enabling the MongoDB access", NULL, NULL, 1);
+#else // !version 2,3
+static MYSQL_THDVAR_BOOL(enable_mongo, PLUGIN_VAR_RQCMDARG,
+ "Enabling the MongoDB access", NULL, NULL, 0);
+#endif // !version 2,3
+#endif // JAVA_SUPPORT || CMGO_SUPPORT
#if defined(XMSG) || defined(NEWMSG)
const char *language_names[]=
@@ -401,9 +429,10 @@ handlerton *connect_hton= NULL;
/***********************************************************************/
/* Function to export session variable values to other source files. */
/***********************************************************************/
-extern "C" int GetTraceValue(void)
- {return connect_hton ? THDVAR(current_thd, xtrace) : 0;}
+uint GetTraceValue(void)
+ {return (uint)(connect_hton ? THDVAR(current_thd, xtrace) : 0);}
bool ExactInfo(void) {return THDVAR(current_thd, exact_info);}
+bool CondPushEnabled(void) {return THDVAR(current_thd, cond_push);}
USETEMP UseTemp(void) {return (USETEMP)THDVAR(current_thd, use_tempfile);}
int GetConvSize(void) {return THDVAR(current_thd, conv_size);}
TYPCONV GetTypeConv(void) {return (TYPCONV)THDVAR(current_thd, type_conv);}
@@ -419,22 +448,20 @@ void SetWorkSize(uint)
push_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, 0,
"Work size too big, try setting a smaller value");
} // end of SetWorkSize
-#if defined(XMSG) || defined(NEWMSG)
-extern "C" const char *msglang(void)
-{
- return language_names[THDVAR(current_thd, msg_lang)];
-} // end of msglang
-#else // !XMSG && !NEWMSG
#if defined(JAVA_SUPPORT)
char *GetJavaWrapper(void)
{return connect_hton ? THDVAR(current_thd, java_wrapper) : (char*)"wrappers/JdbcInterface";}
#endif // JAVA_SUPPORT
-#if defined(JAVA_SUPPORT)
-//bool MongoEnabled(void) { return THDVAR(current_thd, enable_mongo); }
-#endif // JAVA_SUPPORT
+#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
+bool MongoEnabled(void) {return THDVAR(current_thd, enable_mongo);}
+#endif // JAVA_SUPPORT || CMGO_SUPPORT
+#if defined(XMSG) || defined(NEWMSG)
+extern "C" const char *msglang(void)
+ {return language_names[THDVAR(current_thd, msg_lang)];}
+#else // !XMSG && !NEWMSG
extern "C" const char *msglang(void)
{
#if defined(FRENCH)
@@ -726,7 +753,7 @@ static int connect_init_func(void *p)
connect_hton->tablefile_extensions= ha_connect_exts;
connect_hton->discover_table_structure= connect_assisted_discovery;
- if (trace)
+ if (trace(128))
sql_print_information("connect_init: hton=%p", p);
DTVAL::SetTimeShift(); // Initialize time zone shift once for all
@@ -818,7 +845,7 @@ static handler* connect_create_handler(handlerton *hton,
{
handler *h= new (mem_root) ha_connect(hton, table);
- if (trace)
+ if (trace(128))
htrc("New CONNECT %p, table: %.*s\n", h,
table ? table->table_name.length : 6,
table ? table->table_name.str : "<null>");
@@ -874,7 +901,7 @@ ha_connect::ha_connect(handlerton *hton, TABLE_SHARE *table_arg)
/****************************************************************************/
ha_connect::~ha_connect(void)
{
- if (trace)
+ if (trace(128))
htrc("Delete CONNECT %p, table: %.*s, xp=%p count=%d\n", this,
table ? table->s->table_name.length : 6,
table ? table->s->table_name.str : "<null>",
@@ -1086,55 +1113,55 @@ PCSZ GetListOption(PGLOBAL g, PCSZ opname, PCSZ oplist, PCSZ def)
if (!oplist)
return (char*)def;
- char key[16], val[256];
- char *pv, *pn, *pk= (char*)oplist;
- PCSZ opval= def;
- int n;
+ char key[16], val[256];
+ char *pv, *pn, *pk = (char*)oplist;
+ PCSZ opval = def;
+ int n;
while (*pk == ' ')
pk++;
- for (; pk; pk= pn) {
- pn= strchr(pk, ',');
- pv= strchr(pk, '=');
+ for (; pk; pk = pn) {
+ pn = strchr(pk, ',');
+ pv = strchr(pk, '=');
- if (pv && (!pn || pv < pn)) {
+ if (pv && (!pn || pv < pn)) {
n = MY_MIN(static_cast<size_t>(pv - pk), sizeof(key) - 1);
memcpy(key, pk, n);
while (n && key[n - 1] == ' ')
n--;
- key[n]= 0;
+ key[n] = 0;
- while(*(++pv) == ' ') ;
+ while (*(++pv) == ' ');
- n= MY_MIN((pn ? pn - pv : strlen(pv)), sizeof(val) - 1);
- memcpy(val, pv, n);
+ n = MY_MIN((pn ? pn - pv : strlen(pv)), sizeof(val) - 1);
+ memcpy(val, pv, n);
while (n && val[n - 1] == ' ')
n--;
- val[n]= 0;
- } else {
- n= MY_MIN((pn ? pn - pk : strlen(pk)), sizeof(key) - 1);
- memcpy(key, pk, n);
+ val[n] = 0;
+ } else {
+ n = MY_MIN((pn ? pn - pk : strlen(pk)), sizeof(key) - 1);
+ memcpy(key, pk, n);
while (n && key[n - 1] == ' ')
n--;
- key[n]= 0;
- val[0]= 0;
- } // endif pv
+ key[n] = 0;
+ val[0] = 0;
+ } // endif pv
- if (!stricmp(opname, key)) {
- opval= PlugDup(g, val);
- break;
- } else if (!pn)
- break;
+ if (!stricmp(opname, key)) {
+ opval = PlugDup(g, val);
+ break;
+ } else if (!pn)
+ break;
- while (*(++pn) == ' ') ;
- } // endfor pk
+ while (*(++pn) == ' ');
+ } // endfor pk
return opval;
} // end of GetListOption
@@ -1658,7 +1685,7 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s)
s= table->s;
for (int n= 0; (unsigned)n < s->keynames.count; n++) {
- if (trace)
+ if (trace(1))
htrc("Getting created index %d info\n", n + 1);
// Find the index to describe
@@ -2006,7 +2033,7 @@ bool ha_connect::CheckColumnList(PGLOBAL g)
} // endif
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
brc = true;
} catch (const char *msg) {
@@ -2063,7 +2090,7 @@ int ha_connect::MakeRecord(char *buf)
PCOL colp= NULL;
DBUG_ENTER("ha_connect::MakeRecord");
- if (trace > 1)
+ if (trace(2))
htrc("Maps: read=%08X write=%08X vcol=%08X defr=%08X defw=%08X\n",
*table->read_set->bitmap, *table->write_set->bitmap,
(table->vcol_set) ? *table->vcol_set->bitmap : 0,
@@ -2587,14 +2614,14 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
if (!cond)
return NULL;
- if (trace)
+ if (trace(1))
htrc("Cond type=%d\n", cond->type());
if (cond->type() == COND::COND_ITEM) {
PFIL fp;
Item_cond *cond_item= (Item_cond *)cond;
- if (trace)
+ if (trace(1))
htrc("Cond: Ftype=%d name=%s\n", cond_item->functype(),
cond_item->func_name());
@@ -2628,7 +2655,7 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
Item_func *condf= (Item_func *)cond;
Item* *args= condf->arguments();
- if (trace)
+ if (trace(1))
htrc("Func type=%d argnum=%d\n", condf->functype(),
condf->argument_count());
@@ -2657,11 +2684,11 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
return NULL;
for (i= 0; i < condf->argument_count(); i++) {
- if (trace)
+ if (trace(1))
htrc("Argtype(%d)=%d\n", i, args[i]->type());
if (i >= 2 && !ismul) {
- if (trace)
+ if (trace(1))
htrc("Unexpected arg for vop=%d\n", vop);
continue;
@@ -2691,7 +2718,7 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
break;
} // endswitch type
- if (trace) {
+ if (trace(1)) {
htrc("Field index=%d\n", pField->field->field_index);
htrc("Field name=%s\n", pField->field->field_name);
} // endif trace
@@ -2738,7 +2765,7 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
return NULL;
} // endswitch type
- if (trace)
+ if (trace(1))
htrc("Value type=%hd\n", pp->Type);
// Append the value to the argument list
@@ -2756,7 +2783,7 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
filp= MakeFilter(g, colp, pop, pfirst, neg);
} else {
- if (trace)
+ if (trace(1))
htrc("Unsupported condition\n");
return NULL;
@@ -2782,7 +2809,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
if (!cond)
return NULL;
- if (trace)
+ if (trace(1))
htrc("Cond type=%d\n", cond->type());
if (cond->type() == COND::COND_ITEM) {
@@ -2795,7 +2822,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
else
pb0= pb1= pb2= ph0= ph1= ph2= NULL;
- if (trace)
+ if (trace(1))
htrc("Cond: Ftype=%d name=%s\n", cond_item->functype(),
cond_item->func_name());
@@ -2881,7 +2908,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
filp->Bd = filp->Hv = false;
- if (trace)
+ if (trace(1))
htrc("Func type=%d argnum=%d\n", condf->functype(),
condf->argument_count());
@@ -2918,11 +2945,11 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
return NULL;
for (i= 0; i < condf->argument_count(); i++) {
- if (trace)
+ if (trace(1))
htrc("Argtype(%d)=%d\n", i, args[i]->type());
if (i >= 2 && !ismul) {
- if (trace)
+ if (trace(1))
htrc("Unexpected arg for vop=%d\n", vop);
continue;
@@ -2965,7 +2992,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
} // endif's
- if (trace) {
+ if (trace(1)) {
htrc("Field index=%d\n", pField->field->field_index);
htrc("Field name=%s\n", pField->field->field_name);
htrc("Field type=%d\n", pField->field->type());
@@ -3003,7 +3030,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
if ((res= pval->val_str(&tmp)) == NULL)
return NULL; // To be clarified
- if (trace)
+ if (trace(1))
htrc("Value=%.*s\n", res->length(), res->ptr());
// IN and BETWEEN clauses should be col VOP list
@@ -3144,7 +3171,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
filp->Bd = true;
} else {
- if (trace)
+ if (trace(1))
htrc("Unsupported condition\n");
return NULL;
@@ -3177,7 +3204,7 @@ const COND *ha_connect::cond_push(const COND *cond)
{
DBUG_ENTER("ha_connect::cond_push");
- if (tdbp) {
+ if (tdbp && CondPushEnabled()) {
PGLOBAL& g= xp->g;
AMT tty= tdbp->GetAmType();
bool x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC);
@@ -3211,7 +3238,7 @@ const COND *ha_connect::cond_push(const COND *cond)
if (filp->Having && strlen(filp->Having) > 255)
goto fin; // Memory collapse
- if (trace)
+ if (trace(1))
htrc("cond_push: %s\n", filp->Body);
tdbp->SetCond(cond);
@@ -3237,7 +3264,7 @@ const COND *ha_connect::cond_push(const COND *cond)
} // endif tty
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
} catch (const char *msg) {
strcpy(g->Message, msg);
@@ -3290,7 +3317,7 @@ bool ha_connect::get_error_message(int error, String* buf)
&my_charset_latin1,
&dummy_errors);
- if (trace)
+ if (trace(1))
htrc("GEM(%d): len=%u %s\n", error, len, g->Message);
msg[len]= '\0';
@@ -3342,7 +3369,7 @@ int ha_connect::open(const char *name, int mode, uint test_if_locked)
int rc= 0;
DBUG_ENTER("ha_connect::open");
- if (trace)
+ if (trace(1))
htrc("open: name=%s mode=%d test=%u\n", name, mode, test_if_locked);
if (!(share= get_share()))
@@ -3417,7 +3444,7 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT*)
rc = HA_ERR_INTERNAL_ERROR;
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
rc = HA_ERR_INTERNAL_ERROR;
} catch (const char *msg) {
@@ -3565,7 +3592,7 @@ int ha_connect::update_row(const uchar *old_data, uchar *new_data)
PGLOBAL& g= xp->g;
DBUG_ENTER("ha_connect::update_row");
- if (trace > 1)
+ if (trace(2))
htrc("update_row: old=%s new=%s\n", old_data, new_data);
// Check values for possible change in indexed column
@@ -3626,7 +3653,7 @@ int ha_connect::index_init(uint idx, bool sorted)
PGLOBAL& g= xp->g;
DBUG_ENTER("index_init");
- if (trace)
+ if (trace(1))
htrc("index_init: this=%p idx=%u sorted=%d\n", this, idx, sorted);
if (GetIndexType(GetRealType()) == 2) {
@@ -3679,7 +3706,7 @@ int ha_connect::index_init(uint idx, bool sorted)
rc= 0;
} // endif indexing
- if (trace)
+ if (trace(1))
htrc("index_init: rc=%d indexing=%d active_index=%d\n",
rc, indexing, active_index);
@@ -3726,7 +3753,7 @@ int ha_connect::ReadIndexed(uchar *buf, OPVAL op, const key_range *kr)
break;
} // endswitch RC
- if (trace > 1)
+ if (trace(2))
htrc("ReadIndexed: op=%d rc=%d\n", op, rc);
table->status= (rc == RC_OK) ? 0 : STATUS_NOT_FOUND;
@@ -3769,7 +3796,7 @@ int ha_connect::index_read(uchar * buf, const uchar * key, uint key_len,
default: DBUG_RETURN(-1); break;
} // endswitch find_flag
- if (trace > 1)
+ if (trace(2))
htrc("%p index_read: op=%d\n", this, op);
if (indexing > 0) {
@@ -3933,7 +3960,7 @@ int ha_connect::rnd_init(bool scan)
alter= 1;
} // endif xmod
- if (trace)
+ if (trace(1))
htrc("rnd_init: this=%p scan=%d xmod=%d alter=%d\n",
this, scan, xmod, alter);
@@ -4039,7 +4066,7 @@ int ha_connect::rnd_next(uchar *buf)
break;
} // endswitch RC
- if (trace > 1 && (rc || !(xp->nrd++ % 16384))) {
+ if (trace(2) && (rc || !(xp->nrd++ % 16384))) {
ulonglong tb2= my_interval_timer();
double elapsed= (double) (tb2 - xp->tb1) / 1000000000ULL;
DBUG_PRINT("rnd_next", ("rc=%d nrd=%u fnd=%u nfd=%u sec=%.3lf\n",
@@ -4083,7 +4110,7 @@ void ha_connect::position(const uchar *)
DBUG_ENTER("ha_connect::position");
my_store_ptr(ref, ref_length, (my_off_t)tdbp->GetRecpos());
- if (trace > 1)
+ if (trace(2))
htrc("position: pos=%d\n", tdbp->GetRecpos());
DBUG_VOID_RETURN;
@@ -4113,7 +4140,7 @@ int ha_connect::rnd_pos(uchar *buf, uchar *pos)
DBUG_ENTER("ha_connect::rnd_pos");
if (!tdbp->SetRecpos(xp->g, (int)my_get_ptr(pos, ref_length))) {
- if (trace)
+ if (trace(1))
htrc("rnd_pos: %d\n", tdbp->GetRecpos());
tdbp->SetFilter(NULL);
@@ -4179,7 +4206,7 @@ int ha_connect::info(uint flag)
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
} // endif g
- if (trace)
+ if (trace(1))
htrc("%p In info: flag=%u valid_info=%d\n", this, flag, valid_info);
// tdbp must be available to get updated info
@@ -4372,54 +4399,59 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn, bool quick)
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
return true;
} // endif path
- }
+
+ } // endif !quick
+
} else
return false;
- // check FILE_ACL
- // fall through
- case TAB_ODBC:
- case TAB_JDBC:
+ // Fall through
case TAB_MYSQL:
- case TAB_MONGO:
case TAB_DIR:
- case TAB_MAC:
- case TAB_WMI:
case TAB_ZIP:
case TAB_OEM:
#ifdef NO_EMBEDDED_ACCESS_CHECKS
- return false;
-#endif
- /*
- If table or table->mdl_ticket is NULL - it's a DLL, e.g. CREATE TABLE.
- if the table has an MDL_EXCLUSIVE lock - it's a DDL too, e.g. the
- insert step of CREATE ... SELECT.
-
- Otherwise it's a DML, the table was normally opened, locked,
- privilege were already checked, and table->grant.privilege is set.
- With SQL SECURITY DEFINER, table->grant.privilege has definer's privileges.
-
- Unless we're in prelocking mode, in this case table->grant.privilege
- is only checked in start_stmt(), not in external_lock().
- */
- if (!table || !table->mdl_ticket || table->mdl_ticket->get_type() == MDL_EXCLUSIVE)
- return check_access(thd, FILE_ACL, db, NULL, NULL, 0, 0);
- if ((!quick && thd->lex->requires_prelocking()) || table->grant.privilege & FILE_ACL)
- return false;
- status_var_increment(thd->status_var.access_denied_errors);
- my_error(access_denied_error_code(thd->password), MYF(0),
- thd->security_ctx->priv_user, thd->security_ctx->priv_host,
- (thd->password ? ER(ER_YES) : ER(ER_NO)));
- return true;
-
- // This is temporary until a solution is found
+ return false;
+ #endif
+
+ /*
+ Check FILE_ACL
+ If table or table->mdl_ticket is NULL - it's a DLL, e.g. CREATE TABLE.
+ if the table has an MDL_EXCLUSIVE lock - it's a DDL too, e.g. the
+ insert step of CREATE ... SELECT.
+
+ Otherwise it's a DML, the table was normally opened, locked,
+ privilege were already checked, and table->grant.privilege is set.
+ With SQL SECURITY DEFINER, table->grant.privilege has definer's privileges.
+
+ Unless we're in prelocking mode, in this case table->grant.privilege
+ is only checked in start_stmt(), not in external_lock().
+ */
+ if (!table || !table->mdl_ticket || table->mdl_ticket->get_type() == MDL_EXCLUSIVE)
+ return check_access(thd, FILE_ACL, db, NULL, NULL, 0, 0);
+
+ if ((!quick && thd->lex->requires_prelocking()) || table->grant.privilege & FILE_ACL)
+ return false;
+
+ status_var_increment(thd->status_var.access_denied_errors);
+ my_error(access_denied_error_code(thd->password), MYF(0),
+ thd->security_ctx->priv_user, thd->security_ctx->priv_host,
+ (thd->password ? ER(ER_YES) : ER(ER_NO)));
+ return true;
+ case TAB_ODBC:
+ case TAB_JDBC:
+ case TAB_MONGO:
+ case TAB_MAC:
+ case TAB_WMI:
+ return false;
case TAB_TBL:
case TAB_XCL:
case TAB_PRX:
case TAB_OCCUR:
case TAB_PIVOT:
case TAB_VIR:
- return false;
+ // This is temporary until a solution is found
+ return false;
} // endswitch type
my_printf_error(ER_UNKNOWN_ERROR, "check_privileges failed", MYF(0));
@@ -4457,7 +4489,7 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
#if defined(DEVELOPMENT)
if (true) {
#else
- if (trace) {
+ if (trace(65)) {
#endif
LEX_STRING *query_string= thd_query_string(thd);
htrc("%p check_mode: cmdtype=%d\n", this, thd_sql_command(thd));
@@ -4578,7 +4610,7 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
} // endif's newmode
- if (trace)
+ if (trace(1))
htrc("New mode=%d\n", newmode);
return newmode;
@@ -4656,7 +4688,7 @@ int ha_connect::external_lock(THD *thd, int lock_type)
DBUG_ASSERT(thd == current_thd);
- if (trace)
+ if (trace(1))
htrc("external_lock: this=%p thd=%p xp=%p g=%p lock_type=%d\n",
this, thd, xp, g, lock_type);
@@ -4849,7 +4881,7 @@ int ha_connect::external_lock(THD *thd, int lock_type)
if (cras)
g->Createas= 1; // To tell created table to ignore FLAG
- if (trace) {
+ if (trace(1)) {
#if 0
htrc("xcheck=%d cras=%d\n", xcheck, cras);
@@ -4882,7 +4914,7 @@ int ha_connect::external_lock(THD *thd, int lock_type)
// Delay open until used fields are known
} // endif tdbp
- if (trace)
+ if (trace(1))
htrc("external_lock: rc=%d\n", rc);
DBUG_RETURN(rc);
@@ -5018,7 +5050,7 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to)
THD *thd= current_thd;
int sqlcom= thd_sql_command(thd);
- if (trace) {
+ if (trace(1)) {
if (to)
htrc("rename_table: this=%p thd=%p sqlcom=%d from=%s to=%s\n",
this, thd, sqlcom, name, to);
@@ -5129,7 +5161,7 @@ ha_rows ha_connect::records_in_range(uint inx, key_range *min_key,
if (index_init(inx, false))
DBUG_RETURN(HA_POS_ERROR);
- if (trace)
+ if (trace(1))
htrc("records_in_range: inx=%d indexing=%d\n", inx, indexing);
if (indexing > 0) {
@@ -5158,7 +5190,7 @@ ha_rows ha_connect::records_in_range(uint inx, key_range *min_key,
else
rows= HA_POS_ERROR;
- if (trace)
+ if (trace(1))
htrc("records_in_range: rows=%llu\n", rows);
DBUG_RETURN(rows);
@@ -5380,7 +5412,7 @@ static int init_table_share(THD* thd,
} // endif charset
- if (trace)
+ if (trace(1))
htrc("s_init: %.*s\n", sql->length(), sql->ptr());
return table_s->init_from_sql_statement_string(thd, true,
@@ -5413,7 +5445,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#endif // __WIN__
//int hdr, mxe;
int port = 0, mxr = 0, rc = 0, mul = 0, lrecl = 0;
- PCSZ tabtyp = NULL;
+//PCSZ tabtyp = NULL;
#if defined(ODBC_SUPPORT)
POPARM sop= NULL;
PCSZ ucnc= NULL;
@@ -5477,7 +5509,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#endif // __WIN__
port= atoi(GetListOption(g, "port", topt->oplist, "0"));
#if defined(ODBC_SUPPORT)
- tabtyp = GetListOption(g, "Tabtype", topt->oplist, NULL);
+// tabtyp = GetListOption(g, "Tabtype", topt->oplist, NULL);
mxr= atoi(GetListOption(g,"maxres", topt->oplist, "0"));
cto= atoi(GetListOption(g,"ConnectTimeout", topt->oplist, "-1"));
qto= atoi(GetListOption(g,"QueryTimeout", topt->oplist, "-1"));
@@ -5611,7 +5643,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#endif // JAVA_SUPPORT
case TAB_DBF:
dbf = true;
- // Passthru
+ // fall through
case TAB_CSV:
if (!fn && fnc != FNC_NO)
sprintf(g->Message, "Missing %s file name", topt->type);
@@ -5790,7 +5822,8 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
break;
case FNC_TABLE:
- qrp = JDBCTables(g, shm, tab, tabtyp, mxr, true, sjp);
+// qrp = JDBCTables(g, shm, tab, tabtyp, mxr, true, sjp);
+ qrp = JDBCTables(g, shm, tab, NULL, mxr, true, sjp);
break;
#if 0
case FNC_DSN:
@@ -5845,12 +5878,12 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
case TAB_JSON:
qrp = JSONColumns(g, db, dsn, topt, fnc == FNC_COL);
break;
-#if defined(MONGO_SUPPORT)
+#if defined(JAVA_SUPPORT)
case TAB_MONGO:
url = strz(g, create_info->connect_string);
qrp = MGOColumns(g, db, url, topt, fnc == FNC_COL);
break;
-#endif // MONGO_SUPPORT
+#endif // JAVA_SUPPORT
#if defined(LIBXML2_SUPPORT) || defined(DOMDOC_SUPPORT)
case TAB_XML:
qrp = XMLColumns(g, (char*)db, tab, topt, fnc == FNC_COL);
@@ -6093,7 +6126,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
} // endif ok
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
rc = HA_ERR_INTERNAL_ERROR;
} catch (const char *msg) {
@@ -6189,7 +6222,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
table= table_arg; // Used by called functions
- if (trace)
+ if (trace(1))
htrc("create: this=%p thd=%p xp=%p g=%p sqlcom=%d name=%s\n",
this, thd, xp, g, sqlcom, GetTableName());
@@ -6572,7 +6605,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} // endif sqlcom
- if (trace)
+ if (trace(1))
htrc("xchk=%p createas=%d\n", g->Xchk, g->Createas);
if (options->zipped) {
@@ -6943,7 +6976,7 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table,
xcp->newsep= xcp->SetName(g, GetStringOption("optname"));
tshp= NULL;
- if (trace && g->Xchk)
+ if (trace(1) && g->Xchk)
htrc(
"oldsep=%d newsep=%d oldopn=%s newopn=%s oldpix=%p newpix=%p\n",
xcp->oldsep, xcp->newsep,
@@ -7207,10 +7240,11 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
MYSQL_SYSVAR(class_path),
MYSQL_SYSVAR(java_wrapper),
#endif // JAVA_SUPPORT
-#if defined(JAVA_SUPPORT)
-//MYSQL_SYSVAR(enable_mongo),
-#endif // JAVA_SUPPORT
-NULL
+#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
+ MYSQL_SYSVAR(enable_mongo),
+#endif // JAVA_SUPPORT || CMGO_SUPPORT
+ MYSQL_SYSVAR(cond_push),
+ NULL
};
maria_declare_plugin(connect)
@@ -7223,10 +7257,10 @@ maria_declare_plugin(connect)
PLUGIN_LICENSE_GPL,
connect_init_func, /* Plugin Init */
connect_done_func, /* Plugin Deinit */
- 0x0106, /* version number (1.05) */
+ 0x0107, /* version number (1.05) */
NULL, /* status variables */
connect_system_variables, /* system variables */
- "1.06.0005", /* string version */
+ "1.06.0007", /* string version */
MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
}
maria_declare_plugin_end;
diff --git a/storage/connect/inihandl.cpp b/storage/connect/inihandl.cpp
index 96ae0a67a6b..c039a980bcb 100644
--- a/storage/connect/inihandl.cpp
+++ b/storage/connect/inihandl.cpp
@@ -293,7 +293,7 @@ static PROFILESECTION *PROFILE_Load( FILE *file )
next_key = &section->key;
prev_key = NULL;
- if (trace > 1)
+ if (trace(2))
htrc("New section: '%s'\n",section->name);
continue;
@@ -336,7 +336,7 @@ static PROFILESECTION *PROFILE_Load( FILE *file )
next_key = &key->next;
prev_key = key;
- if (trace > 1)
+ if (trace(2))
htrc("New key: name='%s', value='%s'\n",
key->name,key->value?key->value:"(none)");
@@ -359,7 +359,7 @@ static BOOL PROFILE_FlushFile(void)
FILE *file = NULL;
struct stat buf;
- if (trace > 1)
+ if (trace(2))
htrc("PROFILE_FlushFile: CurProfile=%p\n", CurProfile);
if (!CurProfile) {
@@ -398,7 +398,7 @@ static BOOL PROFILE_FlushFile(void)
return FALSE;
} // endif !file
- if (trace > 1)
+ if (trace(2))
htrc("Saving '%s'\n", CurProfile->filename);
PROFILE_Save(file, CurProfile->section);
@@ -447,7 +447,7 @@ static BOOL PROFILE_Open(LPCSTR filename)
struct stat buf;
PROFILE *tempProfile;
- if (trace > 1)
+ if (trace(2))
htrc("PROFILE_Open: CurProfile=%p N=%d\n", CurProfile, N_CACHED_PROFILES);
/* First time around */
@@ -468,7 +468,7 @@ static BOOL PROFILE_Open(LPCSTR filename)
/* Check for a match */
for (i = 0; i < N_CACHED_PROFILES; i++) {
- if (trace > 1)
+ if (trace(2))
htrc("MRU=%s i=%d\n", SVP(MRUProfile[i]->filename), i);
if (MRUProfile[i]->filename && !strcmp(filename, MRUProfile[i]->filename)) {
@@ -483,11 +483,11 @@ static BOOL PROFILE_Open(LPCSTR filename)
} // endif i
if (!stat(CurProfile->filename, &buf) && CurProfile->mtime == buf.st_mtime) {
- if (trace > 1)
+ if (trace(2))
htrc("(%s): already opened (mru=%d)\n", filename, i);
} else {
- if (trace > 1)
+ if (trace(2))
htrc("(%s): already opened, needs refreshing (mru=%d)\n", filename, i);
} // endif stat
@@ -535,11 +535,11 @@ static BOOL PROFILE_Open(LPCSTR filename)
// strcpy(p, filename);
// _strlwr(p);
- if (trace > 1)
+ if (trace(2))
htrc("Opening %s\n", filename);
if ((file = fopen(filename, "r"))) {
- if (trace > 1)
+ if (trace(2))
htrc("(%s): found it\n", filename);
// CurProfile->unix_name = malloc(strlen(buffer)+1);
@@ -574,12 +574,12 @@ void PROFILE_Close(LPCSTR filename)
struct stat buf;
PROFILE *tempProfile;
- if (trace > 1)
+ if (trace(2))
htrc("PROFILE_Close: CurProfile=%p N=%d\n", CurProfile, N_CACHED_PROFILES);
/* Check for a match */
for (i = 0; i < N_CACHED_PROFILES; i++) {
- if (trace > 1)
+ if (trace(2))
htrc("MRU=%s i=%d\n", SVP(MRUProfile[i]->filename), i);
if (MRUProfile[i]->filename && !strcmp(filename, MRUProfile[i]->filename)) {
@@ -591,7 +591,7 @@ void PROFILE_Close(LPCSTR filename)
CurProfile=tempProfile;
} // endif i
- if (trace > 1) {
+ if (trace(2)) {
if (!stat(CurProfile->filename, &buf) && CurProfile->mtime == buf.st_mtime)
htrc("(%s): already opened (mru=%d)\n", filename, i);
else
@@ -620,7 +620,7 @@ void PROFILE_End(void)
{
int i;
- if (trace)
+ if (trace(3))
htrc("PROFILE_End: CurProfile=%p N=%d\n", CurProfile, N_CACHED_PROFILES);
if (!CurProfile) // Sergey Vojtovich
@@ -628,7 +628,7 @@ void PROFILE_End(void)
/* Close all opened files and free the cache structure */
for (i = 0; i < N_CACHED_PROFILES; i++) {
- if (trace)
+ if (trace(3))
htrc("MRU=%s i=%d\n", SVP(MRUProfile[i]->filename), i);
// CurProfile = MRUProfile[i]; Sergey Vojtovich
@@ -894,7 +894,7 @@ static int PROFILE_GetSectionNames(LPSTR buffer, uint len)
uint f,l;
PROFILESECTION *section;
- if (trace > 1)
+ if (trace(2))
htrc("GetSectionNames: buffer=%p len=%u\n", buffer, len);
if (!buffer || !len)
@@ -909,17 +909,17 @@ static int PROFILE_GetSectionNames(LPSTR buffer, uint len)
buf = buffer;
section = CurProfile->section;
- if (trace > 1)
+ if (trace(2))
htrc("GetSectionNames: section=%p\n", section);
while (section != NULL) {
- if (trace > 1)
+ if (trace(2))
htrc("section=%s\n", section->name);
if (section->name[0]) {
l = strlen(section->name) + 1;
- if (trace > 1)
+ if (trace(2))
htrc("l=%u f=%u\n", l, f);
if (l > f) {
@@ -982,7 +982,7 @@ static int PROFILE_GetString(LPCSTR section, LPCSTR key_name,
key = PROFILE_Find(&CurProfile->section, section, key_name, FALSE, FALSE);
PROFILE_CopyEntry(buffer, (key && key->value) ? key->value : def_val, len, FALSE);
- if (trace > 1)
+ if (trace(2))
htrc("('%s','%s','%s'): returning '%s'\n",
section, key_name, def_val, buffer );
@@ -1010,7 +1010,7 @@ static BOOL PROFILE_SetString(LPCSTR section_name, LPCSTR key_name,
LPCSTR value, BOOL create_always)
{
if (!key_name) { /* Delete a whole section */
- if (trace > 1)
+ if (trace(2))
htrc("Deleting('%s')\n", section_name);
CurProfile->changed |= PROFILE_DeleteSection(&CurProfile->section,
@@ -1018,7 +1018,7 @@ static BOOL PROFILE_SetString(LPCSTR section_name, LPCSTR key_name,
return TRUE; /* Even if PROFILE_DeleteSection() has failed,
this is not an error on application's level.*/
} else if (!value) { /* Delete a key */
- if (trace > 1)
+ if (trace(2))
htrc("Deleting('%s','%s')\n", section_name, key_name);
CurProfile->changed |= PROFILE_DeleteKey(&CurProfile->section,
@@ -1027,7 +1027,7 @@ static BOOL PROFILE_SetString(LPCSTR section_name, LPCSTR key_name,
} else { /* Set the key value */
PROFILEKEY *key = PROFILE_Find(&CurProfile->section, section_name,
key_name, TRUE, create_always);
- if (trace > 1)
+ if (trace(2))
htrc("Setting('%s','%s','%s')\n", section_name, key_name, value);
if (!key)
@@ -1040,17 +1040,17 @@ static BOOL PROFILE_SetString(LPCSTR section_name, LPCSTR key_name,
value++;
if (!strcmp(key->value, value)) {
- if (trace > 1)
+ if (trace(2))
htrc(" no change needed\n" );
return TRUE; /* No change needed */
} // endif value
- if (trace > 1)
+ if (trace(2))
htrc(" replacing '%s'\n", key->value);
free(key->value);
- } else if (trace > 1)
+ } else if (trace(2))
htrc(" creating key\n" );
key->value = (char*)malloc(strlen(value) + 1);
@@ -1345,7 +1345,7 @@ GetPrivateProfileSectionNames(LPSTR buffer, DWORD size, LPCSTR filename)
{
DWORD ret = 0;
- if (trace > 1)
+ if (trace(2))
htrc("GPPSN: filename=%s\n", filename);
EnterCriticalSection(&PROFILE_CritSect);
diff --git a/storage/connect/javaconn.cpp b/storage/connect/javaconn.cpp
index 90f834ef9a7..d1be0ca1848 100644
--- a/storage/connect/javaconn.cpp
+++ b/storage/connect/javaconn.cpp
@@ -363,7 +363,7 @@ bool JAVAConn::GetJVM(PGLOBAL g)
bool JAVAConn::Open(PGLOBAL g)
{
bool brc = true, err = false;
- jboolean jt = (trace > 0);
+ jboolean jt = (trace(1));
// Link or check whether jvm library was linked
if (GetJVM(g))
@@ -430,7 +430,7 @@ bool JAVAConn::Open(PGLOBAL g)
jpop->Append(cp);
} // endif cp
- if (trace) {
+ if (trace(1)) {
htrc("ClassPath=%s\n", ClassPath);
htrc("CLASSPATH=%s\n", cp);
htrc("%s\n", jpop->GetStr());
@@ -486,7 +486,7 @@ bool JAVAConn::Open(PGLOBAL g)
break;
} // endswitch rc
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
if (brc)
diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp
index 4c21c2c9681..ddbc3115f0b 100644
--- a/storage/connect/jdbconn.cpp
+++ b/storage/connect/jdbconn.cpp
@@ -1,7 +1,7 @@
/************ Jdbconn C++ Functions Source Code File (.CPP) ************/
-/* Name: JDBCONN.CPP Version 1.1 */
+/* Name: JDBCONN.CPP Version 1.2 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2016-2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2016-2018 */
/* */
/* This file contains the JDBC connection classes functions. */
/***********************************************************************/
@@ -116,10 +116,26 @@ int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v)
return TYPE_ERROR;
else
len = MY_MIN(abs(len), GetConvSize());
+
// Pass through
case 12: // VARCHAR
+ if (tn && !stricmp(tn, "TEXT"))
+ // Postgresql returns 12 for TEXT
+ if (GetTypeConv() == TPC_NO)
+ return TYPE_ERROR;
+
+ // Postgresql can return this
+ if (len == 0x7FFFFFFF)
+ len = GetConvSize();
+
+ // Pass through
case -9: // NVARCHAR (unicode)
+ // Postgresql can return this when size is unknown
+ if (len == 0x7FFFFFFF)
+ len = GetConvSize();
+
v = 'V';
+ // Pass through
case 1: // CHAR
case -15: // NCHAR (unicode)
case -8: // ROWID
@@ -154,13 +170,13 @@ int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v)
case 91: // DATE, YEAR
type = TYPE_DATE;
- if (!tn || toupper(tn[0]) != 'Y') {
- len = 10;
- v = 'D';
- } else {
- len = 4;
- v = 'Y';
- } // endif len
+ if (!tn || toupper(tn[0]) != 'Y') {
+ len = 10;
+ v = 'D';
+ } else {
+ len = 4;
+ v = 'Y';
+ } // endif len
break;
case 92: // TIME
@@ -192,6 +208,104 @@ int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v)
return type;
} // end of TranslateJDBCType
+ /***********************************************************************/
+ /* A helper class to split an optionally qualified table name into */
+ /* components. */
+ /* These formats are understood: */
+ /* "CatalogName.SchemaName.TableName" */
+ /* "SchemaName.TableName" */
+ /* "TableName" */
+ /***********************************************************************/
+class SQLQualifiedName {
+ static const uint max_parts = 3; // Catalog.Schema.Table
+ MYSQL_LEX_STRING m_part[max_parts];
+ char m_buf[512];
+
+ void lex_string_set(MYSQL_LEX_STRING *S, char *str, size_t length)
+ {
+ S->str = str;
+ S->length = length;
+ } // end of lex_string_set
+
+ void lex_string_shorten_down(MYSQL_LEX_STRING *S, size_t offs)
+ {
+ DBUG_ASSERT(offs <= S->length);
+ S->str += offs;
+ S->length -= offs;
+ } // end of lex_string_shorten_down
+
+ /*********************************************************************/
+ /* Find the rightmost '.' delimiter and return the length */
+ /* of the qualifier, including the rightmost '.' delimier. */
+ /* For example, for the string {"a.b.c",5} it will return 4, */
+ /* which is the length of the qualifier "a.b." */
+ /*********************************************************************/
+ size_t lex_string_find_qualifier(MYSQL_LEX_STRING *S)
+ {
+ size_t i;
+ for (i = S->length; i > 0; i--)
+ {
+ if (S->str[i - 1] == '.')
+ {
+ S->str[i - 1] = '\0';
+ return i;
+ }
+ }
+ return 0;
+ } // end of lex_string_find_qualifier
+
+public:
+ /*********************************************************************/
+ /* Initialize to the given optionally qualified name. */
+ /* NULL pointer in "name" is supported. */
+ /* name qualifier has precedence over schema. */
+ /*********************************************************************/
+ SQLQualifiedName(JCATPARM *cap)
+ {
+ const char *name = (const char *)cap->Tab;
+ char *db = (char *)cap->DB;
+ size_t len, i;
+
+ // Initialize the parts
+ for (i = 0; i < max_parts; i++)
+ lex_string_set(&m_part[i], NULL, 0);
+
+ if (name) {
+ // Initialize the first (rightmost) part
+ lex_string_set(&m_part[0], m_buf,
+ strmake(m_buf, name, sizeof(m_buf) - 1) - m_buf);
+
+ // Initialize the other parts, if exist.
+ for (i = 1; i < max_parts; i++) {
+ if (!(len = lex_string_find_qualifier(&m_part[i - 1])))
+ break;
+
+ lex_string_set(&m_part[i], m_part[i - 1].str, len - 1);
+ lex_string_shorten_down(&m_part[i - 1], len);
+ } // endfor i
+
+ } // endif name
+
+ // If it was not specified, set schema as the passed db name
+ if (db && !m_part[1].length)
+ lex_string_set(&m_part[1], db, strlen(db));
+
+ } // end of SQLQualifiedName
+
+ char *ptr(uint i)
+ {
+ DBUG_ASSERT(i < max_parts);
+ return (char *)(m_part[i].length ? m_part[i].str : NULL);
+ } // end of ptr
+
+ size_t length(uint i)
+ {
+ DBUG_ASSERT(i < max_parts);
+ return m_part[i].length;
+ } // end of length
+
+}; // end of class SQLQualifiedName
+
/***********************************************************************/
/* Allocate the structure used to refer to the result set. */
/***********************************************************************/
@@ -270,7 +384,7 @@ PQRYRES JDBCColumns(PGLOBAL g, PCSZ db, PCSZ table, PCSZ colpat,
length[11] = 255;
} // endif jcp
- if (trace)
+ if (trace(1))
htrc("JDBCColumns: max=%d len=%d,%d,%d,%d\n",
maxres, length[0], length[1], length[2], length[3]);
@@ -287,7 +401,7 @@ PQRYRES JDBCColumns(PGLOBAL g, PCSZ db, PCSZ table, PCSZ colpat,
if (info || !qrp) // Info table
return qrp;
- if (trace)
+ if (trace(1))
htrc("Getting col results ncol=%d\n", qrp->Nbcol);
if (!(cap = AllocCatInfo(g, JCAT_COL, db, table, qrp)))
@@ -303,7 +417,7 @@ PQRYRES JDBCColumns(PGLOBAL g, PCSZ db, PCSZ table, PCSZ colpat,
qrp->Nblin = n;
// ResetNullValues(cap);
- if (trace)
+ if (trace(1))
htrc("Columns: NBCOL=%d NBLIN=%d\n", qrp->Nbcol, qrp->Nblin);
} else
@@ -394,7 +508,7 @@ PQRYRES JDBCTables(PGLOBAL g, PCSZ db, PCSZ tabpat, PCSZ tabtyp,
length[4] = 255;
} // endif info
- if (trace)
+ if (trace(1))
htrc("JDBCTables: max=%d len=%d,%d\n", maxres, length[0], length[1]);
/************************************************************************/
@@ -417,7 +531,7 @@ PQRYRES JDBCTables(PGLOBAL g, PCSZ db, PCSZ tabpat, PCSZ tabtyp,
cap->Pat = tabtyp;
- if (trace)
+ if (trace(1))
htrc("Getting table results ncol=%d\n", cap->Qrp->Nbcol);
/************************************************************************/
@@ -427,7 +541,7 @@ PQRYRES JDBCTables(PGLOBAL g, PCSZ db, PCSZ tabpat, PCSZ tabtyp,
qrp->Nblin = n;
// ResetNullValues(cap);
- if (trace)
+ if (trace(1))
htrc("Tables: NBCOL=%d NBLIN=%d\n", qrp->Nbcol, qrp->Nblin);
} else
@@ -475,7 +589,7 @@ PQRYRES JDBCDrivers(PGLOBAL g, int maxres, bool info)
} else
maxres = 0;
- if (trace)
+ if (trace(1))
htrc("JDBCDrivers: max=%d len=%d\n", maxres, length[0]);
/************************************************************************/
@@ -519,7 +633,7 @@ JDBConn::JDBConn(PGLOBAL g, PCSZ wrapper) : JAVAConn(g, wrapper)
xqid = xuid = xid = grs = readid = fetchid = typid = errid = nullptr;
prepid = xpid = pcid = nullptr;
chrfldid = intfldid = dblfldid = fltfldid = bigfldid = nullptr;
- objfldid = datfldid = timfldid = tspfldid = nullptr;
+ objfldid = datfldid = timfldid = tspfldid = uidfldid = nullptr;
DiscFunc = "JdbcDisconnect";
m_Ncol = 0;
m_Aff = 0;
@@ -535,12 +649,84 @@ JDBConn::JDBConn(PGLOBAL g, PCSZ wrapper) : JAVAConn(g, wrapper)
m_IDQuoteChar[1] = 0;
} // end of JDBConn
-//JDBConn::~JDBConn()
-// {
-//if (Connected())
-// EndCom();
+/***********************************************************************/
+/* Search for UUID columns. */
+/***********************************************************************/
+bool JDBConn::SetUUID(PGLOBAL g, PTDBJDBC tjp)
+{
+ int ncol, ctyp;
+ bool brc = true;
+ PCSZ fnc = "GetColumns";
+ PCOL colp;
+ JCATPARM *cap;
+ //jint jtyp;
+ jboolean rc = false;
+ jobjectArray parms;
+ jmethodID catid = nullptr;
+
+ if (gmID(g, catid, fnc, "([Ljava/lang/String;)I"))
+ return true;
+ else if (gmID(g, intfldid, "IntField", "(ILjava/lang/String;)I"))
+ return true;
+ else if (gmID(g, readid, "ReadNext", "()I"))
+ return true;
+
+ cap = AllocCatInfo(g, JCAT_COL, tjp->Schema, tjp->TableName, NULL);
+ SQLQualifiedName name(cap);
+
+ // Build the java string array
+ parms = env->NewObjectArray(4, env->FindClass("java/lang/String"), NULL);
+ env->SetObjectArrayElement(parms, 0, env->NewStringUTF(name.ptr(2)));
+ env->SetObjectArrayElement(parms, 1, env->NewStringUTF(name.ptr(1)));
+ env->SetObjectArrayElement(parms, 2, env->NewStringUTF(name.ptr(0)));
+
+ for (colp = tjp->GetColumns(); colp; colp = colp->GetNext()) {
+ env->SetObjectArrayElement(parms, 3, env->NewStringUTF(colp->GetName()));
+ ncol = env->CallIntMethod(job, catid, parms);
+
+ if (Check(ncol)) {
+ sprintf(g->Message, "%s: %s", fnc, Msg);
+ goto err;
+ } // endif Check
+
+ rc = env->CallBooleanMethod(job, readid);
+
+ if (Check(rc)) {
+ sprintf(g->Message, "ReadNext: %s", Msg);
+ goto err;
+ } else if (rc == 0) {
+ sprintf(g->Message, "table %s does not exist", tjp->TableName);
+ goto err;
+ } // endif rc
-// } // end of ~JDBConn
+ // Returns 666 is case of error
+ //jtyp = env->CallIntMethod(job, typid, 5, nullptr);
+
+ //if (Check((jtyp == 666) ? -1 : 1)) {
+ // sprintf(g->Message, "Getting jtyp: %s", Msg);
+ // goto err;
+ //} // endif ctyp
+
+ ctyp = (int)env->CallIntMethod(job, intfldid, 5, nullptr);
+
+ if (Check(ctyp)) {
+ sprintf(g->Message, "Getting ctyp: %s", Msg);
+ goto err;
+ } // endif ctyp
+
+ if (ctyp == 1111)
+ ((PJDBCCOL)colp)->uuid = true;
+
+ } // endfor colp
+
+ // All is Ok
+ brc = false;
+
+ err:
+ // Not used anymore
+ env->DeleteLocalRef(parms);
+ return brc;
+} // end of SetUUID
/***********************************************************************/
/* Utility routine. */
@@ -586,7 +772,7 @@ bool JDBConn::Connect(PJPARM sop)
int irc = RC_FX;
bool err = false;
jint rc;
- jboolean jt = (trace > 0);
+ jboolean jt = (trace(1));
PGLOBAL& g = m_G;
/*******************************************************************/
@@ -770,6 +956,7 @@ int JDBConn::Rewind(PCSZ sql)
/***********************************************************************/
void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
{
+ const char *field;
PGLOBAL& g = m_G;
jint ctyp;
jstring cn, jn = nullptr;
@@ -793,6 +980,11 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
if (!gmID(g, objfldid, "ObjectField", "(ILjava/lang/String;)Ljava/lang/Object;")) {
jb = env->CallObjectMethod(job, objfldid, (jint)rank, jn);
+ if (Check(0)) {
+ sprintf(g->Message, "Getting jp: %s", Msg);
+ throw (int)TYPE_AM_JDBC;
+ } // endif Check
+
if (jb == nullptr) {
val->Reset();
val->SetNull(true);
@@ -818,7 +1010,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
cn = nullptr;
if (cn) {
- const char *field = env->GetStringUTFChars(cn, (jboolean)false);
+ field = env->GetStringUTFChars(cn, (jboolean)false);
val->SetValue_psz((PSZ)field);
} else
val->Reset();
@@ -885,6 +1077,19 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
break;
case java.sql.Types.BOOLEAN:
System.out.print(jdi.BooleanField(i)); */
+ case 1111: // UUID
+ if (!gmID(g, uidfldid, "UuidField", "(ILjava/lang/String;)Ljava/lang/String;"))
+ cn = (jstring)env->CallObjectMethod(job, uidfldid, (jint)rank, jn);
+ else
+ cn = nullptr;
+
+ if (cn) {
+ const char *field = env->GetStringUTFChars(cn, (jboolean)false);
+ val->SetValue_psz((PSZ)field);
+ } else
+ val->Reset();
+
+ break;
case 0: // NULL
val->SetNull(true);
// passthru
@@ -1055,7 +1260,14 @@ bool JDBConn::SetParam(JDBCCOL *colp)
if (gmID(g, setid, "SetNullParm", "(II)I"))
return true;
- jrc = env->CallIntMethod(job, setid, i, (jint)GetJDBCType(val->GetType()));
+ jrc = env->CallIntMethod(job, setid, i,
+ (colp->uuid ? 1111 : (jint)GetJDBCType(val->GetType())));
+ } else if (colp->uuid) {
+ if (gmID(g, setid, "SetUuidParm", "(ILjava/lang/String;)V"))
+ return true;
+
+ jst = env->NewStringUTF(val->GetCharValue());
+ env->CallVoidMethod(job, setid, i, jst);
} else switch (val->GetType()) {
case TYPE_STRING:
if (gmID(g, setid, "SetStringParm", "(ILjava/lang/String;)V"))
@@ -1275,105 +1487,6 @@ bool JDBConn::SetParam(JDBCCOL *colp)
} // end of GetMetaData
/***********************************************************************/
- /* A helper class to split an optionally qualified table name into */
- /* components. */
- /* These formats are understood: */
- /* "CatalogName.SchemaName.TableName" */
- /* "SchemaName.TableName" */
- /* "TableName" */
- /***********************************************************************/
- class SQLQualifiedName
- {
- static const uint max_parts= 3; // Catalog.Schema.Table
- MYSQL_LEX_STRING m_part[max_parts];
- char m_buf[512];
-
- void lex_string_set(MYSQL_LEX_STRING *S, char *str, size_t length)
- {
- S->str= str;
- S->length= length;
- } // end of lex_string_set
-
- void lex_string_shorten_down(MYSQL_LEX_STRING *S, size_t offs)
- {
- DBUG_ASSERT(offs <= S->length);
- S->str+= offs;
- S->length-= offs;
- } // end of lex_string_shorten_down
-
- /*********************************************************************/
- /* Find the rightmost '.' delimiter and return the length */
- /* of the qualifier, including the rightmost '.' delimier. */
- /* For example, for the string {"a.b.c",5} it will return 4, */
- /* which is the length of the qualifier "a.b." */
- /*********************************************************************/
- size_t lex_string_find_qualifier(MYSQL_LEX_STRING *S)
- {
- size_t i;
- for (i= S->length; i > 0; i--)
- {
- if (S->str[i - 1] == '.')
- {
- S->str[i - 1]= '\0';
- return i;
- }
- }
- return 0;
- } // end of lex_string_find_qualifier
-
- public:
- /*********************************************************************/
- /* Initialize to the given optionally qualified name. */
- /* NULL pointer in "name" is supported. */
- /* name qualifier has precedence over schema. */
- /*********************************************************************/
- SQLQualifiedName(JCATPARM *cap)
- {
- const char *name = (const char *)cap->Tab;
- char *db = (char *)cap->DB;
- size_t len, i;
-
- // Initialize the parts
- for (i = 0; i < max_parts; i++)
- lex_string_set(&m_part[i], NULL, 0);
-
- if (name) {
- // Initialize the first (rightmost) part
- lex_string_set(&m_part[0], m_buf,
- strmake(m_buf, name, sizeof(m_buf) - 1) - m_buf);
-
- // Initialize the other parts, if exist.
- for (i= 1; i < max_parts; i++) {
- if (!(len= lex_string_find_qualifier(&m_part[i - 1])))
- break;
-
- lex_string_set(&m_part[i], m_part[i - 1].str, len - 1);
- lex_string_shorten_down(&m_part[i - 1], len);
- } // endfor i
-
- } // endif name
-
- // If it was not specified, set schema as the passed db name
- if (db && !m_part[1].length)
- lex_string_set(&m_part[1], db, strlen(db));
-
- } // end of SQLQualifiedName
-
- char *ptr(uint i)
- {
- DBUG_ASSERT(i < max_parts);
- return (char *)(m_part[i].length ? m_part[i].str : NULL);
- } // end of ptr
-
- size_t length(uint i)
- {
- DBUG_ASSERT(i < max_parts);
- return m_part[i].length;
- } // end of length
-
- }; // end of class SQLQualifiedName
-
- /***********************************************************************/
/* Allocate recset and call SQLTables, SQLColumns or SQLPrimaryKeys. */
/***********************************************************************/
int JDBConn::GetCatInfo(JCATPARM *cap)
@@ -1443,7 +1556,7 @@ bool JDBConn::SetParam(JDBCCOL *colp)
// Not used anymore
env->DeleteLocalRef(parms);
- if (trace)
+ if (trace(1))
htrc("Method %s returned %d columns\n", fnc, ncol);
// n because we no more ignore the first column
@@ -1488,7 +1601,7 @@ bool JDBConn::SetParam(JDBCCOL *colp)
sprintf(g->Message, "Fetch: %s", Msg);
return -1;
} if (rc == 0) {
- if (trace)
+ if (trace(1))
htrc("End of fetches i=%d\n", i);
break;
diff --git a/storage/connect/jdbconn.h b/storage/connect/jdbconn.h
index 56f318d238b..0c36cccadcf 100644
--- a/storage/connect/jdbconn.h
+++ b/storage/connect/jdbconn.h
@@ -29,6 +29,7 @@ public:
// Attributes
public:
char *GetQuoteChar(void) { return m_IDQuoteChar; }
+ bool SetUUID(PGLOBAL g, PTDBJDBC tjp);
virtual int GetMaxValue(int infotype);
public:
@@ -58,13 +59,6 @@ public:
protected:
// Members
-#if 0
- JavaVM *jvm; // Pointer to the JVM (Java Virtual Machine)
- JNIEnv *env; // Pointer to native interface
- jclass jdi; // Pointer to the java wrapper class
- jobject job; // The java wrapper class object
- jmethodID errid; // The GetErrmsg method ID
-#endif // 0
jmethodID xqid; // The ExecuteQuery method ID
jmethodID xuid; // The ExecuteUpdate method ID
jmethodID xid; // The Execute method ID
@@ -84,8 +78,7 @@ protected:
jmethodID timfldid; // The TimeField method ID
jmethodID tspfldid; // The TimestampField method ID
jmethodID bigfldid; // The BigintField method ID
-// PCSZ Msg;
-// PCSZ m_Wrap;
+ jmethodID uidfldid; // The UuidField method ID
char m_IDQuoteChar[2];
PCSZ m_Pwd;
int m_Ncol;
diff --git a/storage/connect/jmgfam.cpp b/storage/connect/jmgfam.cpp
index c7115cdd720..30f6279146d 100644
--- a/storage/connect/jmgfam.cpp
+++ b/storage/connect/jmgfam.cpp
@@ -298,7 +298,7 @@ int JMGFAM::ReadBuffer(PGLOBAL g)
PSZ str = Jcp->GetDocument();
if (str) {
- if (trace == 1)
+ if (trace(1))
htrc("%s\n", str);
strncpy(Tdbp->GetLine(), str, Lrecl);
diff --git a/storage/connect/jmgoconn.cpp b/storage/connect/jmgoconn.cpp
index 4736641ef3f..1731ccbeb8c 100644
--- a/storage/connect/jmgoconn.cpp
+++ b/storage/connect/jmgoconn.cpp
@@ -254,7 +254,7 @@ bool JMgoConn::MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options,
all = true;
if (pipe && Options) {
- if (trace)
+ if (trace(1))
htrc("Pipeline: %s\n", Options);
p = strrchr(Options, ']');
@@ -312,13 +312,13 @@ bool JMgoConn::MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options,
*(char*)p = ']'; // Restore Colist for discovery
p = s->GetStr();
- if (trace)
+ if (trace(33))
htrc("New Pipeline: %s\n", p);
return AggregateCollection(p);
} else {
if (filter || filp) {
- if (trace) {
+ if (trace(1)) {
if (filter)
htrc("Filter: %s\n", filter);
@@ -346,7 +346,7 @@ bool JMgoConn::MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options,
tdbp->SetFilter(NULL); // Not needed anymore
} // endif To_Filter
- if (trace)
+ if (trace(33))
htrc("selector: %s\n", s->GetStr());
s->Resize(s->GetLength() + 1);
@@ -355,7 +355,7 @@ bool JMgoConn::MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options,
if (!all) {
if (Options && *Options) {
- if (trace)
+ if (trace(1))
htrc("options=%s\n", Options);
op = Options;
@@ -751,7 +751,7 @@ int JMgoConn::DocUpdate(PGLOBAL g, PTDB tdbp)
jlong ar = env->CallLongMethod(job, updateid, upd);
- if (trace)
+ if (trace(1))
htrc("DocUpdate: ar = %ld\n", ar);
if (Check((int)ar)) {
@@ -770,7 +770,7 @@ int JMgoConn::DocDelete(PGLOBAL g, bool all)
int rc = RC_OK;
jlong ar = env->CallLongMethod(job, deleteid, all);
- if (trace)
+ if (trace(1))
htrc("DocDelete: ar = %ld\n", ar);
if (Check((int)ar)) {
diff --git a/storage/connect/json.cpp b/storage/connect/json.cpp
index b86d2da21b7..98a4659cea8 100644
--- a/storage/connect/json.cpp
+++ b/storage/connect/json.cpp
@@ -97,7 +97,7 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma)
PJSON jsp = NULL;
STRG src;
- if (trace)
+ if (trace(1))
htrc("ParseJson: s=%.10s len=%d\n", s, len);
if (!s || !len) {
@@ -165,7 +165,7 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma)
}; // endswitch s[i]
if (!jsp)
- sprintf(g->Message, "Invalid Json string '%.*s'", 50, s);
+ sprintf(g->Message, "Invalid Json string '%.*s'", MY_MIN(len, 50), s);
else if (ptyp && pretty == 3) {
*ptyp = 3; // Not recognized pretty
@@ -178,7 +178,7 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma)
} // endif ptyp
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
jsp = NULL;
} catch (const char *msg) {
@@ -652,7 +652,7 @@ PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty)
} // endif's
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
str = NULL;
} catch (const char *msg) {
@@ -1016,6 +1016,20 @@ PJAR JOBJECT::GetKeyList(PGLOBAL g)
} // end of GetKeyList
/***********************************************************************/
+/* Return all values as an array. */
+/***********************************************************************/
+PJAR JOBJECT::GetValList(PGLOBAL g)
+{
+ PJAR jarp = new(g) JARRAY();
+
+ for (PJPR jpp = First; jpp; jpp = jpp->Next)
+ jarp->AddValue(g, jpp->GetVal());
+
+ jarp->InitArray(g);
+ return jarp;
+} // end of GetValList
+
+/***********************************************************************/
/* Get the value corresponding to the given key. */
/***********************************************************************/
PJVAL JOBJECT::GetValue(const char* key)
@@ -1224,6 +1238,7 @@ PJVAL JARRAY::AddValue(PGLOBAL g, PJVAL jvp, int *x)
Last->Next = jvp;
Last = jvp;
+ Last->Next = NULL;
} // endif x
return jvp;
@@ -1319,6 +1334,24 @@ bool JARRAY::IsNull(void)
/* -------------------------- Class JVALUE- -------------------------- */
/***********************************************************************/
+/* Constructor for a JSON. */
+/***********************************************************************/
+JVALUE::JVALUE(PJSON jsp) : JSON()
+{
+ if (jsp->GetType() == TYPE_JVAL) {
+ Jsp = jsp->GetJsp();
+ Value = jsp->GetValue();
+ } else {
+ Jsp = jsp;
+ Value = NULL;
+ } // endif Type
+
+ Next = NULL;
+ Del = false;
+ Size = 1;
+} // end of JVALUE constructor
+
+/***********************************************************************/
/* Constructor for a Value with a given string or numeric value. */
/***********************************************************************/
JVALUE::JVALUE(PGLOBAL g, PVAL valp) : JSON()
diff --git a/storage/connect/json.h b/storage/connect/json.h
index 375532212c4..dcc97287420 100644
--- a/storage/connect/json.h
+++ b/storage/connect/json.h
@@ -20,7 +20,8 @@ enum JTYP {TYPE_NULL = TYPE_VOID,
TYPE_BINT = TYPE_BIGINT,
TYPE_DTM = TYPE_DATE,
TYPE_INTG = TYPE_INT,
- TYPE_JSON = 12,
+ TYPE_VAL = 12,
+ TYPE_JSON,
TYPE_JAR,
TYPE_JOB,
TYPE_JVAL};
@@ -157,6 +158,7 @@ class JSON : public BLOCK {
//virtual PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL, int *x = NULL) {X return NULL;}
virtual PJPR AddPair(PGLOBAL g, PCSZ key) {X return NULL;}
virtual PJAR GetKeyList(PGLOBAL g) {X return NULL;}
+ virtual PJAR GetValList(PGLOBAL g) {X return NULL;}
virtual PJVAL GetValue(const char *key) {X return NULL;}
virtual PJOB GetObject(void) {return NULL;}
virtual PJAR GetArray(void) {return NULL;}
@@ -205,6 +207,7 @@ class JOBJECT : public JSON {
virtual PJOB GetObject(void) {return this;}
virtual PJVAL GetValue(const char* key);
virtual PJAR GetKeyList(PGLOBAL g);
+ virtual PJAR GetValList(PGLOBAL g);
virtual PSZ GetText(PGLOBAL g, PSZ text);
virtual bool Merge(PGLOBAL g, PJSON jsp);
virtual void SetValue(PGLOBAL g, PJVAL jvp, PCSZ key);
@@ -258,8 +261,7 @@ class JVALUE : public JSON {
friend bool SerializeValue(JOUT *, PJVAL);
public:
JVALUE(void) : JSON() {Clear();}
- JVALUE(PJSON jsp) : JSON()
- {Jsp = jsp; Value = NULL; Next = NULL; Del = false; Size = 1;}
+ JVALUE(PJSON jsp);
JVALUE(PGLOBAL g, PVAL valp);
JVALUE(PGLOBAL g, PCSZ strp);
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index 33af95a2bbc..794a84f22c4 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -1,6 +1,6 @@
/****************** jsonudf C++ Program Source Code File (.CPP) ******************/
-/* PROGRAM NAME: jsonudf Version 1.6 */
-/* (C) Copyright to the author Olivier BERTRAND 2015-2017 */
+/* PROGRAM NAME: jsonudf Version 1.7 */
+/* (C) Copyright to the author Olivier BERTRAND 2015-2018 */
/* This program are the JSON User Defined Functions . */
/*********************************************************************************/
@@ -31,16 +31,39 @@ bool IsNum(PSZ s);
char *NextChr(PSZ s, char sep);
char *GetJsonNull(void);
uint GetJsonGrpSize(void);
-static int IsJson(UDF_ARGS *args, uint i);
+static int IsJson(UDF_ARGS *args, uint i, bool b = false);
static PSZ MakePSZ(PGLOBAL g, UDF_ARGS *args, int i);
static char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error);
static char *bin_handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error);
+static PJSON JsonNew(PGLOBAL g, JTYP type);
+static PJVAL JvalNew(PGLOBAL g, JTYP type, void *vp = NULL);
+static PJSNX JsnxNew(PGLOBAL g, PJSON jsp, int type, int len = 64);
static uint JsonGrpSize = 10;
-/* ----------------------------------- JSNX ------------------------------------ */
+/*********************************************************************************/
+/* SubAlloc a new JSNX class with protection against memory exhaustion. */
+/*********************************************************************************/
+static PJSNX JsnxNew(PGLOBAL g, PJSON jsp, int type, int len)
+{
+ PJSNX jsx;
+
+ try {
+ jsx = new(g) JSNX(g, jsp, type, len);
+ } catch (...) {
+ if (trace(1023))
+ htrc("%s\n", g->Message);
+
+ PUSH_WARNING(g->Message);
+ jsx = NULL;
+ } // end try/catch
+
+ return jsx;
+} /* end of JsnxNew */
+
+ /* ----------------------------------- JSNX ------------------------------------ */
/*********************************************************************************/
/* JSNX public constructor. */
@@ -81,21 +104,7 @@ my_bool JSNX::SetJpath(PGLOBAL g, char *path, my_bool jb)
return true;
Value->SetNullable(true);
-
-#if 0
- if (jb) {
- // Path must return a Json item
- size_t n = strlen(path);
-
- if (!n || path[n - 1] != '*') {
- Jpath = (char*)PlugSubAlloc(g, NULL, n + 3);
- strcat(strcpy(Jpath, path), (n) ? ":*" : "*");
- } else
- Jpath = path;
-
- } else
-#endif // 0
- Jpath = path;
+ Jpath = path;
// Parse the json path
Parsed = false;
@@ -182,7 +191,7 @@ my_bool JSNX::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
// Set concat intermediate string
p[n - 1] = 0;
- if (trace)
+ if (trace(1))
htrc("Concat string=%s\n", p + 1);
jnp->CncVal = AllocateValue(g, p + 1, TYPE_STRING);
@@ -246,7 +255,7 @@ my_bool JSNX::ParseJpath(PGLOBAL g)
// Jpath = Name;
return true;
- if (trace)
+ if (trace(1))
htrc("ParseJpath %s\n", SVP(Jpath));
if (!(pbuf = PlgDBDup(g, Jpath)))
@@ -309,7 +318,7 @@ my_bool JSNX::ParseJpath(PGLOBAL g)
Nod = i;
MulVal = AllocateValue(g, Value);
- if (trace)
+ if (trace(1))
for (i = 0; i < Nod; i++)
htrc("Node(%d) Key=%s Op=%d Rank=%d\n",
i, SVP(Nodes[i].Key), Nodes[i].Op, Nodes[i].Rank);
@@ -506,13 +515,13 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
vp->Reset();
- if (trace)
+ if (trace(1))
htrc("CalculateArray size=%d op=%d\n", ars, op);
- for (i = 0; i < arp->size(); i++) {
+ for (i = 0; i < ars; i++) {
jvrp = arp->GetValue(i);
- if (trace)
+ if (trace(1))
htrc("i=%d nv=%d\n", i, nv);
if (!jvrp->IsNull() || (op == OP_CNC && GetJsonNull())) {
@@ -525,7 +534,7 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
} else
jvp = jvrp;
- if (trace)
+ if (trace(1))
htrc("jvp=%s null=%d\n",
jvp->GetString(g), jvp->IsNull() ? 1 : 0);
@@ -561,7 +570,7 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
if (err)
vp->Reset();
- if (trace) {
+ if (trace(1)) {
char buf(32);
htrc("vp='%s' err=%d\n",
@@ -753,6 +762,7 @@ my_bool JSNX::WriteValue(PGLOBAL g, PJVAL jvalp)
/*********************************************************************************/
PSZ JSNX::Locate(PGLOBAL g, PJSON jsp, PJVAL jvp, int k)
{
+ PSZ str = NULL;
my_bool b = false, err = true;
g->Message[0] = 0;
@@ -762,37 +772,47 @@ PSZ JSNX::Locate(PGLOBAL g, PJSON jsp, PJVAL jvp, int k)
return NULL;
} // endif jsp
- // Write to the path string
- Jp = new(g) JOUTSTR(g);
- Jp->WriteChr('$');
- Jvalp = jvp;
- K = k;
+ try {
+ // Write to the path string
+ Jp = new(g) JOUTSTR(g);
+ Jp->WriteChr('$');
+ Jvalp = jvp;
+ K = k;
- switch (jsp->GetType()) {
- case TYPE_JAR:
- err = LocateArray((PJAR)jsp);
- break;
- case TYPE_JOB:
- err = LocateObject((PJOB)jsp);
- break;
- case TYPE_JVAL:
- err = LocateValue((PJVAL)jsp);
- break;
- default:
- err = true;
+ switch (jsp->GetType()) {
+ case TYPE_JAR:
+ err = LocateArray((PJAR)jsp);
+ break;
+ case TYPE_JOB:
+ err = LocateObject((PJOB)jsp);
+ break;
+ case TYPE_JVAL:
+ err = LocateValue((PJVAL)jsp);
+ break;
+ default:
+ err = true;
} // endswitch Type
- if (err) {
- if (!g->Message[0])
- strcpy(g->Message, "Invalid json tree");
+ if (err) {
+ if (!g->Message[0])
+ strcpy(g->Message, "Invalid json tree");
- } else if (Found) {
- Jp->WriteChr('\0');
- PlugSubAlloc(g, NULL, Jp->N);
- return Jp->Strp;
- } // endif's
+ } else if (Found) {
+ Jp->WriteChr('\0');
+ PlugSubAlloc(g, NULL, Jp->N);
+ str = Jp->Strp;
+ } // endif's
- return NULL;
+ } catch (int n) {
+ if (trace(1))
+ htrc("Exception %d: %s\n", n, g->Message);
+
+ PUSH_WARNING(g->Message);
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ } // end catch
+
+ return str;
} // end of Locate
/*********************************************************************************/
@@ -864,53 +884,62 @@ my_bool JSNX::LocateValue(PJVAL jvp)
/*********************************************************************************/
PSZ JSNX::LocateAll(PGLOBAL g, PJSON jsp, PJVAL jvp, int mx)
{
+ PSZ str = NULL;
my_bool b = false, err = true;
- PJPN jnp = (PJPN)PlugSubAlloc(g, NULL, sizeof(JPN) * mx);
-
- memset(jnp, 0, sizeof(JPN) * mx);
- g->Message[0] = 0;
-
+ PJPN jnp;
+
if (!jsp) {
strcpy(g->Message, "Null json tree");
return NULL;
} // endif jsp
- // Write to the path string
- Jp = new(g)JOUTSTR(g);
- Jvalp = jvp;
- Imax = mx - 1;
- Jpnp = jnp;
- Jp->WriteChr('[');
+ try {
+ jnp = (PJPN)PlugSubAlloc(g, NULL, sizeof(JPN) * mx);
+ memset(jnp, 0, sizeof(JPN) * mx);
+ g->Message[0] = 0;
+
+ // Write to the path string
+ Jp = new(g)JOUTSTR(g);
+ Jvalp = jvp;
+ Imax = mx - 1;
+ Jpnp = jnp;
+ Jp->WriteChr('[');
+
+ switch (jsp->GetType()) {
+ case TYPE_JAR:
+ err = LocateArrayAll((PJAR)jsp);
+ break;
+ case TYPE_JOB:
+ err = LocateObjectAll((PJOB)jsp);
+ break;
+ case TYPE_JVAL:
+ err = LocateValueAll((PJVAL)jsp);
+ break;
+ default:
+ err = true;
+ } // endswitch Type
- switch (jsp->GetType()) {
- case TYPE_JAR:
- err = LocateArrayAll((PJAR)jsp);
- break;
- case TYPE_JOB:
- err = LocateObjectAll((PJOB)jsp);
- break;
- case TYPE_JVAL:
- err = LocateValueAll((PJVAL)jsp);
- break;
- default:
- err = true;
- } // endswitch Type
+ if (!err) {
+ if (Jp->N > 1)
+ Jp->N--;
- if (err) {
- if (!g->Message[0])
+ Jp->WriteChr(']');
+ Jp->WriteChr('\0');
+ PlugSubAlloc(g, NULL, Jp->N);
+ str = Jp->Strp;
+ } else if (!g->Message[0])
strcpy(g->Message, "Invalid json tree");
- return NULL;
- } else {
- if (Jp->N > 1)
- Jp->N--;
+ } catch (int n) {
+ if (trace(1))
+ htrc("Exception %d: %s\n", n, g->Message);
- Jp->WriteChr(']');
- Jp->WriteChr('\0');
- PlugSubAlloc(g, NULL, Jp->N);
- return Jp->Strp;
- } // endif's
+ PUSH_WARNING(g->Message);
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ } // end catch
+ return str;
} // end of LocateAll
/*********************************************************************************/
@@ -1138,6 +1167,72 @@ inline void JsonFreeMem(PGLOBAL g)
} /* end of JsonFreeMem */
/*********************************************************************************/
+/* SubAlloc a new JSON item with protection against memory exhaustion. */
+/*********************************************************************************/
+static PJSON JsonNew(PGLOBAL g, JTYP type)
+{
+ PJSON jsp = NULL;
+
+ try {
+ switch (type) {
+ case TYPE_JAR:
+ jsp = new(g) JARRAY;
+ break;
+ case TYPE_JOB:
+ jsp = new(g) JOBJECT;
+ break;
+ default:
+ break;
+ } // endswitch type
+
+ } catch (...) {
+ if (trace(1023))
+ htrc("%s\n", g->Message);
+
+ PUSH_WARNING(g->Message);
+ } // end try/catch
+
+ return jsp;
+} /* end of JsonNew */
+
+/*********************************************************************************/
+/* SubAlloc a new JValue with protection against memory exhaustion. */
+/*********************************************************************************/
+static PJVAL JvalNew(PGLOBAL g, JTYP type, void *vp)
+{
+ PJVAL jvp = NULL;
+
+ try {
+ if (!vp)
+ jvp = new (g) JVALUE;
+ else switch (type) {
+ case TYPE_JSON:
+ case TYPE_JVAL:
+ case TYPE_JAR:
+ case TYPE_JOB:
+ jvp = new(g) JVALUE((PJSON)vp);
+ break;
+ case TYPE_VAL:
+ jvp = new(g) JVALUE(g, (PVAL)vp);
+ break;
+ case TYPE_STRG:
+ jvp = new(g) JVALUE(g, (PCSZ)vp);
+ break;
+ default:
+ break;
+ } // endswitch type
+
+ } catch (...) {
+ if (trace(1023))
+ htrc("%s\n", g->Message);
+
+ PUSH_WARNING(g->Message);
+ } // end try/catch
+
+ return jvp;
+} /* end of JsonNew */
+
+/*********************************************************************************/
/* Allocate and initialise the memory area. */
/*********************************************************************************/
static my_bool JsonInit(UDF_INIT *initid, UDF_ARGS *args,
@@ -1289,8 +1384,11 @@ static int *GetIntArgPtr(PGLOBAL g, UDF_ARGS *args, uint& n)
for (uint i = n; i < args->arg_count; i++)
if (args->arg_type[i] == INT_RESULT) {
if (args->args[i]) {
- x = (int*)PlugSubAlloc(g, NULL, sizeof(int));
- *x = (int)*(longlong*)args->args[i];
+ if ((x = (int*)PlgDBSubAlloc(g, NULL, sizeof(int))))
+ *x = (int)*(longlong*)args->args[i];
+ else
+ PUSH_WARNING(g->Message);
+
} // endif args
n = i + 1;
@@ -1303,7 +1401,7 @@ static int *GetIntArgPtr(PGLOBAL g, UDF_ARGS *args, uint& n)
/*********************************************************************************/
/* Returns not 0 if the argument is a JSON item or file name. */
/*********************************************************************************/
-static int IsJson(UDF_ARGS *args, uint i)
+static int IsJson(UDF_ARGS *args, uint i, bool b)
{
int n = 0;
@@ -1320,8 +1418,20 @@ static int IsJson(UDF_ARGS *args, uint i)
else
n = 2; // A file name may have been returned
- } else if (!strnicmp(args->attributes[i], "Jfile_", 6))
+ } else if (!strnicmp(args->attributes[i], "Jfile_", 6)) {
n = 2; // arg is a json file name
+ } else if (b) {
+ char *sap;
+ PGLOBAL g = PlugInit(NULL, args->lengths[i] * M + 1024);
+
+ JsonSubSet(g);
+ sap = MakePSZ(g, args, i);
+
+ if (ParseJson(g, sap, strlen(sap)))
+ n = 4;
+
+ JsonFreeMem(g);
+ } // endif's
return n;
} // end of IsJson
@@ -1534,10 +1644,14 @@ static PSZ MakePSZ(PGLOBAL g, UDF_ARGS *args, int i)
{
if (args->arg_count > (unsigned)i && args->args[i]) {
int n = args->lengths[i];
- PSZ s = (PSZ)PlugSubAlloc(g, NULL, n + 1);
+ PSZ s = (PSZ)PlgDBSubAlloc(g, NULL, n + 1);
+
+ if (s) {
+ memcpy(s, args->args[i], n);
+ s[n] = 0;
+ } else
+ PUSH_WARNING(g->Message);
- memcpy(s, args->args[i], n);
- s[n] = 0;
return s;
} else
return NULL;
@@ -1574,9 +1688,12 @@ static PCSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i)
return "Key";
if (!b) {
- p = (PSZ)PlugSubAlloc(g, NULL, n + 1);
- memcpy(p, s, n);
- p[n] = 0;
+ if ((p = (PSZ)PlgDBSubAlloc(g, NULL, n + 1))) {
+ memcpy(p, s, n);
+ p[n] = 0;
+ } else
+ PUSH_WARNING(g->Message);
+
s = p;
} // endif b
@@ -1665,15 +1782,16 @@ static char *GetJsonFile(PGLOBAL g, char *fn)
return NULL;
} // endif len
- str = (char*)PlugSubAlloc(g, NULL, len + 1);
-
- if ((n = read(h, str, len)) < 0) {
- sprintf(g->Message, "Error %d reading %d bytes from %s", errno, len, fn);
- return NULL;
- } // endif n
+ if ((str = (char*)PlgDBSubAlloc(g, NULL, len + 1))) {
+ if ((n = read(h, str, len)) < 0) {
+ sprintf(g->Message, "Error %d reading %d bytes from %s", errno, len, fn);
+ return NULL;
+ } // endif n
- str[n] = 0;
- close(h);
+ str[n] = 0;
+ close(h);
+ } // endif str
+
return str;
} // end of GetJsonFile
@@ -1760,6 +1878,41 @@ static PJVAL MakeValue(PGLOBAL g, UDF_ARGS *args, uint i, PJSON *top = NULL)
} // end of MakeValue
/*********************************************************************************/
+/* Try making a JSON value of the passed type from the passed argument. */
+/*********************************************************************************/
+static PJVAL MakeTypedValue(PGLOBAL g, UDF_ARGS *args, uint i,
+ JTYP type, PJSON *top = NULL)
+{
+ char *sap;
+ PJSON jsp;
+ PJVAL jvp = MakeValue(g, args, i, top);
+
+ //if (type == TYPE_JSON) {
+ // if (jvp->GetValType() >= TYPE_JSON)
+ // return jvp;
+
+ //} else if (jvp->GetValType() == type)
+ // return jvp;
+
+ if (jvp->GetValType() == TYPE_STRG) {
+ sap = jvp->GetString(g);
+
+ if ((jsp = ParseJson(g, sap, strlen(sap)))) {
+ if ((type == TYPE_JSON && jsp->GetType() != TYPE_JVAL) || jsp->GetType() == type) {
+ if (top)
+ *top = jsp;
+
+ jvp->SetValue(jsp);
+ } // endif Type
+
+ } // endif jsp
+
+ } // endif Type
+
+ return jvp;
+} // end of MakeTypedValue
+
+/*********************************************************************************/
/* Make a Json value containing the parameter. */
/*********************************************************************************/
my_bool jsonvalue_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
@@ -1861,9 +2014,9 @@ my_bool json_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *messa
if (args->arg_count < 2) {
strcpy(message, "This function must have at least 2 arguments");
return true;
- } else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
- strcpy(message, "First argument must be a json string or item");
- return true;
+ //} else if (!IsJson(args, 0, true)) {
+ // strcpy(message, "First argument must be a valid json string or item");
+ // return true;
} else
CalcLen(args, false, reslen, memlen);
@@ -1891,23 +2044,14 @@ char *json_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!g->Xchk) {
if (!CheckMemory(g, initid, args, args->arg_count, true)) {
- char *p;
PJSON top;
PJAR arp;
- PJVAL jvp = MakeValue(g, args, 0, &top);
+ PJVAL jvp = MakeTypedValue(g, args, 0, TYPE_JAR, &top);
- if ((p = jvp->GetString(g))) {
- if (!(top = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- return NULL;
- } // endif jsp
-
- jvp->SetValue(top);
- } // endif p
-
if (jvp->GetValType() != TYPE_JAR) {
arp = new(g)JARRAY;
arp->AddValue(g, jvp);
+ top = arp;
} else
arp = jvp->GetArray();
@@ -1915,7 +2059,6 @@ char *json_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
arp->AddValue(g, MakeValue(g, args, i));
arp->InitArray(g);
-// str = Serialize(g, arp, NULL, 0);
str = MakeResult(g, args, top, args->arg_count);
} // endif CheckMemory
@@ -1952,10 +2095,10 @@ my_bool json_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
if (args->arg_count < 2) {
strcpy(message, "This function must have at least 2 arguments");
- return true;
- } else if (!IsJson(args, 0)) {
- strcpy(message, "First argument must be a json item");
- return true;
+ return true;
+ //} else if (!IsJson(args, 0, true)) {
+ // strcpy(message, "First argument is not a valid Json item");
+ // return true;
} else
CalcLen(args, false, reslen, memlen, true);
@@ -1994,22 +2137,38 @@ char *json_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
PJVAL jvp;
PJAR arp;
- jvp = MakeValue(g, args, 0, &top);
+ jvp = MakeTypedValue(g, args, 0, TYPE_JSON, &top);
jsp = jvp->GetJson();
x = GetIntArgPtr(g, args, n);
if (CheckPath(g, args, jsp, jvp, 2))
PUSH_WARNING(g->Message);
- else if (jvp && jvp->GetValType() == TYPE_JAR) {
+ else if (jvp) {
PGLOBAL gb = GetMemPtr(g, args, 0);
- arp = jvp->GetArray();
- arp->AddValue(gb, MakeValue(gb, args, 1), x);
- arp->InitArray(gb);
- str = MakeResult(g, args, top, n);
+ if (jvp->GetValType() != TYPE_JAR) {
+ if ((arp = (PJAR)JsonNew(gb, TYPE_JAR))) {
+ arp->AddValue(gb, JvalNew(gb, TYPE_JVAL, jvp));
+ jvp->SetValue(arp);
+
+ if (!top)
+ top = arp;
+
+ } // endif arp
+
+ } else
+ arp = jvp->GetArray();
+
+ if (arp) {
+ arp->AddValue(gb, MakeValue(gb, args, 1), x);
+ arp->InitArray(gb);
+ str = MakeResult(g, args, top, n);
+ } else
+ PUSH_WARNING(gb->Message);
+
} else {
- PUSH_WARNING("First argument target is not an array");
-// if (g->Mrr) *error = 1; (only if no path)
+ PUSH_WARNING("Target is not an array");
+ // if (g->Mrr) *error = 1; (only if no path)
} // endif jvp
} // endif CheckMemory
@@ -2048,9 +2207,6 @@ my_bool json_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
if (args->arg_count < 2) {
strcpy(message, "This function must have at least 2 arguments");
return true;
- } else if (!IsJson(args, 0)) {
- strcpy(message, "First argument must be a json item");
- return true;
} else
CalcLen(args, false, reslen, memlen, true);
@@ -2087,7 +2243,7 @@ char *json_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
uint n = 1;
PJSON top;
PJAR arp;
- PJVAL jvp = MakeValue(g, args, 0, &top);
+ PJVAL jvp = MakeTypedValue(g, args, 0, TYPE_JSON, &top);
if (!(x = GetIntArgPtr(g, args, n)))
PUSH_WARNING("Missing or null array index");
@@ -2186,9 +2342,14 @@ long long jsonsum_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *err
if (g->N) {
// Keep result of constant function
- long long *np = (long long*)PlugSubAlloc(g, NULL, sizeof(long long));
- *np = n;
- g->Activityp = (PACTIVITY)np;
+ long long *np;
+
+ if ((np = (long long*)PlgDBSubAlloc(g, NULL, sizeof(long long)))) {
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } else
+ PUSH_WARNING(g->Message);
+
} // endif const_item
return n;
@@ -2252,13 +2413,21 @@ double jsonsum_real(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error
} else {
*error = 1;
n = -1.0;
- } // end of CheckMemory
+ } // endif CheckMemory
if (g->N) {
// Keep result of constant function
- double *np = (double*)PlugSubAlloc(g, NULL, sizeof(double));
- *np = n;
- g->Activityp = (PACTIVITY)np;
+ double *np;
+
+ if ((np = (double*)PlgDBSubAlloc(g, NULL, sizeof(double)))) {
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } else {
+ PUSH_WARNING(g->Message);
+ *error = 1;
+ n = -1.0;
+ } // endif np
+
} // endif const_item
return n;
@@ -2312,13 +2481,20 @@ double jsonavg_real(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error
} else {
*error = 1;
n = -1.0;
- } // end of CheckMemory
+ } // endif CheckMemory
if (g->N) {
// Keep result of constant function
- double *np = (double*)PlugSubAlloc(g, NULL, sizeof(double));
- *np = n;
- g->Activityp = (PACTIVITY)np;
+ double *np;
+
+ if ((np = (double*)PlgDBSubAlloc(g, NULL, sizeof(double)))) {
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } else {
+ *error = 1;
+ n = -1.0;
+ } // endif np
+
} // endif const_item
return n;
@@ -2348,12 +2524,15 @@ char *json_make_object(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!g->Xchk) {
if (!CheckMemory(g, initid, args, args->arg_count, false, false, true)) {
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
+
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i++)
+ objp->SetValue(g, MakeValue(g, args, i), MakeKey(g, args, i));
- for (uint i = 0; i < args->arg_count; i++)
- objp->SetValue(g, MakeValue(g, args, i), MakeKey(g, args, i));
+ str = Serialize(g, objp, NULL, 0);
+ } // endif objp
- str = Serialize(g, objp, NULL, 0);
} // endif CheckMemory
if (!str)
@@ -2394,13 +2573,16 @@ char *json_object_nonull(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!g->Xchk) {
if (!CheckMemory(g, initid, args, args->arg_count, false, true)) {
PJVAL jvp;
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
+
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i++)
+ if (!(jvp = MakeValue(g, args, i))->IsNull())
+ objp->SetValue(g, jvp, MakeKey(g, args, i));
- for (uint i = 0; i < args->arg_count; i++)
- if (!(jvp = MakeValue(g, args, i))->IsNull())
- objp->SetValue(g, jvp, MakeKey(g, args, i));
+ str = Serialize(g, objp, NULL, 0);
+ } // endif objp
- str = Serialize(g, objp, NULL, 0);
} // endif CheckMemory
if (!str)
@@ -2444,12 +2626,15 @@ char *json_object_key(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!g->Xchk) {
if (!CheckMemory(g, initid, args, args->arg_count, false, true)) {
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
+
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i += 2)
+ objp->SetValue(g, MakeValue(g, args, i + 1), MakePSZ(g, args, i));
- for (uint i = 0; i < args->arg_count; i += 2)
- objp->SetValue(g, MakeValue(g, args, i+1), MakePSZ(g, args, i));
+ str = Serialize(g, objp, NULL, 0);
+ } // endif objp
- str = Serialize(g, objp, NULL, 0);
} // endif CheckMemory
if (!str)
@@ -2732,6 +2917,82 @@ void json_object_list_deinit(UDF_INIT* initid)
} // end of json_object_list_deinit
/*********************************************************************************/
+/* Returns an array of the Json object values. */
+/*********************************************************************************/
+my_bool json_object_values_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+ unsigned long reslen, memlen;
+
+ if (args->arg_count != 1) {
+ strcpy(message, "This function must have 1 argument");
+ return true;
+ } else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
+ strcpy(message, "Argument must be a json object");
+ return true;
+ } else
+ CalcLen(args, false, reslen, memlen);
+
+ return JsonInit(initid, args, message, true, reslen, memlen);
+} // end of json_object_list_init
+
+char *json_object_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
+ unsigned long *res_length, char *is_null, char *error)
+{
+ char *str = NULL;
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ if (!g->N) {
+ if (!CheckMemory(g, initid, args, 1, true, true)) {
+ char *p;
+ PJSON jsp;
+ PJVAL jvp = MakeValue(g, args, 0);
+
+ if ((p = jvp->GetString(g))) {
+ if (!(jsp = ParseJson(g, p, strlen(p)))) {
+ PUSH_WARNING(g->Message);
+ return NULL;
+ } // endif jsp
+
+ } else
+ jsp = jvp->GetJson();
+
+ if (jsp->GetType() == TYPE_JOB) {
+ PJAR jarp = ((PJOB)jsp)->GetValList(g);
+
+ if (!(str = Serialize(g, jarp, NULL, 0)))
+ PUSH_WARNING(g->Message);
+
+ } else {
+ PUSH_WARNING("First argument is not an object");
+ if (g->Mrr) *error = 1;
+ } // endif jvp
+
+ } // endif CheckMemory
+
+ if (initid->const_item) {
+ // Keep result of constant function
+ g->Xchk = str;
+ g->N = 1; // str can be NULL
+ } // endif const_item
+
+ } else
+ str = (char*)g->Xchk;
+
+ if (!str) {
+ *is_null = 1;
+ *res_length = 0;
+ } else
+ *res_length = strlen(str);
+
+ return str;
+} // end of json_object_values
+
+void json_object_values_deinit(UDF_INIT* initid)
+{
+ JsonFreeMem((PGLOBAL)initid->ptr);
+} // end of json_object_values_deinit
+
+/*********************************************************************************/
/* Set the value of JsonGrpSize. */
/*********************************************************************************/
my_bool jsonset_grp_size_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
@@ -2795,7 +3056,7 @@ my_bool json_array_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
PGLOBAL g = (PGLOBAL)initid->ptr;
PlugSubSet(g, g->Sarea, g->Sarea_Size);
- g->Activityp = (PACTIVITY)new(g) JARRAY;
+ g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JAR);
g->N = (int)n;
return false;
} // end of json_array_grp_init
@@ -2805,7 +3066,7 @@ void json_array_grp_add(UDF_INIT *initid, UDF_ARGS *args, char*, char*)
PGLOBAL g = (PGLOBAL)initid->ptr;
PJAR arp = (PJAR)g->Activityp;
- if (g->N-- > 0)
+ if (arp && g->N-- > 0)
arp->AddValue(g, MakeValue(g, args, 0));
} // end of json_array_grp_add
@@ -2820,12 +3081,16 @@ char *json_array_grp(UDF_INIT *initid, UDF_ARGS *, char *result,
if (g->N < 0)
PUSH_WARNING("Result truncated to json_grp_size values");
- arp->InitArray(g);
+ if (arp) {
+ arp->InitArray(g);
+ str = Serialize(g, arp, NULL, 0);
+ } else
+ str = NULL;
- if (!(str = Serialize(g, arp, NULL, 0)))
- str = strcpy(result, g->Message);
+ if (!str)
+ str = strcpy(result, g->Message);
- *res_length = strlen(str);
+ *res_length = strlen(str);
return str;
} // end of json_array_grp
@@ -2834,8 +3099,8 @@ void json_array_grp_clear(UDF_INIT *initid, char*, char*)
PGLOBAL g = (PGLOBAL)initid->ptr;
PlugSubSet(g, g->Sarea, g->Sarea_Size);
- g->Activityp = (PACTIVITY)new(g) JARRAY;
- g->N = GetJsonGroupSize();
+ g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JAR);
+ g->N = GetJsonGroupSize();
} // end of json_array_grp_clear
void json_array_grp_deinit(UDF_INIT* initid)
@@ -2868,7 +3133,7 @@ my_bool json_object_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
PGLOBAL g = (PGLOBAL)initid->ptr;
PlugSubSet(g, g->Sarea, g->Sarea_Size);
- g->Activityp = (PACTIVITY)new(g) JOBJECT;
+ g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JOB);
g->N = (int)n;
return false;
} // end of json_object_grp_init
@@ -2893,7 +3158,7 @@ char *json_object_grp(UDF_INIT *initid, UDF_ARGS *, char *result,
if (g->N < 0)
PUSH_WARNING("Result truncated to json_grp_size values");
- if (!(str = Serialize(g, objp, NULL, 0)))
+ if (!objp || !(str = Serialize(g, objp, NULL, 0)))
str = strcpy(result, g->Message);
*res_length = strlen(str);
@@ -2905,8 +3170,8 @@ void json_object_grp_clear(UDF_INIT *initid, char*, char*)
PGLOBAL g = (PGLOBAL)initid->ptr;
PlugSubSet(g, g->Sarea, g->Sarea_Size);
- g->Activityp = (PACTIVITY)new(g) JOBJECT;
- g->N = GetJsonGroupSize();
+ g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JOB);
+ g->N = GetJsonGroupSize();
} // end of json_object_grp_clear
void json_object_grp_deinit(UDF_INIT* initid)
@@ -3051,7 +3316,7 @@ my_bool json_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
char *json_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *)
{
- char *p, *path, *str = NULL;
+ char *path, *str = NULL;
PJSON jsp;
PJVAL jvp;
PJSNX jsx;
@@ -3067,17 +3332,10 @@ char *json_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (CheckMemory(g, initid, args, 1, true, true)) {
PUSH_WARNING("CheckMemory error");
goto fin;
- } else
- jvp = MakeValue(g, args, 0);
-
- if ((p = jvp->GetString(g))) {
- if (!(jsp = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- return NULL;
- } // endif jsp
+ } // endif CheckMemory
- } else
- jsp = jvp->GetJson();
+ jvp = MakeTypedValue(g, args, 0, TYPE_JSON);
+ jsp = jvp->GetJson();
if (g->Mrr) { // First argument is a constant
g->Xchk = jsp;
@@ -3088,9 +3346,9 @@ char *json_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g) JSNX(g, jsp, TYPE_STRING, initid->max_length);
+ jsx = JsnxNew(g, jsp, TYPE_STRING, initid->max_length);
- if (jsx->SetJpath(g, path, true)) {
+ if (!jsx || jsx->SetJpath(g, path, true)) {
PUSH_WARNING(g->Message);
*is_null = 1;
return NULL;
@@ -3203,9 +3461,9 @@ char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g) JSNX(g, jsp, TYPE_STRING, initid->max_length);
+ jsx = JsnxNew(g, jsp, TYPE_STRING, initid->max_length);
- if (jsx->SetJpath(g, path)) {
+ if (!jsx || jsx->SetJpath(g, path)) {
PUSH_WARNING(g->Message);
goto err;
} // endif SetJpath
@@ -3220,7 +3478,7 @@ char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result,
g->Activityp = (PACTIVITY)str;
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
PUSH_WARNING(g->Message);
@@ -3320,9 +3578,9 @@ long long jsonget_int(UDF_INIT *initid, UDF_ARGS *args,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g) JSNX(g, jsp, TYPE_BIGINT);
+ jsx = JsnxNew(g, jsp, TYPE_BIGINT);
- if (jsx->SetJpath(g, path)) {
+ if (!jsx || jsx->SetJpath(g, path)) {
PUSH_WARNING(g->Message);
*is_null = 1;
return 0;
@@ -3339,9 +3597,14 @@ long long jsonget_int(UDF_INIT *initid, UDF_ARGS *args,
if (initid->const_item) {
// Keep result of constant function
- long long *np = (long long*)PlugSubAlloc(g, NULL, sizeof(long long));
- *np = n;
- g->Activityp = (PACTIVITY)np;
+ long long *np = (long long*)PlgDBSubAlloc(g, NULL, sizeof(long long));
+
+ if (np) {
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } else
+ PUSH_WARNING(g->Message);
+
} // endif const_item
return n;
@@ -3434,9 +3697,9 @@ double jsonget_real(UDF_INIT *initid, UDF_ARGS *args,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g) JSNX(g, jsp, TYPE_DOUBLE);
+ jsx = JsnxNew(g, jsp, TYPE_DOUBLE);
- if (jsx->SetJpath(g, path)) {
+ if (!jsx || jsx->SetJpath(g, path)) {
PUSH_WARNING(g->Message);
*is_null = 1;
return 0.0;
@@ -3453,9 +3716,17 @@ double jsonget_real(UDF_INIT *initid, UDF_ARGS *args,
if (initid->const_item) {
// Keep result of constant function
- double *dp = (double*)PlugSubAlloc(g, NULL, sizeof(double));
- *dp = d;
- g->Activityp = (PACTIVITY)dp;
+ double *dp;
+
+ if ((dp = (double*)PlgDBSubAlloc(g, NULL, sizeof(double)))) {
+ *dp = d;
+ g->Activityp = (PACTIVITY)dp;
+ } else {
+ PUSH_WARNING(g->Message);
+ *is_null = 1;
+ return 0.0;
+ } // endif dp
+
} // endif const_item
return d;
@@ -3501,7 +3772,7 @@ my_bool jsonlocate_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
{
- char *p, *path = NULL;
+ char *path = NULL;
int k;
PJVAL jvp, jvp2;
PJSON jsp;
@@ -3529,16 +3800,20 @@ char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result,
*error = 1;
goto err;
} else
- jvp = MakeValue(g, args, 0);
-
- if ((p = jvp->GetString(g))) {
- if (!(jsp = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- goto err;
- } // endif jsp
-
- } else
- jsp = jvp->GetJson();
+ jvp = MakeTypedValue(g, args, 0, TYPE_JSON);
+
+ //if ((p = jvp->GetString(g))) {
+ // if (!(jsp = ParseJson(g, p, strlen(p)))) {
+ // PUSH_WARNING(g->Message);
+ // goto err;
+ // } // endif jsp
+ //} else
+ // jsp = jvp->GetJson();
+
+ if (!(jsp = jvp->GetJson())) {
+ PUSH_WARNING("First argument is not a valid JSON item");
+ goto err;
+ } // endif jsp
if (g->Mrr) { // First argument is a constant
g->Xchk = jsp;
@@ -3561,7 +3836,7 @@ char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result,
g->Activityp = (PACTIVITY)path;
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
PUSH_WARNING(g->Message);
@@ -3686,7 +3961,7 @@ char *json_locate_all(UDF_INIT *initid, UDF_ARGS *args, char *result,
g->Activityp = (PACTIVITY)path;
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
PUSH_WARNING(g->Message);
@@ -3845,9 +4120,9 @@ long long jsoncontains_path(UDF_INIT *initid, UDF_ARGS *args, char *result,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g)JSNX(g, jsp, TYPE_BIGINT);
+ jsx = JsnxNew(g, jsp, TYPE_BIGINT);
- if (jsx->SetJpath(g, path)) {
+ if (!jsx || jsx->SetJpath(g, path)) {
PUSH_WARNING(g->Message);
goto err;
} // endif SetJpath
@@ -3856,9 +4131,14 @@ long long jsoncontains_path(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (initid->const_item) {
// Keep result of constant function
- long long *np = (long long*)PlugSubAlloc(g, NULL, sizeof(long long));
- *np = n;
- g->Activityp = (PACTIVITY)np;
+ long long *np = (long long*)PlgDBSubAlloc(g, NULL, sizeof(long long));
+
+ if (np) {
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } else
+ PUSH_WARNING(g->Message);
+
} // endif const_item
return n;
@@ -3961,7 +4241,7 @@ char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
g->Activityp = (PACTIVITY)str;
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
PUSH_WARNING(g->Message);
@@ -4335,18 +4615,23 @@ char *jbin_array(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!bsp || bsp->Changed) {
if (!CheckMemory(g, initid, args, args->arg_count, false)) {
- PJAR arp = new(g) JARRAY;
+ PJAR arp;
- bsp = JbinAlloc(g, args, initid->max_length, arp);
- strcat(bsp->Msg, " array");
+ if ((arp = (PJAR)JsonNew(g, TYPE_JAR)) &&
+ (bsp = JbinAlloc(g, args, initid->max_length, arp))) {
+ strcat(bsp->Msg, " array");
- for (uint i = 0; i < args->arg_count; i++)
- arp->AddValue(g, MakeValue(g, args, i));
+ for (uint i = 0; i < args->arg_count; i++)
+ arp->AddValue(g, MakeValue(g, args, i));
+
+ arp->InitArray(g);
+ } // endif arp && bsp
- arp->InitArray(g);
} else
- if ((bsp = JbinAlloc(g, args, initid->max_length, NULL)))
- strncpy(bsp->Msg, g->Message, 139);
+ bsp = NULL;
+
+ if (!bsp && (bsp = JbinAlloc(g, args, initid->max_length, NULL)))
+ strncpy(bsp->Msg, g->Message, 139);
// Keep result of constant function
g->Xchk = (initid->const_item) ? bsp : NULL;
@@ -4377,9 +4662,6 @@ my_bool jbin_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *messa
if (args->arg_count < 2) {
strcpy(message, "This function must have at least 2 arguments");
return true;
- } else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
- strcpy(message, "First argument must be a json string or item");
- return true;
} else
CalcLen(args, false, reslen, memlen);
@@ -4394,24 +4676,17 @@ char *jbin_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!bsp || bsp->Changed) {
if (!CheckMemory(g, initid, args, args->arg_count, true)) {
- char *p;
PJSON top;
PJAR arp;
- PJVAL jvp = MakeValue(g, args, 0, &top);
+ PJVAL jvp = MakeTypedValue(g, args, 0, TYPE_JAR, &top);
PGLOBAL gb = GetMemPtr(g, args, 0);
- if ((p = jvp->GetString(g))) {
- if (!(top = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- return NULL;
- } // endif jsp
-
- jvp->SetValue(top);
- } // endif p
-
if (jvp->GetValType() != TYPE_JAR) {
- arp = new(gb)JARRAY;
- arp->AddValue(gb, jvp);
+ if ((arp = (PJAR)JsonNew(gb, TYPE_JAR))) {
+ arp->AddValue(gb, jvp);
+ top = arp;
+ } // endif arp
+
} else
arp = jvp->GetArray();
@@ -4458,9 +4733,9 @@ my_bool jbin_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
if (args->arg_count < 2) {
strcpy(message, "This function must have at least 2 arguments");
return true;
- } else if (!IsJson(args, 0)) {
- strcpy(message, "First argument must be a json item");
- return true;
+ //} else if (!IsJson(args, 0)) {
+ // strcpy(message, "First argument must be a json item");
+ // return true;
} else
CalcLen(args, false, reslen, memlen, true);
@@ -4488,20 +4763,32 @@ char *jbin_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
PJVAL jvp;
PJAR arp;
- jvp = MakeValue(g, args, 0, &top);
-// jsp = jvp->GetJson();
+ jvp = MakeTypedValue(g, args, 0, TYPE_JSON, &top);
+ // jsp = jvp->GetJson();
x = GetIntArgPtr(g, args, n);
if (CheckPath(g, args, top, jvp, n))
PUSH_WARNING(g->Message);
- else if (jvp && jvp->GetValType() == TYPE_JAR) {
+ else if (jvp) {
PGLOBAL gb = GetMemPtr(g, args, 0);
- arp = jvp->GetArray();
+ if (jvp->GetValType() != TYPE_JAR) {
+ if ((arp = (PJAR)JsonNew(gb, TYPE_JAR))) {
+ arp->AddValue(gb, (PJVAL)JvalNew(gb, TYPE_JVAL, jvp));
+ jvp->SetValue(arp);
+
+ if (!top)
+ top = arp;
+
+ } // endif arp
+
+ } else
+ arp = jvp->GetArray();
+
arp->AddValue(gb, MakeValue(gb, args, 1), x);
arp->InitArray(gb);
} else {
- PUSH_WARNING("First argument is not an array");
+ PUSH_WARNING("First argument target is not an array");
// if (g->Mrr) *error = 1; (only if no path)
} // endif jvp
@@ -4539,9 +4826,6 @@ my_bool jbin_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
if (args->arg_count < 2) {
strcpy(message, "This function must have at least 2 arguments");
return true;
- } else if (!IsJson(args, 0)) {
- strcpy(message, "First argument must be a json item");
- return true;
} else
CalcLen(args, false, reslen, memlen, true);
@@ -4565,7 +4849,7 @@ char *jbin_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
int *x;
uint n = 1;
PJAR arp;
- PJVAL jvp = MakeValue(g, args, 0, &top);
+ PJVAL jvp = MakeTypedValue(g, args, 0, TYPE_JSON, &top);
if (CheckPath(g, args, top, jvp, 1))
PUSH_WARNING(g->Message);
@@ -4578,8 +4862,8 @@ char *jbin_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
PUSH_WARNING("Missing or null array index");
} else {
- PUSH_WARNING("First argument is not an array");
- if (g->Mrr) *error = 1;
+ PUSH_WARNING("First argument target is not an array");
+// if (g->Mrr) *error = 1;
} // endif jvp
} // endif CheckMemory
@@ -4625,13 +4909,18 @@ char *jbin_object(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!bsp || bsp->Changed) {
if (!CheckMemory(g, initid, args, args->arg_count, true)) {
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
- for (uint i = 0; i < args->arg_count; i++)
- objp->SetValue(g, MakeValue(g, args, i), MakeKey(g, args, i));
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i++)
+ objp->SetValue(g, MakeValue(g, args, i), MakeKey(g, args, i));
+
+
+ if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
+ strcat(bsp->Msg, " object");
- if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
- strcat(bsp->Msg, " object");
+ } else
+ bsp = NULL;
} else
if ((bsp = JbinAlloc(g, args, initid->max_length, NULL)))
@@ -4676,14 +4965,18 @@ char *jbin_object_nonull(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!bsp || bsp->Changed) {
if (!CheckMemory(g, initid, args, args->arg_count, false, true)) {
PJVAL jvp;
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
- for (uint i = 0; i < args->arg_count; i++)
- if (!(jvp = MakeValue(g, args, i))->IsNull())
- objp->SetValue(g, jvp, MakeKey(g, args, i));
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i++)
+ if (!(jvp = MakeValue(g, args, i))->IsNull())
+ objp->SetValue(g, jvp, MakeKey(g, args, i));
- if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
- strcat(bsp->Msg, " object");
+ if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
+ strcat(bsp->Msg, " object");
+
+ } else
+ bsp = NULL;
} else
if ((bsp = JbinAlloc(g, args, initid->max_length, NULL)))
@@ -4732,13 +5025,17 @@ char *jbin_object_key(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!bsp || bsp->Changed) {
if (!CheckMemory(g, initid, args, args->arg_count, false, true)) {
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
+
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i += 2)
+ objp->SetValue(g, MakeValue(g, args, i + 1), MakePSZ(g, args, i));
- for (uint i = 0; i < args->arg_count; i += 2)
- objp->SetValue(g, MakeValue(g, args, i+1), MakePSZ(g, args, i));
+ if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
+ strcat(bsp->Msg, " object");
- if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
- strcat(bsp->Msg, " object");
+ } else
+ bsp = NULL;
} else
if ((bsp = JbinAlloc(g, args, initid->max_length, NULL)))
@@ -4989,7 +5286,7 @@ my_bool jbin_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
char *jbin_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
{
- char *p, *path;
+ char *path;
PJSON jsp;
PJSNX jsx;
PJVAL jvp;
@@ -5006,17 +5303,10 @@ char *jbin_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (CheckMemory(g, initid, args, 1, true, true)) {
PUSH_WARNING("CheckMemory error");
goto fin;
- } else
- jvp = MakeValue(g, args, 0);
-
- if ((p = jvp->GetString(g))) {
- if (!(jsp = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- goto fin;
- } // endif jsp
+ } // endif CheckMemory
- } else
- jsp = jvp->GetJson();
+ jvp = MakeTypedValue(g, args, 0, TYPE_JSON);
+ jsp = jvp->GetJson();
if (g->Mrr) { // First argument is a constant
g->Xchk = jsp;
@@ -5027,16 +5317,16 @@ char *jbin_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g) JSNX(g, jsp, TYPE_STRING, initid->max_length);
+ jsx = JsnxNew(g, jsp, TYPE_STRING, initid->max_length);
- if (jsx->SetJpath(g, path, false)) {
+ if (!jsx || jsx->SetJpath(g, path, false)) {
PUSH_WARNING(g->Message);
goto fin;
} // endif SetJpath
// Get the json tree
if ((jvp = jsx->GetRowValue(g, jsp, 0, false))) {
- jsp = (jvp->GetJsp()) ? jvp->GetJsp() : new(g) JVALUE(g, jvp->GetValue());
+ jsp = (jvp->GetJsp()) ? jvp->GetJsp() : JvalNew(g, TYPE_VAL, jvp->GetValue());
if ((bsp = JbinAlloc(g, args, initid->max_length, jsp)))
strcat(bsp->Msg, " item");
diff --git a/storage/connect/jsonudf.h b/storage/connect/jsonudf.h
index cd3b9768f7a..23e8c0e1aed 100644
--- a/storage/connect/jsonudf.h
+++ b/storage/connect/jsonudf.h
@@ -89,6 +89,10 @@ extern "C" {
DllExport char *json_object_list(UDF_EXEC_ARGS);
DllExport void json_object_list_deinit(UDF_INIT*);
+ DllExport my_bool json_object_values_init(UDF_INIT*, UDF_ARGS*, char*);
+ DllExport char *json_object_values(UDF_EXEC_ARGS);
+ DllExport void json_object_values_deinit(UDF_INIT*);
+
DllExport my_bool jsonset_grp_size_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport long long jsonset_grp_size(UDF_INIT*, UDF_ARGS*, char*, char*);
diff --git a/storage/connect/libdoc.cpp b/storage/connect/libdoc.cpp
index 700d247da38..9b30b315441 100644
--- a/storage/connect/libdoc.cpp
+++ b/storage/connect/libdoc.cpp
@@ -194,7 +194,7 @@ void xtrc(char const *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
-
+ ;
//vfprintf(stderr, fmt, ap);
vsprintf(s, fmt, ap);
if (s[strlen(s)-1] == '\n')
@@ -210,7 +210,7 @@ static xmlStrdupFunc Strdup;
void xmlMyFree(void *mem)
{
- if (trace) {
+ if (trace(1)) {
htrc("%.4d Freeing at %p %s\n", ++m, mem, s);
*s = 0;
} // endif trace
@@ -220,7 +220,7 @@ void xmlMyFree(void *mem)
void *xmlMyMalloc(size_t size)
{
void *p = Malloc(size);
- if (trace) {
+ if (trace(1)) {
htrc("%.4d Allocating %.5d at %p %s\n", ++m, size, p, s);
*s = 0;
} // endif trace
@@ -230,7 +230,7 @@ void *xmlMyMalloc(size_t size)
void *xmlMyMallocAtomic(size_t size)
{
void *p = MallocA(size);
- if (trace) {
+ if (trace(1)) {
htrc("%.4d Atom alloc %.5d at %p %s\n", ++m, size, p, s);
*s = 0;
} // endif trace
@@ -240,7 +240,7 @@ void *xmlMyMallocAtomic(size_t size)
void *xmlMyRealloc(void *mem, size_t size)
{
void *p = Realloc(mem, size);
- if (trace) {
+ if (trace(1)) {
htrc("%.4d ReAlloc %.5d to %p from %p %s\n", ++m, size, p, mem, s);
*s = 0;
} // endif trace
@@ -250,7 +250,7 @@ void *xmlMyRealloc(void *mem, size_t size)
char *xmlMyStrdup(const char *str)
{
char *p = Strdup(str);
- if (trace) {
+ if (trace(1)) {
htrc("%.4d Duplicating to %p from %p %s %s\n", ++m, p, str, str, s);
*s = 0;
} // endif trace
@@ -339,7 +339,7 @@ void CloseXML2File(PGLOBAL g, PFBLOCK fp, bool all)
{
PX2BLOCK xp = (PX2BLOCK)fp;
- if (trace)
+ if (trace(1))
htrc("CloseXML2File: xp=%p count=%d\n", xp, (xp) ? xp->Count : 0);
if (xp && xp->Count > 1 && !all) {
@@ -387,7 +387,7 @@ bool LIBXMLDOC::Initialize(PGLOBAL g, PCSZ entry, bool zipped)
/******************************************************************/
bool LIBXMLDOC::ParseFile(PGLOBAL g, char *fn)
{
- if (trace)
+ if (trace(1))
htrc("ParseFile\n");
if (zip) {
@@ -436,7 +436,7 @@ PFBLOCK LIBXMLDOC::LinkXblock(PGLOBAL g, MODE m, int rc, char *fn)
/******************************************************************/
bool LIBXMLDOC::NewDoc(PGLOBAL g, PCSZ ver)
{
- if (trace)
+ if (trace(1))
htrc("NewDoc\n");
return ((Docp = xmlNewDoc(BAD_CAST ver)) == NULL);
@@ -447,7 +447,7 @@ bool LIBXMLDOC::NewDoc(PGLOBAL g, PCSZ ver)
/******************************************************************/
void LIBXMLDOC::AddComment(PGLOBAL g, char *txtp)
{
- if (trace)
+ if (trace(1))
htrc("AddComment: %s\n", txtp);
xmlNodePtr cp = xmlNewDocComment(Docp, BAD_CAST txtp);
@@ -459,7 +459,7 @@ void LIBXMLDOC::AddComment(PGLOBAL g, char *txtp)
/******************************************************************/
PXNODE LIBXMLDOC::GetRoot(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("GetRoot\n");
xmlNodePtr root = xmlDocGetRootElement(Docp);
@@ -475,7 +475,7 @@ PXNODE LIBXMLDOC::GetRoot(PGLOBAL g)
/******************************************************************/
PXNODE LIBXMLDOC::NewRoot(PGLOBAL g, char *name)
{
- if (trace)
+ if (trace(1))
htrc("NewRoot: %s\n", name);
xmlNodePtr root = xmlNewDocNode(Docp, NULL, BAD_CAST name, NULL);
@@ -493,7 +493,7 @@ PXNODE LIBXMLDOC::NewRoot(PGLOBAL g, char *name)
/******************************************************************/
PXNODE LIBXMLDOC::NewPnode(PGLOBAL g, char *name)
{
- if (trace)
+ if (trace(1))
htrc("NewNode: %s\n", name);
xmlNodePtr nop;
@@ -534,7 +534,7 @@ int LIBXMLDOC::DumpDoc(PGLOBAL g, char *ofn)
int rc = 0;
FILE *of;
- if (trace)
+ if (trace(1))
htrc("DumpDoc: %s\n", ofn);
if (!(of= global_fopen(g, MSGID_CANNOT_OPEN, ofn, "w")))
@@ -576,7 +576,7 @@ int LIBXMLDOC::DumpDoc(PGLOBAL g, char *ofn)
/******************************************************************/
void LIBXMLDOC::CloseDoc(PGLOBAL g, PFBLOCK xp)
{
- if (trace)
+ if (trace(1))
htrc("CloseDoc: xp=%p count=%d\n", xp, (xp) ? xp->Count : 0);
//if (xp && xp->Count == 1) {
@@ -630,24 +630,24 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp)
{
xmlNodeSetPtr nl;
- if (trace)
+ if (trace(1))
htrc("GetNodeList: %s np=%p\n", xp, np);
if (!Ctxp) {
// Init Xpath
- if (trace)
+ if (trace(1))
htrc("Calling xmlPathInit\n");
xmlXPathInit();
- if (trace)
+ if (trace(1))
htrc("Calling xmlXPathNewContext Docp=%p\n", Docp);
// Create xpath evaluation context
if (!(Ctxp = xmlXPathNewContext(Docp))) {
strcpy(g->Message, MSG(XPATH_CNTX_ERR));
- if (trace)
+ if (trace(1))
htrc("Context error: %s\n", g->Message);
return NULL;
@@ -655,7 +655,7 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp)
// Register namespaces from list (if any)
for (PNS nsp = Namespaces; nsp; nsp = nsp->Next) {
- if (trace)
+ if (trace(1))
htrc("Calling xmlXPathRegisterNs Prefix=%s Uri=%s\n",
nsp->Prefix, nsp->Uri);
@@ -663,7 +663,7 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp)
BAD_CAST nsp->Uri)) {
sprintf(g->Message, MSG(REGISTER_ERR), nsp->Prefix, nsp->Uri);
- if (trace)
+ if (trace(1))
htrc("Ns error: %s\n", g->Message);
return NULL;
@@ -674,7 +674,7 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp)
} // endif Ctxp
if (Xop) {
- if (trace)
+ if (trace(1))
htrc("Calling xmlXPathFreeNodeSetList Xop=%p NOFREE=%d\n",
Xop, Nofreelist);
@@ -698,21 +698,21 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp)
// Set the context to the calling node
Ctxp->node = np;
- if (trace)
+ if (trace(1))
htrc("Calling xmlXPathEval %s Ctxp=%p\n", xp, Ctxp);
// Evaluate table xpath
if (!(Xop = xmlXPathEval(BAD_CAST xp, Ctxp))) {
sprintf(g->Message, MSG(XPATH_EVAL_ERR), xp);
- if (trace)
+ if (trace(1))
htrc("Path error: %s\n", g->Message);
return NULL;
} else
nl = Xop->nodesetval;
- if (trace)
+ if (trace(1))
htrc("GetNodeList nl=%p n=%p\n", nl, (nl) ? nl->nodeNr : 0);
return nl;
@@ -811,7 +811,7 @@ XML2NODE::XML2NODE(PXDOC dp, xmlNodePtr np) : XMLNODE(dp)
int XML2NODE::GetType(void)
{
- if (trace)
+ if (trace(1))
htrc("GetType type=%d\n", Nodep->type);
return Nodep->type;
@@ -822,7 +822,7 @@ int XML2NODE::GetType(void)
/******************************************************************/
PXNODE XML2NODE::GetNext(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("GetNext\n");
if (!Nodep->next)
@@ -838,7 +838,7 @@ PXNODE XML2NODE::GetNext(PGLOBAL g)
/******************************************************************/
PXNODE XML2NODE::GetChild(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("GetChild\n");
if (!Nodep->children)
@@ -856,7 +856,7 @@ RCODE XML2NODE::GetContent(PGLOBAL g, char *buf, int len)
{
RCODE rc = RC_OK;
- if (trace)
+ if (trace(1))
htrc("GetContent\n");
if (Content)
@@ -888,7 +888,7 @@ RCODE XML2NODE::GetContent(PGLOBAL g, char *buf, int len)
*p2 = 0;
- if (trace)
+ if (trace(1))
htrc("GetText buf='%s' len=%d\n", buf, len);
xmlFree(Content);
@@ -896,7 +896,7 @@ RCODE XML2NODE::GetContent(PGLOBAL g, char *buf, int len)
} else
*buf = '\0';
- if (trace)
+ if (trace(1))
htrc("GetContent: %s\n", buf);
return rc;
@@ -907,12 +907,12 @@ RCODE XML2NODE::GetContent(PGLOBAL g, char *buf, int len)
/******************************************************************/
bool XML2NODE::SetContent(PGLOBAL g, char *txtp, int len)
{
- if (trace)
+ if (trace(1))
htrc("SetContent: %s\n", txtp);
xmlChar *buf = xmlEncodeEntitiesReentrant(Docp, BAD_CAST txtp);
- if (trace)
+ if (trace(1))
htrc("SetContent: %s -> %s\n", txtp, buf);
xmlNodeSetContent(Nodep, buf);
@@ -925,7 +925,7 @@ bool XML2NODE::SetContent(PGLOBAL g, char *txtp, int len)
/******************************************************************/
PXNODE XML2NODE::Clone(PGLOBAL g, PXNODE np)
{
- if (trace)
+ if (trace(1))
htrc("Clone: np=%p\n", np);
if (np) {
@@ -941,7 +941,7 @@ PXNODE XML2NODE::Clone(PGLOBAL g, PXNODE np)
/******************************************************************/
PXLIST XML2NODE::GetChildElements(PGLOBAL g, char *xp, PXLIST lp)
{
- if (trace)
+ if (trace(1))
htrc("GetChildElements: %s\n", xp);
return SelectNodes(g, (xp) ? xp : (char*)"*", lp);
@@ -952,7 +952,7 @@ PXLIST XML2NODE::GetChildElements(PGLOBAL g, char *xp, PXLIST lp)
/******************************************************************/
PXLIST XML2NODE::SelectNodes(PGLOBAL g, char *xp, PXLIST lp)
{
- if (trace)
+ if (trace(1))
htrc("SelectNodes: %s\n", xp);
xmlNodeSetPtr nl = ((PXDOC2)Doc)->GetNodeList(g, Nodep, xp);
@@ -970,7 +970,7 @@ PXLIST XML2NODE::SelectNodes(PGLOBAL g, char *xp, PXLIST lp)
/******************************************************************/
PXNODE XML2NODE::SelectSingleNode(PGLOBAL g, char *xp, PXNODE np)
{
- if (trace)
+ if (trace(1))
htrc("SelectSingleNode: %s\n", xp);
xmlNodeSetPtr nl = ((PXDOC2)Doc)->GetNodeList(g, Nodep, xp);
@@ -994,7 +994,7 @@ PXATTR XML2NODE::GetAttribute(PGLOBAL g, char *name, PXATTR ap)
{
xmlAttrPtr atp;
- if (trace)
+ if (trace(1))
htrc("GetAttribute: %s\n", SVP(name));
if (name)
@@ -1023,7 +1023,7 @@ PXNODE XML2NODE::AddChildNode(PGLOBAL g, PCSZ name, PXNODE np)
{
char *p, *pn, *pf = NULL, *nmp = PlugDup(g, name);
- if (trace)
+ if (trace(1))
htrc("AddChildNode: %s\n", name);
// Is a prefix specified
@@ -1074,7 +1074,7 @@ PXNODE XML2NODE::AddChildNode(PGLOBAL g, PCSZ name, PXNODE np)
/******************************************************************/
PXATTR XML2NODE::AddProperty(PGLOBAL g, char *name, PXATTR ap)
{
- if (trace)
+ if (trace(1))
htrc("AddProperty: %s\n", name);
xmlAttrPtr atp = xmlNewProp(Nodep, BAD_CAST name, NULL);
@@ -1097,7 +1097,7 @@ PXATTR XML2NODE::AddProperty(PGLOBAL g, char *name, PXATTR ap)
/******************************************************************/
void XML2NODE::AddText(PGLOBAL g, PCSZ txtp)
{
- if (trace)
+ if (trace(1))
htrc("AddText: %s\n", txtp);
// This is to avoid a blank line when inserting a new line
@@ -1119,7 +1119,7 @@ void XML2NODE::DeleteChild(PGLOBAL g, PXNODE dnp)
{
xmlErrorPtr xerr;
- if (trace)
+ if (trace(1))
htrc("DeleteChild: node=%p\n", dnp);
xmlNodePtr np = ((PNODE2)dnp)->Nodep;
@@ -1157,7 +1157,7 @@ void XML2NODE::DeleteChild(PGLOBAL g, PXNODE dnp)
return;
err:
- if (trace)
+ if (trace(1))
htrc("DeleteChild: errmsg=%s\n", xerr->message);
xmlResetError(xerr);
@@ -1187,7 +1187,7 @@ int XML2NODELIST::GetLength(void)
/******************************************************************/
PXNODE XML2NODELIST::GetItem(PGLOBAL g, int n, PXNODE np)
{
- if (trace)
+ if (trace(1))
htrc("GetItem: %d\n", n);
if (!Listp || Listp->nodeNr <= n)
@@ -1206,7 +1206,7 @@ PXNODE XML2NODELIST::GetItem(PGLOBAL g, int n, PXNODE np)
/******************************************************************/
bool XML2NODELIST::DropItem(PGLOBAL g, int n)
{
- if (trace)
+ if (trace(1))
htrc("DropItem: n=%d\n", n);
// We should do something here
@@ -1234,7 +1234,7 @@ XML2ATTR::XML2ATTR(PXDOC dp, xmlAttrPtr ap, xmlNodePtr np)
/******************************************************************/
PXATTR XML2ATTR::GetNext(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("Attr GetNext\n");
if (!Atrp->next)
@@ -1252,7 +1252,7 @@ RCODE XML2ATTR::GetText(PGLOBAL g, char *buf, int len)
RCODE rc = RC_OK;
xmlChar *txt;
- if (trace)
+ if (trace(1))
htrc("GetText\n");
if ((txt = xmlGetProp(Atrp->parent, Atrp->name))) {
@@ -1269,7 +1269,7 @@ RCODE XML2ATTR::GetText(PGLOBAL g, char *buf, int len)
} else
*buf = '\0';
- if (trace)
+ if (trace(1))
htrc("GetText: %s\n", buf);
return rc;
@@ -1280,7 +1280,7 @@ RCODE XML2ATTR::GetText(PGLOBAL g, char *buf, int len)
/******************************************************************/
bool XML2ATTR::SetText(PGLOBAL g, char *txtp, int len)
{
- if (trace)
+ if (trace(1))
htrc("SetText: %s %d\n", txtp, len);
xmlSetProp(Parent, Atrp->name, BAD_CAST txtp);
diff --git a/storage/connect/macutil.cpp b/storage/connect/macutil.cpp
index b9600bdac2e..f95f3adcc6e 100644
--- a/storage/connect/macutil.cpp
+++ b/storage/connect/macutil.cpp
@@ -230,13 +230,13 @@ bool MACINFO::GetOneInfo(PGLOBAL g, int flag, void *v, int lv)
case 11: // Description
if ((p = strstr(Curp->Description, " - Packet Scheduler Miniport"))) {
strncpy(buf, Curp->Description, p - Curp->Description);
- i = p - Curp->Description;
+ i = (int)(p - Curp->Description);
strncpy(buf, Curp->Description, i);
buf[i] = 0;
p = buf;
} else if ((p = strstr(Curp->Description,
" - Miniport d'ordonnancement de paquets"))) {
- i = p - Curp->Description;
+ i = (int)(p - Curp->Description);
strncpy(buf, Curp->Description, i);
buf[i] = 0;
p = buf;
diff --git a/storage/connect/mongo.cpp b/storage/connect/mongo.cpp
index 088dc2d29d1..53e2bf377c4 100644
--- a/storage/connect/mongo.cpp
+++ b/storage/connect/mongo.cpp
@@ -172,7 +172,7 @@ PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt, bool info)
goto err;
skipit:
- if (trace)
+ if (trace(1))
htrc("MGOColumns: n=%d len=%d\n", n, length[0]);
/*********************************************************************/
@@ -276,7 +276,7 @@ int MGODISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt)
tdp->Wrapname = (PSZ)GetStringTableOption(g, topt, "Wrapper",
(tdp->Version == 2) ? "Mongo2Interface" : "Mongo3Interface");
- if (trace)
+ if (trace(1))
htrc("Uri %s coll=%s db=%s colist=%s filter=%s lvl=%d\n",
tdp->Uri, tdp->Tabname, tdp->Tabschema, tdp->Colist, tdp->Filter, lvl);
diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc
index bb77512be62..cc8f75b2976 100644
--- a/storage/connect/mycat.cc
+++ b/storage/connect/mycat.cc
@@ -94,9 +94,9 @@
#if defined(XML_SUPPORT)
#include "tabxml.h"
#endif // XML_SUPPORT
-#if defined(JAVA_SUPPORT)
+#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
#include "mongo.h"
-#endif // JAVA_SUPPORT
+#endif // JAVA_SUPPORT || CMGO_SUPPORT
#if defined(ZIP_SUPPORT)
#include "tabzip.h"
#endif // ZIP_SUPPORT
@@ -109,9 +109,10 @@
extern "C" HINSTANCE s_hModule; // Saved module handle
#endif // !__WIN__
-#if defined(JAVA_SUPPORT)
-//bool MongoEnabled(void);
-#endif // JAVA_SUPPORT
+#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
+bool MongoEnabled(void);
+#endif // JAVA_SUPPORT || CMGO_SUPPORT
+
PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
/***********************************************************************/
@@ -146,6 +147,9 @@ TABTYPE GetTypeID(const char *type)
: (!stricmp(type, "JDBC")) ? TAB_JDBC
: (!stricmp(type, "MONGO")) ? TAB_MONGO
#endif
+#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
+ : (!stricmp(type, "MONGO") && MongoEnabled()) ? TAB_MONGO
+#endif
: (!stricmp(type, "MYSQL")) ? TAB_MYSQL
: (!stricmp(type, "MYPRX")) ? TAB_MYSQL
: (!stricmp(type, "DIR")) ? TAB_DIR
@@ -488,7 +492,7 @@ void MYCAT::Reset(void)
PRELDEF MYCAT::GetTableDesc(PGLOBAL g, PTABLE tablep,
LPCSTR type, PRELDEF *)
{
- if (trace)
+ if (trace(1))
printf("GetTableDesc: name=%s am=%s\n", tablep->GetName(), SVP(type));
// If not specified get the type of this table
@@ -509,7 +513,7 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
LPCSTR schema = (PSZ)PlugDup(g, tablep->GetSchema());
PRELDEF tdp= NULL;
- if (trace)
+ if (trace(1))
printf("MakeTableDesc: name=%s schema=%s am=%s\n",
name, SVP(schema), SVP(am));
@@ -562,8 +566,16 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
break;
#endif // MONGO_SUPPORT
#if defined(ZIP_SUPPORT)
- case TAB_ZIP: tdp= new(g) ZIPDEF; break;
+ case TAB_ZIP: tdp = new(g) ZIPDEF; break;
#endif // ZIP_SUPPORT
+#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
+ case TAB_MONGO:
+ if (MongoEnabled()) {
+ tdp = new(g) MGODEF;
+ break;
+ } // endif enabled
+ // fall through
+#endif // JAVA_SUPPORT || CMGO_SUPPORT
default:
sprintf(g->Message, MSG(BAD_TABLE_TYPE), am, name);
} // endswitch
@@ -584,14 +596,14 @@ PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode, LPCSTR type)
PTDB tdbp= NULL;
// LPCSTR name= tablep->GetName();
- if (trace)
+ if (trace(1))
printf("GetTableDB: name=%s\n", tablep->GetName());
// Look for the description of the requested table
tdp= GetTableDesc(g, tablep, type);
if (tdp) {
- if (trace)
+ if (trace(1))
printf("tdb=%p type=%s\n", tdp, tdp->GetType());
if (tablep->GetSchema())
@@ -601,7 +613,7 @@ PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode, LPCSTR type)
} // endif tdp
if (tdbp) {
- if (trace)
+ if (trace(1))
printf("tdbp=%p name=%s amtype=%d\n", tdbp, tdbp->GetName(),
tdbp->GetAmType());
tablep->SetTo_Tdb(tdbp);
diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp
index fe00f6a1eab..253c42bb002 100644
--- a/storage/connect/myconn.cpp
+++ b/storage/connect/myconn.cpp
@@ -177,7 +177,7 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
return NULL;
} // endif b
- if (trace)
+ if (trace(1))
htrc("MyColumns: cmd='%s'\n", cmd.GetStr());
if ((n = myc.GetResultSize(g, cmd.GetStr())) < 0) {
@@ -248,7 +248,7 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
while (true) {
p2 = strchr(p1, '\'');
- len = MY_MAX(len, p2 - p1);
+ len = MY_MAX(len, (int)(p2 - p1));
if (*++p2 != ',') break;
p1 = p2 + 2;
} // endwhile
@@ -482,7 +482,7 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
return RC_FX;
} // endif m_DB
- if (trace)
+ if (trace(1))
htrc("MYSQLC Open: m_DB=%.4X size=%d\n", m_DB, (int)sizeof(*m_DB));
// Removed to do like FEDERATED do
@@ -744,7 +744,7 @@ int MYSQLC::ExecSQL(PGLOBAL g, const char *query, int *w)
m_Fields = mysql_num_fields(m_Res);
m_Rows = (!m_Use) ? (int)mysql_num_rows(m_Res) : 0;
- if (trace)
+ if (trace(1))
htrc("ExecSQL: m_Res=%.4X size=%d m_Fields=%d m_Rows=%d\n",
m_Res, sizeof(*m_Res), m_Fields, m_Rows);
@@ -1068,7 +1068,7 @@ void MYSQLC::Close(void)
{
FreeResult();
- if (trace)
+ if (trace(1))
htrc("MYSQLC Close: m_DB=%.4X\n", m_DB);
mysql_close(m_DB);
diff --git a/storage/connect/mysql-test/connect/r/jdbc_postgresql.result b/storage/connect/mysql-test/connect/r/jdbc_postgresql.result
index 6d77d79d5d3..7969672dd66 100644
--- a/storage/connect/mysql-test/connect/r/jdbc_postgresql.result
+++ b/storage/connect/mysql-test/connect/r/jdbc_postgresql.result
@@ -1,9 +1,11 @@
+SET GLOBAL connect_class_path='C:/MariaDB-10.2/MariaDB/storage/connect/mysql-test/connect/std_data/JavaWrappers.jar;C:/Jconnectors/postgresql-42.2.1.jar';
CREATE TABLE t2 (
command varchar(128) not null,
number int(5) not null flag=1,
message varchar(255) flag=2)
-ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:postgresql://localhost/mtr'
-OPTION_LIST='User=mtr,Password=mtr,Schema=public,Execsrc=1';
+ENGINE=CONNECT TABLE_TYPE=JDBC
+CONNECTION='jdbc:postgresql://localhost/test?user=postgres&password=tinono'
+OPTION_LIST='Execsrc=1';
SELECT * FROM t2 WHERE command='drop table employee';
command number message
drop table employee 0 Execute: org.postgresql.util.PSQLException: ERREUR: la table « employee » n'existe pas
@@ -14,17 +16,18 @@ SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'E
command number message
insert into employee values(4567,'Johnson', 'Engineer', 12560.50) 1 Affected rows
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables
-CONNECTION='jdbc:postgresql://localhost/mtr'
-OPTION_LIST='User=mtr,Password=mtr,Schema=public,Tabtype=TABLE,Maxres=10';
+CONNECTION='jdbc:postgresql://localhost/test?user=postgres&password=tinono'
+OPTION_LIST='Tabtype=TABLE,Maxres=10';
SELECT * FROM t1;
Table_Cat Table_Schema Table_Name Table_Type Remark
- public employee TABLE NULL
- public t1 TABLE NULL
- public t2 TABLE NULL
+NULL public employee TABLE NULL
+NULL public t1 TABLE NULL
+NULL public t2 TABLE NULL
+NULL public tchar TABLE NULL
+NULL public testuuid TABLE NULL
DROP TABLE t1;
-CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=columns
-CONNECTION='jdbc:postgresql://localhost/mtr' tabname=employee
-OPTION_LIST='User=mtr,Password=mtr,Maxres=10';
+CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC tabname=employee CATFUNC=columns
+CONNECTION='jdbc:postgresql://localhost/test?user=postgres&password=tinono';
SELECT * FROM t1;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
NULL public employee id 4 int4 10 0 0 10 0 NULL
@@ -34,13 +37,14 @@ NULL public employee salary 2 numeric 8 0 2 10 1 NULL
DROP TABLE t1;
CREATE SERVER 'postgresql' FOREIGN DATA WRAPPER 'postgresql' OPTIONS (
HOST 'localhost',
-DATABASE 'mtr',
-USER 'mtr',
-PASSWORD 'mtr',
+DATABASE 'test',
+USER 'postgres',
+PASSWORD 'tinono',
PORT 0,
SOCKET '',
OWNER 'root');
-CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='postgresql/public.employee';
+CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
+CONNECTION='postgresql/public.employee';
SELECT * FROM t1;
id name title salary
4567 Johnson Engineer 12560.50
@@ -60,6 +64,3 @@ SELECT * FROM t2 WHERE command='drop table employee';
command number message
drop table employee 0 Affected rows
DROP TABLE t2;
-SET GLOBAL connect_jvm_path=NULL;
-SET GLOBAL connect_class_path=NULL;
-SET GLOBAL time_zone = SYSTEM;
diff --git a/storage/connect/mysql-test/connect/r/json_java_2.result b/storage/connect/mysql-test/connect/r/json_java_2.result
index 783d86e6595..1a90132dede 100644
--- a/storage/connect/mysql-test/connect/r/json_java_2.result
+++ b/storage/connect/mysql-test/connect/r/json_java_2.result
@@ -1,4 +1,5 @@
-SET GLOBAL connect_class_path='C:/MariaDB-10.1/MariaDB/storage/connect/mysql-test/connect/std_data/Mongo2.jar';
+SET GLOBAL connect_class_path='C:/MariaDB-10.2/MariaDB/storage/connect/mysql-test/connect/std_data/Mongo2.jar';
+set connect_enable_mongo=1;
#
# Test the MONGO table type
#
@@ -381,3 +382,7 @@ planner 167 41.75
postcard 23 5.75
DROP TABLE t1;
true
+<<<<<<< HEAD
+=======
+set connect_enable_mongo=0;
+>>>>>>> connect/10.0
diff --git a/storage/connect/mysql-test/connect/r/json_java_3.result b/storage/connect/mysql-test/connect/r/json_java_3.result
index a301e0273d5..4c5fc94fca6 100644
--- a/storage/connect/mysql-test/connect/r/json_java_3.result
+++ b/storage/connect/mysql-test/connect/r/json_java_3.result
@@ -1,4 +1,5 @@
-SET GLOBAL connect_class_path='C:/MariaDB-10.1/MariaDB/storage/connect/mysql-test/connect/std_data/Mongo3.jar';
+SET GLOBAL connect_class_path='C:/MariaDB-10.2/MariaDB/storage/connect/mysql-test/connect/std_data/Mongo3.jar';
+set connect_enable_mongo=1;
#
# Test the MONGO table type
#
@@ -381,3 +382,4 @@ planner 167 41.75
postcard 23 5.75
DROP TABLE t1;
true
+set connect_enable_mongo=0;
diff --git a/storage/connect/mysql-test/connect/r/json_mongo_c.result b/storage/connect/mysql-test/connect/r/json_mongo_c.result
index 8adc006a51b..550e94f286e 100644
--- a/storage/connect/mysql-test/connect/r/json_mongo_c.result
+++ b/storage/connect/mysql-test/connect/r/json_mongo_c.result
@@ -1,3 +1,4 @@
+set connect_enable_mongo=1;
#
# Test the MONGO table type
#
@@ -380,3 +381,4 @@ planner 167 41.75
postcard 23 5.75
DROP TABLE t1;
true
+set connect_enable_mongo=0;
diff --git a/storage/connect/mysql-test/connect/r/json_udf.result b/storage/connect/mysql-test/connect/r/json_udf.result
index 7d81ca5e73d..09544bb1ecb 100644
--- a/storage/connect/mysql-test/connect/r/json_udf.result
+++ b/storage/connect/mysql-test/connect/r/json_udf.result
@@ -50,17 +50,19 @@ SELECT Json_Array_Add(Json_Make_Array(56, 3.1416, 'foo', NULL), 'One more') Arra
Array
[56,3.141600,"foo",null,"One more"]
SELECT Json_Array_Add(JsonValue('one value'), 'One more');
-ERROR HY000: Can't initialize function 'json_array_add'; First argument must be a json item
+Json_Array_Add(JsonValue('one value'), 'One more')
+["\"one value\"","One more"]
SELECT Json_Array_Add('one value', 'One more');
-ERROR HY000: Can't initialize function 'json_array_add'; First argument must be a json item
+Json_Array_Add('one value', 'One more')
+["one value","One more"]
SELECT Json_Array_Add('one value' json_, 'One more');
Json_Array_Add('one value' json_, 'One more')
one value
Warnings:
Warning 1105 Error 2 opening one value
-Warning 1105 First argument target is not an array
SELECT Json_Array_Add(5 json_, 'One more');
-ERROR HY000: Can't initialize function 'json_array_add'; First argument must be a json item
+Json_Array_Add(5 json_, 'One more')
+[5,"One more"]
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 0);
Json_Array_Add('[5,3,8,7,9]' json_, 4, 0)
[4,5,3,8,7,9]
diff --git a/storage/connect/mysql-test/connect/r/json_udf_bin.result b/storage/connect/mysql-test/connect/r/json_udf_bin.result
index 0c009d612fe..d0819619c33 100644
--- a/storage/connect/mysql-test/connect/r/json_udf_bin.result
+++ b/storage/connect/mysql-test/connect/r/json_udf_bin.result
@@ -272,10 +272,9 @@ Json_Serialize(Jbin_Array('a','b','c'))
["a","b","c"]
SELECT Json_Serialize(Jbin_Array_Add(Jbin_File('not_exist.json'), 'd'));
Json_Serialize(Jbin_Array_Add(Jbin_File('not_exist.json'), 'd'))
-Null json tree
+[null,"d"]
Warnings:
Warning 1105 Open(map) error 2 on not_exist.json
-Warning 1105 First argument is not an array
# This does not modify the file
SELECT Json_Serialize(Jbin_Array_Add(Jbin_File('bt1.json'), 'd'));
Json_Serialize(Jbin_Array_Add(Jbin_File('bt1.json'), 'd'))
diff --git a/storage/connect/mysql-test/connect/r/mongo_c.result b/storage/connect/mysql-test/connect/r/mongo_c.result
index c7aadcf1165..132bb34ce64 100644
--- a/storage/connect/mysql-test/connect/r/mongo_c.result
+++ b/storage/connect/mysql-test/connect/r/mongo_c.result
@@ -1,3 +1,4 @@
+set connect_enable_mongo=1;
#
# Test the MONGO table type
#
@@ -376,3 +377,4 @@ planner 167 41.750000
postcard 23 5.750000
DROP TABLE t1;
true
+set connect_enable_mongo=0;
diff --git a/storage/connect/mysql-test/connect/r/mongo_java_2.result b/storage/connect/mysql-test/connect/r/mongo_java_2.result
index 708b6f1cc7c..67c67653e88 100644
--- a/storage/connect/mysql-test/connect/r/mongo_java_2.result
+++ b/storage/connect/mysql-test/connect/r/mongo_java_2.result
@@ -1,4 +1,5 @@
-SET GLOBAL connect_class_path='C:/MariaDB-10.1/MariaDB/storage/connect/mysql-test/connect/std_data/Mongo2.jar';
+SET GLOBAL connect_class_path='C:/MariaDB-10.2/MariaDB/storage/connect/mysql-test/connect/std_data/Mongo2.jar';
+set connect_enable_mongo=1;
#
# Test the MONGO table type
#
@@ -377,3 +378,4 @@ planner 167 41.75
postcard 23 5.75
DROP TABLE t1;
true
+set connect_enable_mongo=0;
diff --git a/storage/connect/mysql-test/connect/r/mongo_java_3.result b/storage/connect/mysql-test/connect/r/mongo_java_3.result
index 672d9f15b80..665178bd3ea 100644
--- a/storage/connect/mysql-test/connect/r/mongo_java_3.result
+++ b/storage/connect/mysql-test/connect/r/mongo_java_3.result
@@ -1,4 +1,5 @@
-SET GLOBAL connect_class_path='C:/MariaDB-10.1/MariaDB/storage/connect/mysql-test/connect/std_data/Mongo3.jar';
+SET GLOBAL connect_class_path='C:/MariaDB-10.2/MariaDB/storage/connect/mysql-test/connect/std_data/Mongo3.jar';
+set connect_enable_mongo=1;
#
# Test the MONGO table type
#
@@ -377,3 +378,4 @@ planner 167 41.75
postcard 23 5.75
DROP TABLE t1;
true
+set connect_enable_mongo=0;
diff --git a/storage/connect/mysql-test/connect/r/tbl_thread.result b/storage/connect/mysql-test/connect/r/tbl_thread.result
index e07fc0988fd..9633f358c97 100644
--- a/storage/connect/mysql-test/connect/r/tbl_thread.result
+++ b/storage/connect/mysql-test/connect/r/tbl_thread.result
@@ -79,7 +79,7 @@ a b
CREATE TABLE total (a int, b char(10))
ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2,t3,t4,t5'
OPTION_LIST='thread=yes,port=PORT';
-set connect_xtrace=1;
+set connect_xtrace=96;
SELECT * FROM total order by a desc;
a b
19 test19
@@ -118,7 +118,7 @@ SELECT * FROM t2;
v
22
CREATE TABLE total (v BIGINT(20) UNSIGNED NOT NULL) ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2' OPTION_LIST='thread=yes,port=PORT';;
-set connect_xtrace=1;
+set connect_xtrace=96;
SELECT * FROM total order by v desc;
v
22
@@ -137,7 +137,7 @@ SELECT * FROM t2;
v
22
CREATE TABLE total (v BIGINT(20) UNSIGNED NOT NULL) ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2' OPTION_LIST='thread=yes,port=PORT';;
-set connect_xtrace=1;
+set connect_xtrace=96;
SELECT * FROM total order by v desc;
v
22
diff --git a/storage/connect/mysql-test/connect/r/vcol.result b/storage/connect/mysql-test/connect/r/vcol.result
new file mode 100644
index 00000000000..4c59a3b06d8
--- /dev/null
+++ b/storage/connect/mysql-test/connect/r/vcol.result
@@ -0,0 +1,29 @@
+create table t1 (
+#linenum int(6) not null default 0 special=rowid,
+name char(12) not null,
+city char(11) not null,
+birth date not null date_format='DD/MM/YYYY',
+hired date not null date_format='DD/MM/YYYY' flag=36,
+agehired int(3) as (floor(datediff(hired,birth)/365.25))
+)
+engine=CONNECT table_type=FIX file_name='boys.txt' mapped=YES lrecl=47 ending=1;
+select * from t1;
+name city birth hired agehired
+John Boston 1986-01-25 2010-06-02 24
+Henry Boston 1987-06-07 2008-04-01 20
+George San Jose 1981-08-10 2010-06-02 28
+Sam Chicago 1979-11-22 2007-10-10 27
+James Dallas 1992-05-13 2009-12-14 17
+Bill Boston 1986-09-11 2008-02-10 21
+drop table t1;
+create table t1 (
+#linenum int(6) not null default 0 special=rowid,
+name char(12) not null,
+city char(11) not null,
+birth date not null date_format='DD/MM/YYYY',
+hired date not null date_format='DD/MM/YYYY' flag=36,
+agehired int(3) as (floor(datediff(hired,birth)/365.25)),
+index (agehired)
+)
+engine=CONNECT table_type=FIX file_name='boys.txt' mapped=YES lrecl=47 ending=1;
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column
diff --git a/storage/connect/mysql-test/connect/std_data/JavaWrappers.jar b/storage/connect/mysql-test/connect/std_data/JavaWrappers.jar
new file mode 100644
index 00000000000..33b29e7685b
--- /dev/null
+++ b/storage/connect/mysql-test/connect/std_data/JavaWrappers.jar
Binary files differ
diff --git a/storage/connect/mysql-test/connect/std_data/Mongo2.jar b/storage/connect/mysql-test/connect/std_data/Mongo2.jar
index d019bf6906b..9be654bd4c8 100644
--- a/storage/connect/mysql-test/connect/std_data/Mongo2.jar
+++ b/storage/connect/mysql-test/connect/std_data/Mongo2.jar
Binary files differ
diff --git a/storage/connect/mysql-test/connect/std_data/Mongo3.jar b/storage/connect/mysql-test/connect/std_data/Mongo3.jar
index 21c6c2d10bd..2850177a668 100644
--- a/storage/connect/mysql-test/connect/std_data/Mongo3.jar
+++ b/storage/connect/mysql-test/connect/std_data/Mongo3.jar
Binary files differ
diff --git a/storage/connect/mysql-test/connect/t/jdbc_postgresql.test b/storage/connect/mysql-test/connect/t/jdbc_postgresql.test
index 1041ef468d7..8036f71020d 100644
--- a/storage/connect/mysql-test/connect/t/jdbc_postgresql.test
+++ b/storage/connect/mysql-test/connect/t/jdbc_postgresql.test
@@ -3,25 +3,32 @@
#
# This test is run against Postgresql driver
#
+eval SET GLOBAL connect_class_path='$MTR_SUITE_DIR/std_data/JavaWrappers.jar;C:/Jconnectors/postgresql-42.2.1.jar';
CREATE TABLE t2 (
command varchar(128) not null,
number int(5) not null flag=1,
message varchar(255) flag=2)
-ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:postgresql://localhost/mtr'
-OPTION_LIST='User=mtr,Password=mtr,Schema=public,Execsrc=1';
+ENGINE=CONNECT TABLE_TYPE=JDBC
+CONNECTION='jdbc:postgresql://localhost/test?user=postgres&password=tinono'
+OPTION_LIST='Execsrc=1';
+#CONNECTION='jdbc:postgresql://localhost/mtr'
+#OPTION_LIST='User=mtr,Password=mtr,Schema=public,Execsrc=1';
SELECT * FROM t2 WHERE command='drop table employee';
SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary decimal(8,2))';
SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)";
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables
-CONNECTION='jdbc:postgresql://localhost/mtr'
-OPTION_LIST='User=mtr,Password=mtr,Schema=public,Tabtype=TABLE,Maxres=10';
+CONNECTION='jdbc:postgresql://localhost/test?user=postgres&password=tinono'
+OPTION_LIST='Tabtype=TABLE,Maxres=10';
+#CONNECTION='jdbc:postgresql://localhost/mtr'
+#OPTION_LIST='User=mtr,Password=mtr,Schema=public,Tabtype=TABLE,Maxres=10';
SELECT * FROM t1;
DROP TABLE t1;
-CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=columns
-CONNECTION='jdbc:postgresql://localhost/mtr' tabname=employee
-OPTION_LIST='User=mtr,Password=mtr,Maxres=10';
+CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC tabname=employee CATFUNC=columns
+CONNECTION='jdbc:postgresql://localhost/test?user=postgres&password=tinono';
+#CONNECTION='jdbc:postgresql://localhost/mtr' tabname=employee;
+#OPTION_LIST='User=mtr,Password=mtr,Maxres=10';
SELECT * FROM t1;
DROP TABLE t1;
@@ -30,14 +37,18 @@ DROP TABLE t1;
#
CREATE SERVER 'postgresql' FOREIGN DATA WRAPPER 'postgresql' OPTIONS (
HOST 'localhost',
-DATABASE 'mtr',
-USER 'mtr',
-PASSWORD 'mtr',
+DATABASE 'test',
+USER 'postgres',
+PASSWORD 'tinono',
PORT 0,
SOCKET '',
OWNER 'root');
+#DATABASE 'mtr',
+#USER 'mtr',
+#PASSWORD 'mtr',
-CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='postgresql/public.employee';
+CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
+CONNECTION='postgresql/public.employee';
SELECT * FROM t1;
INSERT INTO t1 VALUES(3126,'Smith', 'Clerk', 5230.00);
UPDATE t1 SET salary = salary + 100.00;
diff --git a/storage/connect/mysql-test/connect/t/jdbconn.inc b/storage/connect/mysql-test/connect/t/jdbconn.inc
index 05122f51924..81ec80c13d6 100644
--- a/storage/connect/mysql-test/connect/t/jdbconn.inc
+++ b/storage/connect/mysql-test/connect/t/jdbconn.inc
@@ -22,10 +22,11 @@ DROP TABLE t1;
# 1 - The current directory.
# 2 - The paths of the connect_class_path global variable.
# 3 - The paths of the CLASSPATH environment variable.
-# In this test we use an executable jar file that contains all what is needed.
-eval SET GLOBAL connect_class_path='$MTR_SUITE_DIR/std_data/JdbcMariaDB.jar';
+# In this test we use an executable jar file that contains all the eisting wrappers.
+#eval SET GLOBAL connect_class_path='$MTR_SUITE_DIR/std_data/JdbcMariaDB.jar';
+eval SET GLOBAL connect_class_path='$MTR_SUITE_DIR/std_data/JavaWrappers.jar';
-# Paths to the JDK classes and to the MySQL and MariaDB drivers can be defined in the CLASSPATH environment variable
+# Paths to the JDK classes and to the JDBC drivers should be defined in the CLASSPATH environment variable
#CREATE FUNCTION envar RETURNS STRING SONAME 'ha_connect.dll';
#SELECT envar('CLASSPATH');
diff --git a/storage/connect/mysql-test/connect/t/json_udf.test b/storage/connect/mysql-test/connect/t/json_udf.test
index 35dbbfed706..d45131f32ba 100644
--- a/storage/connect/mysql-test/connect/t/json_udf.test
+++ b/storage/connect/mysql-test/connect/t/json_udf.test
@@ -29,12 +29,12 @@ SELECT Json_Make_Array(Json_Make_Array(56, 3.1416, 'foo'), TRUE);
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Add(Json_Make_Array(56, 3.1416, 'foo', NULL)) Array;
SELECT Json_Array_Add(Json_Make_Array(56, 3.1416, 'foo', NULL), 'One more') Array;
---error ER_CANT_INITIALIZE_UDF
+#--error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Add(JsonValue('one value'), 'One more');
---error ER_CANT_INITIALIZE_UDF
+#--error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Add('one value', 'One more');
SELECT Json_Array_Add('one value' json_, 'One more');
---error ER_CANT_INITIALIZE_UDF
+#--error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Add(5 json_, 'One more');
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 0);
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 2) Array;
diff --git a/storage/connect/mysql-test/connect/t/mongo.inc b/storage/connect/mysql-test/connect/t/mongo.inc
index 2d7cbcfa8bd..fab2ca84139 100644
--- a/storage/connect/mysql-test/connect/t/mongo.inc
+++ b/storage/connect/mysql-test/connect/t/mongo.inc
@@ -1,3 +1,3 @@
-let $MONGO= C:/PROGRA~1/MongoDB/Server/3.4/bin/mongo;
-let $MONGOIMPORT= C:/PROGRA~1/MongoDB/Server/3.4/bin/mongoimport;
+let $MONGO= C:/Applic/MongoDB/Server/3.6/bin/mongo;
+let $MONGOIMPORT= C:/Applic/MongoDB/Server/3.6/bin/mongoimport;
diff --git a/storage/connect/mysql-test/connect/t/mongo_test.inc b/storage/connect/mysql-test/connect/t/mongo_test.inc
index dfc223e9074..357fa55240b 100644
--- a/storage/connect/mysql-test/connect/t/mongo_test.inc
+++ b/storage/connect/mysql-test/connect/t/mongo_test.inc
@@ -1,4 +1,4 @@
-#set connect_enable_mongo=1;
+set connect_enable_mongo=1;
--echo #
--echo # Test the MONGO table type
@@ -130,7 +130,9 @@ DROP TABLE t1;
--echo #
--echo # try CRUD operations
--echo #
+--disable_query_log
--exec $MONGO --eval "db.testcoll.drop()" --quiet
+--enable_query_log
eval CREATE TABLE t1 (_id INT(4) NOT NULL, msg CHAR(64))
ENGINE=CONNECT TABLE_TYPE=$TYPE TABNAME='testcoll'
OPTION_LIST='Driver=$DRV,Version=$VERS' $CONN;
@@ -147,7 +149,9 @@ DROP TABLE t1;
--echo #
--echo # List states whose population is equal or more than 10 millions
--echo #
+--disable_query_log
--exec $MONGO --eval "db.cities.drop()" --quiet
+--enable_query_log
--exec $MONGOIMPORT --quiet $MTR_SUITE_DIR/std_data/cities.json
eval CREATE TABLE t1 (
_id char(5) NOT NULL,
@@ -204,4 +208,4 @@ SELECT * FROM t1;
DROP TABLE t1;
--exec $MONGO --eval "db.testcoll.drop()" --quiet
-#set connect_enable_mongo=0;
+set connect_enable_mongo=0;
diff --git a/storage/connect/mysql-test/connect/t/tbl_thread.test b/storage/connect/mysql-test/connect/t/tbl_thread.test
index 68a0ebcd44d..05409c695fb 100644
--- a/storage/connect/mysql-test/connect/t/tbl_thread.test
+++ b/storage/connect/mysql-test/connect/t/tbl_thread.test
@@ -56,7 +56,7 @@ SELECT * FROM t5;
eval CREATE TABLE total (a int, b char(10))
ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2,t3,t4,t5'
OPTION_LIST='thread=yes,port=$PORT';
-set connect_xtrace=1;
+set connect_xtrace=96;
SELECT * FROM total order by a desc;
set connect_xtrace=0;
@@ -85,7 +85,7 @@ SELECT * FROM t2;
--replace_result $PORT PORT
--eval CREATE TABLE total (v BIGINT(20) UNSIGNED NOT NULL) ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2' OPTION_LIST='thread=yes,port=$PORT';
-set connect_xtrace=1;
+set connect_xtrace=96;
SELECT * FROM total order by v desc;
set connect_xtrace=0;
DROP TABLE t1,t2,total;
@@ -101,7 +101,7 @@ SELECT * FROM t2;
--replace_result $PORT PORT
--eval CREATE TABLE total (v BIGINT(20) UNSIGNED NOT NULL) ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2' OPTION_LIST='thread=yes,port=$PORT';
-set connect_xtrace=1;
+set connect_xtrace=96;
SELECT * FROM total order by v desc;
set connect_xtrace=0;
diff --git a/storage/connect/mysql-test/connect/t/vcol.test b/storage/connect/mysql-test/connect/t/vcol.test
new file mode 100644
index 00000000000..88b822102d0
--- /dev/null
+++ b/storage/connect/mysql-test/connect/t/vcol.test
@@ -0,0 +1,31 @@
+let datadir= `select @@datadir`;
+--copy_file $MTR_SUITE_DIR/std_data/boys.txt $datadir/test/boys.txt
+
+create table t1 (
+ #linenum int(6) not null default 0 special=rowid,
+ name char(12) not null,
+ city char(11) not null,
+ birth date not null date_format='DD/MM/YYYY',
+ hired date not null date_format='DD/MM/YYYY' flag=36,
+ agehired int(3) as (floor(datediff(hired,birth)/365.25))
+ )
+engine=CONNECT table_type=FIX file_name='boys.txt' mapped=YES lrecl=47 ending=1;
+select * from t1;
+drop table t1;
+
+--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN
+create table t1 (
+ #linenum int(6) not null default 0 special=rowid,
+ name char(12) not null,
+ city char(11) not null,
+ birth date not null date_format='DD/MM/YYYY',
+ hired date not null date_format='DD/MM/YYYY' flag=36,
+ agehired int(3) as (floor(datediff(hired,birth)/365.25)),
+ index (agehired)
+ )
+engine=CONNECT table_type=FIX file_name='boys.txt' mapped=YES lrecl=47 ending=1;
+
+#
+# Clean up
+#
+--remove_file $datadir/test/boys.txt
diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp
index 70a0a6a1450..f7b1a43a95d 100644
--- a/storage/connect/odbconn.cpp
+++ b/storage/connect/odbconn.cpp
@@ -137,10 +137,10 @@ int TranslateSQLType(int stp, int prec, int& len, char& v, bool& w)
case SQL_WLONGVARCHAR: // (-10)
w = true;
case SQL_LONGVARCHAR: // (-1)
- if (GetTypeConv() == TPC_YES) {
+ if (GetTypeConv() == TPC_YES || GetTypeConv() == TPC_FORCE) {
v = 'V';
type = TYPE_STRING;
- len = MY_MIN(abs(len), GetConvSize());
+ len = (len) ? MY_MIN(abs(len), GetConvSize()) : GetConvSize();
} else
type = TYPE_ERROR;
@@ -190,12 +190,23 @@ int TranslateSQLType(int stp, int prec, int& len, char& v, bool& w)
case SQL_BIGINT: // (-5)
type = TYPE_BIGINT;
break;
- case SQL_UNKNOWN_TYPE: // 0
case SQL_BINARY: // (-2)
case SQL_VARBINARY: // (-3)
case SQL_LONGVARBINARY: // (-4)
- case SQL_GUID: // (-11)
- default:
+ if (GetTypeConv() == TPC_FORCE) {
+ v = 'V';
+ type = TYPE_STRING;
+ len = (len) ? MY_MIN(abs(len), GetConvSize()) : GetConvSize();
+ } else
+ type = TYPE_ERROR;
+
+ break;
+ case SQL_GUID: // (-11)
+ type = TYPE_STRING;
+ len = 36;
+ break;
+ case SQL_UNKNOWN_TYPE: // 0
+ default:
type = TYPE_ERROR;
len = 0;
} // endswitch type
@@ -364,7 +375,7 @@ PQRYRES ODBCColumns(PGLOBAL g, PCSZ dsn, PCSZ db, PCSZ table,
length[11] = 255;
} // endif ocp
- if (trace)
+ if (trace(1))
htrc("ODBCColumns: max=%d len=%d,%d,%d,%d\n",
maxres, length[0], length[1], length[2], length[3]);
@@ -381,7 +392,7 @@ PQRYRES ODBCColumns(PGLOBAL g, PCSZ dsn, PCSZ db, PCSZ table,
if (info || !qrp) // Info table
return qrp;
- if (trace)
+ if (trace(1))
htrc("Getting col results ncol=%d\n", qrp->Nbcol);
if (!(cap = AllocCatInfo(g, CAT_COL, db, table, qrp)))
@@ -396,7 +407,7 @@ PQRYRES ODBCColumns(PGLOBAL g, PCSZ dsn, PCSZ db, PCSZ table,
qrp->Nblin = n;
// ResetNullValues(cap);
- if (trace)
+ if (trace(1))
htrc("Columns: NBCOL=%d NBLIN=%d\n", qrp->Nbcol, qrp->Nblin);
} else
@@ -536,7 +547,7 @@ PQRYRES ODBCDrivers(PGLOBAL g, int maxres, bool info)
} else
maxres = 0;
- if (trace)
+ if (trace(1))
htrc("ODBCDrivers: max=%d len=%d\n", maxres, length[0]);
/************************************************************************/
@@ -593,7 +604,7 @@ PQRYRES ODBCDataSources(PGLOBAL g, int maxres, bool info)
maxres = 0;
} // endif info
- if (trace)
+ if (trace(1))
htrc("ODBCDataSources: max=%d len=%d\n", maxres, length[0]);
/************************************************************************/
@@ -666,7 +677,7 @@ PQRYRES ODBCTables(PGLOBAL g, PCSZ dsn, PCSZ db, PCSZ tabpat, PCSZ tabtyp,
length[4] = 255;
} // endif info
- if (trace)
+ if (trace(1))
htrc("ODBCTables: max=%d len=%d,%d\n", maxres, length[0], length[1]);
/************************************************************************/
@@ -687,7 +698,7 @@ PQRYRES ODBCTables(PGLOBAL g, PCSZ dsn, PCSZ db, PCSZ tabpat, PCSZ tabtyp,
cap->Pat = tabtyp;
- if (trace)
+ if (trace(1))
htrc("Getting table results ncol=%d\n", cap->Qrp->Nbcol);
/************************************************************************/
@@ -697,7 +708,7 @@ PQRYRES ODBCTables(PGLOBAL g, PCSZ dsn, PCSZ db, PCSZ tabpat, PCSZ tabtyp,
qrp->Nblin = n;
// ResetNullValues(cap);
- if (trace)
+ if (trace(1))
htrc("Tables: NBCOL=%d NBLIN=%d\n", qrp->Nbcol, qrp->Nblin);
} else
@@ -755,7 +766,7 @@ PQRYRES ODBCPrimaryKeys(PGLOBAL g, ODBConn *op, char *dsn, char *table)
n = ocp->GetMaxValue(SQL_MAX_COLUMN_NAME_LEN);
length[3] = (n) ? (n + 1) : 128;
- if (trace)
+ if (trace(1))
htrc("ODBCPrimaryKeys: max=%d len=%d,%d,%d\n",
maxres, length[0], length[1], length[2]);
@@ -765,7 +776,7 @@ PQRYRES ODBCPrimaryKeys(PGLOBAL g, ODBConn *op, char *dsn, char *table)
qrp = PlgAllocResult(g, ncol, maxres, IDS_PKEY,
buftyp, NULL, length, false, true);
- if (trace)
+ if (trace(1))
htrc("Getting pkey results ncol=%d\n", qrp->Nbcol);
cap = AllocCatInfo(g, CAT_KEY, NULL, table, qrp);
@@ -777,7 +788,7 @@ PQRYRES ODBCPrimaryKeys(PGLOBAL g, ODBConn *op, char *dsn, char *table)
qrp->Nblin = n;
// ResetNullValues(cap);
- if (trace)
+ if (trace(1))
htrc("PrimaryKeys: NBCOL=%d NBLIN=%d\n", qrp->Nbcol, qrp->Nblin);
} else
@@ -838,7 +849,7 @@ PQRYRES ODBCStatistics(PGLOBAL g, ODBConn *op, char *dsn, char *pat,
n = ocp->GetMaxValue(SQL_MAX_COLUMN_NAME_LEN);
length[7] = (n) ? (n + 1) : 128;
- if (trace)
+ if (trace(1))
htrc("SemStatistics: max=%d pat=%s\n", maxres, SVP(pat));
/************************************************************************/
@@ -847,7 +858,7 @@ PQRYRES ODBCStatistics(PGLOBAL g, ODBConn *op, char *dsn, char *pat,
qrp = PlgAllocResult(g, ncol, maxres, IDS_STAT,
buftyp, NULL, length, false, true);
- if (trace)
+ if (trace(1))
htrc("Getting stat results ncol=%d\n", qrp->Nbcol);
cap = AllocCatInfo(g, CAT_STAT, NULL, pat, qrp);
@@ -861,7 +872,7 @@ PQRYRES ODBCStatistics(PGLOBAL g, ODBConn *op, char *dsn, char *pat,
qrp->Nblin = n;
// ResetNullValues(cap);
- if (trace)
+ if (trace(1))
htrc("Statistics: NBCOL=%d NBLIN=%d\n", qrp->Nbcol, qrp->Nblin);
} else
@@ -918,7 +929,7 @@ bool DBX::BuildErrorMessage(ODBConn* pdb, HSTMT hstmt)
&& strcmp((char*)state, "00000"); i++) {
m_ErrMsg[i] = (PSZ)PlugDup(g, (char*)msg);
- if (trace)
+ if (trace(1))
htrc("%s: %s, Native=%d\n", state, msg, native);
rc = SQLError(pdb->m_henv, pdb->m_hdbc, hstmt, state,
@@ -932,7 +943,7 @@ bool DBX::BuildErrorMessage(ODBConn* pdb, HSTMT hstmt)
MSG(BAD_HANDLE_VAL));
m_ErrMsg[0] = (PSZ)PlugDup(g, (char*)msg);
- if (trace)
+ if (trace(1))
htrc("%s: rc=%hd\n", SVP(m_ErrMsg[0]), m_RC);
return true;
@@ -941,7 +952,7 @@ bool DBX::BuildErrorMessage(ODBConn* pdb, HSTMT hstmt)
} else
m_ErrMsg[0] = "No connexion address provided";
- if (trace)
+ if (trace(1))
htrc("%s: rc=%hd (%s)\n", SVP(m_Msg), m_RC, SVP(m_ErrMsg[0]));
return true;
@@ -1004,7 +1015,7 @@ bool ODBConn::Check(RETCODE rc)
{
switch (rc) {
case SQL_SUCCESS_WITH_INFO:
- if (trace) {
+ if (trace(1)) {
DBX x(rc);
if (x.BuildErrorMessage(this, m_hstmt))
@@ -1223,7 +1234,7 @@ void ODBConn::AllocConnect(DWORD Options)
if ((signed)m_LoginTimeout >= 0) {
rc = SQLSetConnectOption(m_hdbc, SQL_LOGIN_TIMEOUT, m_LoginTimeout);
- if (trace && rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
+ if (trace(1) && rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
htrc("Warning: Failure setting login timeout\n");
} // endif Timeout
@@ -1231,7 +1242,7 @@ void ODBConn::AllocConnect(DWORD Options)
if (!m_Updatable) {
rc = SQLSetConnectOption(m_hdbc, SQL_ACCESS_MODE, SQL_MODE_READ_ONLY);
- if (trace && rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
+ if (trace(1) && rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
htrc("Warning: Failure setting read only access mode\n");
} // endif
@@ -1385,7 +1396,7 @@ void ODBConn::GetConnectInfo()
else
m_Updatable = false;
- if (trace)
+ if (trace(1))
htrc("Warning: data source is readonly\n");
} else // Make data source is !Updatable
@@ -1397,7 +1408,7 @@ void ODBConn::GetConnectInfo()
rc = SQLGetInfo(m_hdbc, SQL_IDENTIFIER_QUOTE_CHAR,
m_IDQuoteChar, sizeof(m_IDQuoteChar), &nResult);
- if (trace)
+ if (trace(1))
htrc("DBMS: %s, Version: %s, rc=%d\n",
GetStringInfo(SQL_DBMS_NAME), GetStringInfo(SQL_DBMS_VER), rc);
@@ -1447,7 +1458,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols)
OnSetOptions(hstmt);
b = true;
- if (trace)
+ if (trace(1))
htrc("ExecDirect hstmt=%p %.256s\n", hstmt, sql);
if (m_Tdb->Srcdef) {
@@ -1510,7 +1521,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols)
ThrowDBX(m_G->Message);
} // endif tp
- if (trace)
+ if (trace(1))
htrc("Binding col=%u type=%d buf=%p len=%d slen=%p\n",
n, tp, buffer, len, colp->GetStrLen());
@@ -1523,7 +1534,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols)
} // endif pcol
} catch(DBX *x) {
- if (trace)
+ if (trace(1))
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
htrc(x->m_ErrMsg[i]);
@@ -1569,7 +1580,7 @@ int ODBConn::GetResultSize(char *sql, ODBCCOL *colp)
} catch(DBX *x) {
strcpy(m_G->Message, x->GetErrorMessage(0));
- if (trace)
+ if (trace(1))
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
htrc(x->m_ErrMsg[i]);
@@ -1610,7 +1621,7 @@ int ODBConn::Fetch(int pos)
} // endif m_RowsetSize
// } while (rc == SQL_STILL_EXECUTING);
- if (trace > 1)
+ if (trace(2))
htrc("Fetch: hstmt=%p RowseSize=%d rc=%d\n",
m_hstmt, m_RowsetSize, rc);
@@ -1626,7 +1637,7 @@ int ODBConn::Fetch(int pos)
m_Fetch++;
m_Rows += irc;
} catch(DBX *x) {
- if (trace)
+ if (trace(1))
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
htrc(x->m_ErrMsg[i]);
@@ -1662,7 +1673,7 @@ int ODBConn::PrepareSQL(char *sql)
m_Transact = true;
} catch(DBX *x) {
- if (trace)
+ if (trace(1))
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
htrc(x->m_ErrMsg[i]);
@@ -1693,7 +1704,7 @@ int ODBConn::PrepareSQL(char *sql)
OnSetOptions(hstmt);
b = true;
- if (trace)
+ if (trace(1))
htrc("Prepare hstmt=%p %.64s\n", hstmt, sql);
do {
@@ -1708,7 +1719,7 @@ int ODBConn::PrepareSQL(char *sql)
} while (rc == SQL_STILL_EXECUTING);
} catch(DBX *x) {
- if (trace)
+ if (trace(1))
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
htrc(x->m_ErrMsg[i]);
@@ -1881,7 +1892,7 @@ bool ODBConn::ExecSQLcommand(char *sql)
OnSetOptions(hstmt);
b = true;
- if (trace)
+ if (trace(1))
htrc("ExecSQLcommand hstmt=%p %.64s\n", hstmt, sql);
// Proceed with command execution
@@ -1908,7 +1919,7 @@ bool ODBConn::ExecSQLcommand(char *sql)
} // endif ncol
} catch(DBX *x) {
- if (trace)
+ if (trace(1))
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
htrc(x->m_ErrMsg[i]);
@@ -2250,10 +2261,10 @@ public:
return (SQLCHAR *) (m_part[i].length ? m_part[i].str : NULL);
} // end of ptr
- size_t length(uint i)
+ SQLSMALLINT length(uint i)
{
DBUG_ASSERT(i < max_parts);
- return m_part[i].length;
+ return (SQLSMALLINT)m_part[i].length;
} // end of length
}; // end of class SQLQualifiedName
@@ -2394,7 +2405,7 @@ int ODBConn::GetCatInfo(CATPARM *cap)
if ((rc = SQLFetch(hstmt)) == SQL_NO_DATA_FOUND)
break;
else if (rc != SQL_SUCCESS) {
- if (trace > 1 || (trace && rc != SQL_SUCCESS_WITH_INFO)) {
+ if (trace(2) || (trace(1) && rc != SQL_SUCCESS_WITH_INFO)) {
UCHAR msg[SQL_MAX_MESSAGE_LENGTH + 1];
UCHAR state[SQL_SQLSTATE_SIZE + 1];
RETCODE erc;
@@ -2427,7 +2438,7 @@ int ODBConn::GetCatInfo(CATPARM *cap)
else if (vlen[n] == SQL_NULL_DATA)
pval[n]->SetNull(true);
else if (crp->Type == TYPE_STRING/* && vlen[n] != SQL_NULL_DATA*/)
- pval[n]->SetValue_char(pbuf[n], vlen[n]);
+ pval[n]->SetValue_char(pbuf[n], (int)vlen[n]);
else
pval[n]->SetNull(false);
@@ -2466,7 +2477,7 @@ int ODBConn::GetCatInfo(CATPARM *cap)
irc = (int)crow;
} catch(DBX *x) {
- if (trace)
+ if (trace(1))
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
htrc(x->m_ErrMsg[i]);
@@ -2605,12 +2616,12 @@ void ODBConn::Close()
rc = SQLDisconnect(m_hdbc);
- if (trace && rc != SQL_SUCCESS)
+ if (trace(1) && rc != SQL_SUCCESS)
htrc("Error: SQLDisconnect rc=%d\n", rc);
rc = SQLFreeConnect(m_hdbc);
- if (trace && rc != SQL_SUCCESS)
+ if (trace(1) && rc != SQL_SUCCESS)
htrc("Error: SQLFreeConnect rc=%d\n", rc);
m_hdbc = SQL_NULL_HDBC;
@@ -2619,7 +2630,7 @@ void ODBConn::Close()
if (m_henv != SQL_NULL_HENV) {
rc = SQLFreeEnv(m_henv);
- if (trace && rc != SQL_SUCCESS) // Nothing we can do
+ if (trace(1) && rc != SQL_SUCCESS) // Nothing we can do
htrc("Error: SQLFreeEnv failure ignored in Close\n");
m_henv = SQL_NULL_HENV;
diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h
index 6a0a8be8ff8..5446e0d2a07 100644
--- a/storage/connect/plgdbsem.h
+++ b/storage/connect/plgdbsem.h
@@ -362,7 +362,8 @@ enum COLUSE {U_P = 0x01, /* the projection list. */
U_IS_NULL = 0x80, /* The column has a null value */
U_SPECIAL = 0x100, /* The column is special */
U_UNSIGNED = 0x200, /* The column type is unsigned */
- U_ZEROFILL = 0x400}; /* The column is zero filled */
+ U_ZEROFILL = 0x400, /* The column is zero filled */
+ U_UUID = 0x800}; /* The column is a UUID */
/***********************************************************************/
/* DB description class and block pointer definitions. */
diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp
index f669d644637..e296553d8e2 100644
--- a/storage/connect/plgdbutl.cpp
+++ b/storage/connect/plgdbutl.cpp
@@ -1,11 +1,11 @@
/********** PlgDBUtl Fpe C++ Program Source Code File (.CPP) ***********/
/* PROGRAM NAME: PLGDBUTL */
/* ------------- */
-/* Version 4.0 */
+/* Version 4.1 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 1998-2017 */
+/* (C) Copyright to the author Olivier BERTRAND 1998-2018 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -215,35 +215,13 @@ int global_open(GLOBAL *g, int msgid, const char *path, int flags, int mode)
}
DllExport void SetTrc(void)
- {
+{
// If tracing is on, debug must be initialized.
debug = pfile;
- } // end of SetTrc
-
-#if 0
-/**************************************************************************/
-/* Tracing output function. */
-/**************************************************************************/
-void ptrc(char const *fmt, ...)
- {
- va_list ap;
- va_start (ap, fmt);
-
-// if (trace == 0 || (trace == 1 && !pfile) || !fmt)
-// printf("In %s wrong trace=%d pfile=%p fmt=%p\n",
-// __FILE__, trace, pfile, fmt);
-
- if (trace == 1)
- vfprintf(pfile, fmt, ap);
- else
- vprintf(fmt, ap);
-
- va_end (ap);
- } // end of ptrc
-#endif // 0
+} // end of SetTrc
/**************************************************************************/
-/* Allocate the result structure that will contain result data. */
+/* SubAllocate the result structure that will contain result data. */
/**************************************************************************/
PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
int *buftyp, XFLD *fldtyp,
@@ -307,7 +285,7 @@ PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
else
crp->Kdata = NULL;
- if (trace)
+ if (trace(1))
htrc("Column(%d) %s type=%d len=%d value=%p\n",
crp->Ncol, crp->Name, crp->Type, crp->Length, crp->Kdata);
@@ -475,7 +453,7 @@ bool PlugEvalLike(PGLOBAL g, LPCSTR strg, LPCSTR pat, bool ci)
char *tp, *sp;
bool b;
- if (trace)
+ if (trace(2))
htrc("LIKE: strg='%s' pattern='%s'\n", strg, pat);
if (ci) { /* Case insensitive test */
@@ -541,10 +519,10 @@ bool EvalLikePattern(LPCSTR sp, LPCSTR tp)
{
LPSTR p;
char c;
- int n;
+ ssize_t n;
bool b, t = false;
- if (trace)
+ if (trace(2))
htrc("Eval Like: sp=%s tp=%s\n",
(sp) ? sp : "Null", (tp) ? tp : "Null");
@@ -582,7 +560,7 @@ bool EvalLikePattern(LPCSTR sp, LPCSTR tp)
else
n = strlen(tp); /* Get length of pattern head */
- if (trace)
+ if (trace(2))
htrc(" testing: t=%d sp=%s tp=%s p=%p\n", t, sp, tp, p);
if (n > (signed)strlen(sp)) /* If head is longer than strg */
@@ -628,7 +606,7 @@ bool EvalLikePattern(LPCSTR sp, LPCSTR tp)
b = !strcmp(sp, tp);
} /* endif p */
- if (trace)
+ if (trace(2))
htrc(" done: b=%d n=%d sp=%s tp=%s\n",
b, n, (sp) ? sp : "Null", tp);
@@ -668,7 +646,7 @@ char *MakeEscape(PGLOBAL g, char* str, char q)
/***********************************************************************/
void PlugConvertConstant(PGLOBAL g, void* & value, short& type)
{
- if (trace)
+ if (trace(1))
htrc("PlugConvertConstant: value=%p type=%hd\n", value, type);
if (type != TYPE_XOBJECT) {
@@ -688,7 +666,7 @@ PDTP MakeDateFormat(PGLOBAL g, PCSZ dfmt, bool in, bool out, int flag)
int rc;
PDTP pdp = (PDTP)PlugSubAlloc(g, NULL, sizeof(DATPAR));
- if (trace)
+ if (trace(1))
htrc("MakeDateFormat: dfmt=%s\n", dfmt);
memset(pdp, 0, sizeof(DATPAR));
@@ -711,7 +689,7 @@ PDTP MakeDateFormat(PGLOBAL g, PCSZ dfmt, bool in, bool out, int flag)
rc = fmdflex(pdp);
pthread_mutex_unlock(&parmut);
- if (trace)
+ if (trace(1))
htrc("Done: in=%s out=%s rc=%d\n", SVP(pdp->InFmt), SVP(pdp->OutFmt), rc);
return pdp;
@@ -733,7 +711,7 @@ int ExtractDate(char *dts, PDTP pdp, int defy, int val[6])
else // assume standard MySQL date format
fmt = "%4d-%2d-%2d %2d:%2d:%2d";
- if (trace > 1)
+ if (trace(2))
htrc("ExtractDate: dts=%s fmt=%s defy=%d\n", dts, fmt, defy);
// Set default values for time only use
@@ -816,7 +794,7 @@ int ExtractDate(char *dts, PDTP pdp, int defy, int val[6])
} // endfor i
- if (trace > 1)
+ if (trace(2))
htrc("numval=%d val=(%d,%d,%d,%d,%d,%d)\n",
numval, val[0], val[1], val[2], val[3], val[4], val[5]);
@@ -833,18 +811,18 @@ FILE *PlugOpenFile(PGLOBAL g, LPCSTR fname, LPCSTR ftype)
PFBLOCK fp;
PDBUSER dbuserp = (PDBUSER)g->Activityp->Aptr;
- if (trace) {
+ if (trace(1)) {
htrc("PlugOpenFile: fname=%s ftype=%s\n", fname, ftype);
htrc("dbuserp=%p\n", dbuserp);
} // endif trace
if ((fop= global_fopen(g, MSGID_OPEN_MODE_STRERROR, fname, ftype)) != NULL) {
- if (trace)
+ if (trace(1))
htrc(" fop=%p\n", fop);
fp = (PFBLOCK)PlugSubAlloc(g, NULL, sizeof(FBLOCK));
- if (trace)
+ if (trace(1))
htrc(" fp=%p\n", fp);
// fname may be in volatile memory such as stack
@@ -857,7 +835,7 @@ FILE *PlugOpenFile(PGLOBAL g, LPCSTR fname, LPCSTR ftype)
dbuserp->Openlist = fp;
} /* endif fop */
- if (trace)
+ if (trace(1))
htrc(" returning fop=%p\n", fop);
return (fop);
@@ -888,7 +866,7 @@ int PlugCloseFile(PGLOBAL g, PFBLOCK fp, bool all)
{
int rc = 0;
- if (trace)
+ if (trace(1))
htrc("PlugCloseFile: fp=%p count=%hd type=%hd\n",
fp, ((fp) ? fp->Count : 0), ((fp) ? fp->Type : 0));
@@ -1050,7 +1028,7 @@ int GetIniSize(char *section, char *key, char *def, char *ini)
n *= 1024;
} // endswitch c
- if (trace)
+ if (trace(1))
htrc("GetIniSize: key=%s buff=%s i=%d n=%d\n", key, buff, i, n);
return n;
@@ -1086,7 +1064,7 @@ DllExport PSZ GetIniString(PGLOBAL g, void *mp, LPCSTR sec, LPCSTR key,
p = (PSZ)PlugSubAlloc(g, mp, n + 1);
- if (trace)
+ if (trace(1))
htrc("GetIniString: sec=%s key=%s buf=%s\n", sec, key, buf);
strcpy(p, buf);
@@ -1237,7 +1215,7 @@ char *GetExceptionDesc(PGLOBAL g, unsigned int e)
/* so it can be freed at the normal or error query completion. */
/***********************************************************************/
void *PlgDBalloc(PGLOBAL g, void *area, MBLOCK& mp)
- {
+{
//bool b;
size_t maxsub, minsub;
void *arp = (area) ? area : g->Sarea;
@@ -1253,7 +1231,7 @@ void *PlgDBalloc(PGLOBAL g, void *area, MBLOCK& mp)
// done to check whether the block is already there.
// b = mp.Sub;
mp.Sub = false; // Restrict suballocation to one quarter
- } // endif Memp
+ } // endif Memp
// Suballoc when possible if mp.Sub is initially true, but leaving
// a minimum amount of storage for future operations such as the
@@ -1263,35 +1241,40 @@ void *PlgDBalloc(PGLOBAL g, void *area, MBLOCK& mp)
maxsub = (pph->FreeBlk < minsub) ? 0 : pph->FreeBlk - minsub;
mp.Sub = mp.Size <= ((mp.Sub) ? maxsub : (maxsub >> 2));
- if (trace > 1)
- htrc("PlgDBalloc: in %p size=%d used=%d free=%d sub=%d\n",
- arp, mp.Size, pph->To_Free, pph->FreeBlk, mp.Sub);
+ if (trace(2))
+ htrc("PlgDBalloc: in %p size=%d used=%d free=%d sub=%d\n",
+ arp, mp.Size, pph->To_Free, pph->FreeBlk, mp.Sub);
- if (!mp.Sub) {
+ if (!mp.Sub) {
// For allocations greater than one fourth of remaining storage
// in the area, do allocate from virtual storage.
+ const char*v = "malloc";
#if defined(__WIN__)
- if (mp.Size >= BIGMEM)
- mp.Memp = VirtualAlloc(NULL, mp.Size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
- else
+ if (mp.Size >= BIGMEM) {
+ v = "VirtualAlloc";
+ mp.Memp = VirtualAlloc(NULL, mp.Size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+ } else
#endif
mp.Memp = malloc(mp.Size);
- if (!mp.Inlist && mp.Memp) {
+ if (trace(8))
+ htrc("PlgDBalloc: %s(%d) at %p\n", v, mp.Size, mp.Memp);
+
+ if (!mp.Inlist && mp.Memp) {
// New allocated block, put it in the memory block chain.
PDBUSER dbuserp = (PDBUSER)g->Activityp->Aptr;
mp.Next = dbuserp->Memlist;
dbuserp->Memlist = &mp;
mp.Inlist = true;
- } // endif mp
+ } // endif mp
} else
// Suballocating is Ok.
mp.Memp = PlugSubAlloc(g, area, mp.Size);
return mp.Memp;
- } // end of PlgDBalloc
+} // end of PlgDBalloc
/***********************************************************************/
/* PlgDBrealloc: reallocates memory conditionally. */
@@ -1306,7 +1289,7 @@ void *PlgDBrealloc(PGLOBAL g, void *area, MBLOCK& mp, size_t newsize)
// assert (mp.Memp != NULL);
#endif
- if (trace > 1)
+ if (trace(2))
htrc("PlgDBrealloc: %p size=%d sub=%d\n", mp.Memp, mp.Size, mp.Sub);
if (newsize == mp.Size)
@@ -1326,10 +1309,14 @@ void *PlgDBrealloc(PGLOBAL g, void *area, MBLOCK& mp, size_t newsize)
mp.Memp = PlugSubAlloc(g, area, newsize);
memcpy(mp.Memp, m.Memp, MY_MIN(m.Size, newsize));
PlgDBfree(m); // Free the old block
- } else if (!(mp.Memp = realloc(mp.Memp, newsize))) {
- mp = m; // Possible only if newsize > Size
- return NULL; // Failed
- } // endif's
+ } else {
+ if (!(mp.Memp = realloc(mp.Memp, newsize))) {
+ mp = m; // Possible only if newsize > Size
+ return NULL; // Failed
+ } else if (trace(8))
+ htrc("PlgDBrealloc: realloc(%ld) at %p\n", newsize, mp.Memp);
+
+ } // endif's
mp.Size = newsize;
} else if (!mp.Sub || newsize > mp.Size) {
@@ -1352,7 +1339,7 @@ void *PlgDBrealloc(PGLOBAL g, void *area, MBLOCK& mp, size_t newsize)
} // endif's
- if (trace)
+ if (trace(8))
htrc(" newsize=%d newp=%p sub=%d\n", mp.Size, mp.Memp, mp.Sub);
return mp.Memp;
@@ -1363,16 +1350,20 @@ void *PlgDBrealloc(PGLOBAL g, void *area, MBLOCK& mp, size_t newsize)
/***********************************************************************/
void PlgDBfree(MBLOCK& mp)
{
- if (trace > 1)
- htrc("PlgDBfree: %p sub=%d size=%d\n", mp.Memp, mp.Sub, mp.Size);
-
- if (!mp.Sub && mp.Memp)
+ if (!mp.Sub && mp.Memp) {
+ const char*v = "free";
#if defined(__WIN__)
- if (mp.Size >= BIGMEM)
- VirtualFree(mp.Memp, 0, MEM_RELEASE);
- else
+ if (mp.Size >= BIGMEM) {
+ v = "VirtualFree";
+ VirtualFree(mp.Memp, 0, MEM_RELEASE);
+ } else
#endif
- free(mp.Memp);
+ free(mp.Memp);
+
+ if (trace(8))
+ htrc("PlgDBfree: %s(%p) size=%d\n", v, mp.Memp, mp.Size);
+
+ } // endif mp
// Do not reset Next to avoid cutting the Mblock chain
mp.Memp = NULL;
@@ -1384,7 +1375,7 @@ void PlgDBfree(MBLOCK& mp)
/* Program for sub-allocating one item in a storage area. */
/* Note: This function is equivalent to PlugSubAlloc except that in */
/* case of insufficient memory, it returns NULL instead of doing a */
-/* long jump. The caller must test the return value for error. */
+/* throw. The caller must test the return value for error. */
/***********************************************************************/
void *PlgDBSubAlloc(PGLOBAL g, void *memp, size_t size)
{
@@ -1400,7 +1391,7 @@ void *PlgDBSubAlloc(PGLOBAL g, void *memp, size_t size)
size = ((size + 7) / 8) * 8; /* Round up size to multiple of 8 */
pph = (PPOOLHEADER)memp;
- if (trace > 1)
+ if (trace(16))
htrc("PlgDBSubAlloc: memp=%p size=%d used=%d free=%d\n",
memp, size, pph->To_Free, pph->FreeBlk);
@@ -1409,7 +1400,7 @@ void *PlgDBSubAlloc(PGLOBAL g, void *memp, size_t size)
"Not enough memory in Work area for request of %d (used=%d free=%d)",
(int) size, pph->To_Free, pph->FreeBlk);
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
return NULL;
@@ -1422,7 +1413,7 @@ void *PlgDBSubAlloc(PGLOBAL g, void *memp, size_t size)
pph->To_Free += size; // New offset of pool free block
pph->FreeBlk -= size; // New size of pool free block
- if (trace > 1)
+ if (trace(16))
htrc("Done memp=%p used=%d free=%d\n",
memp, pph->To_Free, pph->FreeBlk);
@@ -1453,7 +1444,7 @@ void PlugPutOut(PGLOBAL g, FILE *f, short t, void *v, uint n)
{
char m[64];
- if (trace)
+ if (trace(1))
htrc("PUTOUT: f=%p t=%d v=%p n=%d\n", f, t, v, n);
if (!v)
diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp
index 7b408870238..887527e38ab 100644
--- a/storage/connect/plugutil.cpp
+++ b/storage/connect/plugutil.cpp
@@ -136,7 +136,7 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
{
PGLOBAL g;
- if (trace > 1)
+ if (trace(2))
htrc("PlugInit: Language='%s'\n",
((!Language) ? "Null" : (char*)Language));
@@ -205,7 +205,7 @@ LPSTR PlugRemoveType(LPSTR pBuff, LPCSTR FileName)
_splitpath(FileName, drive, direc, fname, ftype);
- if (trace > 1) {
+ if (trace(2)) {
htrc("after _splitpath: FileName=%s\n", FileName);
htrc("drive=%s dir=%s fname=%s ext=%s\n",
SVP(drive), direc, fname, ftype);
@@ -213,7 +213,7 @@ LPSTR PlugRemoveType(LPSTR pBuff, LPCSTR FileName)
_makepath(pBuff, drive, direc, fname, "");
- if (trace > 1)
+ if (trace(2))
htrc("buff='%s'\n", pBuff);
return pBuff;
@@ -246,7 +246,7 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath)
char *drive = NULL, *defdrv = NULL;
#endif
- if (trace > 1)
+ if (trace(2))
htrc("prefix=%s fn=%s path=%s\n", prefix, FileName, defpath);
if (!strncmp(FileName, "//", 2) || !strncmp(FileName, "\\\\", 2)) {
@@ -263,7 +263,7 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath)
#if !defined(__WIN__)
if (*FileName == '~') {
if (_fullpath(pBuff, FileName, _MAX_PATH)) {
- if (trace > 1)
+ if (trace(2))
htrc("pbuff='%s'\n", pBuff);
return pBuff;
@@ -298,7 +298,7 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath)
_splitpath(tmpdir, defdrv, defdir, NULL, NULL);
- if (trace > 1) {
+ if (trace(2)) {
htrc("after _splitpath: FileName=%s\n", FileName);
#if defined(__WIN__)
htrc("drive=%s dir=%s fname=%s ext=%s\n", drive, direc, fname, ftype);
@@ -325,11 +325,11 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath)
_makepath(newname, drive, direc, fname, ftype);
- if (trace > 1)
+ if (trace(2))
htrc("newname='%s'\n", newname);
if (_fullpath(pBuff, newname, _MAX_PATH)) {
- if (trace > 1)
+ if (trace(2))
htrc("pbuff='%s'\n", pBuff);
return pBuff;
@@ -470,7 +470,7 @@ bool AllocSarea(PGLOBAL g, uint size)
#if defined(DEVELOPMENT)
if (true) {
#else
- if (trace) {
+ if (trace(8)) {
#endif
if (g->Sarea)
htrc("Work area of %u allocated at %p\n", size, g->Sarea);
@@ -498,7 +498,7 @@ void FreeSarea(PGLOBAL g)
#if defined(DEVELOPMENT)
if (true)
#else
- if (trace)
+ if (trace(8))
#endif
htrc("Freeing Sarea at %p size = %d\n", g->Sarea, g->Sarea_Size);
@@ -545,7 +545,7 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
size = ((size + 7) / 8) * 8; /* Round up size to multiple of 8 */
pph = (PPOOLHEADER)memp;
- if (trace > 3)
+ if (trace(16))
htrc("SubAlloc in %p size=%d used=%d free=%d\n",
memp, size, pph->To_Free, pph->FreeBlk);
@@ -556,10 +556,10 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
"Not enough memory in %s area for request of %u (used=%d free=%d)",
pname, (uint)size, pph->To_Free, pph->FreeBlk);
- if (trace)
+ if (trace(1))
htrc("PlugSubAlloc: %s\n", g->Message);
- throw 1234;
+ throw 1234;
} /* endif size OS32 code */
/*********************************************************************/
@@ -569,7 +569,7 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
pph->To_Free += (OFFSET)size; /* New offset of pool free block */
pph->FreeBlk -= (uint)size; /* New size of pool free block */
- if (trace > 3)
+ if (trace(16))
htrc("Done memp=%p used=%d free=%d\n",
memp, pph->To_Free, pph->FreeBlk);
diff --git a/storage/connect/preparse.h b/storage/connect/preparse.h
index f16624548fb..3db7a2af1cd 100644
--- a/storage/connect/preparse.h
+++ b/storage/connect/preparse.h
@@ -8,7 +8,7 @@
/***********************************************************************/
typedef struct _datpar {
const char *Format; // Points to format to decode
- char *Curp; // Points to current parsing position
+ const char *Curp; // Points to current parsing position
char *InFmt; // Start of input format
char *OutFmt; // Start of output format
int Index[8]; // Indexes of date values
diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp
index 0fb24baa785..e4f169575f8 100644
--- a/storage/connect/reldef.cpp
+++ b/storage/connect/reldef.cpp
@@ -450,7 +450,7 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
} // endswitch tc
// lrecl must be at least recln to avoid buffer overflow
- if (trace)
+ if (trace(1))
htrc("Lrecl: Calculated=%d defined=%d\n",
recln, Hc->GetIntegerOption("Lrecl"));
diff --git a/storage/connect/tabcol.cpp b/storage/connect/tabcol.cpp
index 5065d86ce6a..93de0598fe8 100644
--- a/storage/connect/tabcol.cpp
+++ b/storage/connect/tabcol.cpp
@@ -33,7 +33,7 @@ XTAB::XTAB(LPCSTR name, LPCSTR srcdef) : Name(name)
Schema = NULL;
Qualifier = NULL;
- if (trace)
+ if (trace(1))
htrc("XTAB: making new TABLE %s %s\n", Name, Srcdef);
} // end of XTAB constructor
@@ -49,7 +49,7 @@ XTAB::XTAB(PTABLE tp) : Name(tp->Name)
Schema = tp->Schema;
Qualifier = tp->Qualifier;
- if (trace)
+ if (trace(1))
htrc(" making copy TABLE %s %s\n", Name, SVP(Srcdef));
} // end of XTAB constructor
@@ -61,7 +61,7 @@ PTABLE XTAB::Link(PTABLE tab2)
{
PTABLE tabp;
- if (trace)
+ if (trace(1))
htrc("Linking tables %s... to %s\n", Name, tab2->Name);
for (tabp = this; tabp->Next; tabp = tabp->Next) ;
@@ -117,7 +117,7 @@ COLUMN::COLUMN(LPCSTR name) : Name(name)
To_Col = NULL;
Qualifier = NULL;
- if (trace)
+ if (trace(1))
htrc(" making new COLUMN %s\n", Name);
} // end of COLUMN constructor
diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp
index 5b9667a6c84..29cbbb35765 100644
--- a/storage/connect/tabdos.cpp
+++ b/storage/connect/tabdos.cpp
@@ -704,7 +704,7 @@ int TDBDOS::MakeBlockValues(PGLOBAL g)
// savmin = cdp->GetBmap();
// cdp->SetBmap(PlugSubAlloc(g, NULL, block * sizeof(int)));
- if (trace)
+ if (trace(1))
htrc("Dval(%p) Bmap(%p) col(%d) %s Block=%d lg=%d\n",
cdp->GetDval(), cdp->GetBmap(), i, cdp->GetName(), block, lg);
@@ -729,7 +729,7 @@ int TDBDOS::MakeBlockValues(PGLOBAL g)
memset(cdp->GetMax(), 0, block * lg);
} // endif Type
- if (trace)
+ if (trace(1))
htrc("min(%p) max(%p) col(%d) %s Block=%d lg=%d\n",
cdp->GetMin(), cdp->GetMax(), i, cdp->GetName(), block, lg);
@@ -901,7 +901,7 @@ bool TDBDOS::SaveBlockValues(PGLOBAL g)
"wb", (int)errno, filename);
strcat(strcat(g->Message, ": "), strerror(errno));
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
return true;
@@ -1634,7 +1634,7 @@ int TDBDOS::TestBlock(PGLOBAL g)
To_Filter = NULL; // So remove filter
} // endswitch Beval
- if (trace)
+ if (trace(1))
htrc("BF Eval Beval=%d\n", Beval);
} // endif To_BlkFil
@@ -1647,8 +1647,8 @@ int TDBDOS::TestBlock(PGLOBAL g)
/***********************************************************************/
int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
{
- int k, n, rc = RC_OK;
- bool fixed, doit, sep, b = (pxdf != NULL);
+ int k, n, rc = RC_OK;
+ bool fixed, doit, sep, b = (pxdf != NULL);
PCOL *keycols, colp;
PIXDEF xdp, sxp = NULL;
PKPDEF kdp;
@@ -1694,8 +1694,8 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
try {
// Allocate all columns that will be used by indexes.
- // This must be done before opening the table so specific
- // column initialization can be done (in particular by TDBVCT)
+ // This must be done before opening the table so specific
+ // column initialization can be done (in particular by TDBVCT)
for (n = 0, xdp = pxdf; xdp; xdp = xdp->GetNext())
for (kdp = xdp->GetToKeyParts(); kdp; kdp = kdp->GetNext()) {
if (!(colp = ColDB(g, kdp->GetName(), 0))) {
@@ -1779,7 +1779,7 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
return RC_INFO; // Error or Physical table does not exist
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
rc = RC_FX;
} catch (const char *msg) {
@@ -1902,7 +1902,7 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, volatile PIXDEF xdp, bool sorted)
} // endif brc
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
brc = true;
} catch (const char *msg) {
@@ -2001,7 +2001,7 @@ int TDBDOS::Cardinality(PGLOBAL g)
if (len >= 0) {
int rec;
- if (trace)
+ if (trace(1))
htrc("Estimating lines len=%d ending=%d/n",
len, ((PDOSDEF)To_Def)->Ending);
@@ -2018,7 +2018,7 @@ int TDBDOS::Cardinality(PGLOBAL g)
Cardinal = (len + rec - 1) / rec;
- if (trace)
+ if (trace(1))
htrc("avglen=%d MaxSize%d\n", rec, Cardinal);
} // endif len
@@ -2048,7 +2048,7 @@ int TDBDOS::GetMaxSize(PGLOBAL g)
if (len >= 0) {
int rec;
- if (trace)
+ if (trace(1))
htrc("Estimating lines len=%d ending=%d/n",
len, ((PDOSDEF)To_Def)->Ending);
@@ -2059,7 +2059,7 @@ int TDBDOS::GetMaxSize(PGLOBAL g)
rec = EstimatedLength() + ((PDOSDEF)To_Def)->Ending;
MaxSize = (len + rec - 1) / rec;
- if (trace)
+ if (trace(1))
htrc("avglen=%d MaxSize%d\n", rec, MaxSize);
} // endif len
@@ -2108,7 +2108,7 @@ bool TDBDOS::IsUsingTemp(PGLOBAL)
/***********************************************************************/
bool TDBDOS::OpenDB(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("DOS OpenDB: tdbp=%p tdb=R%d use=%d mode=%d\n",
this, Tdb_No, Use, Mode);
@@ -2184,7 +2184,7 @@ bool TDBDOS::OpenDB(PGLOBAL g)
} else
memset(To_Line, 0, linelen);
- if (trace)
+ if (trace(1))
htrc("OpenDos: R%hd mode=%d To_Line=%p\n", Tdb_No, Mode, To_Line);
if (SkipHeader(g)) // When called from CSV/FMT files
@@ -2202,7 +2202,7 @@ bool TDBDOS::OpenDB(PGLOBAL g)
/***********************************************************************/
int TDBDOS::ReadDB(PGLOBAL g)
{
- if (trace > 1)
+ if (trace(2))
htrc("DOS ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p To_Line=%p\n",
GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex, To_Line);
@@ -2227,7 +2227,7 @@ int TDBDOS::ReadDB(PGLOBAL g)
if (SetRecpos(g, recpos))
return RC_FX;
- if (trace > 1)
+ if (trace(2))
htrc("File position is now %d\n", GetRecpos());
if (Mode == MODE_READ)
@@ -2243,7 +2243,7 @@ int TDBDOS::ReadDB(PGLOBAL g)
} // endif To_Kindex
- if (trace > 1)
+ if (trace(2))
htrc(" ReadDB: this=%p To_Line=%p\n", this, To_Line);
/*********************************************************************/
@@ -2279,14 +2279,14 @@ bool TDBDOS::PrepareWriting(PGLOBAL)
/***********************************************************************/
int TDBDOS::WriteDB(PGLOBAL g)
{
- if (trace > 1)
+ if (trace(2))
htrc("DOS WriteDB: R%d Mode=%d \n", Tdb_No, Mode);
// Make the line to write
if (PrepareWriting(g))
return RC_FX;
- if (trace > 1)
+ if (trace(2))
htrc("Write: line is='%s'\n", To_Line);
// Now start the writing process
@@ -2403,7 +2403,7 @@ DOSCOL::DOSCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PCSZ am)
Dcm = (*p) ? atoi(p) : GetScale();
} // endif fmt
- if (trace)
+ if (trace(1))
htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this);
} // end of DOSCOL constructor
@@ -2518,7 +2518,7 @@ void DOSCOL::ReadColumn(PGLOBAL g)
double dval;
PTDBDOS tdbp = (PTDBDOS)To_Tdb;
- if (trace > 1)
+ if (trace(2))
htrc(
"DOS ReadColumn: col %s R%d coluse=%.4X status=%.4X buf_type=%d\n",
Name, tdbp->GetTdb_No(), ColUse, Status, Buf_Type);
@@ -2607,13 +2607,13 @@ void DOSCOL::WriteColumn(PGLOBAL g)
int i, k, len, field;
PTDBDOS tdbp = (PTDBDOS)To_Tdb;
- if (trace > 1)
+ if (trace(2))
htrc("DOS WriteColumn: col %s R%d coluse=%.4X status=%.4X\n",
Name, tdbp->GetTdb_No(), ColUse, Status);
p = tdbp->To_Line + Deplac;
- if (trace > 1)
+ if (trace(2))
htrc("Lrecl=%d deplac=%d int=%d\n", tdbp->Lrecl, Deplac, Long);
field = Long;
@@ -2630,7 +2630,7 @@ void DOSCOL::WriteColumn(PGLOBAL g)
} // endif Ftype
- if (trace > 1)
+ if (trace(2))
htrc("Long=%d field=%d coltype=%d colval=%p\n",
Long, field, Buf_Type, Value);
@@ -2703,7 +2703,7 @@ void DOSCOL::WriteColumn(PGLOBAL g)
} else // Standard CONNECT format
p2 = Value->ShowValue(Buf, field);
- if (trace)
+ if (trace(1))
htrc("new length(%p)=%d\n", p2, strlen(p2));
if ((len = strlen(p2)) > field) {
@@ -2714,7 +2714,7 @@ void DOSCOL::WriteColumn(PGLOBAL g)
if (p2[i] == '.')
p2[i] = Dsp;
- if (trace > 1)
+ if (trace(2))
htrc("buffer=%s\n", p2);
/*******************************************************************/
@@ -2724,7 +2724,7 @@ void DOSCOL::WriteColumn(PGLOBAL g)
memset(p, ' ', field);
memcpy(p, p2, len);
- if (trace > 1)
+ if (trace(2))
htrc(" col write: '%.*s'\n", len, p);
} // endif Use
@@ -2881,4 +2881,3 @@ bool DOSCOL::AddDistinctValue(PGLOBAL g)
} // end of AddDistinctValue
/* ------------------------------------------------------------------- */
-
diff --git a/storage/connect/tabdos.h b/storage/connect/tabdos.h
index 948b357dc1f..bdde37adaad 100644
--- a/storage/connect/tabdos.h
+++ b/storage/connect/tabdos.h
@@ -29,6 +29,7 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
friend class TXTFAM;
friend class DBFBASE;
friend class UNZIPUTL;
+ friend class JSONCOL;
public:
// Constructor
DOSDEF(void);
diff --git a/storage/connect/tabext.cpp b/storage/connect/tabext.cpp
index a75b373b564..64d401bef15 100644
--- a/storage/connect/tabext.cpp
+++ b/storage/connect/tabext.cpp
@@ -433,7 +433,7 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
} else
Query->Resize(len);
- if (trace)
+ if (trace(33))
htrc("Query=%s\n", Query->GetStr());
return false;
@@ -527,7 +527,7 @@ bool TDBEXT::MakeCommand(PGLOBAL g)
return true;
} // endif p
- if (trace)
+ if (trace(33))
htrc("Command=%s\n", stmt);
Query = new(g)STRING(g, 0, stmt);
@@ -585,7 +585,7 @@ EXTCOL::EXTCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
tdbp->SetColumns(this);
} // endif cprec
- if (trace)
+ if (trace(1))
htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this);
// Set additional remote access method information for column.
diff --git a/storage/connect/tabfix.cpp b/storage/connect/tabfix.cpp
index a78d5861e53..1969fd4465f 100644
--- a/storage/connect/tabfix.cpp
+++ b/storage/connect/tabfix.cpp
@@ -291,7 +291,7 @@ bool TDBFIX::IsUsingTemp(PGLOBAL)
/***********************************************************************/
bool TDBFIX::OpenDB(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("FIX OpenDB: tdbp=%p tdb=R%d use=%d key=%p mode=%d Ftype=%d\n",
this, Tdb_No, Use, To_Key_Col, Mode, Ftype);
@@ -345,7 +345,7 @@ bool TDBFIX::OpenDB(PGLOBAL g)
/*********************************************************************/
To_BlkFil = InitBlockFilter(g, To_Filter);
- if (trace)
+ if (trace(1))
htrc("OpenFix: R%hd mode=%d BlkFil=%p\n", Tdb_No, Mode, To_BlkFil);
/*********************************************************************/
@@ -474,7 +474,7 @@ void BINCOL::ReadColumn(PGLOBAL g)
int rc;
PTDBFIX tdbp = (PTDBFIX)To_Tdb;
- if (trace > 1)
+ if (trace(2))
htrc("BIN ReadColumn: col %s R%d coluse=%.4X status=%.4X buf_type=%d\n",
Name, tdbp->GetTdb_No(), ColUse, Status, Buf_Type);
@@ -565,7 +565,7 @@ void BINCOL::WriteColumn(PGLOBAL g)
longlong n;
PTDBFIX tdbp = (PTDBFIX)To_Tdb;
- if (trace) {
+ if (trace(1)) {
htrc("BIN WriteColumn: col %s R%d coluse=%.4X status=%.4X",
Name, tdbp->GetTdb_No(), ColUse, Status);
htrc(" Lrecl=%d\n", tdbp->Lrecl);
diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp
index 516601a5eb4..63fa2a63668 100644
--- a/storage/connect/tabfmt.cpp
+++ b/storage/connect/tabfmt.cpp
@@ -185,7 +185,7 @@ PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info)
mxr = MY_MAX(0, tdp->Maxerr);
- if (trace)
+ if (trace(1))
htrc("File %s Sep=%c Qot=%c Header=%d maxerr=%d\n",
SVP(tdp->Fn), tdp->Sep, tdp->Qot, tdp->Header, tdp->Maxerr);
@@ -379,7 +379,7 @@ PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info)
skip: ; // Skip erroneous line
} // endfor num_read
- if (trace) {
+ if (trace(1)) {
htrc("imax=%d Lengths:", imax);
for (i = 0; i < imax; i++)
@@ -391,7 +391,7 @@ PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info)
tdbp->CloseDB(g);
skipit:
- if (trace)
+ if (trace(1))
htrc("CSVColumns: imax=%d hmax=%d len=%d\n",
imax, hmax, length[0]);
@@ -701,7 +701,7 @@ int TDBCSV::EstimatedLength(void)
int n = 0;
PCOLDEF cdp;
- if (trace)
+ if (trace(1))
htrc("EstimatedLength: Fields=%d Columns=%p\n", Fields, Columns);
for (cdp = To_Def->GetCols(); cdp; cdp = cdp->GetNext())
@@ -906,7 +906,7 @@ int TDBCSV::ReadBuffer(PGLOBAL g)
int i, n, len, rc = Txfp->ReadBuffer(g);
bool bad = false;
- if (trace > 1)
+ if (trace(2))
htrc("CSV: Row is '%s' rc=%d\n", To_Line, rc);
if (rc != RC_OK || !Fields)
@@ -934,7 +934,7 @@ int TDBCSV::ReadBuffer(PGLOBAL g)
if (p) {
//len = p++ - p2;
- len = p - p2 - 1;;
+ len = (int)(p - p2 - 1);
// if (Sep != ' ')
// for (; *p == ' '; p++) ; // Skip blanks
@@ -978,7 +978,7 @@ int TDBCSV::ReadBuffer(PGLOBAL g)
return RC_NF;
} else if ((p = strchr(p2, Sep)))
- len = p - p2;
+ len = (int)(p - p2);
else if (i == Fields - 1)
len = strlen(p2);
else if (Accept && Maxerr == 0) {
@@ -996,7 +996,7 @@ int TDBCSV::ReadBuffer(PGLOBAL g)
} else
len = 0;
- Offset[i] = p2 - To_Line;
+ Offset[i] = (int)(p2 - To_Line);
if (Mode != MODE_UPDATE)
Fldlen[i] = len;
@@ -1024,7 +1024,7 @@ bool TDBCSV::PrepareWriting(PGLOBAL g)
char sep[2], qot[2];
int i, nlen, oldlen = strlen(To_Line);
- if (trace > 1)
+ if (trace(2))
htrc("CSV WriteDB: R%d Mode=%d key=%p link=%p\n",
Tdb_No, Mode, To_Key_Col, To_Link);
@@ -1090,7 +1090,7 @@ bool TDBCSV::PrepareWriting(PGLOBAL g)
To_Line[nlen] = '\0';
} // endif
- if (trace > 1)
+ if (trace(2))
htrc("Write: line is=%s", To_Line);
return false;
@@ -1118,7 +1118,7 @@ int TDBCSV::CheckWrite(PGLOBAL g)
{
int maxlen, n, nlen = (Fields - 1);
- if (trace > 1)
+ if (trace(2))
htrc("CheckWrite: R%d Mode=%d\n", Tdb_No, Mode);
// Before writing the line we must check its length
@@ -1290,7 +1290,7 @@ int TDBFMT::ReadBuffer(PGLOBAL g)
else
++Linenum;
- if (trace > 1)
+ if (trace(2))
htrc("FMT: Row %d is '%s' rc=%d\n", Linenum, To_Line, rc);
// Find the offsets and lengths of the columns for this row
@@ -1445,7 +1445,7 @@ void CSVCOL::ReadColumn(PGLOBAL g)
Deplac = tdbp->Offset[Fldnum]; // Field offset
Long = tdbp->Fldlen[Fldnum]; // Field length
- if (trace > 1)
+ if (trace(2))
htrc("CSV ReadColumn %s Fldnum=%d offset=%d fldlen=%d\n",
Name, Fldnum, Deplac, Long);
@@ -1489,13 +1489,13 @@ void CSVCOL::WriteColumn(PGLOBAL g)
int flen;
PTDBCSV tdbp = (PTDBCSV)To_Tdb;
- if (trace > 1)
+ if (trace(2))
htrc("CSV WriteColumn: col %s R%d coluse=%.4X status=%.4X\n",
Name, tdbp->GetTdb_No(), ColUse, Status);
flen = GetLength();
- if (trace > 1)
+ if (trace(2))
htrc("Lrecl=%d Long=%d field=%d coltype=%d colval=%p\n",
tdbp->Lrecl, Long, flen, Buf_Type, Value);
@@ -1510,7 +1510,7 @@ void CSVCOL::WriteColumn(PGLOBAL g)
/*********************************************************************/
p = Value->ShowValue(buf);
- if (trace > 1)
+ if (trace(2))
htrc("new length(%p)=%d\n", p, strlen(p));
if ((signed)strlen(p) > flen) {
@@ -1522,7 +1522,7 @@ void CSVCOL::WriteColumn(PGLOBAL g)
if (p[i] == '.')
p[i] = Dsp;
- if (trace > 1)
+ if (trace(2))
htrc("buffer=%s\n", p);
/*********************************************************************/
@@ -1536,7 +1536,7 @@ void CSVCOL::WriteColumn(PGLOBAL g)
} else
strncpy(tdbp->Field[Fldnum], p, flen);
- if (trace > 1)
+ if (trace(2))
htrc(" col written: '%s'\n", p);
} // end of WriteColumn
diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp
index b6a1487955b..275b5edaeae 100644
--- a/storage/connect/tabjdbc.cpp
+++ b/storage/connect/tabjdbc.cpp
@@ -153,7 +153,7 @@ int JDBCDEF::ParseURL(PGLOBAL g, char *url, bool b)
// Tabname = GetStringCatInfo(g, "Tabname", Tabname);
} // endif
- if (trace)
+ if (trace(1))
htrc("server: %s Tabname: %s", url, Tabname);
// Now make the required URL
@@ -470,7 +470,7 @@ bool TDBJDBC::MakeInsert(PGLOBAL g)
else
Prepared = true;
- if (trace)
+ if (trace(33))
htrc("Insert=%s\n", Query->GetStr());
return false;
@@ -553,7 +553,7 @@ bool TDBJDBC::OpenDB(PGLOBAL g)
{
bool rc = true;
- if (trace)
+ if (trace(1))
htrc("JDBC OpenDB: tdbp=%p tdb=R%d use=%d mode=%d\n",
this, Tdb_No, Use, Mode);
@@ -572,7 +572,7 @@ bool TDBJDBC::OpenDB(PGLOBAL g)
if (Memory < 3) {
// Method will depend on cursor type
- if ((Rbuf = Jcp->Rewind(Query->GetStr())) < 0)
+ if ((Rbuf = Query ? Jcp->Rewind(Query->GetStr()) : 0) < 0)
if (Mode != MODE_READX) {
Jcp->Close();
return true;
@@ -605,6 +605,10 @@ bool TDBJDBC::OpenDB(PGLOBAL g)
else if (Quoted)
Quote = Jcp->GetQuoteChar();
+ if (Mode != MODE_READ && Mode != MODE_READX)
+ if (Jcp->SetUUID(g, this))
+ PushWarning(g, this, 1);
+
Use = USE_OPEN; // Do it now in case we are recursively called
/*********************************************************************/
@@ -767,7 +771,7 @@ bool TDBJDBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
Mode = MODE_READ;
} // endif's op
- if (trace)
+ if (trace(33))
htrc("JDBC ReadKey: Query=%s\n", Query->GetStr());
rc = Jcp->ExecuteQuery((char*)Query->GetStr());
@@ -783,7 +787,7 @@ int TDBJDBC::ReadDB(PGLOBAL g)
{
int rc;
- if (trace > 1)
+ if (trace(2))
htrc("JDBC ReadDB: R%d Mode=%d\n", GetTdb_No(), Mode);
if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
@@ -836,7 +840,7 @@ int TDBJDBC::ReadDB(PGLOBAL g)
} // endif placed
- if (trace > 1)
+ if (trace(2))
htrc(" Read: Rbuf=%d rc=%d\n", Rbuf, rc);
return rc;
@@ -897,7 +901,7 @@ int TDBJDBC::WriteDB(PGLOBAL g)
Query->RepLast(')');
- if (trace > 1)
+ if (trace(2))
htrc("Inserting: %s\n", Query->GetStr());
rc = Jcp->ExecuteUpdate(Query->GetStr());
@@ -925,7 +929,7 @@ int TDBJDBC::DeleteDB(PGLOBAL g, int irc)
AftRows = Jcp->m_Aff;
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
PushWarning(g, this, 0); // 0 means a Note
@@ -946,14 +950,14 @@ void TDBJDBC::CloseDB(PGLOBAL g)
if (Jcp)
Jcp->Close();
- if (trace)
+ if (trace(1))
htrc("JDBC CloseDB: closing %s\n", Name);
if (!Werr &&
(Mode == MODE_INSERT || Mode == MODE_UPDATE || Mode == MODE_DELETE)) {
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
PushWarning(g, this, 0); // 0 means a Note
@@ -970,6 +974,7 @@ void TDBJDBC::CloseDB(PGLOBAL g)
JDBCCOL::JDBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
: EXTCOL(cdp, tdbp, cprec, i, am)
{
+ uuid = false;
} // end of JDBCCOL constructor
/***********************************************************************/
@@ -977,6 +982,7 @@ JDBCCOL::JDBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
/***********************************************************************/
JDBCCOL::JDBCCOL(void) : EXTCOL()
{
+ uuid = false;
} // end of JDBCCOL constructor
/***********************************************************************/
@@ -985,12 +991,11 @@ JDBCCOL::JDBCCOL(void) : EXTCOL()
/***********************************************************************/
JDBCCOL::JDBCCOL(JDBCCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp)
{
+ uuid = col1->uuid;
} // end of JDBCCOL copy constructor
/***********************************************************************/
-/* ReadColumn: when SQLFetch is used there is nothing to do as the */
-/* column buffer was bind to the record set. This is also the case */
-/* when calculating MaxSize (Bufp is NULL even when Rows is not). */
+/* ReadColumn: retrieve the column value via the JDBC driver. */
/***********************************************************************/
void JDBCCOL::ReadColumn(PGLOBAL g)
{
@@ -1117,7 +1122,7 @@ bool TDBXJDC::OpenDB(PGLOBAL g)
{
bool rc = false;
- if (trace)
+ if (trace(1))
htrc("JDBC OpenDB: tdbp=%p tdb=R%d use=%d mode=%d\n",
this, Tdb_No, Use, Mode);
diff --git a/storage/connect/tabjdbc.h b/storage/connect/tabjdbc.h
index d422ed26ef2..078129a14e3 100644
--- a/storage/connect/tabjdbc.h
+++ b/storage/connect/tabjdbc.h
@@ -101,6 +101,7 @@ protected:
/***********************************************************************/
class JDBCCOL : public EXTCOL {
friend class TDBJDBC;
+ friend class JDBConn;
public:
// Constructors
JDBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am = "JDBC");
@@ -119,6 +120,7 @@ protected:
JDBCCOL(void);
// Members
+ bool uuid; // For PostgreSQL
}; // end of class JDBCCOL
/***********************************************************************/
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index 8778b7d4b47..9e4f5ab987d 100644
--- a/storage/connect/tabjson.cpp
+++ b/storage/connect/tabjson.cpp
@@ -54,16 +54,16 @@
USETEMP UseTemp(void);
char *GetJsonNull(void);
-typedef struct _jncol {
- struct _jncol *Next;
- char *Name;
- char *Fmt;
- int Type;
- int Len;
- int Scale;
- bool Cbn;
- bool Found;
-} JCOL, *PJCL;
+//typedef struct _jncol {
+// struct _jncol *Next;
+// char *Name;
+// char *Fmt;
+// int Type;
+// int Len;
+// int Scale;
+// bool Cbn;
+// bool Found;
+//} JCOL, *PJCL;
/***********************************************************************/
/* JSONColumns: construct the result blocks containing the description */
@@ -76,26 +76,13 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
FLD_LENGTH, FLD_SCALE, FLD_NULL, FLD_FORMAT};
static unsigned int length[] = {0, 6, 8, 10, 10, 6, 6, 0};
- char *p, colname[65], fmt[129];
- int i, j, lvl, n = 0;
+ int i, n = 0;
int ncol = sizeof(buftyp) / sizeof(int);
- bool mgo = (GetTypeID(topt->type) == TAB_MONGO);
- PCSZ sep, level;
- PVAL valp;
- JCOL jcol;
- PJCL jcp, fjcp = NULL, pjcp = NULL;
- PJPR *jrp, jpp;
- PJSON jsp;
- PJVAL jvp;
- PJOB row;
- PJDEF tdp;
- TDBJSN *tjnp = NULL;
- PJTDB tjsp = NULL;
+ PJCL jcp;
+ JSONDISC *pjdc = NULL;
PQRYRES qrp;
PCOLRES crp;
- jcol.Name = jcol.Fmt = NULL;
-
if (info) {
length[0] = 128;
length[7] = 256;
@@ -107,20 +94,100 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
return NULL;
} // endif Multiple
- /*********************************************************************/
- /* Open the input file. */
+ pjdc = new(g) JSONDISC(g, length);
+
+ if (!(n = pjdc->GetColumns(g, db, dsn, topt)))
+ return NULL;
+
+ skipit:
+ if (trace(1))
+ htrc("JSONColumns: n=%d len=%d\n", n, length[0]);
+
+ /*********************************************************************/
+ /* Allocate the structures used to refer to the result set. */
+ /*********************************************************************/
+ qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
+ buftyp, fldtyp, length, false, false);
+
+ crp = qrp->Colresp->Next->Next->Next->Next->Next->Next;
+ crp->Name = "Nullable";
+ crp->Next->Name = "Jpath";
+
+ if (info || !qrp)
+ return qrp;
+
+ qrp->Nblin = n;
+
/*********************************************************************/
- level = GetStringTableOption(g, topt, "Level", NULL);
+ /* Now get the results into blocks. */
+ /*********************************************************************/
+ for (i = 0, jcp = pjdc->fjcp; jcp; i++, jcp = jcp->Next) {
+ if (jcp->Type == TYPE_UNKNOWN)
+ jcp->Type = TYPE_STRING; // Void column
+
+ crp = qrp->Colresp; // Column Name
+ crp->Kdata->SetValue(jcp->Name, i);
+ crp = crp->Next; // Data Type
+ crp->Kdata->SetValue(jcp->Type, i);
+ crp = crp->Next; // Type Name
+ crp->Kdata->SetValue(GetTypeName(jcp->Type), i);
+ crp = crp->Next; // Precision
+ crp->Kdata->SetValue(jcp->Len, i);
+ crp = crp->Next; // Length
+ crp->Kdata->SetValue(jcp->Len, i);
+ crp = crp->Next; // Scale (precision)
+ crp->Kdata->SetValue(jcp->Scale, i);
+ crp = crp->Next; // Nullable
+ crp->Kdata->SetValue(jcp->Cbn ? 1 : 0, i);
+ crp = crp->Next; // Field format
+
+ if (crp->Kdata)
+ crp->Kdata->SetValue(jcp->Fmt, i);
+
+ } // endfor i
+
+ /*********************************************************************/
+ /* Return the result pointer. */
+ /*********************************************************************/
+ return qrp;
+ } // end of JSONColumns
+
+/* -------------------------- Class JSONDISC ------------------------- */
+
+/***********************************************************************/
+/* Class used to get the columns of a JSON table. */
+/***********************************************************************/
+JSONDISC::JSONDISC(PGLOBAL g, uint *lg)
+{
+ length = lg;
+ jcp = fjcp = pjcp = NULL;
+ tjnp = NULL;
+ jpp = NULL;
+ tjsp = NULL;
+ jsp = NULL;
+ row = NULL;
+ sep = NULL;
+ i = n = bf = ncol = lvl = 0;
+ all = false;
+} // end of JSONDISC constructor
+
+int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
+{
+ bool mgo = (GetTypeID(topt->type) == TAB_MONGO);
+ PCSZ level = GetStringTableOption(g, topt, "Level", NULL);
if (level) {
lvl = atoi(level);
lvl = (lvl > 16) ? 16 : lvl;
- } else
+ } else
lvl = 0;
sep = GetStringTableOption(g, topt, "Separator", ".");
- tdp = new(g) JSONDEF;
+ /*********************************************************************/
+ /* Open the input file. */
+ /*********************************************************************/
+ tdp = new(g) JSONDEF;
#if defined(ZIP_SUPPORT)
tdp->Entry = GetStringTableOption(g, topt, "Entry", NULL);
tdp->Zipped = GetBooleanTableOption(g, topt, "Zipped", false);
@@ -128,23 +195,23 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
tdp->Fn = GetStringTableOption(g, topt, "Filename", NULL);
if (!(tdp->Database = SetPath(g, db)))
- return NULL;
+ return 0;
- tdp->Objname = GetStringTableOption(g, topt, "Object", NULL);
- tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0;
- tdp->Pretty = GetIntegerTableOption(g, topt, "Pretty", 2);
+ tdp->Objname = GetStringTableOption(g, topt, "Object", NULL);
+ tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0;
+ tdp->Pretty = GetIntegerTableOption(g, topt, "Pretty", 2);
tdp->Xcol = GetStringTableOption(g, topt, "Expand", NULL);
tdp->Accept = GetBooleanTableOption(g, topt, "Accept", false);
tdp->Uri = (dsn && *dsn ? dsn : NULL);
if (!tdp->Fn && !tdp->Uri) {
strcpy(g->Message, MSG(MISSING_FNAME));
- return NULL;
+ return 0;
} // endif Fn
- if (trace)
- htrc("File %s objname=%s pretty=%d lvl=%d\n",
- tdp->Fn, tdp->Objname, tdp->Pretty, lvl);
+ if (trace(1))
+ htrc("File %s objname=%s pretty=%d lvl=%d\n",
+ tdp->Fn, tdp->Objname, tdp->Pretty, lvl);
if (tdp->Uri) {
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
@@ -160,34 +227,34 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
tdp->Pretty = 0;
#else // !MONGO_SUPPORT
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "MONGO");
- return NULL;
+ return 0;
#endif // !MONGO_SUPPORT
} // endif Uri
- if (tdp->Pretty == 2) {
+ if (tdp->Pretty == 2) {
if (tdp->Zipped) {
#if defined(ZIP_SUPPORT)
tjsp = new(g) TDBJSON(tdp, new(g) UNZFAM(tdp));
#else // !ZIP_SUPPORT
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
- return NULL;
+ return 0;
#endif // !ZIP_SUPPORT
- } else
- tjsp = new(g) TDBJSON(tdp, new(g) MAPFAM(tdp));
+ } else
+ tjsp = new(g) TDBJSON(tdp, new(g) MAPFAM(tdp));
- if (tjsp->MakeDocument(g))
- return NULL;
+ if (tjsp->MakeDocument(g))
+ return 0;
- jsp = (tjsp->GetDoc()) ? tjsp->GetDoc()->GetValue(0) : NULL;
- } else {
- if (!(tdp->Lrecl = GetIntegerTableOption(g, topt, "Lrecl", 0)))
+ jsp = (tjsp->GetDoc()) ? tjsp->GetDoc()->GetValue(0) : NULL;
+ } else {
+ if (!(tdp->Lrecl = GetIntegerTableOption(g, topt, "Lrecl", 0)))
if (!mgo) {
sprintf(g->Message, "LRECL must be specified for pretty=%d", tdp->Pretty);
- return NULL;
- } else
+ return 0;
+ } else
tdp->Lrecl = 8192; // Should be enough
- tdp->Ending = GetIntegerTableOption(g, topt, "Ending", CRLF);
+ tdp->Ending = GetIntegerTableOption(g, topt, "Ending", CRLF);
if (tdp->Zipped) {
#if defined(ZIP_SUPPORT)
@@ -196,36 +263,36 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
return NULL;
#endif // !ZIP_SUPPORT
- } else if (tdp->Uri) {
+ } else if (tdp->Uri) {
if (tdp->Driver && toupper(*tdp->Driver) == 'C') {
#if defined(CMGO_SUPPORT)
tjnp = new(g) TDBJSN(tdp, new(g) CMGFAM(tdp));
#else
sprintf(g->Message, "Mongo %s Driver not available", "C");
- return NULL;
+ return 0;
#endif
- } else if (tdp->Driver && toupper(*tdp->Driver) == 'J') {
+ } else if (tdp->Driver && toupper(*tdp->Driver) == 'J') {
#if defined(JAVA_SUPPORT)
tjnp = new(g) TDBJSN(tdp, new(g) JMGFAM(tdp));
#else
sprintf(g->Message, "Mongo %s Driver not available", "Java");
- return NULL;
+ return 0;
#endif
- } else { // Driver not specified
+ } else { // Driver not specified
#if defined(CMGO_SUPPORT)
tjnp = new(g) TDBJSN(tdp, new(g) CMGFAM(tdp));
#elif defined(JAVA_SUPPORT)
tjnp = new(g) TDBJSN(tdp, new(g) JMGFAM(tdp));
#else
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "MONGO");
- return NULL;
+ return 0;
#endif
} // endif Driver
- } else
+ } else
tjnp = new(g) TDBJSN(tdp, new(g) DOSFAM(tdp));
- tjnp->SetMode(MODE_READ);
+ tjnp->SetMode(MODE_READ);
// Allocate the parse work memory
PGLOBAL G = (PGLOBAL)PlugSubAlloc(g, NULL, sizeof(GLOBAL));
@@ -237,248 +304,227 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
tjnp->SetG(G);
if (tjnp->OpenDB(g))
- return NULL;
+ return 0;
- switch (tjnp->ReadDB(g)) {
- case RC_EF:
- strcpy(g->Message, "Void json table");
- case RC_FX:
- goto err;
- default:
- jsp = tjnp->GetRow();
- } // endswitch ReadDB
+ switch (tjnp->ReadDB(g)) {
+ case RC_EF:
+ strcpy(g->Message, "Void json table");
+ case RC_FX:
+ goto err;
+ default:
+ jsp = tjnp->GetRow();
+ } // endswitch ReadDB
- } // endif pretty
+ } // endif pretty
- if (!(row = (jsp) ? jsp->GetObject() : NULL)) {
- strcpy(g->Message, "Can only retrieve columns from object rows");
- goto err;
- } // endif row
+ if (!(row = (jsp) ? jsp->GetObject() : NULL)) {
+ strcpy(g->Message, "Can only retrieve columns from object rows");
+ goto err;
+ } // endif row
- jcol.Next = NULL;
- jcol.Found = true;
- colname[64] = 0;
- fmt[128] = 0;
+ all = GetBooleanTableOption(g, topt, "Fullarray", false);
+ jcol.Name = jcol.Fmt = NULL;
+ jcol.Next = NULL;
+ jcol.Found = true;
+ colname[0] = 0;
if (!tdp->Uri) {
- *fmt = '$';
+ fmt[0] = '$';
fmt[1] = '.';
- p = fmt + 2;
- } else
- p = fmt;
-
- jrp = (PJPR*)PlugSubAlloc(g, NULL, sizeof(PJPR) * MY_MAX(lvl, 0));
-
- /*********************************************************************/
- /* Analyse the JSON tree and define columns. */
- /*********************************************************************/
- for (i = 1; ; i++) {
- for (jpp = row->GetFirst(); jpp; jpp = jpp->GetNext()) {
- for (j = 0; j < lvl; j++)
- jrp[j] = NULL;
-
- more:
- strncpy(colname, jpp->GetKey(), 64);
- *p = 0;
- j = 0;
- jvp = jpp->GetVal();
-
- retry:
- if ((valp = jvp ? jvp->GetValue() : NULL)) {
- jcol.Type = valp->GetType();
- jcol.Len = valp->GetValLen();
- jcol.Scale = valp->GetValPrec();
- jcol.Cbn = valp->IsNull();
- } else if (!jvp || jvp->IsNull()) {
- jcol.Type = TYPE_UNKNOWN;
- jcol.Len = jcol.Scale = 0;
- jcol.Cbn = true;
- } else if (j < lvl) {
- if (!*p)
- strcat(fmt, colname);
-
- jsp = jvp->GetJson();
-
- switch (jsp->GetType()) {
- case TYPE_JOB:
- if (!jrp[j])
- jrp[j] = jsp->GetFirst();
-
- if (*jrp[j]->GetKey() != '$') {
- strncat(strncat(fmt, sep, 128), jrp[j]->GetKey(), 128);
- strncat(strncat(colname, "_", 64), jrp[j]->GetKey(), 64);
- } // endif Key
-
- jvp = jrp[j]->GetVal();
- j++;
- break;
- case TYPE_JAR:
- if (!tdp->Xcol || stricmp(tdp->Xcol, colname)) {
- if (tdp->Uri)
- strncat(strncat(fmt, sep, 128), "0", 128);
- else
- strncat(fmt, "[0]", 128);
-
- } else
- strncat(fmt, (tdp->Uri ? sep : "[]"), 128);
-
- jvp = jsp->GetValue(0);
- break;
- default:
- sprintf(g->Message, "Logical error after %s", fmt);
- goto err;
- } // endswitch jsp
-
- goto retry;
- } else if (lvl >= 0) {
- jcol.Type = TYPE_STRING;
- jcol.Len = 256;
- jcol.Scale = 0;
- jcol.Cbn = true;
- } else
- continue;
+ bf = 2;
+ } // endif Uri
- // Check whether this column was already found
- for (jcp = fjcp; jcp; jcp = jcp->Next)
- if (!strcmp(colname, jcp->Name))
- break;
-
- if (jcp) {
- if (jcp->Type != jcol.Type) {
- if (jcp->Type == TYPE_UNKNOWN)
- jcp->Type = jcol.Type;
- else if (jcol.Type != TYPE_UNKNOWN)
- jcp->Type = TYPE_STRING;
+ /*********************************************************************/
+ /* Analyse the JSON tree and define columns. */
+ /*********************************************************************/
+ for (i = 1; ; i++) {
+ for (jpp = row->GetFirst(); jpp; jpp = jpp->GetNext()) {
+ strncpy(colname, jpp->GetKey(), 64);
+ fmt[bf] = 0;
+
+ if (Find(g, jpp->GetVal(), MY_MIN(lvl, 0)))
+ goto err;
+
+ } // endfor jpp
+
+ // Missing column can be null
+ for (jcp = fjcp; jcp; jcp = jcp->Next) {
+ jcp->Cbn |= !jcp->Found;
+ jcp->Found = false;
+ } // endfor jcp
+
+ if (tdp->Pretty != 2) {
+ // Read next record
+ switch (tjnp->ReadDB(g)) {
+ case RC_EF:
+ jsp = NULL;
+ break;
+ case RC_FX:
+ goto err;
+ default:
+ jsp = tjnp->GetRow();
+ } // endswitch ReadDB
- } // endif Type
+ } else
+ jsp = tjsp->GetDoc()->GetValue(i);
- if (*p && (!jcp->Fmt || strlen(jcp->Fmt) < strlen(fmt))) {
- jcp->Fmt = PlugDup(g, fmt);
- length[7] = MY_MAX(length[7], strlen(fmt));
- } // endif fmt
-
- jcp->Len = MY_MAX(jcp->Len, jcol.Len);
- jcp->Scale = MY_MAX(jcp->Scale, jcol.Scale);
- jcp->Cbn |= jcol.Cbn;
- jcp->Found = true;
- } else if (jcol.Type != TYPE_UNKNOWN || tdp->Accept) {
- // New column
- jcp = (PJCL)PlugSubAlloc(g, NULL, sizeof(JCOL));
- *jcp = jcol;
- jcp->Cbn |= (i > 1);
- jcp->Name = PlugDup(g, colname);
- length[0] = MY_MAX(length[0], strlen(colname));
-
- if (*p) {
- jcp->Fmt = PlugDup(g, fmt);
- length[7] = MY_MAX(length[7], strlen(fmt));
- } else
- jcp->Fmt = NULL;
-
- if (pjcp) {
- jcp->Next = pjcp->Next;
- pjcp->Next = jcp;
- } else
- fjcp = jcp;
+ if (!(row = (jsp) ? jsp->GetObject() : NULL))
+ break;
- n++;
- } // endif jcp
+ } // endfor i
- pjcp = jcp;
+ if (tdp->Pretty != 2)
+ tjnp->CloseDB(g);
- for (j = lvl - 1; j >= 0; j--)
- if (jrp[j] && (jrp[j] = jrp[j]->GetNext()))
- goto more;
+ return n;
- } // endfor jpp
+err:
+ if (tdp->Pretty != 2)
+ tjnp->CloseDB(g);
- // Missing column can be null
- for (jcp = fjcp; jcp; jcp = jcp->Next) {
- jcp->Cbn |= !jcp->Found;
- jcp->Found = false;
- } // endfor jcp
+ return 0;
+} // end of GetColumns
- if (tdp->Pretty != 2) {
- // Read next record
- switch (tjnp->ReadDB(g)) {
- case RC_EF:
- jsp = NULL;
- break;
- case RC_FX:
- goto err;
- default:
- jsp = tjnp->GetRow();
- } // endswitch ReadDB
+bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, int j)
+{
+ char *p, *pc = colname + strlen(colname);
+ int ars;
+ PJOB job;
+ PJAR jar;
+
+ if ((valp = jvp ? jvp->GetValue() : NULL)) {
+ jcol.Type = valp->GetType();
+ jcol.Len = valp->GetValLen();
+ jcol.Scale = valp->GetValPrec();
+ jcol.Cbn = valp->IsNull();
+ } else if (!jvp || jvp->IsNull()) {
+ jcol.Type = TYPE_UNKNOWN;
+ jcol.Len = jcol.Scale = 0;
+ jcol.Cbn = true;
+ } else if (j < lvl) {
+ if (!fmt[bf])
+ strcat(fmt, colname);
+
+ p = fmt + strlen(fmt);
+ jsp = jvp->GetJson();
+
+ switch (jsp->GetType()) {
+ case TYPE_JOB:
+ job = (PJOB)jsp;
+
+ for (PJPR jrp = job->GetFirst(); jrp; jrp = jrp->GetNext()) {
+ if (*jrp->GetKey() != '$') {
+ strncat(strncat(fmt, sep, 128), jrp->GetKey(), 128);
+ strncat(strncat(colname, "_", 64), jrp->GetKey(), 64);
+ } // endif Key
+
+ if (Find(g, jrp->GetVal(), j + 1))
+ return true;
+
+ *p = *pc = 0;
+ } // endfor jrp
+
+ return false;
+ case TYPE_JAR:
+ jar = (PJAR)jsp;
+
+ if (all || (tdp->Xcol && !stricmp(tdp->Xcol, colname)))
+ ars = jar->GetSize(false);
+ else
+ ars = MY_MIN(jar->GetSize(false), 1);
- } else
- jsp = tjsp->GetDoc()->GetValue(i);
+ for (int k = 0; k < ars; k++) {
+ if (!tdp->Xcol || stricmp(tdp->Xcol, colname)) {
+ sprintf(buf, "%d", k);
- if (!(row = (jsp) ? jsp->GetObject() : NULL))
- break;
+ if (tdp->Uri)
+ strncat(strncat(fmt, sep, 128), buf, 128);
+ else
+ strncat(strncat(strncat(fmt, "[", 128), buf, 128), "]", 128);
- } // endor i
+ if (all)
+ strncat(strncat(colname, "_", 64), buf, 64);
- if (tdp->Pretty != 2)
- tjnp->CloseDB(g);
+ } else
+ strncat(fmt, (tdp->Uri ? sep : "[*]"), 128);
- skipit:
- if (trace)
- htrc("JSONColumns: n=%d len=%d\n", n, length[0]);
+ if (Find(g, jar->GetValue(k), j))
+ return true;
- /*********************************************************************/
- /* Allocate the structures used to refer to the result set. */
- /*********************************************************************/
- qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
- buftyp, fldtyp, length, false, false);
+ *p = *pc = 0;
+ } // endfor k
- crp = qrp->Colresp->Next->Next->Next->Next->Next->Next;
- crp->Name = "Nullable";
- crp->Next->Name = "Jpath";
+ return false;
+ default:
+ sprintf(g->Message, "Logical error after %s", fmt);
+ return true;
+ } // endswitch Type
- if (info || !qrp)
- return qrp;
+ } else if (lvl >= 0) {
+ jcol.Type = TYPE_STRING;
+ jcol.Len = 256;
+ jcol.Scale = 0;
+ jcol.Cbn = true;
+ } else
+ return false;
- qrp->Nblin = n;
+ AddColumn(g);
+ return false;
+} // end of Find
- /*********************************************************************/
- /* Now get the results into blocks. */
- /*********************************************************************/
- for (i = 0, jcp = fjcp; jcp; i++, jcp = jcp->Next) {
- if (jcp->Type == TYPE_UNKNOWN)
- jcp->Type = TYPE_STRING; // Void column
+void JSONDISC::AddColumn(PGLOBAL g)
+{
+ bool b = fmt[bf] != 0; // True if formatted
- crp = qrp->Colresp; // Column Name
- crp->Kdata->SetValue(jcp->Name, i);
- crp = crp->Next; // Data Type
- crp->Kdata->SetValue(jcp->Type, i);
- crp = crp->Next; // Type Name
- crp->Kdata->SetValue(GetTypeName(jcp->Type), i);
- crp = crp->Next; // Precision
- crp->Kdata->SetValue(jcp->Len, i);
- crp = crp->Next; // Length
- crp->Kdata->SetValue(jcp->Len, i);
- crp = crp->Next; // Scale (precision)
- crp->Kdata->SetValue(jcp->Scale, i);
- crp = crp->Next; // Nullable
- crp->Kdata->SetValue(jcp->Cbn ? 1 : 0, i);
- crp = crp->Next; // Field format
+ // Check whether this column was already found
+ for (jcp = fjcp; jcp; jcp = jcp->Next)
+ if (!strcmp(colname, jcp->Name))
+ break;
- if (crp->Kdata)
- crp->Kdata->SetValue(jcp->Fmt, i);
+ if (jcp) {
+ if (jcp->Type != jcol.Type) {
+ if (jcp->Type == TYPE_UNKNOWN)
+ jcp->Type = jcol.Type;
+ else if (jcol.Type != TYPE_UNKNOWN)
+ jcp->Type = TYPE_STRING;
+
+ } // endif Type
+
+ if (b && (!jcp->Fmt || strlen(jcp->Fmt) < strlen(fmt))) {
+ jcp->Fmt = PlugDup(g, fmt);
+ length[7] = MY_MAX(length[7], strlen(fmt));
+ } // endif fmt
+
+ jcp->Len = MY_MAX(jcp->Len, jcol.Len);
+ jcp->Scale = MY_MAX(jcp->Scale, jcol.Scale);
+ jcp->Cbn |= jcol.Cbn;
+ jcp->Found = true;
+ } else if (jcol.Type != TYPE_UNKNOWN || tdp->Accept) {
+ // New column
+ jcp = (PJCL)PlugSubAlloc(g, NULL, sizeof(JCOL));
+ *jcp = jcol;
+ jcp->Cbn |= (i > 1);
+ jcp->Name = PlugDup(g, colname);
+ length[0] = MY_MAX(length[0], strlen(colname));
+
+ if (b) {
+ jcp->Fmt = PlugDup(g, fmt);
+ length[7] = MY_MAX(length[7], strlen(fmt));
+ } else
+ jcp->Fmt = NULL;
- } // endfor i
+ if (pjcp) {
+ jcp->Next = pjcp->Next;
+ pjcp->Next = jcp;
+ } else
+ fjcp = jcp;
- /*********************************************************************/
- /* Return the result pointer. */
- /*********************************************************************/
- return qrp;
+ n++;
+ } // endif jcp
-err:
- if (tdp->Pretty != 2)
- tjnp->CloseDB(g);
+ pjcp = jcp;
+} // end of AddColumn
- return NULL;
- } // end of JSONColumns
/* -------------------------- Class JSONDEF -------------------------- */
@@ -513,6 +559,7 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR, int poff)
Limit = GetIntCatInfo("Limit", 10);
Base = GetIntCatInfo("Base", 0) ? 1 : 0;
Sep = *GetStringCatInfo(g, "Separator", ".");
+ Accept = GetBoolCatInfo("Accept", false);
if (Uri = GetStringCatInfo(g, "Connect", NULL)) {
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
@@ -1471,6 +1518,9 @@ void JSONCOL::ReadColumn(PGLOBAL g)
if (!Tjp->SameRow || Xnod >= Tjp->SameRow)
Value->SetValue_pval(GetColumnValue(g, Tjp->Row, 0));
+ if (Xpd && Value->IsNull() && !((PJDEF)Tjp->To_Def)->Accept)
+ throw("Null expandable JSON value");
+
// Set null when applicable
if (!Nullable)
Value->SetNull(false);
@@ -1546,11 +1596,16 @@ PVAL JSONCOL::GetColumnValue(PGLOBAL g, PJSON row, int i)
/***********************************************************************/
PVAL JSONCOL::ExpandArray(PGLOBAL g, PJAR arp, int n)
{
- int ars;
+ int ars = MY_MIN(Tjp->Limit, arp->size());
PJVAL jvp;
JVALUE jval;
- ars = MY_MIN(Tjp->Limit, arp->size());
+ if (!ars) {
+ Value->Reset();
+ Value->SetNull(true);
+ Tjp->NextSame = 0;
+ return Value;
+ } // endif ars
if (!(jvp = arp->GetValue((Nodes[n].Rx = Nodes[n].Nx)))) {
strcpy(g->Message, "Logical error expanding array");
@@ -1591,14 +1646,14 @@ PVAL JSONCOL::CalculateArray(PGLOBAL g, PJAR arp, int n)
vp->Reset();
ars = MY_MIN(Tjp->Limit, arp->size());
- if (trace)
+ if (trace(1))
htrc("CalculateArray: size=%d op=%d nextsame=%d\n",
ars, op, nextsame);
for (i = 0; i < ars; i++) {
jvrp = arp->GetValue(i);
- if (trace)
+ if (trace(1))
htrc("i=%d nv=%d\n", i, nv);
if (!jvrp->IsNull() || (op == OP_CNC && GetJsonNull())) do {
@@ -1612,7 +1667,7 @@ PVAL JSONCOL::CalculateArray(PGLOBAL g, PJAR arp, int n)
} else
jvp = jvrp;
- if (trace)
+ if (trace(1))
htrc("jvp=%s null=%d\n",
jvp->GetString(g), jvp->IsNull() ? 1 : 0);
@@ -1648,7 +1703,7 @@ PVAL JSONCOL::CalculateArray(PGLOBAL g, PJAR arp, int n)
if (err)
vp->Reset();
- if (trace) {
+ if (trace(1)) {
char buf(32);
htrc("vp='%s' err=%d\n",
diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h
index 17583cba333..0341c0f8aa0 100644
--- a/storage/connect/tabjson.h
+++ b/storage/connect/tabjson.h
@@ -15,6 +15,7 @@ enum JMODE {MODE_OBJECT, MODE_ARRAY, MODE_VALUE};
typedef class JSONDEF *PJDEF;
typedef class TDBJSON *PJTDB;
typedef class JSONCOL *PJCOL;
+class TDBJSN;
/***********************************************************************/
/* The JSON tree node. Can be an Object or an Array. */
@@ -29,6 +30,47 @@ typedef struct _jnode {
int Nx; // Next to read row number
} JNODE, *PJNODE;
+typedef struct _jncol {
+ struct _jncol *Next;
+ char *Name;
+ char *Fmt;
+ int Type;
+ int Len;
+ int Scale;
+ bool Cbn;
+ bool Found;
+} JCOL, *PJCL;
+
+/***********************************************************************/
+/* Class used to get the columns of a mongo collection. */
+/***********************************************************************/
+class JSONDISC : public BLOCK {
+public:
+ // Constructor
+ JSONDISC(PGLOBAL g, uint *lg);
+
+ // Functions
+ int GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt);
+ bool Find(PGLOBAL g, PJVAL jvp, int j);
+ void AddColumn(PGLOBAL g);
+
+ // Members
+ JCOL jcol;
+ PJCL jcp, fjcp, pjcp;
+ PVAL valp;
+ PJDEF tdp;
+ TDBJSN *tjnp;
+ PJTDB tjsp;
+ PJPR jpp;
+ PJSON jsp;
+ PJOB row;
+ PCSZ sep;
+ char colname[65], fmt[129], buf[16];
+ uint *length;
+ int i, n, bf, ncol, lvl;
+ bool all;
+}; // end of JSONDISC
+
/***********************************************************************/
/* JSON table. */
/***********************************************************************/
@@ -36,13 +78,13 @@ class DllExport JSONDEF : public DOSDEF { /* Table description */
friend class TDBJSON;
friend class TDBJSN;
friend class TDBJCL;
+ friend class JSONDISC;
#if defined(CMGO_SUPPORT)
friend class CMGFAM;
#endif // CMGO_SUPPORT
#if defined(JAVA_SUPPORT)
friend class JMGFAM;
#endif // JAVA_SUPPORT
- friend PQRYRES JSONColumns(PGLOBAL, PCSZ, PCSZ, PTOS, bool);
public:
// Constructor
JSONDEF(void);
diff --git a/storage/connect/table.cpp b/storage/connect/table.cpp
index 61aefc93082..d4d3a34d67e 100644
--- a/storage/connect/table.cpp
+++ b/storage/connect/table.cpp
@@ -128,7 +128,7 @@ PCOL TDB::ColDB(PGLOBAL g, PSZ name, int num)
PCOLDEF cdp;
PCOL cp, colp = NULL, cprec = NULL;
- if (trace)
+ if (trace(1))
htrc("ColDB: am=%d colname=%s tabname=%s num=%d\n",
GetAmType(), SVP(name), Name, num);
@@ -146,7 +146,7 @@ PCOL TDB::ColDB(PGLOBAL g, PSZ name, int num)
else if (cp->GetIndex() < i)
cprec = cp;
- if (trace)
+ if (trace(1))
htrc("cdp(%d).Name=%s cp=%p\n", i, cdp->GetName(), cp);
/*****************************************************************/
@@ -159,7 +159,7 @@ PCOL TDB::ColDB(PGLOBAL g, PSZ name, int num)
else if (Mode != MODE_INSERT)
colp = InsertSpcBlk(g, cdp);
- if (trace)
+ if (trace(1))
htrc("colp=%p\n", colp);
if (name || num)
@@ -256,7 +256,7 @@ PCOL TDB::InsertSpcBlk(PGLOBAL g, PCOLDEF cdp)
/***********************************************************************/
void TDB::MarkDB(PGLOBAL, PTDB tdb2)
{
- if (trace)
+ if (trace(1))
htrc("DOS MarkDB: tdbp=%p tdb2=%p\n", this, tdb2);
} // end of MarkDB
@@ -416,7 +416,7 @@ PCOL TDBASE::ColDB(PGLOBAL g, PSZ name, int num)
PCOLDEF cdp;
PCOL cp, colp = NULL, cprec = NULL;
- if (trace)
+ if (trace(1))
htrc("ColDB: am=%d colname=%s tabname=%s num=%d\n",
GetAmType(), SVP(name), Name, num);
@@ -434,7 +434,7 @@ PCOL TDBASE::ColDB(PGLOBAL g, PSZ name, int num)
else if (cp->GetIndex() < i)
cprec = cp;
- if (trace)
+ if (trace(1))
htrc("cdp(%d).Name=%s cp=%p\n", i, cdp->GetName(), cp);
/*****************************************************************/
@@ -447,7 +447,7 @@ PCOL TDBASE::ColDB(PGLOBAL g, PSZ name, int num)
else if (Mode != MODE_INSERT)
colp = InsertSpcBlk(g, cdp);
- if (trace)
+ if (trace(1))
htrc("colp=%p\n", colp);
if (name || num)
@@ -592,7 +592,7 @@ void TDBASE::PrintAM(FILE *f, char *m)
/***********************************************************************/
void TDBASE::MarkDB(PGLOBAL, PTDB tdb2)
{
- if (trace)
+ if (trace(1))
htrc("DOS MarkDB: tdbp=%p tdb2=%p\n", this, tdb2);
} // end of MarkDB
diff --git a/storage/connect/tabmac.cpp b/storage/connect/tabmac.cpp
index a28b5d7108c..8260ab65391 100644
--- a/storage/connect/tabmac.cpp
+++ b/storage/connect/tabmac.cpp
@@ -367,13 +367,13 @@ void MACCOL::ReadColumn(PGLOBAL g)
case 11: // Description
if ((p = strstr(adp->Description, " - Packet Scheduler Miniport"))) {
strncpy(buf, adp->Description, p - adp->Description);
- i = p - adp->Description;
+ i = (int)(p - adp->Description);
strncpy(buf, adp->Description, i);
buf[i] = 0;
p = buf;
} else if ((p = strstr(adp->Description,
" - Miniport d'ordonnancement de paquets"))) {
- i = p - adp->Description;
+ i = (int)(p - adp->Description);
strncpy(buf, adp->Description, i);
buf[i] = 0;
p = buf;
diff --git a/storage/connect/tabmul.cpp b/storage/connect/tabmul.cpp
index 0967afca6cd..649fc6706c6 100644
--- a/storage/connect/tabmul.cpp
+++ b/storage/connect/tabmul.cpp
@@ -134,7 +134,7 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
PSZ filename;
int rc, n = 0;
- if (trace)
+ if (trace(1))
htrc("in InitFileName: fn[]=%d\n", FNSZ);
filename = (char*)PlugSubAlloc(g, NULL, FNSZ);
@@ -144,7 +144,7 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath());
- if (trace)
+ if (trace(1))
htrc("InitFileName: fn='%s'\n", filename);
if (Mul != 2) {
@@ -159,7 +159,7 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
if (dirp->OpenDB(g))
return true;
- if (trace && Mul == 3) {
+ if (trace(1) && Mul == 3) {
int nf = ((PTDBSDR)dirp)->FindInDir(g);
htrc("Number of files = %d\n", nf);
} // endif trace
@@ -319,7 +319,7 @@ int TDBMUL::GetMaxSize(PGLOBAL g)
int i;
int mxsz;
- if (trace)
+ if (trace(1))
htrc("TDBMUL::GetMaxSize: Filenames=%p\n", Filenames);
if (!Filenames && InitFileNames(g))
@@ -375,7 +375,7 @@ int TDBMUL::RowNumber(PGLOBAL g, bool b)
/***********************************************************************/
bool TDBMUL::OpenDB(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("MUL OpenDB: tdbp=%p tdb=R%d use=%d key=%p mode=%d\n",
this, Tdb_No, Use, To_Key_Col, Mode);
@@ -546,7 +546,7 @@ bool TDBMSD::InitFileNames(PGLOBAL g)
PSZ filename;
int rc, n = 0;
- if (trace)
+ if (trace(1))
htrc("in InitFileName: fn[]=%d\n", FNSZ);
filename = (char*)PlugSubAlloc(g, NULL, FNSZ);
@@ -556,7 +556,7 @@ bool TDBMSD::InitFileNames(PGLOBAL g)
PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath());
- if (trace)
+ if (trace(1))
htrc("InitFileName: fn='%s'\n", filename);
dirp = new(g) TDBSDR(filename);
@@ -787,7 +787,7 @@ int TDBDIR::GetMaxSize(PGLOBAL g)
/***********************************************************************/
bool TDBDIR::OpenDB(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("DIR OpenDB: tdbp=%p tdb=R%d use=%d mode=%d\n",
this, Tdb_No, Use, Mode);
@@ -985,7 +985,7 @@ void DIRCOL::SetTimeValue(PGLOBAL g, FILETIME& ftime)
/***********************************************************************/
void DIRCOL::ReadColumn(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("DIR ReadColumn: col %s R%d use=%.4X status=%.4X type=%d N=%d\n",
Name, Tdbp->GetTdb_No(), ColUse, Status, Buf_Type, N);
@@ -1452,7 +1452,7 @@ int TDBDHR::GetMaxSize(PGLOBAL g)
/***********************************************************************/
bool TDBDHR::OpenDB(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("DHR OpenDB: tdbp=%p tdb=R%d use=%d mode=%d\n",
this, Tdb_No, Use, Mode);
@@ -1589,7 +1589,7 @@ void DHRCOL::ReadColumn(PGLOBAL g)
int rc;
PTDBDHR tdbp = (PTDBDHR)To_Tdb;
- if (trace)
+ if (trace(1))
htrc("DHR ReadColumn: col %s R%d use=%.4X status=%.4X type=%d N=%d\n",
Name, tdbp->GetTdb_No(), ColUse, Status, Buf_Type, N);
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index d1e2ae69608..605b3822430 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -124,8 +124,8 @@ bool MYSQLDEF::GetServerInfo(PGLOBAL g, const char *server_name)
DBUG_RETURN(true);
} // endif server
- DBUG_PRINT("info", ("get_server_by_name returned server at %lx",
- (size_t) server));
+ DBUG_PRINT("info", ("get_server_by_name returned server at %p",
+ server));
// TODO: We need to examine which of these can really be NULL
Hostname = PlugDup(g, server->host);
@@ -203,7 +203,7 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b)
// Otherwise, straight server name,
Tabname = (b) ? GetStringCatInfo(g, "Tabname", Name) : NULL;
- if (trace)
+ if (trace(1))
htrc("server: %s TableName: %s", url, Tabname);
Server = url;
@@ -567,7 +567,7 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx)
return true;
} // endif Query
- if (trace)
+ if (trace(33))
htrc("Query=%s\n", Query->GetStr());
return false;
@@ -681,7 +681,7 @@ bool TDBMYSQL::MakeCommand(PGLOBAL g)
strlwr(strcpy(name, Name)); // Not a keyword
if ((p = strstr(qrystr, name))) {
- Query->Set(Qrystr, p - qrystr);
+ Query->Set(Qrystr, (uint)(p - qrystr));
if (qtd && *(p-1) == ' ') {
Query->Append('`');
@@ -1042,7 +1042,7 @@ int TDBMYSQL::SendCommand(PGLOBAL g)
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
PushWarning(g, this, 0); // 0 means a Note
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
if (w && Myc.ExecSQL(g, "SHOW WARNINGS") == RC_OK) {
@@ -1109,7 +1109,7 @@ bool TDBMYSQL::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
Mode = MODE_READ;
} // endif's op
- if (trace)
+ if (trace(33))
htrc("MYSQL ReadKey: Query=%s\n", Query->GetStr());
m_Rc = Myc.ExecSQL(g, Query->GetStr());
@@ -1124,7 +1124,7 @@ int TDBMYSQL::ReadDB(PGLOBAL g)
{
int rc;
- if (trace > 1)
+ if (trace(2))
htrc("MySQL ReadDB: R%d Mode=%d\n", GetTdb_No(), Mode);
if (Mode == MODE_UPDATE || Mode == MODE_DELETE)
@@ -1137,7 +1137,7 @@ int TDBMYSQL::ReadDB(PGLOBAL g)
N++;
Fetched = ((rc = Myc.Fetch(g, -1)) == RC_OK);
- if (trace > 1)
+ if (trace(2))
htrc(" Read: rc=%d\n", rc);
return rc;
@@ -1220,7 +1220,7 @@ void TDBMYSQL::CloseDB(PGLOBAL g)
Myc.Close();
} // endif Myc
- if (trace)
+ if (trace(1))
htrc("MySQL CloseDB: closing %s rc=%d\n", Name, m_Rc);
} // end of CloseDB
@@ -1248,7 +1248,7 @@ MYSQLCOL::MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
Slen = 0;
Rank = -1; // Not known yet
- if (trace)
+ if (trace(1))
htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this);
} // end of MYSQLCOL constructor
@@ -1279,7 +1279,7 @@ MYSQLCOL::MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PCSZ am)
Slen = 0;
Rank = i;
- if (trace)
+ if (trace(1))
htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this);
} // end of MYSQLCOL constructor
@@ -1409,7 +1409,7 @@ void MYSQLCOL::ReadColumn(PGLOBAL g)
tdbp->Fetched = true;
if ((buf = ((PTDBMY)To_Tdb)->Myc.GetCharField(Rank))) {
- if (trace > 1)
+ if (trace(2))
htrc("MySQL ReadColumn: name=%s buf=%s\n", Name, buf);
// TODO: have a true way to differenciate temporal values
@@ -1679,7 +1679,7 @@ MYXCOL::MYXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
MYXCOL::MYXCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PCSZ am)
: MYSQLCOL(fld, tdbp, i, am)
{
- if (trace)
+ if (trace(1))
htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this);
} // end of MYSQLCOL constructor
diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp
index 56e5e72efd6..f7bc3934fbd 100644
--- a/storage/connect/tabodbc.cpp
+++ b/storage/connect/tabodbc.cpp
@@ -289,7 +289,7 @@ void TDBODBC::SetFile(PGLOBAL g, PCSZ fn)
sprintf(Connect, MulConn, fn);
} // endif MultConn
- DBQ = (PSZ)fn;
+ DBQ = PlugDup(g, fn);
} // end of SetFile
/***********************************************************************/
@@ -538,7 +538,7 @@ bool TDBODBC::OpenDB(PGLOBAL g)
{
bool rc = true;
- if (trace)
+ if (trace(1))
htrc("ODBC OpenDB: tdbp=%p tdb=R%d use=%dmode=%d\n",
this, Tdb_No, Use, Mode);
@@ -750,7 +750,7 @@ bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
Mode = MODE_READ;
} // endif's op
- if (trace)
+ if (trace(33))
htrc("ODBC ReadKey: Query=%s\n", Query->GetStr());
Rows = Ocp->ExecDirectSQL((char*)Query->GetStr(), (PODBCCOL)Columns);
@@ -765,7 +765,7 @@ int TDBODBC::ReadDB(PGLOBAL g)
{
int rc;
- if (trace > 1)
+ if (trace(2))
htrc("ODBC ReadDB: R%d Mode=%d\n", GetTdb_No(), Mode);
if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
@@ -776,7 +776,7 @@ int TDBODBC::ReadDB(PGLOBAL g)
if (!Ocp->ExecSQLcommand(Query->GetStr())) {
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
PushWarning(g, this, 0); // 0 means a Note
@@ -817,7 +817,7 @@ int TDBODBC::ReadDB(PGLOBAL g)
} // endif Placed
- if (trace > 1)
+ if (trace(2))
htrc(" Read: Rbuf=%d rc=%d\n", Rbuf, rc);
return rc;
@@ -852,7 +852,7 @@ int TDBODBC::DeleteDB(PGLOBAL g, int irc)
if (!Ocp->ExecSQLcommand(Query->GetStr())) {
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
- if (trace)
+ if (trace(1))
htrc("%s\n", g->Message);
PushWarning(g, this, 0); // 0 means a Note
@@ -874,7 +874,7 @@ void TDBODBC::CloseDB(PGLOBAL g)
Ocp->Close();
- if (trace)
+ if (trace(1))
htrc("ODBC CloseDB: closing %s\n", Name);
} // end of CloseDB
@@ -975,7 +975,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g)
} // endif Buf_Type
- if (trace > 1) {
+ if (trace(2)) {
char buf[64];
htrc("ODBC Column %s: rows=%d buf=%p type=%d value=%s\n",
@@ -1214,7 +1214,7 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
{
bool rc = false;
- if (trace)
+ if (trace(1))
htrc("ODBC OpenDB: tdbp=%p tdb=R%d use=%dmode=%d\n",
this, Tdb_No, Use, Mode);
diff --git a/storage/connect/tabpivot.cpp b/storage/connect/tabpivot.cpp
index 76a46e6899b..da5d134f347 100644
--- a/storage/connect/tabpivot.cpp
+++ b/storage/connect/tabpivot.cpp
@@ -299,7 +299,7 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
Qryp->Nbcol += (ndif - 2);
return Qryp;
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
} catch (const char *msg) {
strcpy(g->Message, msg);
diff --git a/storage/connect/tabsys.cpp b/storage/connect/tabsys.cpp
index 7f0d9881298..f73a2b6578d 100644
--- a/storage/connect/tabsys.cpp
+++ b/storage/connect/tabsys.cpp
@@ -180,7 +180,7 @@ PTDB TDBINI::Clone(PTABS t)
/***********************************************************************/
char *TDBINI::GetSeclist(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("GetSeclist: Seclist=%p\n", Seclist);
if (!Seclist) {
@@ -267,7 +267,7 @@ bool TDBINI::OpenDB(PGLOBAL g)
if (!colp->IsSpecial()) // Not a pseudo column
colp->AllocBuf(g);
- if (trace)
+ if (trace(1))
htrc("INI OpenDB: seclist=%s seclen=%d ifile=%s\n",
Seclist, Seclen, Ifile);
@@ -287,7 +287,7 @@ int TDBINI::ReadDB(PGLOBAL)
else
Section += (strlen(Section) + 1);
- if (trace > 1)
+ if (trace(2))
htrc("INI ReadDB: section=%s N=%d\n", Section, N);
N++;
@@ -453,7 +453,7 @@ void INICOL::ReadColumn(PGLOBAL)
{
PTDBINI tdbp = (PTDBINI)To_Tdb;
- if (trace > 1)
+ if (trace(2))
htrc("INI ReadColumn: col %s R%d flag=%d\n",
Name, tdbp->GetTdb_No(), Flag);
@@ -493,7 +493,7 @@ void INICOL::WriteColumn(PGLOBAL g)
bool rc;
PTDBINI tdbp = (PTDBINI)To_Tdb;
- if (trace > 1)
+ if (trace(2))
htrc("INI WriteColumn: col %s R%d coluse=%.4X status=%.4X\n",
Name, tdbp->GetTdb_No(), ColUse, Status);
@@ -823,7 +823,7 @@ void XINCOL::WriteColumn(PGLOBAL g)
bool rc;
PTDBXIN tdbp = (PTDBXIN)To_Tdb;
- if (trace > 1)
+ if (trace(2))
htrc("XIN WriteColumn: col %s R%d coluse=%.4X status=%.4X\n",
Name, tdbp->GetTdb_No(), ColUse, Status);
diff --git a/storage/connect/tabtbl.cpp b/storage/connect/tabtbl.cpp
index 7925e8f29a8..e194568ccf8 100644
--- a/storage/connect/tabtbl.cpp
+++ b/storage/connect/tabtbl.cpp
@@ -132,7 +132,7 @@ bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR, int)
tbl = new(g) XTAB(pn, def);
tbl->SetSchema(pdb);
- if (trace)
+ if (trace(1))
htrc("TBL: Name=%s db=%s\n", tbl->GetName(), tbl->GetSchema());
// Link the blocks
@@ -436,7 +436,7 @@ int TDBTBL::RowNumber(PGLOBAL g, bool b)
/***********************************************************************/
bool TDBTBL::OpenDB(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("TBL OpenDB: tdbp=%p tdb=R%d use=%d key=%p mode=%d\n",
this, Tdb_No, Use, To_Key_Col, Mode);
@@ -475,7 +475,7 @@ bool TDBTBL::OpenDB(PGLOBAL g)
else if (((PPRXCOL)cp)->Init(g, NULL) && !Accept)
return TRUE;
- if (trace)
+ if (trace(1))
htrc("Opening subtable %s\n", Tdbp->GetName());
// Now we can safely open the table
@@ -530,7 +530,7 @@ int TDBTBL::ReadDB(PGLOBAL g)
else if (((PPRXCOL)cp)->Init(g, NULL) && !Accept)
return RC_FX;
- if (trace)
+ if (trace(1))
htrc("Opening subtable %s\n", Tdbp->GetName());
// Now we can safely open the table
@@ -555,7 +555,7 @@ int TDBTBL::ReadDB(PGLOBAL g)
/***********************************************************************/
void TBTBLK::ReadColumn(PGLOBAL)
{
- if (trace)
+ if (trace(1))
htrc("TBT ReadColumn: name=%s\n", Name);
Value->SetValue_psz((char*)((PTDBTBL)To_Tdb)->Tdbp->GetName());
@@ -575,27 +575,30 @@ pthread_handler_t ThreadOpen(void *p)
if (!my_thread_init()) {
set_current_thd(cmp->Thd);
- if (trace)
+ if (trace(1))
htrc("ThreadOpen: Thd=%d\n", cmp->Thd);
// Try to open the connection
- if (!cmp->Tap->GetTo_Tdb()->OpenDB(cmp->G)) {
- pthread_mutex_lock(&tblmut);
- if (trace)
+ pthread_mutex_lock(&tblmut);
+
+ if (!cmp->Tap->GetTo_Tdb()->OpenDB(cmp->G)) {
+// pthread_mutex_lock(&tblmut);
+ if (trace(1))
htrc("Table %s ready\n", cmp->Tap->GetName());
cmp->Ready = true;
- pthread_mutex_unlock(&tblmut);
+// pthread_mutex_unlock(&tblmut);
} else {
- pthread_mutex_lock(&tblmut);
- if (trace)
+// pthread_mutex_lock(&tblmut);
+ if (trace(1))
htrc("Opening %s failed\n", cmp->Tap->GetName());
cmp->Rc = RC_FX;
- pthread_mutex_unlock(&tblmut);
+// pthread_mutex_unlock(&tblmut);
} // endif OpenDB
- my_thread_end();
+ pthread_mutex_unlock(&tblmut);
+ my_thread_end();
} else
cmp->Rc = RC_FX;
@@ -672,7 +675,7 @@ bool TDBTBM::OpenTables(PGLOBAL g)
// Remove remote table from the local list
*ptabp = tabp->Next;
- if (trace)
+ if (trace(1))
htrc("=====> New remote table %s\n", tabp->GetName());
// Make the remote table block
@@ -698,7 +701,7 @@ bool TDBTBM::OpenTables(PGLOBAL g)
ptp = &tp->Next;
Nrc++; // Number of remote connections
} else {
- if (trace)
+ if (trace(1))
htrc("=====> Local table %s\n", tabp->GetName());
ptabp = &tabp->Next;
@@ -714,7 +717,7 @@ bool TDBTBM::OpenTables(PGLOBAL g)
/***********************************************************************/
bool TDBTBM::OpenDB(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("TBM OpenDB: tdbp=%p tdb=R%d use=%d key=%p mode=%d\n",
this, Tdb_No, Use, To_Key_Col, Mode);
@@ -762,7 +765,7 @@ bool TDBTBM::OpenDB(PGLOBAL g)
else if (((PPRXCOL)cp)->Init(g, NULL) && !Accept)
return TRUE;
- if (trace)
+ if (trace(1))
htrc("Opening subtable %s\n", Tdbp->GetName());
// Now we can safely open the table
@@ -863,7 +866,7 @@ int TDBTBM::ReadNextRemote(PGLOBAL g)
else if (((PPRXCOL)cp)->Init(g, NULL) && !Accept)
return RC_FX;
- if (trace)
+ if (trace(1))
htrc("Reading subtable %s\n", Tdbp->GetName());
return RC_OK;
diff --git a/storage/connect/tabutil.cpp b/storage/connect/tabutil.cpp
index 5d8d7c1b9f8..68b66aec31f 100644
--- a/storage/connect/tabutil.cpp
+++ b/storage/connect/tabutil.cpp
@@ -457,7 +457,7 @@ PTDB TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b)
hc->get_table()->s->option_struct->srcdef = sp;
} // endif s
- if (trace && tdbp)
+ if (trace(1) && tdbp)
htrc("Subtable %s in %s\n",
name, SVP(tdbp->GetDef()->GetDB()));
@@ -647,7 +647,7 @@ PRXCOL::PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
Pseudo = false;
Colnum = cdp->GetOffset(); // If columns are retrieved by number
- if (trace)
+ if (trace(1))
htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this);
} // end of PRXCOL constructor
@@ -732,7 +732,7 @@ void PRXCOL::Reset(void)
/***********************************************************************/
void PRXCOL::ReadColumn(PGLOBAL g)
{
- if (trace > 1)
+ if (trace(2))
htrc("PRX ReadColumn: name=%s\n", Name);
if (Colp) {
@@ -759,7 +759,7 @@ void PRXCOL::ReadColumn(PGLOBAL g)
/***********************************************************************/
void PRXCOL::WriteColumn(PGLOBAL g)
{
- if (trace > 1)
+ if (trace(2))
htrc("PRX WriteColumn: name=%s\n", Name);
if (Colp) {
diff --git a/storage/connect/tabvct.cpp b/storage/connect/tabvct.cpp
index 533986e44da..11b344ef652 100644
--- a/storage/connect/tabvct.cpp
+++ b/storage/connect/tabvct.cpp
@@ -304,7 +304,7 @@ bool TDBVCT::IsUsingTemp(PGLOBAL)
/***********************************************************************/
bool TDBVCT::OpenDB(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("VCT OpenDB: tdbp=%p tdb=R%d use=%d key=%p mode=%d\n",
this, Tdb_No, Use, To_Key_Col, Mode);
@@ -364,7 +364,7 @@ bool TDBVCT::OpenDB(PGLOBAL g)
/***********************************************************************/
int TDBVCT::ReadDB(PGLOBAL g)
{
- if (trace)
+ if (trace(1))
htrc("VCT ReadDB: R%d Mode=%d CurBlk=%d CurNum=%d key=%p link=%p Kindex=%p\n",
GetTdb_No(), Mode, Txfp->CurBlk, Txfp->CurNum,
To_Key_Col, To_Link, To_Kindex);
@@ -546,7 +546,7 @@ void VCTCOL::ReadColumn(PGLOBAL g)
assert (!To_Kcol);
#endif
- if (trace > 1)
+ if (trace(2))
htrc("VCT ReadColumn: col %s R%d coluse=%.4X status=%.4X buf_type=%d\n",
Name, To_Tdb->GetTdb_No(), ColUse, Status, Buf_Type);
@@ -574,7 +574,7 @@ void VCTCOL::WriteColumn(PGLOBAL)
{
PTXF txfp = ((PTDBVCT)To_Tdb)->Txfp;;
- if (trace > 1)
+ if (trace(2))
htrc("VCT WriteColumn: col %s R%d coluse=%.4X status=%.4X buf_type=%d\n",
Name, To_Tdb->GetTdb_No(), ColUse, Status, Buf_Type);
diff --git a/storage/connect/tabwmi.cpp b/storage/connect/tabwmi.cpp
index 335ffce5d7f..8a8e1bcbcb6 100644
--- a/storage/connect/tabwmi.cpp
+++ b/storage/connect/tabwmi.cpp
@@ -34,7 +34,7 @@ PWMIUT InitWMI(PGLOBAL g, PCSZ nsp, PCSZ classname)
HRESULT res;
PWMIUT wp = (PWMIUT)PlugSubAlloc(g, NULL, sizeof(WMIUTIL));
- if (trace)
+ if (trace(1))
htrc("WMIColumns class %s space %s\n", SVP(classname), SVP(nsp));
/*********************************************************************/
@@ -103,7 +103,7 @@ PWMIUT InitWMI(PGLOBAL g, PCSZ nsp, PCSZ classname)
loc->Release();
- if (trace)
+ if (trace(1))
htrc("Successfully connected to namespace.\n");
/*********************************************************************/
diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp
index 6402f48e090..c96e0844497 100644
--- a/storage/connect/tabxml.cpp
+++ b/storage/connect/tabxml.cpp
@@ -153,7 +153,7 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
lvl = (lvl < 0) ? 0 : (lvl > 16) ? 16 : lvl;
} // endif fn
- if (trace)
+ if (trace(1))
htrc("File %s lvl=%d\n", topt->filename, lvl);
tdp = new(g) XMLDEF;
@@ -362,7 +362,7 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
txmp->CloseDB(g);
skipit:
- if (trace)
+ if (trace(1))
htrc("XMLColumns: n=%d len=%d\n", n, length[0]);
/*********************************************************************/
@@ -686,7 +686,7 @@ PTDB TDBXML::Clone(PTABS t)
/***********************************************************************/
PCOL TDBXML::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
{
- if (trace)
+ if (trace(1))
htrc("TDBXML: MakeCol %s n=%d\n", (cdp) ? cdp->GetName() : "<null>", n);
return new(g) XMLCOL(cdp, this, cprec, n);
@@ -720,7 +720,7 @@ int TDBXML::LoadTableFile(PGLOBAL g, char *filename)
if (Docp)
return rc; // Already done
- if (trace)
+ if (trace(1))
htrc("TDBXML: loading %s\n", filename);
/*********************************************************************/
@@ -753,7 +753,7 @@ int TDBXML::LoadTableFile(PGLOBAL g, char *filename)
return RC_FX;
} // endif init
- if (trace)
+ if (trace(1))
htrc("TDBXML: parsing %s rc=%d\n", filename, rc);
// Parse the XML file
@@ -1182,7 +1182,7 @@ int TDBXML::ReadDB(PGLOBAL g)
} // endswitch recpos
} else {
- if (trace)
+ if (trace(1))
htrc("TDBXML ReadDB: Irow=%d Nrow=%d\n", Irow, Nrow);
// This is to force the table to be expanded when constructing
@@ -1209,7 +1209,7 @@ int TDBXML::ReadDB(PGLOBAL g)
} // endif To_Kindex
if (!same) {
- if (trace > 1)
+ if (trace(2))
htrc("TDBXML ReadDB: Irow=%d RowNode=%p\n", Irow, RowNode);
// Get the new row node
@@ -1319,7 +1319,7 @@ void TDBXML::CloseDB(PGLOBAL g)
Docp->CloseDoc(g, To_Xb);
// This causes a crash in Diagnostics_area::set_error_status
-// throw (int)TYPE_AM_XML;
+// throw (int)TYPE_AM_XML;
} // endif DumpDoc
} // endif Changed
@@ -1472,7 +1472,7 @@ bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
} else
strcat(pbuf, Xname);
- if (trace)
+ if (trace(1))
htrc("XMLCOL: pbuf=%s\n", pbuf);
// For Update or Insert the Xpath must be analyzed
@@ -1555,7 +1555,7 @@ bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
if (Type || Nod)
Tdbp->Hasnod = true;
- if (trace)
+ if (trace(1))
htrc("XMLCOL: Xname=%s\n", pbuf);
// Save the calculated Xpath
@@ -1679,7 +1679,7 @@ void XMLCOL::WriteColumn(PGLOBAL g)
int i, n, k = 0;
PXNODE TopNode = NULL;
- if (trace > 1)
+ if (trace(2))
htrc("XML WriteColumn: col %s R%d coluse=%.4X status=%.4X\n",
Name, Tdbp->GetTdb_No(), ColUse, Status);
@@ -1913,7 +1913,7 @@ void XMULCOL::WriteColumn(PGLOBAL g)
int i, n, len, k = 0;
PXNODE TopNode = NULL;
- if (trace)
+ if (trace(1))
htrc("XML WriteColumn: col %s R%d coluse=%.4X status=%.4X\n",
Name, Tdbp->GetTdb_No(), ColUse, Status);
@@ -2129,7 +2129,7 @@ void XPOSCOL::WriteColumn(PGLOBAL g)
char *p, buf[16];
int i, k, n;
- if (trace)
+ if (trace(1))
htrc("XML WriteColumn: col %s R%d coluse=%.4X status=%.4X\n",
Name, Tdbp->GetTdb_No(), ColUse, Status);
diff --git a/storage/connect/user_connect.cc b/storage/connect/user_connect.cc
index cb62667c0fe..9532d7c2a8d 100644
--- a/storage/connect/user_connect.cc
+++ b/storage/connect/user_connect.cc
@@ -178,7 +178,7 @@ bool user_connect::CheckCleanup(bool force)
g->Mrr = 0;
last_query_id= thdp->query_id;
- if (trace && !force)
+ if (trace(65) && !force)
printf("=====> Begin new query %llu\n", last_query_id);
return true;
diff --git a/storage/connect/valblk.cpp b/storage/connect/valblk.cpp
index 018c7ee3fe1..73ca135691c 100644
--- a/storage/connect/valblk.cpp
+++ b/storage/connect/valblk.cpp
@@ -53,7 +53,7 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
{
PVBLK blkp;
- if (trace)
+ if (trace(1))
htrc("AVB: mp=%p type=%d nval=%d len=%d check=%u blank=%u\n",
mp, type, nval, len, check, blank);
diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp
index 74a3a1f8075..e159efaa989 100644
--- a/storage/connect/value.cpp
+++ b/storage/connect/value.cpp
@@ -337,7 +337,7 @@ PVAL AllocateValue(PGLOBAL g, void *value, short type, short prec)
{
PVAL valp;
- if (trace)
+ if (trace(1))
htrc("AllocateConstant: value=%p type=%hd\n", value, type);
switch (type) {
@@ -727,7 +727,7 @@ bool TYPVAL<TYPE>::SetValue_char(const char *p, int n)
else
Tval = (TYPE)val;
- if (trace > 1) {
+ if (trace(2)) {
char buf[64];
htrc(strcat(strcat(strcpy(buf, " setting %s to: "), Fmt), "\n"),
GetTypeName(Type), Tval);
@@ -750,7 +750,7 @@ bool TYPVAL<double>::SetValue_char(const char *p, int n)
buf[n] = '\0';
Tval = atof(buf);
- if (trace > 1)
+ if (trace(2))
htrc(" setting double: '%s' -> %lf\n", buf, Tval);
Null = false;
@@ -996,7 +996,7 @@ int TYPVAL<TYPE>::CompareValue(PVAL vp)
// Process filtering on numeric values.
TYPE n = GetTypedValue(vp);
-//if (trace)
+//if (trace(1))
// htrc(" Comparing: val=%d,%d\n", Tval, n);
return (Tval > n) ? 1 : (Tval < n) ? (-1) : 0;
@@ -1384,7 +1384,7 @@ bool TYPVAL<PSZ>::SetValue_char(const char *cp, int n)
strncpy(Strp, cp, n);
Strp[n] = '\0';
- if (trace > 1)
+ if (trace(2))
htrc(" Setting string to: '%s'\n", Strp);
} else
@@ -1631,7 +1631,7 @@ int TYPVAL<PSZ>::CompareValue(PVAL vp)
int n;
//assert(vp->GetType() == Type);
- if (trace)
+ if (trace(1))
htrc(" Comparing: val='%s','%s'\n", Strp, vp->GetCharValue());
// Process filtering on character strings.
@@ -1656,14 +1656,14 @@ bool TYPVAL<PSZ>::Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op)
char *p[2], val[2][32];
int i;
- if (trace)
+ if (trace(1))
htrc("Compute: np=%d op=%d\n", np, op);
for (i = 0; i < np; i++)
if (!vp[i]->IsNull()) {
p[i] = vp[i]->GetCharString(val[i]);
- if (trace)
+ if (trace(1))
htrc("p[%d]=%s\n", i, p[i]);
} else
@@ -1679,7 +1679,7 @@ bool TYPVAL<PSZ>::Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op)
if ((i = Len - (signed)strlen(Strp)) > 0)
strncat(Strp, p[np - 1], i);
- if (trace)
+ if (trace(1))
htrc("Strp=%s\n", Strp);
break;
@@ -1747,7 +1747,7 @@ DECVAL::DECVAL(PSZ s) : TYPVAL<PSZ>(s)
if (s) {
char *p = strchr(Strp, '.');
- Prec = (p) ? Len - (p - Strp) : 0;
+ Prec = (p) ? (int)(Len - (p - Strp)) : 0;
} // endif s
Type = TYPE_DECIM;
@@ -1854,7 +1854,7 @@ int DECVAL::CompareValue(PVAL vp)
// Process filtering on numeric values.
double f = atof(Strp), n = vp->GetFloatValue();
-//if (trace)
+//if (trace(1))
// htrc(" Comparing: val=%d,%d\n", f, n);
return (f > n) ? 1 : (f < n) ? (-1) : 0;
@@ -2410,7 +2410,7 @@ void DTVAL::SetTimeShift(void)
Shift = (int)mktime(&dtm) - 86400;
- if (trace)
+ if (trace(1))
htrc("DTVAL Shift=%d\n", Shift);
} // end of SetTimeShift
@@ -2485,7 +2485,7 @@ bool DTVAL::MakeTime(struct tm *ptm)
int n, y = ptm->tm_year;
time_t t = mktime_mysql(ptm);
- if (trace > 1)
+ if (trace(2))
htrc("MakeTime from (%d,%d,%d,%d,%d,%d)\n",
ptm->tm_year, ptm->tm_mon, ptm->tm_mday,
ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
@@ -2508,7 +2508,7 @@ bool DTVAL::MakeTime(struct tm *ptm)
}
Tval= (int) t;
- if (trace > 1)
+ if (trace(2))
htrc("MakeTime Ival=%d\n", Tval);
return false;
@@ -2528,14 +2528,14 @@ bool DTVAL::MakeDate(PGLOBAL g, int *val, int nval)
datm.tm_mon=0;
datm.tm_year=70;
- if (trace > 1)
+ if (trace(2))
htrc("MakeDate from(%d,%d,%d,%d,%d,%d) nval=%d\n",
val[0], val[1], val[2], val[3], val[4], val[5], nval);
for (i = 0; i < nval; i++) {
n = val[i];
-// if (trace > 1)
+// if (trace(2))
// htrc("i=%d n=%d\n", i, n);
switch (i) {
@@ -2545,7 +2545,7 @@ bool DTVAL::MakeDate(PGLOBAL g, int *val, int nval)
datm.tm_year = n;
-// if (trace > 1)
+// if (trace(2))
// htrc("n=%d tm_year=%d\n", n, datm.tm_year);
break;
@@ -2564,7 +2564,7 @@ bool DTVAL::MakeDate(PGLOBAL g, int *val, int nval)
datm.tm_mon = m;
datm.tm_year += n;
-// if (trace > 1)
+// if (trace(2))
// htrc("n=%d m=%d tm_year=%d tm_mon=%d\n", n, m, datm.tm_year, datm.tm_mon);
break;
@@ -2581,7 +2581,7 @@ bool DTVAL::MakeDate(PGLOBAL g, int *val, int nval)
datm.tm_mday = m;
datm.tm_year += n;
-// if (trace > 1)
+// if (trace(2))
// htrc("n=%d m=%d tm_year=%d tm_mon=%d\n", n, m, datm.tm_year, datm.tm_mon);
break;
@@ -2592,7 +2592,7 @@ bool DTVAL::MakeDate(PGLOBAL g, int *val, int nval)
} // endfor i
- if (trace > 1)
+ if (trace(2))
htrc("MakeDate datm=(%d,%d,%d,%d,%d,%d)\n",
datm.tm_year, datm.tm_mon, datm.tm_mday,
datm.tm_hour, datm.tm_min, datm.tm_sec);
@@ -2656,7 +2656,7 @@ bool DTVAL::SetValue_char(const char *p, int n)
// Trim trailing blanks
for (p2 = p + n -1; p < p2 && *p2 == ' '; p2--);
- if ((rc = (n = p2 - p + 1) > Len))
+ if ((rc = (n = (int)(p2 - p + 1)) > Len))
n = Len;
memcpy(Sdate, p, n);
@@ -2667,7 +2667,7 @@ bool DTVAL::SetValue_char(const char *p, int n)
ndv = ExtractDate(Sdate, Pdtp, DefYear, dval);
MakeDate(NULL, dval, ndv);
- if (trace > 1)
+ if (trace(2))
htrc(" setting date: '%s' -> %d\n", Sdate, Tval);
Null = (Nullable && ndv == 0);
@@ -2694,7 +2694,7 @@ void DTVAL::SetValue_psz(PCSZ p)
ndv = ExtractDate(Sdate, Pdtp, DefYear, dval);
MakeDate(NULL, dval, ndv);
- if (trace > 1)
+ if (trace(2))
htrc(" setting date: '%s' -> %d\n", Sdate, Tval);
Null = (Nullable && ndv == 0);
@@ -2849,13 +2849,13 @@ bool DTVAL::FormatValue(PVAL vp, PCSZ fmt)
char *buf = (char*)vp->GetTo_Val(); // Should be big enough
struct tm tm, *ptm = GetGmTime(&tm);
- if (trace > 1)
+ if (trace(2))
htrc("FormatValue: ptm=%p len=%d\n", ptm, vp->GetValLen());
if (ptm) {
size_t n = strftime(buf, vp->GetValLen(), fmt, ptm);
- if (trace > 1)
+ if (trace(2))
htrc("strftime: n=%d buf=%s\n", n, (n) ? buf : "???");
return (n == 0);
diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp
index 30dce3b7fef..efefc17b5f5 100755
--- a/storage/connect/xindex.cpp
+++ b/storage/connect/xindex.cpp
@@ -344,7 +344,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
} // endif n
- if (trace)
+ if (trace(1))
htrc("XINDEX Make: n=%d\n", n);
// File position must be stored
@@ -417,7 +417,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
if (kcp->Init(g, colp, n, true, 0))
return true;
- if (trace)
+ if (trace(1))
htrc("Adding colp=%p Buf_Type=%d size=%d\n",
colp, colp->GetResultType(), n);
@@ -484,7 +484,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
} else
To_Rec[nkey] = Tdbp->GetRecpos();
- if (trace > 1)
+ if (trace(2))
htrc("Make: To_Rec[%d]=%d\n", nkey, To_Rec[nkey]);
/*******************************************************************/
@@ -553,7 +553,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
if ((Ndif = Qsort(g, Num_K)) < 0)
goto err; // Error during sort
- if (trace)
+ if (trace(1))
htrc("Make: Nk=%d n=%d Num_K=%d Ndif=%d addcolp=%p BlkFil=%p X=%p\n",
Nk, n, Num_K, Ndif, addcolp, Tdbp->To_BlkFil, X);
@@ -883,7 +883,7 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp)
n[5] = Nblk; n[6] = Sblk;
n[7] = Srtd ? 1 : 0; // Values are sorted in the file
- if (trace) {
+ if (trace(1)) {
htrc("Saving index %s\n", Xdp->GetName());
htrc("ID=%d Nk=%d nof=%d Num_K=%d Incr=%d Nblk=%d Sblk=%d Srtd=%d\n",
ID, Nk, nof, Num_K, Incr, Nblk, Sblk, Srtd);
@@ -926,7 +926,7 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp)
// dup->ProgCur += 5;
} // endfor kcp
- if (trace)
+ if (trace(1))
htrc("Index %s saved, Size=%d\n", Xdp->GetName(), size);
end:
@@ -1016,7 +1016,7 @@ bool XINDEX::Init(PGLOBAL g)
PlugSetPath(fn, fn, Tdbp->GetPath());
- if (trace)
+ if (trace(1))
htrc("Index %s file: %s\n", Xdp->GetName(), fn);
/*********************************************************************/
@@ -1039,7 +1039,7 @@ bool XINDEX::Init(PGLOBAL g)
} else
Srtd = false;
- if (trace)
+ if (trace(1))
htrc("nv=%d %d %d %d %d %d %d (%d)\n",
nv[0], nv[1], nv[2], nv[3], nv[4], nv[5], nv[6], Srtd);
@@ -1048,7 +1048,7 @@ bool XINDEX::Init(PGLOBAL g)
if (/*nv[0] != ID ||*/ nv[1] != Nk) {
sprintf(g->Message, MSG(BAD_INDEX_FILE), fn);
- if (trace)
+ if (trace(1))
htrc("nv[0]=%d ID=%d nv[1]=%d Nk=%d\n", nv[0], ID, nv[1], Nk);
goto err;
@@ -1269,7 +1269,7 @@ bool XINDEX::MapInit(PGLOBAL g)
PlugSetPath(fn, fn, Tdbp->GetPath());
- if (trace)
+ if (trace(1))
htrc("Index %s file: %s\n", Xdp->GetName(), fn);
/*********************************************************************/
@@ -1300,7 +1300,7 @@ bool XINDEX::MapInit(PGLOBAL g)
nv0 = nv[0];
} // endif nv
- if (trace)
+ if (trace(1))
htrc("nv=%d %d %d %d %d %d %d %d\n",
nv0, nv[1], nv[2], nv[3], nv[4], nv[5], nv[6], Srtd);
@@ -1310,7 +1310,7 @@ bool XINDEX::MapInit(PGLOBAL g)
// Not this index
sprintf(g->Message, MSG(BAD_INDEX_FILE), fn);
- if (trace)
+ if (trace(1))
htrc("nv0=%d ID=%d nv[1]=%d Nk=%d\n", nv0, ID, nv[1], Nk);
goto err;
@@ -1483,7 +1483,7 @@ bool XINDEX::GetAllSizes(PGLOBAL g,/* int &ndif,*/ int &numk)
PlugSetPath(fn, fn, Tdbp->GetPath());
- if (trace)
+ if (trace(1))
htrc("Index %s file: %s\n", Xdp->GetName(), fn);
/*********************************************************************/
@@ -1500,7 +1500,7 @@ bool XINDEX::GetAllSizes(PGLOBAL g,/* int &ndif,*/ int &numk)
if (X->Read(g, nv, NZ, sizeof(int)))
goto err;
- if (trace)
+ if (trace(1))
htrc("nv=%d %d %d %d\n", nv[0], nv[1], nv[2], nv[3]);
// The test on ID was suppressed because MariaDB can change an index ID
@@ -1508,7 +1508,7 @@ bool XINDEX::GetAllSizes(PGLOBAL g,/* int &ndif,*/ int &numk)
if (/*nv[0] != ID ||*/ nv[1] != Nk) {
sprintf(g->Message, MSG(BAD_INDEX_FILE), fn);
- if (trace)
+ if (trace(1))
htrc("nv[0]=%d ID=%d nv[1]=%d Nk=%d\n", nv[0], ID, nv[1], Nk);
goto err;
@@ -1770,7 +1770,7 @@ int XINDEX::Fetch(PGLOBAL g)
if (Num_K == 0)
return -1; // means end of file
- if (trace > 1)
+ if (trace(2))
htrc("XINDEX Fetch: Op=%d\n", Op);
/*********************************************************************/
@@ -1834,7 +1834,7 @@ int XINDEX::Fetch(PGLOBAL g)
Nth++;
- if (trace > 1)
+ if (trace(2))
htrc("Fetch: Looking for new value Nth=%d\n", Nth);
Cur_K = FastFind();
@@ -1907,7 +1907,7 @@ int XINDEX::FastFind(void)
sup = To_KeyCol->Ndf;
} // endif Nblk
- if (trace > 2)
+ if (trace(4))
htrc("XINDEX FastFind: Nblk=%d Op=%d inf=%d sup=%d\n",
Nblk, Op, inf, sup);
@@ -1985,7 +1985,7 @@ int XINDEX::FastFind(void)
curk = (kcp->Kof) ? kcp->Kof[kcp->Val_K] : kcp->Val_K;
} // endfor kcp
- if (trace > 2)
+ if (trace(4))
htrc("XINDEX FastFind: curk=%d\n", curk);
return curk;
@@ -2123,7 +2123,7 @@ int XINDXS::Fetch(PGLOBAL g)
if (Num_K == 0)
return -1; // means end of file
- if (trace > 1)
+ if (trace(2))
htrc("XINDXS Fetch: Op=%d\n", Op);
/*********************************************************************/
@@ -2176,7 +2176,7 @@ int XINDXS::Fetch(PGLOBAL g)
else
Nth++;
- if (trace > 1)
+ if (trace(2))
htrc("Fetch: Looking for new value Nth=%d\n", Nth);
Cur_K = FastFind();
@@ -2243,7 +2243,7 @@ int XINDXS::FastFind(void)
sup = Ndif;
} // endif Nblk
- if (trace > 2)
+ if (trace(4))
htrc("XINDXS FastFind: Nblk=%d Op=%d inf=%d sup=%d\n",
Nblk, Op, inf, sup);
@@ -2269,7 +2269,7 @@ int XINDXS::FastFind(void)
n = 0;
} // endif sup
- if (trace > 2)
+ if (trace(4))
htrc("XINDXS FastFind: n=%d i=%d\n", n, i);
// Loop on kcp because of dynamic indexing
@@ -2337,7 +2337,7 @@ bool XFILE::Open(PGLOBAL g, char *filename, int id, MODE mode)
} // endswitch mode
if (!(Xfile= global_fopen(g, MSGID_OPEN_ERROR_AND_STRERROR, filename, pmod))) {
- if (trace)
+ if (trace(1))
htrc("Open: %s\n", g->Message);
return true;
@@ -2354,7 +2354,7 @@ bool XFILE::Open(PGLOBAL g, char *filename, int id, MODE mode)
NewOff.v.Low = (int)ftell(Xfile);
- if (trace)
+ if (trace(1))
htrc("XFILE Open: NewOff.v.Low=%d\n", NewOff.v.Low);
} else if (mode == MODE_WRITE) {
@@ -2365,7 +2365,7 @@ bool XFILE::Open(PGLOBAL g, char *filename, int id, MODE mode)
fseek(Xfile, 0, SEEK_END);
NewOff.v.Low = (int)ftell(Xfile);
- if (trace)
+ if (trace(1))
htrc("XFILE Open: NewOff.v.Low=%d\n", NewOff.v.Low);
} // endif id
@@ -2377,7 +2377,7 @@ bool XFILE::Open(PGLOBAL g, char *filename, int id, MODE mode)
return true;
} // endif MAX_INDX
- if (trace)
+ if (trace(1))
htrc("XFILE Open: noff[%d].v.Low=%d\n", id, noff[id].v.Low);
// Position the cursor at the offset of this index
@@ -2510,7 +2510,7 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
return true;
} // endif
- if (trace)
+ if (trace(1))
htrc(" Xopen: filename=%s id=%d mode=%d\n", filename, id, mode);
#if defined(__WIN__)
@@ -2554,7 +2554,7 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
return true;
} // endif Hfile
- if (trace)
+ if (trace(1))
htrc(" access=%p share=%p creation=%d handle=%p fn=%s\n",
access, share, creation, Hfile, filename);
@@ -2628,13 +2628,13 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
if (Hfile == INVALID_HANDLE_VALUE) {
/*rc = errno;*/
- if (trace)
+ if (trace(1))
htrc("Open: %s\n", g->Message);
return true;
} // endif Hfile
- if (trace)
+ if (trace(1))
htrc(" oflag=%p mode=%d handle=%d fn=%s\n",
oflag, mode, Hfile, filename);
@@ -2647,7 +2647,7 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
return true;
} // endif
- if (trace)
+ if (trace(1))
htrc("INSERT: NewOff=%lld\n", NewOff.Val);
} else if (mode == MODE_WRITE) {
@@ -2657,7 +2657,7 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
NewOff.v.Low = write(Hfile, &noff, sizeof(noff));
} // endif id
- if (trace)
+ if (trace(1))
htrc("WRITE: NewOff=%lld\n", NewOff.Val);
} else if (mode == MODE_READ && id >= 0) {
@@ -2667,7 +2667,7 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
return true;
} // endif read
- if (trace)
+ if (trace(1))
htrc("noff[%d]=%lld\n", id, noff[id].Val);
// Position the cursor at the offset of this index
@@ -2705,13 +2705,13 @@ bool XHUGE::Seek(PGLOBAL g, int low, int high, int origin)
if (lseek64(Hfile, pos, origin) < 0) {
sprintf(g->Message, MSG(ERROR_IN_LSK), errno);
- if (trace)
+ if (trace(1))
htrc("lseek64 error %d\n", errno);
return true;
} // endif lseek64
- if (trace)
+ if (trace(1))
htrc("Seek: low=%d high=%d\n", low, high);
#endif // UNIX
@@ -2750,13 +2750,13 @@ bool XHUGE::Read(PGLOBAL g, void *buf, int n, int size)
#else // UNIX
ssize_t count = (ssize_t)(n * size);
- if (trace)
+ if (trace(1))
htrc("Hfile=%d n=%d size=%d count=%d\n", Hfile, n, size, count);
if (read(Hfile, buf, count) != count) {
sprintf(g->Message, MSG(READ_ERROR), "Index file", strerror(errno));
- if (trace)
+ if (trace(1))
htrc("read error %d\n", errno);
rc = true;
@@ -2810,7 +2810,7 @@ int XHUGE::Write(PGLOBAL g, void *buf, int n, int size, bool& rc)
/***********************************************************************/
void XHUGE::Close(char *fn, int id)
{
- if (trace)
+ if (trace(1))
htrc("XHUGE::Close: fn=%s id=%d NewOff=%lld\n", fn, id, NewOff.Val);
#if defined(__WIN__)
@@ -3022,7 +3022,7 @@ bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln)
Prefix = true;
} // endif kln
- if (trace)
+ if (trace(1))
htrc("KCOL(%p) Init: col=%s n=%d type=%d sm=%d\n",
this, colp->GetName(), n, colp->GetResultType(), sm);
@@ -3076,7 +3076,7 @@ BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m)
Type = colp->GetResultType();
- if (trace)
+ if (trace(1))
htrc("MapInit(%p): colp=%p type=%d n=%d len=%d m=%p\n",
this, colp, Type, n[0], len, m);
@@ -3196,7 +3196,7 @@ bool KXYCOL::InitFind(PGLOBAL g, PXOB xp)
Valp->SetValue_pval(xp->GetValue(), false);
} // endif Type
- if (trace > 1) {
+ if (trace(2)) {
char buf[32];
htrc("KCOL InitFind: value=%s\n", Valp->GetCharString(buf));
@@ -3237,7 +3237,7 @@ int KXYCOL::Compare(int i1, int i2)
// Do the actual comparison between values.
register int k = Kblp->CompVal(i1, i2);
- if (trace > 2)
+ if (trace(4))
htrc("Compare done result=%d\n", k);
return (Asc) ? k : -k;
@@ -3249,7 +3249,7 @@ int KXYCOL::Compare(int i1, int i2)
int KXYCOL::CompVal(int i)
{
// Do the actual comparison between numerical values.
- if (trace > 2) {
+ if (trace(4)) {
register int k = (int)Kblp->CompVal(Valp, (int)i);
htrc("Compare done result=%d\n", k);
diff --git a/storage/connect/xobject.cpp b/storage/connect/xobject.cpp
index 02d3e974dcc..c595ce5d6c4 100644
--- a/storage/connect/xobject.cpp
+++ b/storage/connect/xobject.cpp
@@ -204,7 +204,7 @@ STRING::STRING(PGLOBAL g, uint n, PCSZ str)
*Strp = 0;
Next = GetNext();
- Size = Next - Strp;
+ Size = (int)(Next - Strp);
Trc = false;
} else {
// This should normally never happen
@@ -239,7 +239,7 @@ char *STRING::Realloc(uint len)
p = Strp;
Next = GetNext();
- Size = Next - p;
+ Size = (int)(Next - p);
return p;
} // end of Realloc
@@ -439,4 +439,3 @@ bool STRING::Resize(uint newsize)
return newsize > Size;
} // end of Resize
-
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 28d329ea604..b6064899a1e 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2005, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -4875,13 +4875,15 @@ processed_field:
}
/** Get the auto-increment value of the table on commit.
-@param ha_alter_info Data used during in-place alter
-@param ctx In-place ALTER TABLE context
-@param altered_table MySQL table that is being altered
-@param old_table MySQL table as it is before the ALTER operation
-@return the next auto-increment value (0 if not present) */
+@param[in] ha_alter_info Data used during in-place alter
+@param[in,out] ctx In-place ALTER TABLE context
+ return autoinc value in ctx->max_autoinc
+@param altered_table[in] MySQL table that is being altered
+@param old_table[in] MySQL table as it is before the ALTER operation
+retval true Failure
+@retval false Success*/
static MY_ATTRIBUTE((nonnull, warn_unused_result))
-ulonglong
+bool
commit_get_autoinc(
/*===============*/
Alter_inplace_info* ha_alter_info,
@@ -4889,23 +4891,28 @@ commit_get_autoinc(
const TABLE* altered_table,
const TABLE* old_table)
{
- ulonglong max_autoinc;
DBUG_ENTER("commit_get_autoinc");
if (!altered_table->found_next_number_field) {
/* There is no AUTO_INCREMENT column in the table
after the ALTER operation. */
- max_autoinc = 0;
+ ctx->max_autoinc = 0;
} else if (ctx->add_autoinc != ULINT_UNDEFINED) {
/* An AUTO_INCREMENT column was added. Get the last
value from the sequence, which may be based on a
supplied AUTO_INCREMENT value. */
- max_autoinc = ctx->sequence.last();
+ ctx->max_autoinc = ctx->sequence.last();
} else if ((ha_alter_info->handler_flags
& Alter_inplace_info::CHANGE_CREATE_OPTION)
&& (ha_alter_info->create_info->used_fields
& HA_CREATE_USED_AUTO)) {
+
+ /* Check if the table is discarded */
+ if(dict_table_is_discarded(ctx->old_table)) {
+ DBUG_RETURN(true);
+ }
+
/* An AUTO_INCREMENT value was supplied, but the table was not
rebuilt. Get the user-supplied value or the last value from the
sequence. */
@@ -4920,7 +4927,8 @@ commit_get_autoinc(
dict_index_t* index = dict_table_get_index_on_name(
ctx->old_table, autoinc_key->name);
- max_autoinc = ha_alter_info->create_info->auto_increment_value;
+ ctx->max_autoinc =
+ ha_alter_info->create_info->auto_increment_value;
dict_table_autoinc_lock(ctx->old_table);
@@ -4929,8 +4937,8 @@ commit_get_autoinc(
if (err != DB_SUCCESS) {
ut_ad(0);
- max_autoinc = 0;
- } else if (max_autoinc <= max_value_table) {
+ ctx->max_autoinc = 0;
+ } else if (ctx->max_autoinc <= max_value_table) {
ulonglong col_max_value;
ulonglong offset;
@@ -4938,7 +4946,7 @@ commit_get_autoinc(
old_table->found_next_number_field);
offset = ctx->prebuilt->autoinc_offset;
- max_autoinc = innobase_next_autoinc(
+ ctx->max_autoinc = innobase_next_autoinc(
max_value_table, 1, 1, offset,
col_max_value);
}
@@ -4948,11 +4956,11 @@ commit_get_autoinc(
Read the old counter value from the table. */
ut_ad(old_table->found_next_number_field);
dict_table_autoinc_lock(ctx->old_table);
- max_autoinc = ctx->old_table->autoinc;
+ ctx->max_autoinc = ctx->old_table->autoinc;
dict_table_autoinc_unlock(ctx->old_table);
}
- DBUG_RETURN(max_autoinc);
+ DBUG_RETURN(false);
}
/** Add or drop foreign key constraints to the data dictionary tables,
@@ -5947,8 +5955,13 @@ ha_innobase::commit_inplace_alter_table(
DBUG_ASSERT(new_clustered == ctx->need_rebuild());
- ctx->max_autoinc = commit_get_autoinc(
- ha_alter_info, ctx, altered_table, table);
+ if (commit_get_autoinc(ha_alter_info, ctx, altered_table,
+ table)) {
+ fail = true;
+ my_error(ER_TABLESPACE_DISCARDED, MYF(0),
+ table->s->table_name.str);
+ goto rollback_trx;
+ }
if (ctx->need_rebuild()) {
ctx->tmp_name = dict_mem_create_temporary_tablename(
@@ -5980,6 +5993,8 @@ ha_innobase::commit_inplace_alter_table(
#endif
}
+rollback_trx:
+
/* Commit or roll back the changes to the data dictionary. */
if (fail) {
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 0d5657b30ff..7304d1e5d87 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -45,7 +45,7 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 5
#define INNODB_VERSION_MINOR 6
-#define INNODB_VERSION_BUGFIX 37
+#define INNODB_VERSION_BUGFIX 40
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 3e60287a2e4..04456043f8a 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2012, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2015, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -1810,6 +1810,7 @@ PageConverter::update_records(
while (!m_rec_iter.end()) {
rec_t* rec = m_rec_iter.current();
+
ibool deleted = rec_get_deleted_flag(rec, comp);
/* For the clustered index we have to adjust the BLOB
@@ -1921,6 +1922,10 @@ PageConverter::update_index_page(
return(DB_SUCCESS);
}
+ if (!page_is_leaf(block->frame)) {
+ return (DB_SUCCESS);
+ }
+
return(update_records(block));
}
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index fd5a13bbaab..c170e7e8cd3 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -466,6 +466,8 @@ err_exit:
*avail = srv_sort_buf_size - log->tail.bytes;
if (size > *avail) {
+ /* Make sure log->tail.buf is large enough */
+ ut_ad(size <= sizeof log->tail.buf);
return(log->tail.buf);
} else {
return(log->tail.block + log->tail.bytes);
@@ -584,12 +586,10 @@ row_log_table_delete(
{
ulint old_pk_extra_size;
ulint old_pk_size;
- ulint ext_size = 0;
ulint mrec_size;
ulint avail_size;
mem_heap_t* heap = NULL;
const dtuple_t* old_pk;
- row_ext_t* ext;
ut_ad(dict_index_is_clust(index));
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -670,72 +670,20 @@ row_log_table_delete(
&old_pk_extra_size);
ut_ad(old_pk_extra_size < 0x100);
- mrec_size = 6 + old_pk_size;
-
- /* Log enough prefix of the BLOB unless both the
- old and new table are in COMPACT or REDUNDANT format,
- which store the prefix in the clustered index record. */
- if (rec_offs_any_extern(offsets)
- && (dict_table_get_format(index->table) >= UNIV_FORMAT_B
- || dict_table_get_format(new_table) >= UNIV_FORMAT_B)) {
-
- /* Build a cache of those off-page column prefixes
- that are referenced by secondary indexes. It can be
- that none of the off-page columns are needed. */
- row_build(ROW_COPY_DATA, index, rec,
- offsets, NULL, NULL, NULL, &ext, heap);
- if (ext) {
- /* Log the row_ext_t, ext->ext and ext->buf */
- ext_size = ext->n_ext * ext->max_len
- + sizeof(*ext)
- + ext->n_ext * sizeof(ulint)
- + (ext->n_ext - 1) * sizeof ext->len;
- mrec_size += ext_size;
- }
- }
+ /* 2 = 1 (extra_size) + at least 1 byte payload */
+ mrec_size = 2 + old_pk_size;
if (byte* b = row_log_table_open(index->online_log,
mrec_size, &avail_size)) {
*b++ = ROW_T_DELETE;
*b++ = static_cast<byte>(old_pk_extra_size);
- /* Log the size of external prefix we saved */
- mach_write_to_4(b, ext_size);
- b += 4;
-
rec_convert_dtuple_to_temp(
b + old_pk_extra_size, new_index,
old_pk->fields, old_pk->n_fields);
b += old_pk_size;
- if (ext_size) {
- ulint cur_ext_size = sizeof(*ext)
- + (ext->n_ext - 1) * sizeof ext->len;
-
- memcpy(b, ext, cur_ext_size);
- b += cur_ext_size;
-
- /* Check if we need to col_map to adjust the column
- number. If columns were added/removed/reordered,
- adjust the column number. */
- if (const ulint* col_map =
- index->online_log->col_map) {
- for (ulint i = 0; i < ext->n_ext; i++) {
- const_cast<ulint&>(ext->ext[i]) =
- col_map[ext->ext[i]];
- }
- }
-
- memcpy(b, ext->ext, ext->n_ext * sizeof(*ext->ext));
- b += ext->n_ext * sizeof(*ext->ext);
-
- ext_size -= cur_ext_size
- + ext->n_ext * sizeof(*ext->ext);
- memcpy(b, ext->buf, ext_size);
- b += ext_size;
- }
-
row_log_table_close(index, b, mrec_size, avail_size);
}
@@ -1654,15 +1602,13 @@ row_log_table_apply_insert(
/******************************************************//**
Deletes a record from a table that is being rebuilt.
@return DB_SUCCESS or error code */
-static MY_ATTRIBUTE((nonnull(1, 2, 4, 5), warn_unused_result))
+static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t
row_log_table_apply_delete_low(
/*===========================*/
btr_pcur_t* pcur, /*!< in/out: B-tree cursor,
will be trashed */
const ulint* offsets, /*!< in: offsets on pcur */
- const row_ext_t* save_ext, /*!< in: saved external field
- info, or NULL */
mem_heap_t* heap, /*!< in/out: memory heap */
mtr_t* mtr) /*!< in/out: mini-transaction,
will be committed */
@@ -1686,11 +1632,7 @@ row_log_table_apply_delete_low(
/* Build a row template for purging secondary index entries. */
row = row_build(
ROW_COPY_DATA, index, btr_pcur_get_rec(pcur),
- offsets, NULL, NULL, NULL,
- save_ext ? NULL : &ext, heap);
- if (!save_ext) {
- save_ext = ext;
- }
+ offsets, NULL, NULL, NULL, &ext, heap);
} else {
row = NULL;
}
@@ -1709,7 +1651,7 @@ row_log_table_apply_delete_low(
}
const dtuple_t* entry = row_build_index_entry(
- row, save_ext, index, heap);
+ row, ext, index, heap);
mtr_start(mtr);
btr_pcur_open(index, entry, PAGE_CUR_LE,
BTR_MODIFY_TREE, pcur, mtr);
@@ -1752,11 +1694,10 @@ flag_ok:
/******************************************************//**
Replays a delete operation on a table that was rebuilt.
@return DB_SUCCESS or error code */
-static MY_ATTRIBUTE((nonnull(1, 3, 4, 5, 6, 7), warn_unused_result))
+static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t
row_log_table_apply_delete(
/*=======================*/
- que_thr_t* thr, /*!< in: query graph */
ulint trx_id_col, /*!< in: position of
DB_TRX_ID in the new
clustered index */
@@ -1765,9 +1706,7 @@ row_log_table_apply_delete(
mem_heap_t* offsets_heap, /*!< in/out: memory heap
that can be emptied */
mem_heap_t* heap, /*!< in/out: memory heap */
- const row_log_t* log, /*!< in: online log */
- const row_ext_t* save_ext) /*!< in: saved external field
- info, or NULL */
+ const row_log_t* log) /*!< in: online log */
{
dict_table_t* new_table = log->table;
dict_index_t* index = dict_table_get_first_index(new_table);
@@ -1867,8 +1806,7 @@ all_done:
}
}
- return(row_log_table_apply_delete_low(&pcur, offsets, save_ext,
- heap, &mtr));
+ return row_log_table_apply_delete_low(&pcur, offsets, heap, &mtr);
}
/******************************************************//**
@@ -2079,7 +2017,7 @@ func_exit_committed:
/* Some BLOBs are missing, so we are interpreting
this ROW_T_UPDATE as ROW_T_DELETE (see *1). */
error = row_log_table_apply_delete_low(
- &pcur, cur_offsets, NULL, heap, &mtr);
+ &pcur, cur_offsets, heap, &mtr);
goto func_exit_committed;
}
@@ -2117,7 +2055,7 @@ func_exit_committed:
}
error = row_log_table_apply_delete_low(
- &pcur, cur_offsets, NULL, heap, &mtr);
+ &pcur, cur_offsets, heap, &mtr);
ut_ad(mtr.state == MTR_COMMITTED);
if (error == DB_SUCCESS) {
@@ -2263,8 +2201,6 @@ row_log_table_apply_op(
ulint extra_size;
const mrec_t* next_mrec;
dtuple_t* old_pk;
- row_ext_t* ext;
- ulint ext_size;
ut_ad(dict_index_is_clust(dup->index));
ut_ad(dup->index->table != log->table);
@@ -2272,7 +2208,7 @@ row_log_table_apply_op(
*error = DB_SUCCESS;
- /* 3 = 1 (op type) + 1 (ext_size) + at least 1 byte payload */
+ /* 3 = 1 (op type) + 1 (extra_size) + at least 1 byte payload */
if (mrec + 3 >= mrec_end) {
return(NULL);
}
@@ -2322,14 +2258,12 @@ row_log_table_apply_op(
break;
case ROW_T_DELETE:
- /* 1 (extra_size) + 4 (ext_size) + at least 1 (payload) */
- if (mrec + 6 >= mrec_end) {
+ /* 1 (extra_size) + at least 1 (payload) */
+ if (mrec + 2 >= mrec_end) {
return(NULL);
}
extra_size = *mrec++;
- ext_size = mach_read_from_4(mrec);
- mrec += 4;
ut_ad(mrec < mrec_end);
/* We assume extra_size < 0x100 for the PRIMARY KEY prefix.
@@ -2338,40 +2272,16 @@ row_log_table_apply_op(
rec_offs_set_n_fields(offsets, new_index->n_uniq + 2);
rec_init_offsets_temp(mrec, new_index, offsets);
- next_mrec = mrec + rec_offs_data_size(offsets) + ext_size;
+ next_mrec = mrec + rec_offs_data_size(offsets);
if (next_mrec > mrec_end) {
return(NULL);
}
log->head.total += next_mrec - mrec_start;
- /* If there are external fields, retrieve those logged
- prefix info and reconstruct the row_ext_t */
- if (ext_size) {
- /* We use memcpy to avoid unaligned
- access on some non-x86 platforms.*/
- ext = static_cast<row_ext_t*>(
- mem_heap_dup(heap,
- mrec + rec_offs_data_size(offsets),
- ext_size));
-
- byte* ext_start = reinterpret_cast<byte*>(ext);
-
- ulint ext_len = sizeof(*ext)
- + (ext->n_ext - 1) * sizeof ext->len;
-
- ext->ext = reinterpret_cast<ulint*>(ext_start + ext_len);
- ext_len += ext->n_ext * sizeof(*ext->ext);
-
- ext->buf = static_cast<byte*>(ext_start + ext_len);
- } else {
- ext = NULL;
- }
-
*error = row_log_table_apply_delete(
- thr, new_trx_id_col,
- mrec, offsets, offsets_heap, heap,
- log, ext);
+ new_trx_id_col,
+ mrec, offsets, offsets_heap, heap, log);
break;
case ROW_T_UPDATE:
@@ -2796,7 +2706,15 @@ all_done:
while (!trx_is_interrupted(trx)) {
mrec = next_mrec;
- ut_ad(mrec < mrec_end);
+ ut_ad(mrec <= mrec_end);
+
+ if (mrec == mrec_end) {
+ /* We are at the end of the log.
+ Mark the replay all_done. */
+ if (has_index_lock) {
+ goto all_done;
+ }
+ }
if (!has_index_lock) {
/* We are applying operations from a different
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index aa1dd98234b..e34e4fa94ff 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2015, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -1499,8 +1499,7 @@ error_exit:
doc_ids difference should not exceed
FTS_DOC_ID_MAX_STEP value. */
- if (next_doc_id > 1
- && doc_id - next_doc_id >= FTS_DOC_ID_MAX_STEP) {
+ if (doc_id - next_doc_id >= FTS_DOC_ID_MAX_STEP) {
fprintf(stderr,
"InnoDB: Doc ID " UINT64PF " is too"
" big. Its difference with largest"
@@ -5239,7 +5238,8 @@ row_rename_table_for_mysql(
}
}
- if (dict_table_has_fts_index(table)
+ if ((dict_table_has_fts_index(table)
+ || DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID))
&& !dict_tables_have_same_db(old_name, new_name)) {
err = fts_rename_aux_tables(table, new_name, trx);
if (err != DB_TABLE_NOT_FOUND) {
diff --git a/storage/perfschema/ha_perfschema.cc b/storage/perfschema/ha_perfschema.cc
index 971f0c46be8..cdbbc022d50 100644
--- a/storage/perfschema/ha_perfschema.cc
+++ b/storage/perfschema/ha_perfschema.cc
@@ -225,7 +225,7 @@ maria_declare_plugin(perfschema)
0x0001,
pfs_status_vars,
NULL,
- "5.6.36",
+ "5.6.40",
MariaDB_PLUGIN_MATURITY_STABLE
}
maria_declare_plugin_end;
diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt
index 31374b1ff81..30f60ada93a 100644
--- a/storage/tokudb/CMakeLists.txt
+++ b/storage/tokudb/CMakeLists.txt
@@ -1,4 +1,4 @@
-SET(TOKUDB_VERSION 5.6.38-83.0)
+SET(TOKUDB_VERSION 5.6.39-83.1)
# PerconaFT only supports x86-64 and cmake-2.8.9+
IF(CMAKE_VERSION VERSION_LESS "2.8.9")
MESSAGE(STATUS "CMake 2.8.9 or higher is required by TokuDB")
diff --git a/storage/tokudb/PerconaFT/.clang-format b/storage/tokudb/PerconaFT/.clang-format
new file mode 100644
index 00000000000..0888185848d
--- /dev/null
+++ b/storage/tokudb/PerconaFT/.clang-format
@@ -0,0 +1,36 @@
+Language: Cpp
+BasedOnStyle: Google
+
+# The following parameters are default for Google style,
+# but as they are important for our project they
+# are set explicitly here
+AlignAfterOpenBracket: Align
+BreakBeforeBinaryOperators: None
+ColumnLimit: 80
+PointerAlignment: Left
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 2
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+UseTab: Never
+
+# Non-default parametes
+NamespaceIndentation: All
+IndentWidth: 4
+TabWidth: 4
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+BinPackParameters: false
+BinPackArguments: false
+ExperimentalAutoDetectBinPacking: false
+AllowAllParametersOfDeclarationOnNextLine: false
+#AlignConsecutiveAssignments: yes
+#AlignConsecutiveDeclarations: yes
+BreakStringLiterals: false
+ReflowComments: true
diff --git a/storage/tokudb/PerconaFT/CMakeLists.txt b/storage/tokudb/PerconaFT/CMakeLists.txt
index 3973ec71b52..3b6b909f635 100644
--- a/storage/tokudb/PerconaFT/CMakeLists.txt
+++ b/storage/tokudb/PerconaFT/CMakeLists.txt
@@ -9,6 +9,12 @@ project(TokuDB)
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
+# See: https://jira.percona.com/browse/TDB-93
+IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-address-of-packed-member")
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-address-of-packed-member")
+ENDIF()
+
# detect when we are being built as a subproject
if (DEFINED MYSQL_PROJECT_NAME_DOCSTRING)
add_definitions( -DMYSQL_TOKUDB_ENGINE=1)
diff --git a/storage/tokudb/PerconaFT/README.md b/storage/tokudb/PerconaFT/README.md
index d53caf00190..ffb646b67af 100644
--- a/storage/tokudb/PerconaFT/README.md
+++ b/storage/tokudb/PerconaFT/README.md
@@ -9,20 +9,18 @@ PerconaFT is provided as a shared library with an interface similar to
Berkeley DB.
To build the full MySQL product, see the instructions for
-[Percona/tokudb-engine][tokudb-engine]. To build TokuMX, see the instructions
-for [Percona/percona-server-mongodb][mongo]. This document covers PerconaFT only.
+[Percona/percona-server][percona-server]. This document covers PerconaFT only.
-[tokudb-engine]: https://github.com/Percona/tokudb-engine
-[mongo]: https://github.com/Percona/percona-server-mongodb
+[percona-server]: https://github.com/Percona/percona-server
Building
--------
PerconaFT is built using CMake >= 2.8.9. Out-of-source builds are
-recommended. You need a C++11 compiler, though only GCC >= 4.7 and
-Apple's Clang are tested. You also need zlib development packages
-(`yum install zlib-devel` or `apt-get install zlib1g-dev`).
+recommended. You need a C++11 compiler, though only some versions
+of GCC >= 4.7 and Clang are tested. You also need zlib development
+packages (`yum install zlib-devel` or `apt-get install zlib1g-dev`).
You will also need the source code for jemalloc, checked out in
`third_party/`.
@@ -42,16 +40,16 @@ CC=gcc47 CXX=g++47 cmake \
cmake --build . --target install
```
-This will build `libtokudb.so` and `libtokuportability.so` and install it,
+This will build `libft.so` and `libtokuportability.so` and install it,
some header files, and some examples to `percona-ft/prefix/`. It will also
build jemalloc and install it alongside these libraries, you should link
to that if you are planning to run benchmarks or in production.
### Platforms
-PerconaFT is supported on 64-bit Centos, should work on other 64-bit linux
-distributions, and may work on OSX 10.8 and FreeBSD. PerconaFT is not
-supported on 32-bit systems.
+PerconaFT is supported on 64-bit Centos, Debian, and Ubuntu and should work
+on other 64-bit linux distributions, and may work on OSX 10.8 and FreeBSD.
+PerconaFT is not supported on 32-bit systems.
[Transparent hugepages][transparent-hugepages] is a feature in newer linux
kernel versions that causes problems for the memory usage tracking
@@ -97,16 +95,9 @@ We have two publicly accessible mailing lists for TokuDB:
- tokudb-dev@googlegroups.com is for discussion of the development of
TokuDB.
-and two for TokuMX:
-
- - tokumx-user@googlegroups.com is for general and support related
- questions about the use of TokuMX.
- - tokumx-dev@googlegroups.com is for discussion of the development of
- TokuMX.
-
All source code and test contributions must be provided under a [BSD 2-Clause][bsd-2] license. For any small change set, the license text may be contained within the commit comment and the pull request. For larger contributions, the license must be presented in a COPYING.<feature_name> file in the root of the PerconaFT project. Please see the [BSD 2-Clause license template][bsd-2] for the content of the license text.
-[jira]: https://tokutek.atlassian.net/browse/FT/
+[jira]: https://jira.percona.com/projects/TDB
[bsd-2]: http://opensource.org/licenses/BSD-2-Clause/
diff --git a/storage/tokudb/PerconaFT/ft/ft-ops.cc b/storage/tokudb/PerconaFT/ft/ft-ops.cc
index 60885ed9f33..d036366dd63 100644
--- a/storage/tokudb/PerconaFT/ft/ft-ops.cc
+++ b/storage/tokudb/PerconaFT/ft/ft-ops.cc
@@ -4880,6 +4880,94 @@ static void toku_pfs_keys_init(const char *toku_instr_group_name) {
toku_instr_probe_1 = new toku_instr_probe(*fti_probe_1_key);
}
+static void toku_pfs_keys_destroy(void) {
+ delete kibbutz_mutex_key;
+ delete minicron_p_mutex_key;
+ delete queue_result_mutex_key;
+ delete tpool_lock_mutex_key;
+ delete workset_lock_mutex_key;
+ delete bjm_jobs_lock_mutex_key;
+ delete log_internal_lock_mutex_key;
+ delete cachetable_ev_thread_lock_mutex_key;
+ delete cachetable_disk_nb_mutex_key;
+ delete safe_file_size_lock_mutex_key;
+ delete cachetable_m_mutex_key;
+ delete checkpoint_safe_mutex_key;
+ delete ft_ref_lock_mutex_key;
+ delete ft_open_close_lock_mutex_key;
+ delete loader_error_mutex_key;
+ delete bfs_mutex_key;
+ delete loader_bl_mutex_key;
+ delete loader_fi_lock_mutex_key;
+ delete loader_out_mutex_key;
+ delete result_output_condition_lock_mutex_key;
+ delete block_table_mutex_key;
+ delete rollback_log_node_cache_mutex_key;
+ delete txn_lock_mutex_key;
+ delete txn_state_lock_mutex_key;
+ delete txn_child_manager_mutex_key;
+ delete txn_manager_lock_mutex_key;
+ delete treenode_mutex_key;
+ delete locktree_request_info_mutex_key;
+ delete locktree_request_info_retry_mutex_key;
+ delete manager_mutex_key;
+ delete manager_escalation_mutex_key;
+ delete db_txn_struct_i_txn_mutex_key;
+ delete manager_escalator_mutex_key;
+ delete indexer_i_indexer_lock_mutex_key;
+ delete indexer_i_indexer_estimate_lock_mutex_key;
+
+ delete tokudb_file_data_key;
+ delete tokudb_file_load_key;
+ delete tokudb_file_tmp_key;
+ delete tokudb_file_log_key;
+
+ delete fti_probe_1_key;
+
+ delete extractor_thread_key;
+ delete fractal_thread_key;
+ delete io_thread_key;
+ delete eviction_thread_key;
+ delete kibbutz_thread_key;
+ delete minicron_thread_key;
+ delete tp_internal_thread_key;
+
+ delete result_state_cond_key;
+ delete bjm_jobs_wait_key;
+ delete cachetable_p_refcount_wait_key;
+ delete cachetable_m_flow_control_cond_key;
+ delete cachetable_m_ev_thread_cond_key;
+ delete bfs_cond_key;
+ delete result_output_condition_key;
+ delete manager_m_escalator_done_key;
+ delete lock_request_m_wait_cond_key;
+ delete queue_result_cond_key;
+ delete ws_worker_wait_key;
+ delete rwlock_wait_read_key;
+ delete rwlock_wait_write_key;
+ delete rwlock_cond_key;
+ delete tp_thread_wait_key;
+ delete tp_pool_wait_free_key;
+ delete frwlock_m_wait_read_key;
+ delete kibbutz_k_cond_key;
+ delete minicron_p_condvar_key;
+ delete locktree_request_info_retry_cv_key;
+
+ delete multi_operation_lock_key;
+ delete low_priority_multi_operation_lock_key;
+ delete cachetable_m_list_lock_key;
+ delete cachetable_m_pending_lock_expensive_key;
+ delete cachetable_m_pending_lock_cheap_key;
+ delete cachetable_m_lock_key;
+ delete result_i_open_dbs_rwlock_key;
+ delete checkpoint_safe_rwlock_key;
+ delete cachetable_value_key;
+ delete safe_file_size_lock_rwlock_key;
+
+ delete cachetable_disk_nb_rwlock_key;
+ delete toku_instr_probe_1;
+}
+
int toku_ft_layer_init(void) {
int r = 0;
@@ -4916,8 +5004,7 @@ void toku_ft_layer_destroy(void) {
toku_status_destroy();
partitioned_counters_destroy();
toku_scoped_malloc_destroy();
-
- delete toku_instr_probe_1;
+ toku_pfs_keys_destroy();
// Portability must be cleaned up last
toku_portability_destroy();
diff --git a/storage/tokudb/PerconaFT/ft/tests/ft-clock-test.cc b/storage/tokudb/PerconaFT/ft/tests/ft-clock-test.cc
index 26a3dae673c..00ff8cf204b 100644
--- a/storage/tokudb/PerconaFT/ft/tests/ft-clock-test.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/ft-clock-test.cc
@@ -184,11 +184,11 @@ static void test2(int fd, FT ft_h, FTNODE *dn) {
PAIR_ATTR attr;
memset(&attr, 0, sizeof(attr));
toku_ftnode_pe_callback(*dn, attr, ft_h, def_pe_finalize_impl, nullptr);
- invariant(BP_STATE(*dn, 0) == (is_leaf) ? PT_ON_DISK : PT_COMPRESSED);
+ invariant(BP_STATE(*dn, 0) == ((is_leaf) ? PT_ON_DISK : PT_COMPRESSED));
invariant(BP_STATE(*dn, 1) == PT_AVAIL);
invariant(BP_SHOULD_EVICT(*dn, 1));
toku_ftnode_pe_callback(*dn, attr, ft_h, def_pe_finalize_impl, nullptr);
- invariant(BP_STATE(*dn, 1) == (is_leaf) ? PT_ON_DISK : PT_COMPRESSED);
+ invariant(BP_STATE(*dn, 1) == ((is_leaf) ? PT_ON_DISK : PT_COMPRESSED));
bool req = toku_ftnode_pf_req_callback(*dn, &bfe_subset);
invariant(req);
diff --git a/storage/tokudb/PerconaFT/ft/tests/log-test4.cc b/storage/tokudb/PerconaFT/ft/tests/log-test4.cc
index e0bbedb95bf..019852bb729 100644
--- a/storage/tokudb/PerconaFT/ft/tests/log-test4.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/log-test4.cc
@@ -54,7 +54,7 @@ test_main (int argc __attribute__((__unused__)),
{
ml_lock(&logger->input_lock);
toku_logger_make_space_in_inbuf(logger, 5);
- snprintf(logger->inbuf.buf+logger->inbuf.n_in_buf, 5, "a1234");
+ memcpy(logger->inbuf.buf+logger->inbuf.n_in_buf, "a1234", 5);
logger->inbuf.n_in_buf+=5;
logger->lsn.lsn++;
logger->inbuf.max_lsn_in_buf = logger->lsn;
diff --git a/storage/tokudb/PerconaFT/portability/tests/test-max-data.cc b/storage/tokudb/PerconaFT/portability/tests/test-max-data.cc
index dbbea974a49..fb5fc37111a 100644
--- a/storage/tokudb/PerconaFT/portability/tests/test-max-data.cc
+++ b/storage/tokudb/PerconaFT/portability/tests/test-max-data.cc
@@ -64,7 +64,7 @@ int main(int argc, char *const argv[]) {
if (verbose) printf("maxdata=%" PRIu64 " 0x%" PRIx64 "\n", maxdata, maxdata);
// check the data size
-#if defined(__x86_64__) || defined(__aarch64__)
+#if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__)
assert(maxdata > (1ULL << 32));
#elif __i386__
assert(maxdata < (1ULL << 32));
diff --git a/storage/tokudb/PerconaFT/portability/toku_instrumentation.h b/storage/tokudb/PerconaFT/portability/toku_instrumentation.h
index 8c9390edc0a..c300f9275b8 100644
--- a/storage/tokudb/PerconaFT/portability/toku_instrumentation.h
+++ b/storage/tokudb/PerconaFT/portability/toku_instrumentation.h
@@ -52,6 +52,8 @@ class toku_instr_key {
UU(const char *name)) {}
explicit toku_instr_key(UU(pfs_key_t key_id)) {}
+
+ ~toku_instr_key() {}
};
typedef toku_instr_probe_empty toku_instr_probe;
diff --git a/storage/tokudb/PerconaFT/portability/toku_portability.h b/storage/tokudb/PerconaFT/portability/toku_portability.h
index 1096467a35d..8a3dcf5afc4 100644
--- a/storage/tokudb/PerconaFT/portability/toku_portability.h
+++ b/storage/tokudb/PerconaFT/portability/toku_portability.h
@@ -157,7 +157,7 @@ extern "C" {
#endif
// Deprecated functions.
-#if !defined(TOKU_ALLOW_DEPRECATED)
+#if !defined(TOKU_ALLOW_DEPRECATED) && !defined(__clang__)
int creat(const char *pathname, mode_t mode) __attribute__((__deprecated__));
int fstat(int fd, struct stat *buf) __attribute__((__deprecated__));
int stat(const char *path, struct stat *buf) __attribute__((__deprecated__));
diff --git a/storage/tokudb/PerconaFT/portability/toku_pthread.h b/storage/tokudb/PerconaFT/portability/toku_pthread.h
index 44de01244d2..e3bd3bce598 100644
--- a/storage/tokudb/PerconaFT/portability/toku_pthread.h
+++ b/storage/tokudb/PerconaFT/portability/toku_pthread.h
@@ -168,11 +168,7 @@ typedef struct toku_mutex_aligned {
}
#else // __linux__, at least
#define ZERO_COND_INITIALIZER \
- { \
- { \
- { 0 } \
- } \
- }
+ {}
#endif
static inline void toku_mutexattr_init(toku_pthread_mutexattr_t *attr) {
diff --git a/storage/tokudb/PerconaFT/portability/toku_race_tools.h b/storage/tokudb/PerconaFT/portability/toku_race_tools.h
index 9ed46ec909d..96712ffffdc 100644
--- a/storage/tokudb/PerconaFT/portability/toku_race_tools.h
+++ b/storage/tokudb/PerconaFT/portability/toku_race_tools.h
@@ -95,8 +95,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
# define TOKU_ANNOTATE_IGNORE_WRITES_BEGIN() ((void) 0)
# define TOKU_ANNOTATE_IGNORE_WRITES_END() ((void) 0)
# define TOKU_VALGRIND_RESET_MUTEX_ORDERING_INFO(mutex)
+#undef RUNNING_ON_VALGRIND
# define RUNNING_ON_VALGRIND (0U)
-
#endif
// Valgrind 3.10.1 (and previous versions).
diff --git a/storage/tokudb/PerconaFT/portability/toku_time.h b/storage/tokudb/PerconaFT/portability/toku_time.h
index a1278ef0337..c4c45b8e8c7 100644
--- a/storage/tokudb/PerconaFT/portability/toku_time.h
+++ b/storage/tokudb/PerconaFT/portability/toku_time.h
@@ -43,6 +43,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include <time.h>
#include <sys/time.h>
#include <stdint.h>
+#if defined(__powerpc__)
+# include <sys/platform/ppc.h>
+#endif
static inline float toku_tdiff (struct timeval *a, struct timeval *b) {
return (float)((a->tv_sec - b->tv_sec) + 1e-6 * (a->tv_usec - b->tv_usec));
@@ -106,6 +109,8 @@ static inline tokutime_t toku_time_now(void) {
uint64_t result;
__asm __volatile__ ("mrs %[rt], cntvct_el0" : [rt] "=r" (result));
return result;
+#elif defined(__powerpc__)
+ return __ppc_get_timebase();
#else
#error No timer implementation for this platform
#endif
diff --git a/storage/tokudb/PerconaFT/src/tests/checkpoint_stress.cc b/storage/tokudb/PerconaFT/src/tests/checkpoint_stress.cc
index 135a9843ce4..d3e5ddd5031 100644
--- a/storage/tokudb/PerconaFT/src/tests/checkpoint_stress.cc
+++ b/storage/tokudb/PerconaFT/src/tests/checkpoint_stress.cc
@@ -351,7 +351,7 @@ test_main (int argc, char * const argv[]) {
// arg that suppresses valgrind on this child process
break;
}
- // otherwise, fall through to an error
+ /* fall through */ // otherwise, fall through to an error
case 'h':
case '?':
usage(argv[0]);
diff --git a/storage/tokudb/PerconaFT/src/tests/directory_lock.cc b/storage/tokudb/PerconaFT/src/tests/directory_lock.cc
index f040e680903..b28a71704cf 100644
--- a/storage/tokudb/PerconaFT/src/tests/directory_lock.cc
+++ b/storage/tokudb/PerconaFT/src/tests/directory_lock.cc
@@ -69,7 +69,7 @@ static void verify_shared_ops_fail(DB_ENV* env, DB* db) {
uint32_t flags = 0;
DBT key,val;
DBT in_key,in_val;
- uint32_t in_key_data, in_val_data = 0;
+ uint32_t in_key_data = 0, in_val_data = 0;
memset(&in_key, 0, sizeof(in_key));
memset(&in_val, 0, sizeof(in_val));
in_key.size = sizeof(in_key_data);
diff --git a/storage/tokudb/PerconaFT/src/tests/loader-cleanup-test.cc b/storage/tokudb/PerconaFT/src/tests/loader-cleanup-test.cc
index ea894683c23..a229cb5b565 100644
--- a/storage/tokudb/PerconaFT/src/tests/loader-cleanup-test.cc
+++ b/storage/tokudb/PerconaFT/src/tests/loader-cleanup-test.cc
@@ -172,12 +172,12 @@ err_type_str (enum test_type t) {
case einval_o: return "open";
case enospc_fc: return "fclose";
case abort_via_poll: return "abort_via_poll";
- case commit: assert(0);
- case abort_txn: assert(0);
- case abort_loader: assert(0);
+ case commit: abort();
+ case abort_txn: abort();
+ case abort_loader: abort();
}
// I know that Barry prefers the single-return case, but writing the code this way means that the compiler will complain if I forget something in the enum. -Bradley
- assert(0);
+ abort();
return NULL;
}
@@ -193,12 +193,12 @@ err_msg_type_str (enum test_type t) {
case einval_o: return "EINVAL";
case enospc_fc: return "ENOSPC";
case abort_via_poll: return "non-zero";
- case commit: assert(0);
- case abort_txn: assert(0);
- case abort_loader: assert(0);
+ case commit: abort();
+ case abort_txn: abort();
+ case abort_loader: abort();
}
// I know that Barry prefers the single-return case, but writing the code this way means that the compiler will complain if I forget something in the enum. -Bradley
- assert(0);
+ abort();
return NULL;
}
@@ -873,7 +873,7 @@ static void run_test(enum test_type t, int trigger)
case abort_via_poll:
poll_count_trigger = trigger; break;
default:
- assert(0);
+ abort();
}
diff --git a/storage/tokudb/PerconaFT/src/tests/recover-del-multiple-abort.cc b/storage/tokudb/PerconaFT/src/tests/recover-del-multiple-abort.cc
index a8455c0f406..425c12e1a90 100644
--- a/storage/tokudb/PerconaFT/src/tests/recover-del-multiple-abort.cc
+++ b/storage/tokudb/PerconaFT/src/tests/recover-del-multiple-abort.cc
@@ -81,7 +81,7 @@ put_callback(DB *dest_db, DB *src_db, DBT_ARRAY *dest_keys, DBT_ARRAY *dest_vals
memcpy(dest_key->data, &pri_data[dbnum], dest_key->size);
break;
default:
- assert(0);
+ abort();
}
if (dest_val) {
@@ -95,9 +95,9 @@ put_callback(DB *dest_db, DB *src_db, DBT_ARRAY *dest_keys, DBT_ARRAY *dest_vals
}
break;
case DB_DBT_REALLOC:
- assert(0);
+ abort();
default:
- assert(0);
+ abort();
}
}
diff --git a/storage/tokudb/PerconaFT/src/tests/recover-del-multiple-srcdb-fdelete-all.cc b/storage/tokudb/PerconaFT/src/tests/recover-del-multiple-srcdb-fdelete-all.cc
index e823a74627d..75479cb69c4 100644
--- a/storage/tokudb/PerconaFT/src/tests/recover-del-multiple-srcdb-fdelete-all.cc
+++ b/storage/tokudb/PerconaFT/src/tests/recover-del-multiple-srcdb-fdelete-all.cc
@@ -85,7 +85,7 @@ put_callback(DB *dest_db, DB *src_db, DBT_ARRAY *dest_keys, DBT_ARRAY *dest_vals
memcpy(dest_key->data, &pri_data[dbnum], dest_key->size);
break;
default:
- assert(0);
+ abort();
}
if (dest_val) {
@@ -99,9 +99,9 @@ put_callback(DB *dest_db, DB *src_db, DBT_ARRAY *dest_keys, DBT_ARRAY *dest_vals
}
break;
case DB_DBT_REALLOC:
- assert(0);
+ abort();
default:
- assert(0);
+ abort();
}
}
diff --git a/storage/tokudb/PerconaFT/src/tests/recover-del-multiple.cc b/storage/tokudb/PerconaFT/src/tests/recover-del-multiple.cc
index c2ee80c438f..9f4b1cd9cb8 100644
--- a/storage/tokudb/PerconaFT/src/tests/recover-del-multiple.cc
+++ b/storage/tokudb/PerconaFT/src/tests/recover-del-multiple.cc
@@ -84,7 +84,7 @@ put_callback(DB *dest_db, DB *src_db, DBT_ARRAY *dest_keys, DBT_ARRAY *dest_vals
memcpy(dest_key->data, &pri_data[dbnum], dest_key->size);
break;
default:
- assert(0);
+ abort();
}
if (dest_val) {
@@ -98,9 +98,9 @@ put_callback(DB *dest_db, DB *src_db, DBT_ARRAY *dest_keys, DBT_ARRAY *dest_vals
}
break;
case DB_DBT_REALLOC:
- assert(0);
+ abort();
default:
- assert(0);
+ abort();
}
}
diff --git a/storage/tokudb/PerconaFT/src/tests/recover-put-multiple-abort.cc b/storage/tokudb/PerconaFT/src/tests/recover-put-multiple-abort.cc
index d045800960c..da40a61f24b 100644
--- a/storage/tokudb/PerconaFT/src/tests/recover-put-multiple-abort.cc
+++ b/storage/tokudb/PerconaFT/src/tests/recover-put-multiple-abort.cc
@@ -81,7 +81,7 @@ put_callback(DB *dest_db, DB *src_db, DBT_ARRAY *dest_keys, DBT_ARRAY *dest_vals
memcpy(dest_key->data, &pri_data[dbnum], dest_key->size);
break;
default:
- assert(0);
+ abort();
}
if (dest_val) {
@@ -95,9 +95,9 @@ put_callback(DB *dest_db, DB *src_db, DBT_ARRAY *dest_keys, DBT_ARRAY *dest_vals
}
break;
case DB_DBT_REALLOC:
- assert(0);
+ abort();
default:
- assert(0);
+ abort();
}
}
diff --git a/storage/tokudb/PerconaFT/src/tests/recovery_fileops_unit.cc b/storage/tokudb/PerconaFT/src/tests/recovery_fileops_unit.cc
index cc99ab560d8..45f0b465db4 100644
--- a/storage/tokudb/PerconaFT/src/tests/recovery_fileops_unit.cc
+++ b/storage/tokudb/PerconaFT/src/tests/recovery_fileops_unit.cc
@@ -158,7 +158,7 @@ do_args(int argc, char * const argv[]) {
choices[i] = -1;
}
- char c;
+ signed char c;
while ((c = getopt(argc, argv, "vqhcrO:A:B:C:D:E:F:G:H:I:J:X:")) != -1) {
switch (c) {
case 'v':
@@ -217,7 +217,7 @@ do_args(int argc, char * const argv[]) {
// arg that suppresses valgrind on this child process
break;
}
- // otherwise, fall through to an error
+ /* fall through */ // otherwise, fall through to an error
default:
usage();
break;
diff --git a/storage/tokudb/PerconaFT/src/tests/test-prepare3.cc b/storage/tokudb/PerconaFT/src/tests/test-prepare3.cc
index 5cb3796a26b..f57fc963529 100644
--- a/storage/tokudb/PerconaFT/src/tests/test-prepare3.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test-prepare3.cc
@@ -128,6 +128,7 @@ static void check_prepared_list (enum prepared_state ps[NTXNS], long count, DB_P
goto next;
case PREPARED:
count_prepared++;
+ /* fall through */
case MAYBE_COMMITTED:
case MAYBE_ABORTED:
count_maybe_prepared++;
diff --git a/storage/tokudb/hatoku_hton.cc b/storage/tokudb/hatoku_hton.cc
index ac0976fb119..1016ae83ad2 100644
--- a/storage/tokudb/hatoku_hton.cc
+++ b/storage/tokudb/hatoku_hton.cc
@@ -978,7 +978,7 @@ static bool tokudb_sync_on_prepare(void) {
}
static int tokudb_xa_prepare(handlerton* hton, THD* thd, bool all) {
- TOKUDB_DBUG_ENTER("");
+ TOKUDB_DBUG_ENTER("%u", all);
TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "enter");
int r = 0;
@@ -1006,6 +1006,22 @@ static int tokudb_xa_prepare(handlerton* hton, THD* thd, bool all) {
r = txn->xa_prepare(txn, &thd_xid, syncflag);
// test hook to induce a crash on a debug build
DBUG_EXECUTE_IF("tokudb_crash_prepare_after", DBUG_SUICIDE(););
+
+ // XA log entries can be interleaved in the binlog since XA prepare on the master
+ // flushes to the binlog. There can be log entries from different clients pushed
+ // into the binlog before XA commit is executed on the master. Therefore, the slave
+ // thread must be able to juggle multiple XA transactions. Tokudb does this by
+ // zapping the client transaction context on the slave when executing the XA prepare
+ // and expecting to process XA commit with commit_by_xid (which supplies the XID so
+ // that the transaction can be looked up and committed).
+ if (r == 0 && all && thd->slave_thread) {
+ TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "zap txn context %u", thd_sql_command(thd));
+ if (thd_sql_command(thd) == SQLCOM_XA_PREPARE) {
+ trx->all = NULL;
+ trx->sub_sp_level = NULL;
+ trx->sp_level = NULL;
+ }
+ }
} else {
TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "nothing to prepare %d", all);
}
@@ -1036,6 +1052,7 @@ static int tokudb_xa_recover(handlerton* hton, XID* xid_list, uint len) {
static int tokudb_commit_by_xid(handlerton* hton, XID* xid) {
TOKUDB_DBUG_ENTER("");
TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "enter");
+ TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "xid %p", xid);
int r = 0;
DB_TXN* txn = NULL;
TOKU_XA_XID* toku_xid = (TOKU_XA_XID*)xid;
@@ -1055,6 +1072,7 @@ cleanup:
static int tokudb_rollback_by_xid(handlerton* hton, XID* xid) {
TOKUDB_DBUG_ENTER("");
TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "enter");
+ TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "xid %p", xid);
int r = 0;
DB_TXN* txn = NULL;
TOKU_XA_XID* toku_xid = (TOKU_XA_XID*)xid;
diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt
index 67d068748d2..f5ec6fd746d 100644
--- a/storage/xtradb/CMakeLists.txt
+++ b/storage/xtradb/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -509,9 +509,11 @@ MYSQL_ADD_PLUGIN(xtradb ${INNOBASE_SOURCES} STORAGE_ENGINE
DEFAULT RECOMPILE_FOR_EMBEDDED
LINK_LIBRARIES ${ZLIB_LIBRARY} ${LINKER_SCRIPT})
-IF(TARGET xtradb AND NOT XTRADB_OK)
- MESSAGE(FATAL_ERROR "Percona XtraDB is not supported on this platform")
+IF(TARGET xtradb)
+ IF(NOT XTRADB_OK)
+ MESSAGE(FATAL_ERROR "Percona XtraDB is not supported on this platform")
+ ENDIF()
+ ADD_DEPENDENCIES(xtradb GenError)
ENDIF()
ADD_SUBDIRECTORY(${CMAKE_SOURCE_DIR}/extra/mariabackup ${CMAKE_BINARY_DIR}/extra/mariabackup)
-
diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc
index 9257321c7ef..4aa29de1cf4 100644
--- a/storage/xtradb/dict/dict0dict.cc
+++ b/storage/xtradb/dict/dict0dict.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
Copyright (c) 2013, 2017, MariaDB Corporation.
@@ -2080,6 +2080,30 @@ dict_table_remove_from_cache_low(
foreign->referenced_index = NULL;
}
+ /* The check for dropped index should happen before we release
+ all the indexes */
+
+ if (lru_evict && table->drop_aborted) {
+ /* When evicting the table definition,
+ drop the orphan indexes from the data dictionary
+ and free the index pages. */
+ trx_t* trx = trx_allocate_for_background();
+
+ ut_ad(mutex_own(&dict_sys->mutex));
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
+#endif /* UNIV_SYNC_DEBUG */
+ /* Mimic row_mysql_lock_data_dictionary(). */
+ trx->dict_operation_lock_mode = RW_X_LATCH;
+
+ trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
+ row_merge_drop_indexes_dict(trx, table->id);
+
+ trx_commit_for_mysql(trx);
+ trx->dict_operation_lock_mode = 0;
+ trx_free_for_background(trx);
+ }
+
/* Remove the indexes from the cache */
for (index = UT_LIST_GET_LAST(table->indexes);
@@ -2112,27 +2136,6 @@ dict_table_remove_from_cache_low(
dict_table_autoinc_store(table);
}
- if (lru_evict && table->drop_aborted) {
- /* When evicting the table definition,
- drop the orphan indexes from the data dictionary
- and free the index pages. */
- trx_t* trx = trx_allocate_for_background();
-
- ut_ad(mutex_own(&dict_sys->mutex));
-#ifdef UNIV_SYNC_DEBUG
- ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
-#endif /* UNIV_SYNC_DEBUG */
- /* Mimic row_mysql_lock_data_dictionary(). */
- trx->dict_operation_lock_mode = RW_X_LATCH;
-
- trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
- row_merge_drop_indexes_dict(trx, table->id);
-
- trx_commit_for_mysql(trx);
- trx->dict_operation_lock_mode = 0;
- trx_free_for_background(trx);
- }
-
dict_mem_table_free(table);
}
diff --git a/storage/xtradb/dict/dict0mem.cc b/storage/xtradb/dict/dict0mem.cc
index cf27caf6c28..ab6167b920b 100644
--- a/storage/xtradb/dict/dict0mem.cc
+++ b/storage/xtradb/dict/dict0mem.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
Copyright (c) 2013, 2018, MariaDB Corporation.
diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc
index bcd406816a0..42cb2056dfc 100644
--- a/storage/xtradb/fts/fts0fts.cc
+++ b/storage/xtradb/fts/fts0fts.cc
@@ -4747,9 +4747,17 @@ fts_process_token(
t_str.f_str = static_cast<byte*>(
mem_heap_alloc(heap, t_str.f_len));
- newlen = innobase_fts_casedn_str(
- doc->charset, (char*) str.f_str, str.f_len,
- (char*) t_str.f_str, t_str.f_len);
+ /* For binary collations, a case sensitive search is
+ performed. Hence don't convert to lower case. */
+ if (my_binary_compare(result_doc->charset)) {
+ memcpy(t_str.f_str, str.f_str, str.f_len);
+ t_str.f_str[str.f_len]= 0;
+ newlen= str.f_len;
+ } else {
+ newlen = innobase_fts_casedn_str(
+ doc->charset, (char*) str.f_str, str.f_len,
+ (char*) t_str.f_str, t_str.f_len);
+ }
t_str.f_len = newlen;
t_str.f_str[newlen] = 0;
diff --git a/storage/xtradb/fts/fts0que.cc b/storage/xtradb/fts/fts0que.cc
index 0b0aecaeaa2..100dbcd70ca 100644
--- a/storage/xtradb/fts/fts0que.cc
+++ b/storage/xtradb/fts/fts0que.cc
@@ -3783,10 +3783,19 @@ fts_query_str_preprocess(
str_len = query_len * charset->casedn_multiply + 1;
str_ptr = static_cast<byte*>(ut_malloc(str_len));
- *result_len = innobase_fts_casedn_str(
- charset, const_cast<char*>(reinterpret_cast<const char*>(
- query_str)), query_len,
- reinterpret_cast<char*>(str_ptr), str_len);
+ /* For binary collations, a case sensitive search is
+ performed. Hence don't convert to lower case. */
+ if (my_binary_compare(charset)) {
+ memcpy(str_ptr, query_str, query_len);
+ str_ptr[query_len]= 0;
+ *result_len= query_len;
+ } else {
+ *result_len = innobase_fts_casedn_str(
+ charset, const_cast<char*>
+ (reinterpret_cast<const char*>( query_str)),
+ query_len,
+ reinterpret_cast<char*>(str_ptr), str_len);
+ }
ut_ad(*result_len < str_len);
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index f120837ef1f..238627ce003 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -4564,6 +4564,14 @@ innobase_change_buffering_inited_ok:
/* Turn on monitor counters that are default on */
srv_mon_default_on();
+#ifndef UNIV_HOTBACKUP
+#ifdef _WIN32
+ if (ut_win_init_time()) {
+ goto mem_free_and_error;
+ }
+#endif /* _WIN32 */
+#endif /* !UNIV_HOTBACKUP */
+
DBUG_RETURN(FALSE);
error:
DBUG_RETURN(TRUE);
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index f4adc2e8e54..7e1a6b0eeac 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -45,10 +45,10 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 5
#define INNODB_VERSION_MINOR 6
-#define INNODB_VERSION_BUGFIX 38
+#define INNODB_VERSION_BUGFIX 39
#ifndef PERCONA_INNODB_VERSION
-#define PERCONA_INNODB_VERSION 83.0
+#define PERCONA_INNODB_VERSION 83.1
#endif
/* Enable UNIV_LOG_ARCHIVE in XtraDB */
diff --git a/storage/xtradb/include/ut0ut.h b/storage/xtradb/include/ut0ut.h
index 5fba1c7f547..726c01a2e0f 100644
--- a/storage/xtradb/include/ut0ut.h
+++ b/storage/xtradb/include/ut0ut.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2017, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -283,6 +283,15 @@ UNIV_INTERN
ulint
ut_time_ms(void);
/*============*/
+#ifdef _WIN32
+/**********************************************************//**
+Initialise highest available time resolution API on Windows
+@return 0 if all OK else -1 */
+int
+ut_win_init_time();
+
+#endif /* _WIN32 */
+
#endif /* !UNIV_HOTBACKUP */
/**********************************************************//**
diff --git a/storage/xtradb/row/row0log.cc b/storage/xtradb/row/row0log.cc
index 040fb37ee30..21f1a1c5974 100644
--- a/storage/xtradb/row/row0log.cc
+++ b/storage/xtradb/row/row0log.cc
@@ -466,6 +466,8 @@ err_exit:
*avail = srv_sort_buf_size - log->tail.bytes;
if (size > *avail) {
+ /* Make sure log->tail.buf is large enough */
+ ut_ad(size <= sizeof log->tail.buf);
return(log->tail.buf);
} else {
return(log->tail.block + log->tail.bytes);
@@ -584,12 +586,10 @@ row_log_table_delete(
{
ulint old_pk_extra_size;
ulint old_pk_size;
- ulint ext_size = 0;
ulint mrec_size;
ulint avail_size;
mem_heap_t* heap = NULL;
const dtuple_t* old_pk;
- row_ext_t* ext;
ut_ad(dict_index_is_clust(index));
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -670,72 +670,20 @@ row_log_table_delete(
&old_pk_extra_size);
ut_ad(old_pk_extra_size < 0x100);
- mrec_size = 6 + old_pk_size;
-
- /* Log enough prefix of the BLOB unless both the
- old and new table are in COMPACT or REDUNDANT format,
- which store the prefix in the clustered index record. */
- if (rec_offs_any_extern(offsets)
- && (dict_table_get_format(index->table) >= UNIV_FORMAT_B
- || dict_table_get_format(new_table) >= UNIV_FORMAT_B)) {
-
- /* Build a cache of those off-page column prefixes
- that are referenced by secondary indexes. It can be
- that none of the off-page columns are needed. */
- row_build(ROW_COPY_DATA, index, rec,
- offsets, NULL, NULL, NULL, &ext, heap);
- if (ext) {
- /* Log the row_ext_t, ext->ext and ext->buf */
- ext_size = ext->n_ext * ext->max_len
- + sizeof(*ext)
- + ext->n_ext * sizeof(ulint)
- + (ext->n_ext - 1) * sizeof ext->len;
- mrec_size += ext_size;
- }
- }
+ /* 2 = 1 (extra_size) + at least 1 byte payload */
+ mrec_size = 2 + old_pk_size;
if (byte* b = row_log_table_open(index->online_log,
mrec_size, &avail_size)) {
*b++ = ROW_T_DELETE;
*b++ = static_cast<byte>(old_pk_extra_size);
- /* Log the size of external prefix we saved */
- mach_write_to_4(b, ext_size);
- b += 4;
-
rec_convert_dtuple_to_temp(
b + old_pk_extra_size, new_index,
old_pk->fields, old_pk->n_fields);
b += old_pk_size;
- if (ext_size) {
- ulint cur_ext_size = sizeof(*ext)
- + (ext->n_ext - 1) * sizeof ext->len;
-
- memcpy(b, ext, cur_ext_size);
- b += cur_ext_size;
-
- /* Check if we need to col_map to adjust the column
- number. If columns were added/removed/reordered,
- adjust the column number. */
- if (const ulint* col_map =
- index->online_log->col_map) {
- for (ulint i = 0; i < ext->n_ext; i++) {
- const_cast<ulint&>(ext->ext[i]) =
- col_map[ext->ext[i]];
- }
- }
-
- memcpy(b, ext->ext, ext->n_ext * sizeof(*ext->ext));
- b += ext->n_ext * sizeof(*ext->ext);
-
- ext_size -= cur_ext_size
- + ext->n_ext * sizeof(*ext->ext);
- memcpy(b, ext->buf, ext_size);
- b += ext_size;
- }
-
row_log_table_close(index, b, mrec_size, avail_size);
}
@@ -1654,15 +1602,13 @@ row_log_table_apply_insert(
/******************************************************//**
Deletes a record from a table that is being rebuilt.
@return DB_SUCCESS or error code */
-static MY_ATTRIBUTE((nonnull(1, 2, 4, 5), warn_unused_result))
+static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t
row_log_table_apply_delete_low(
/*===========================*/
btr_pcur_t* pcur, /*!< in/out: B-tree cursor,
will be trashed */
const ulint* offsets, /*!< in: offsets on pcur */
- const row_ext_t* save_ext, /*!< in: saved external field
- info, or NULL */
mem_heap_t* heap, /*!< in/out: memory heap */
mtr_t* mtr) /*!< in/out: mini-transaction,
will be committed */
@@ -1686,11 +1632,7 @@ row_log_table_apply_delete_low(
/* Build a row template for purging secondary index entries. */
row = row_build(
ROW_COPY_DATA, index, btr_pcur_get_rec(pcur),
- offsets, NULL, NULL, NULL,
- save_ext ? NULL : &ext, heap);
- if (!save_ext) {
- save_ext = ext;
- }
+ offsets, NULL, NULL, NULL, &ext, heap);
} else {
row = NULL;
}
@@ -1709,7 +1651,7 @@ row_log_table_apply_delete_low(
}
const dtuple_t* entry = row_build_index_entry(
- row, save_ext, index, heap);
+ row, ext, index, heap);
mtr_start(mtr);
btr_pcur_open(index, entry, PAGE_CUR_LE,
BTR_MODIFY_TREE, pcur, mtr);
@@ -1752,11 +1694,10 @@ flag_ok:
/******************************************************//**
Replays a delete operation on a table that was rebuilt.
@return DB_SUCCESS or error code */
-static MY_ATTRIBUTE((nonnull(1, 3, 4, 5, 6, 7), warn_unused_result))
+static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t
row_log_table_apply_delete(
/*=======================*/
- que_thr_t* thr, /*!< in: query graph */
ulint trx_id_col, /*!< in: position of
DB_TRX_ID in the new
clustered index */
@@ -1765,9 +1706,7 @@ row_log_table_apply_delete(
mem_heap_t* offsets_heap, /*!< in/out: memory heap
that can be emptied */
mem_heap_t* heap, /*!< in/out: memory heap */
- const row_log_t* log, /*!< in: online log */
- const row_ext_t* save_ext) /*!< in: saved external field
- info, or NULL */
+ const row_log_t* log) /*!< in: online log */
{
dict_table_t* new_table = log->table;
dict_index_t* index = dict_table_get_first_index(new_table);
@@ -1867,8 +1806,7 @@ all_done:
}
}
- return(row_log_table_apply_delete_low(&pcur, offsets, save_ext,
- heap, &mtr));
+ return row_log_table_apply_delete_low(&pcur, offsets, heap, &mtr);
}
/******************************************************//**
@@ -2079,7 +2017,7 @@ func_exit_committed:
/* Some BLOBs are missing, so we are interpreting
this ROW_T_UPDATE as ROW_T_DELETE (see *1). */
error = row_log_table_apply_delete_low(
- &pcur, cur_offsets, NULL, heap, &mtr);
+ &pcur, cur_offsets, heap, &mtr);
goto func_exit_committed;
}
@@ -2117,7 +2055,7 @@ func_exit_committed:
}
error = row_log_table_apply_delete_low(
- &pcur, cur_offsets, NULL, heap, &mtr);
+ &pcur, cur_offsets, heap, &mtr);
ut_ad(mtr.state == MTR_COMMITTED);
if (error == DB_SUCCESS) {
@@ -2263,8 +2201,6 @@ row_log_table_apply_op(
ulint extra_size;
const mrec_t* next_mrec;
dtuple_t* old_pk;
- row_ext_t* ext;
- ulint ext_size;
ut_ad(dict_index_is_clust(dup->index));
ut_ad(dup->index->table != log->table);
@@ -2272,7 +2208,7 @@ row_log_table_apply_op(
*error = DB_SUCCESS;
- /* 3 = 1 (op type) + 1 (ext_size) + at least 1 byte payload */
+ /* 3 = 1 (op type) + 1 (extra_size) + at least 1 byte payload */
if (mrec + 3 >= mrec_end) {
return(NULL);
}
@@ -2322,14 +2258,12 @@ row_log_table_apply_op(
break;
case ROW_T_DELETE:
- /* 1 (extra_size) + 4 (ext_size) + at least 1 (payload) */
- if (mrec + 6 >= mrec_end) {
+ /* 1 (extra_size) + at least 1 (payload) */
+ if (mrec + 2 >= mrec_end) {
return(NULL);
}
extra_size = *mrec++;
- ext_size = mach_read_from_4(mrec);
- mrec += 4;
ut_ad(mrec < mrec_end);
/* We assume extra_size < 0x100 for the PRIMARY KEY prefix.
@@ -2338,40 +2272,16 @@ row_log_table_apply_op(
rec_offs_set_n_fields(offsets, new_index->n_uniq + 2);
rec_init_offsets_temp(mrec, new_index, offsets);
- next_mrec = mrec + rec_offs_data_size(offsets) + ext_size;
+ next_mrec = mrec + rec_offs_data_size(offsets);
if (next_mrec > mrec_end) {
return(NULL);
}
log->head.total += next_mrec - mrec_start;
- /* If there are external fields, retrieve those logged
- prefix info and reconstruct the row_ext_t */
- if (ext_size) {
- /* We use memcpy to avoid unaligned
- access on some non-x86 platforms.*/
- ext = static_cast<row_ext_t*>(
- mem_heap_dup(heap,
- mrec + rec_offs_data_size(offsets),
- ext_size));
-
- byte* ext_start = reinterpret_cast<byte*>(ext);
-
- ulint ext_len = sizeof(*ext)
- + (ext->n_ext - 1) * sizeof ext->len;
-
- ext->ext = reinterpret_cast<ulint*>(ext_start + ext_len);
- ext_len += ext->n_ext * sizeof(*ext->ext);
-
- ext->buf = static_cast<byte*>(ext_start + ext_len);
- } else {
- ext = NULL;
- }
-
*error = row_log_table_apply_delete(
- thr, new_trx_id_col,
- mrec, offsets, offsets_heap, heap,
- log, ext);
+ new_trx_id_col,
+ mrec, offsets, offsets_heap, heap, log);
break;
case ROW_T_UPDATE:
diff --git a/storage/xtradb/ut/ut0ut.cc b/storage/xtradb/ut/ut0ut.cc
index fd52537ae11..695be4907e0 100644
--- a/storage/xtradb/ut/ut0ut.cc
+++ b/storage/xtradb/ut/ut0ut.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2017, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -47,6 +47,10 @@ Created 5/11/1994 Heikki Tuuri
#endif /* UNIV_HOTBACKUP */
#ifdef __WIN__
+#include <innodb_priv.h> /* For sql_print_error */
+typedef VOID(WINAPI *time_fn)(LPFILETIME);
+static time_fn ut_get_system_time_as_file_time = GetSystemTimeAsFileTime;
+
/*****************************************************************//**
NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix
epoch starts from 1970/1/1. For selection of constant see:
@@ -54,6 +58,28 @@ http://support.microsoft.com/kb/167296/ */
#define WIN_TO_UNIX_DELTA_USEC ((ib_int64_t) 11644473600000000ULL)
+/**
+Initialise highest available time resolution API on Windows
+@return 0 if all OK else -1 */
+int
+ut_win_init_time()
+{
+ HMODULE h = LoadLibrary("kernel32.dll");
+ if (h != NULL)
+ {
+ time_fn pfn = (time_fn)GetProcAddress(h, "GetSystemTimePreciseAsFileTime");
+ if (pfn != NULL)
+ {
+ ut_get_system_time_as_file_time = pfn;
+ }
+ return false;
+ }
+ DWORD error = GetLastError();
+ sql_print_error(
+ "LoadLibrary(\"kernel32.dll\") failed: GetLastError returns %lu", error);
+ return(-1);
+}
+
/*****************************************************************//**
This is the Windows version of gettimeofday(2).
@return 0 if all OK else -1 */
@@ -72,7 +98,7 @@ ut_gettimeofday(
return(-1);
}
- GetSystemTimeAsFileTime(&ft);
+ ut_get_system_time_as_file_time(&ft);
tm = (ib_int64_t) ft.dwHighDateTime << 32;
tm |= ft.dwLowDateTime;