summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2017-01-18 19:46:52 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2017-01-18 22:21:19 +0200
commit96c49808bd64e2dd45c24e8746b32b96c37da98a (patch)
tree90b646ce116d94a6c0fa71382598e79f522c763c
parenta1315a650a69745bac7166cfe1423215dfaac6e1 (diff)
parentf7d030489d2980c9deb733925515099ec256f6d2 (diff)
downloadmariadb-git-10.2-merge.tar.gz
WIP merge 10.1 to 10.210.2-merge
Bootstrap fails: mysqld: sql/field.h:957: bool Field::has_explicit_value(): Assertion `table->has_value_set' failed. assertion=0x1411e89 "table->has_value_set", file=0x1411e9e "/home/marko/mariadb/server/sql/field.h", line=957, function=0x1411ec5 "bool Field::has_explicit_value()") at assert.c:101 at /home/marko/mariadb/server/sql/field.h:957 table_list=0x7fff7407b4f0, fields=..., values_list=..., update_fields=..., update_values=..., duplic=DUP_ERROR, ignore=false) at /home/marko/mariadb/server/sql/sql_insert.cc:1017 at /home/marko/mariadb/server/sql/sql_parse.cc:4370 rawbuf=0x7fff740f43e0 " INSERT INTO global_suppressions VALUES (\".SELECT UNIX_TIMESTAMP... failed on master\"), (\"Aborted connection\"), (\"Client requested master to start replication from impossible position\"), (\"Could"..., length=6339, parser_state=0x7fffe8efcab8, is_com_multi=false, is_next_command=false) at /home/marko/mariadb/server/sql/sql_parse.cc:7839 at /home/marko/mariadb/server/sql/sql_parse.cc:1033 There are unresolved conflicts in the following files: mysql-test/suite/galera/r/galera_var_cluster_address.result mysql-test/suite/innodb/r/innodb-wl5522-debug-zip.result mysql-test/suite/innodb/r/innodb-wl5522-debug.result mysql-test/suite/innodb/r/innodb_bug14147491.result mysql-test/suite/innodb/r/xa_recovery.result mysql-test/suite/innodb/t/doublewrite.test mysql-test/suite/innodb/t/innodb-wl5522-debug-zip.test mysql-test/suite/innodb/t/innodb-wl5522-debug.test mysql-test/suite/innodb/t/innodb_bug14147491.test mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result mysql-test/suite/sys_vars/r/sysvars_innodb.result mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff mysql-test/suite/vcol/inc/vcol_trigger_sp.inc mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result
-rw-r--r--.gitignore2
-rw-r--r--client/mysqladmin.cc6
-rw-r--r--debian/mariadb-server-10.2.install1
-rwxr-xr-xdebian/patches/33_scripts__mysql_create_system_tables__no_test.dpatch24
-rw-r--r--extra/CMakeLists.txt3
-rw-r--r--extra/mysqld_safe_helper.c77
-rw-r--r--include/my_sys.h4
-rw-r--r--man/mysql_secure_installation.172
-rw-r--r--mysql-test/extra/rpl_tests/rpl_special_charset.inc2
-rw-r--r--mysql-test/r/cast.result73
-rw-r--r--mysql-test/r/create.result7
-rw-r--r--mysql-test/r/ctype_ucs.result10
-rw-r--r--mysql-test/r/ctype_ucs2_def.result2
-rw-r--r--mysql-test/r/ctype_ucs2_query_cache.result2
-rw-r--r--mysql-test/r/ctype_utf16.result10
-rw-r--r--mysql-test/r/ctype_utf16_def.result2
-rw-r--r--mysql-test/r/ctype_utf32.result10
-rw-r--r--mysql-test/r/events_slowlog.result13
-rw-r--r--mysql-test/r/func_time.result6
-rw-r--r--mysql-test/r/index_merge_innodb.result29
-rw-r--r--mysql-test/r/information_schema_part.result8
-rw-r--r--mysql-test/r/insert_update.result4
-rw-r--r--mysql-test/r/join_cache.result16
-rw-r--r--mysql-test/r/loaddata.result22
-rw-r--r--mysql-test/r/log_slow.result2
-rw-r--r--mysql-test/r/mysqld--help.result5
-rw-r--r--mysql-test/r/order_by.result11
-rw-r--r--mysql-test/r/subselect.result11
-rw-r--r--mysql-test/r/subselect2.result45
-rw-r--r--mysql-test/r/subselect4.result39
-rw-r--r--mysql-test/r/subselect_no_exists_to_in.result11
-rw-r--r--mysql-test/r/subselect_no_mat.result11
-rw-r--r--mysql-test/r/subselect_no_opts.result11
-rw-r--r--mysql-test/r/subselect_no_scache.result11
-rw-r--r--mysql-test/r/subselect_no_semijoin.result11
-rw-r--r--mysql-test/r/trigger_no_defaults-11698.result22
-rw-r--r--mysql-test/r/trigger_null-8605.result10
-rw-r--r--mysql-test/r/union.result33
-rw-r--r--mysql-test/std_data/bug20683959loaddata.txt1
-rw-r--r--mysql-test/std_data/loaddata/mdev-11079.txt1
-rw-r--r--mysql-test/std_data/loaddata/mdev-11631.txt1
-rw-r--r--mysql-test/suite/binlog_encryption/rpl_special_charset.result2
-rw-r--r--mysql-test/suite/encryption/disabled.def4
-rw-r--r--mysql-test/suite/encryption/r/innodb_lotoftables.result24
-rw-r--r--mysql-test/suite/funcs_2/t/innodb_charset.test1
-rw-r--r--mysql-test/suite/galera/r/galera_var_cluster_address.result4
-rw-r--r--mysql-test/suite/galera/suite.pm1
-rw-r--r--mysql-test/suite/galera/t/galera_var_cluster_address.test2
-rw-r--r--mysql-test/suite/innodb/include/ibd_convert.pl25
-rw-r--r--mysql-test/suite/innodb/r/101_compatibility.result48
-rw-r--r--mysql-test/suite/innodb/r/doublewrite.result2
-rw-r--r--mysql-test/suite/innodb/r/group_commit_crash.result1
-rw-r--r--mysql-test/suite/innodb/r/group_commit_crash_no_optimize_thread.result1
-rw-r--r--mysql-test/suite/innodb/r/innodb-alter-tempfile.result4
-rw-r--r--mysql-test/suite/innodb/r/innodb-wl5522-debug-zip.result18
-rw-r--r--mysql-test/suite/innodb/r/innodb-wl5522-debug.result9
-rw-r--r--mysql-test/suite/innodb/r/innodb_bug14147491.result17
-rw-r--r--mysql-test/suite/innodb/r/xa_recovery.result5
-rw-r--r--mysql-test/suite/innodb/t/101_compatibility.test101
-rw-r--r--mysql-test/suite/innodb/t/doublewrite.test48
-rw-r--r--mysql-test/suite/innodb/t/group_commit_crash.test2
-rw-r--r--mysql-test/suite/innodb/t/group_commit_crash_no_optimize_thread.test2
-rw-r--r--mysql-test/suite/innodb/t/innodb-alter-tempfile.test7
-rw-r--r--mysql-test/suite/innodb/t/innodb-wl5522-debug-zip.test6
-rw-r--r--mysql-test/suite/innodb/t/innodb-wl5522-debug.test5
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug14147491.test18
-rw-r--r--mysql-test/suite/innodb/t/xa_recovery.test16
-rw-r--r--mysql-test/suite/rpl/r/rpl_gtid_crash.result1
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result69
-rw-r--r--mysql-test/suite/rpl/r/rpl_special_charset.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_strict_password_validation.result13
-rw-r--r--mysql-test/suite/rpl/t/rpl_gtid_crash.test5
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test121
-rw-r--r--mysql-test/suite/rpl/t/rpl_strict_password_validation.test24
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb.result18
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff345
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_embedded.result14
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff361
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result14
-rw-r--r--mysql-test/suite/sys_vars/t/sysvars_innodb.test5
-rw-r--r--mysql-test/suite/vcol/inc/vcol_trigger_sp.inc11
-rw-r--r--mysql-test/suite/vcol/r/vcol_misc.result7
-rw-r--r--mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result10
-rw-r--r--mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result10
-rw-r--r--mysql-test/suite/vcol/r/wrong_arena.result61
-rw-r--r--mysql-test/suite/vcol/t/vcol_misc.test11
-rw-r--r--mysql-test/suite/vcol/t/wrong_arena.test35
-rw-r--r--mysql-test/t/cast.test39
-rw-r--r--mysql-test/t/create.test9
-rw-r--r--mysql-test/t/ctype_ucs.test8
-rw-r--r--mysql-test/t/ctype_ucs2_def.test2
-rw-r--r--mysql-test/t/ctype_ucs2_query_cache.test2
-rw-r--r--mysql-test/t/ctype_utf16.test9
-rw-r--r--mysql-test/t/ctype_utf16_def.test2
-rw-r--r--mysql-test/t/ctype_utf32.test9
-rw-r--r--mysql-test/t/events_slowlog.test28
-rw-r--r--mysql-test/t/func_time.test5
-rw-r--r--mysql-test/t/index_merge_innodb.test33
-rw-r--r--mysql-test/t/information_schema_part.test7
-rw-r--r--mysql-test/t/insert_update.test6
-rw-r--r--mysql-test/t/join_cache.test10
-rw-r--r--mysql-test/t/loaddata.test22
-rw-r--r--mysql-test/t/log_slow.test2
-rw-r--r--mysql-test/t/order_by.test10
-rw-r--r--mysql-test/t/subselect.test11
-rw-r--r--mysql-test/t/subselect2.test50
-rw-r--r--mysql-test/t/subselect4.test41
-rw-r--r--mysql-test/t/trigger_no_defaults-11698.test25
-rw-r--r--mysql-test/t/trigger_null-8605.test14
-rw-r--r--mysql-test/t/union.test24
-rw-r--r--mysql-test/unstable-tests144
-rw-r--r--mysql-test/valgrind.supp8
-rw-r--r--mysys/CMakeLists.txt2
-rw-r--r--mysys/my_malloc.c15
-rw-r--r--mysys/my_setuser.c82
-rw-r--r--plugin/server_audit/server_audit.c1
-rw-r--r--scripts/mysql_install_db.sh40
-rw-r--r--scripts/mysql_system_tables_data.sql27
-rw-r--r--scripts/mysqld_safe.sh96
-rw-r--r--sql/event_db_repository.cc15
-rw-r--r--sql/field.cc22
-rw-r--r--sql/filesort.cc2
-rw-r--r--sql/handler.cc2
-rw-r--r--sql/item.cc50
-rw-r--r--sql/item.h2
-rw-r--r--sql/item_cmpfunc.cc22
-rw-r--r--sql/item_cmpfunc.h11
-rw-r--r--sql/item_func.cc5
-rw-r--r--sql/item_func.h12
-rw-r--r--sql/item_subselect.cc19
-rw-r--r--sql/item_timefunc.cc9
-rw-r--r--sql/log_event.cc1
-rw-r--r--sql/my_json_writer.cc8
-rw-r--r--sql/mysqld.cc128
-rw-r--r--sql/signal_handler.cc2
-rw-r--r--sql/sp_head.cc22
-rw-r--r--sql/sql_acl.cc9
-rw-r--r--sql/sql_base.cc2
-rw-r--r--sql/sql_class.cc9
-rw-r--r--sql/sql_class.h21
-rw-r--r--sql/sql_connect.cc10
-rw-r--r--sql/sql_delete.cc3
-rw-r--r--sql/sql_insert.cc121
-rw-r--r--sql/sql_insert.h3
-rw-r--r--sql/sql_lex.cc6
-rw-r--r--sql/sql_load.cc4
-rw-r--r--sql/sql_parse.cc17
-rw-r--r--sql/sql_parse.h1
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_select.cc32
-rw-r--r--sql/sql_select.h6
-rw-r--r--sql/sql_table.cc12
-rw-r--r--sql/sql_trigger.cc3
-rw-r--r--sql/sql_udf.cc6
-rw-r--r--sql/sql_yacc.yy8
-rw-r--r--sql/sys_vars.cc10
-rw-r--r--sql/sys_vars.ic2
-rw-r--r--sql/table.cc21
-rw-r--r--storage/connect/ApacheInterface.java5
-rw-r--r--storage/connect/CMakeLists.txt45
-rw-r--r--storage/connect/JavaWrappers.jarbin0 -> 19696 bytes
-rw-r--r--storage/connect/JdbcInterface.java16
-rw-r--r--storage/connect/domdoc.cpp40
-rw-r--r--storage/connect/domdoc.h4
-rw-r--r--storage/connect/filamap.cpp53
-rw-r--r--storage/connect/filamap.h3
-rw-r--r--storage/connect/filamgz.cpp1426
-rw-r--r--storage/connect/filamgz.h170
-rw-r--r--storage/connect/filamzip.cpp1740
-rw-r--r--storage/connect/filamzip.h249
-rw-r--r--storage/connect/ha_connect.cc50
-rw-r--r--storage/connect/ha_connect.h39
-rw-r--r--storage/connect/ioapi.c247
-rw-r--r--storage/connect/ioapi.h209
-rw-r--r--storage/connect/jdbccat.h1
-rw-r--r--storage/connect/jdbconn.cpp178
-rw-r--r--storage/connect/jdbconn.h6
-rw-r--r--storage/connect/jsonudf.cpp47
-rw-r--r--storage/connect/jsonudf.h3
-rw-r--r--storage/connect/libdoc.cpp30
-rw-r--r--storage/connect/mycat.cc22
-rw-r--r--storage/connect/mycat.h1
-rw-r--r--storage/connect/mysql-test/connect/disabled.def4
-rw-r--r--storage/connect/mysql-test/connect/r/jdbc_new.result6
-rw-r--r--storage/connect/mysql-test/connect/std_data/JdbcMariaDB.jarbin5993273 -> 6021947 bytes
-rw-r--r--storage/connect/mysql-test/connect/t/jdbc.test1
-rw-r--r--storage/connect/mysql-test/connect/t/jdbc_new.test1
-rw-r--r--storage/connect/mysql-test/connect/t/windows.inc5
-rw-r--r--storage/connect/plgdbsem.h17
-rw-r--r--storage/connect/plgdbutl.cpp14
-rw-r--r--storage/connect/plgxml.cpp55
-rw-r--r--storage/connect/plgxml.h16
-rw-r--r--storage/connect/reldef.cpp29
-rw-r--r--storage/connect/tabdos.cpp83
-rw-r--r--storage/connect/tabdos.h20
-rw-r--r--storage/connect/tabfix.cpp19
-rw-r--r--storage/connect/tabfmt.cpp217
-rw-r--r--storage/connect/tabfmt.h29
-rw-r--r--storage/connect/tabjdbc.cpp4
-rw-r--r--storage/connect/tabjdbc.h1
-rw-r--r--storage/connect/tabjson.cpp102
-rw-r--r--storage/connect/tabjson.h3
-rw-r--r--storage/connect/tabxml.cpp63
-rw-r--r--storage/connect/tabxml.h18
-rw-r--r--storage/connect/tabzip.cpp230
-rw-r--r--storage/connect/tabzip.h100
-rw-r--r--storage/connect/unzip.c2125
-rw-r--r--storage/connect/unzip.h437
-rw-r--r--storage/connect/value.cpp35
-rw-r--r--storage/connect/value.h66
-rwxr-xr-xstorage/connect/xindex.cpp8
-rw-r--r--storage/connect/zip.c2007
-rw-r--r--storage/connect/zip.h362
-rw-r--r--storage/innobase/btr/btr0defragment.cc2
-rw-r--r--storage/innobase/buf/buf0buf.cc2
-rw-r--r--storage/innobase/buf/buf0dblwr.cc245
-rw-r--r--storage/innobase/buf/buf0dump.cc2
-rw-r--r--storage/innobase/buf/buf0flu.cc4
-rw-r--r--storage/innobase/buf/buf0mtflu.cc2
-rw-r--r--storage/innobase/dict/dict0dict.cc50
-rw-r--r--storage/innobase/dict/dict0load.cc12
-rw-r--r--storage/innobase/dict/dict0stats.cc13
-rw-r--r--storage/innobase/dict/dict0stats_bg.cc2
-rw-r--r--storage/innobase/fil/fil0crypt.cc2
-rw-r--r--storage/innobase/fil/fil0fil.cc324
-rw-r--r--storage/innobase/fsp/fsp0file.cc109
-rw-r--r--storage/innobase/fsp/fsp0fsp.cc144
-rw-r--r--storage/innobase/fsp/fsp0space.cc10
-rw-r--r--storage/innobase/fsp/fsp0sysspace.cc4
-rw-r--r--storage/innobase/fts/fts0opt.cc9
-rw-r--r--storage/innobase/handler/ha_innodb.cc52
-rw-r--r--storage/innobase/handler/handler0alter.cc82
-rw-r--r--storage/innobase/include/dict0dict.h1
-rw-r--r--storage/innobase/include/dict0dict.ic77
-rw-r--r--storage/innobase/include/dict0pagecompress.h13
-rw-r--r--storage/innobase/include/dict0pagecompress.ic76
-rw-r--r--storage/innobase/include/fil0fil.h17
-rw-r--r--storage/innobase/include/fil0pagecompress.h11
-rw-r--r--storage/innobase/include/fsp0file.h21
-rw-r--r--storage/innobase/include/fsp0fsp.h226
-rw-r--r--storage/innobase/include/fsp0fsp.ic156
-rw-r--r--storage/innobase/include/fsp0pagecompress.h11
-rw-r--r--storage/innobase/include/fsp0pagecompress.ic26
-rw-r--r--storage/innobase/include/fsp0types.h270
-rw-r--r--storage/innobase/include/log0recv.h4
-rw-r--r--storage/innobase/include/os0thread.h19
-rw-r--r--storage/innobase/include/srv0srv.h1
-rw-r--r--storage/innobase/lock/lock0wait.cc2
-rw-r--r--storage/innobase/log/log0log.cc2
-rw-r--r--storage/innobase/log/log0recv.cc2
-rw-r--r--storage/innobase/mach/mach0data.cc105
-rw-r--r--storage/innobase/os/os0thread.cc37
-rw-r--r--storage/innobase/row/row0ftsort.cc4
-rw-r--r--storage/innobase/row/row0import.cc90
-rw-r--r--storage/innobase/row/row0merge.cc7
-rw-r--r--storage/innobase/row/row0mysql.cc13
-rw-r--r--storage/innobase/row/row0trunc.cc10
-rw-r--r--storage/innobase/srv/srv0srv.cc19
-rw-r--r--storage/innobase/srv/srv0start.cc25
-rw-r--r--storage/innobase/trx/trx0roll.cc2
-rw-r--r--storage/perfschema/pfs.cc34
-rw-r--r--storage/perfschema/pfs_digest.cc118
-rw-r--r--storage/perfschema/pfs_digest.h5
-rw-r--r--storage/perfschema/pfs_lock.h14
-rw-r--r--storage/perfschema/table_esms_by_digest.cc22
-rw-r--r--storage/perfschema/unittest/pfs-t.cc1
-rw-r--r--storage/xtradb/buf/buf0dblwr.cc236
-rw-r--r--storage/xtradb/dict/dict0load.cc20
-rw-r--r--storage/xtradb/fil/fil0fil.cc395
-rw-r--r--storage/xtradb/fsp/fsp0fsp.cc3
-rw-r--r--storage/xtradb/include/dict0dict.ic40
-rw-r--r--storage/xtradb/include/dict0pagecompress.h13
-rw-r--r--storage/xtradb/include/dict0pagecompress.ic88
-rw-r--r--storage/xtradb/include/fil0fil.h41
-rw-r--r--storage/xtradb/include/fil0pagecompress.h13
-rw-r--r--storage/xtradb/include/fsp0fsp.h437
-rw-r--r--storage/xtradb/include/fsp0fsp.ic153
-rw-r--r--storage/xtradb/include/fsp0pagecompress.h11
-rw-r--r--storage/xtradb/include/fsp0pagecompress.ic28
-rw-r--r--storage/xtradb/row/row0import.cc94
-rw-r--r--storage/xtradb/row/row0mysql.cc11
-rw-r--r--storage/xtradb/srv/srv0start.cc18
-rw-r--r--support-files/CMakeLists.txt19
-rw-r--r--support-files/mysql.server.sh8
-rw-r--r--support-files/policy/selinux/mariadb.te9
-rw-r--r--support-files/rpm/server-postin.sh7
286 files changed, 13655 insertions, 4735 deletions
diff --git a/.gitignore b/.gitignore
index 737528ffdd4..9fd9637d7ef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,6 +51,7 @@ extra/jemalloc/build/
extra/jemalloc/tmp/
extra/my_print_defaults
extra/mysql_waitpid
+extra/mysqld_safe_helper
extra/perror
extra/replace
extra/resolve_stack_dump
@@ -224,6 +225,7 @@ support-files/mysql.spec
support-files/mysqld_multi.server
support-files/wsrep.cnf
support-files/wsrep_notify
+support-files/policy/selinux/mysqld-safe.pp
tags
tests/async_queries
tests/bug25714
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index d186a4c7fcc..e670079c99e 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -1571,8 +1571,10 @@ static my_bool get_pidfile(MYSQL *mysql, char *pidfile)
if (mysql_query(mysql, "SHOW VARIABLES LIKE 'pid_file'"))
{
- my_printf_error(0, "query failed; error: '%s'", error_flags,
- mysql_error(mysql));
+ my_printf_error(mysql_errno(mysql),
+ "The query to get the server's pid file failed,"
+ " error: '%s'. Continuing.", error_flags,
+ mysql_error(mysql));
}
result = mysql_store_result(mysql);
if (result)
diff --git a/debian/mariadb-server-10.2.install b/debian/mariadb-server-10.2.install
index 71aeb1f560b..7ab6ccd7c7a 100644
--- a/debian/mariadb-server-10.2.install
+++ b/debian/mariadb-server-10.2.install
@@ -27,6 +27,7 @@ usr/bin/mysql_tzinfo_to_sql
usr/bin/mysqlbinlog
usr/bin/mysqld_multi
usr/bin/mysqld_safe
+usr/bin/mysqld_safe_helper
usr/bin/mysqlhotcopy
usr/bin/perror
usr/bin/replace
diff --git a/debian/patches/33_scripts__mysql_create_system_tables__no_test.dpatch b/debian/patches/33_scripts__mysql_create_system_tables__no_test.dpatch
index 6547e4434f1..183212ef678 100755
--- a/debian/patches/33_scripts__mysql_create_system_tables__no_test.dpatch
+++ b/debian/patches/33_scripts__mysql_create_system_tables__no_test.dpatch
@@ -8,8 +8,8 @@
## DP: http://bugs.mysql.com/bug.php?id=6901
@DPATCH@
---- old/scripts/mysql_system_tables_data.sql 2008-12-04 22:59:44.000000000 +0100
-+++ new/scripts/mysql_system_tables_data.sql 2008-12-04 23:00:07.000000000 +0100
+--- a/scripts/mysql_system_tables_data.sql
++++ b/scripts/mysql_system_tables_data.sql
@@ -26,16 +26,6 @@
-- a plain character
SELECT LOWER( REPLACE((SELECT REPLACE(@@hostname,'_','\_')),'%','\%') )INTO @current_hostname;
@@ -26,14 +26,14 @@
-
-- Fill "user" table with default users allowing root access
-- from local machine if "user" table didn't exist before
- CREATE TEMPORARY TABLE tmp_user LIKE user;
-@@ -43,8 +33,6 @@ INSERT INTO tmp_user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','
- REPLACE INTO tmp_user SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0 FROM dual WHERE @current_hostname != 'localhost';
- REPLACE INTO tmp_user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0);
- REPLACE INTO tmp_user VALUES ('::1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N', '', 0);
--INSERT INTO tmp_user (host,user) VALUES ('localhost','');
--INSERT INTO tmp_user (host,user) SELECT @current_hostname,'' FROM dual WHERE @current_hostname != 'localhost';
- INSERT INTO user SELECT * FROM tmp_user WHERE @had_user_table=0;
- DROP TABLE tmp_user;
+ CREATE TEMPORARY TABLE tmp_user_nopasswd LIKE user;
+@@ -48,9 +38,6 @@ REPLACE INTO tmp_user_nopasswd VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y'
+ REPLACE INTO tmp_user_nopasswd VALUES ('::1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N', '', 0);
+ -- More secure root account using unix sucket auth.
+ INSERT INTO tmp_user_socket VALUES ('localhost',IFNULL(@auth_root_socket, 'root'),'','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'unix_socket','','N', 'N','', 0);
+--- Anonymous user with no privileges.
+-INSERT INTO tmp_user_anonymous (host,user) VALUES ('localhost','');
+-INSERT INTO tmp_user_anonymous (host,user) SELECT @current_hostname,'' FROM dual WHERE @current_hostname != 'localhost';
-
+ INSERT INTO user SELECT * FROM tmp_user_nopasswd WHERE @had_user_table=0 AND @skip_auth_root_nopasswd IS NULL;
+ INSERT INTO user SELECT * FROM tmp_user_socket WHERE @had_user_table=0 AND @auth_root_socket IS NOT NULL;
diff --git a/extra/CMakeLists.txt b/extra/CMakeLists.txt
index 480cd6e7fbb..9cc5e7faa86 100644
--- a/extra/CMakeLists.txt
+++ b/extra/CMakeLists.txt
@@ -98,4 +98,7 @@ IF(UNIX)
MYSQL_ADD_EXECUTABLE(mysql_waitpid mysql_waitpid.c COMPONENT Client)
TARGET_LINK_LIBRARIES(mysql_waitpid mysys)
+
+ MYSQL_ADD_EXECUTABLE(mysqld_safe_helper mysqld_safe_helper.c COMPONENT Server)
+ TARGET_LINK_LIBRARIES(mysqld_safe_helper mysys)
ENDIF()
diff --git a/extra/mysqld_safe_helper.c b/extra/mysqld_safe_helper.c
new file mode 100644
index 00000000000..09e507c6e1c
--- /dev/null
+++ b/extra/mysqld_safe_helper.c
@@ -0,0 +1,77 @@
+#include <my_global.h>
+#include <m_string.h>
+#include <my_sys.h>
+#include <my_pthread.h>
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+
+void my_exit(int c)
+{
+ my_end(0);
+ exit(c);
+}
+
+void do_usage()
+{
+ printf("Usage:\n"
+ " %s <user> log <filename>\n"
+ " %s <user> exec <command> <args>\n",
+ my_progname, my_progname);
+ my_exit(1);
+}
+
+void do_log(const char *logfile)
+{
+ FILE *f;
+ uchar buf[4096];
+ int size;
+
+ if (!logfile)
+ do_usage();
+
+ f= my_fopen(logfile, O_WRONLY|O_APPEND|O_CREAT, MYF(MY_WME));
+ if (!f)
+ my_exit(1);
+
+ while ((size= my_fread(stdin, buf, sizeof(buf), MYF(MY_WME))) > 0)
+ if ((int)my_fwrite(f, buf, size, MYF(MY_WME)) != size)
+ my_exit(1);
+
+ my_fclose(f, MYF(0));
+ my_exit(0);
+}
+
+void do_exec(char *args[])
+{
+ if (!args[0])
+ do_usage();
+
+ my_end(0);
+ execvp(args[0], args);
+}
+
+int main(int argc, char *argv[])
+{
+ struct passwd *user_info;
+ MY_INIT(argv[0]);
+
+ if (argc < 3)
+ do_usage(argv[0]);
+
+ user_info= my_check_user(argv[1], MYF(0));
+ if (user_info ? my_set_user(argv[1], user_info, MYF(MY_WME))
+ : my_errno == EINVAL)
+ my_exit(1);
+
+ if (strcmp(argv[2], "log") == 0)
+ do_log(argv[3]);
+
+ if (strcmp(argv[2], "exec") == 0)
+ do_exec(argv+3);
+
+ my_end(0);
+ return 1;
+}
diff --git a/include/my_sys.h b/include/my_sys.h
index 2e9f842d06e..2e24bfd02d3 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -678,8 +678,12 @@ extern void *my_memmem(const void *haystack, size_t haystacklen,
#ifdef _WIN32
extern int my_access(const char *path, int amode);
+#define my_check_user(A,B) (NULL)
+#define my_set_user(A,B,C) (0)
#else
#define my_access access
+struct passwd *my_check_user(const char *user, myf MyFlags);
+int my_set_user(const char *user, struct passwd *user_info, myf MyFlags);
#endif
extern int check_if_legal_filename(const char *path);
diff --git a/man/mysql_secure_installation.1 b/man/mysql_secure_installation.1
index 19522042e87..71e9d67dee4 100644
--- a/man/mysql_secure_installation.1
+++ b/man/mysql_secure_installation.1
@@ -1,6 +1,6 @@
'\" t
.\"
-.TH "\FBMYSQL_SECURE_INST" "1" "22/3/2016" "MariaDB 10\&.2" "MariaDB Database System"
+.TH "\FBMYSQL_SECURE_INST" "1" "3 January 2017" "MariaDB 10\&.2" "MariaDB Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -71,9 +71,8 @@ test
database, which by default can be accessed by anonymous users\&.
.RE
.PP
-Invoke
\fBmysql_secure_installation\fR
-without arguments:
+can be invoked without arguments:
.sp
.if n \{\
.RS 4
@@ -86,10 +85,75 @@ shell> \fBmysql_secure_installation\fR
.\}
.PP
The script will prompt you to determine which actions to perform\&.
+.PP
+\fBmysql_secure_installation\fR
+accepts some options:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" mysql_secure_installation: basedir option
+.\" basedir option: mysql_secure_installation
+\fB\-\-basedir=\fR\fB\fIdir_name\fR\fR
+.sp
+Base directory\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" mysql_secure_installation: defaults-extra-file option
+.\" defaults-extra-file option: mysql_secure_installation
+\fB\-\-defaults\-extra\-file=\fR\fB\fIfile_name\fR\fR
+.sp
+Additional option file\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" mysql_secure_installation: defaults-file option
+.\" defaults-file option: mysql_secure_installation
+\fB\-\-defaults\-file=\fR\fB\fIfile_name\fR\fR
+.sp
+Option file\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" mysql_secure_installation: no-defaults option
+.\" no-defaults option: mysql_secure_installation
+\fB\-\-no\-defaults\fR
+.sp
+Don't read any defaults file\&.
+.RE
+.sp
+Other unrecognized options will be passed on to the server\&.
.SH "COPYRIGHT"
.br
.PP
-Copyright 2007-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc., 2010-2015 MariaDB Foundation
+Copyright 2007-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc., 2010-2017 MariaDB Foundation
.PP
This documentation is free software; you can redistribute it and/or modify it only under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License.
.PP
diff --git a/mysql-test/extra/rpl_tests/rpl_special_charset.inc b/mysql-test/extra/rpl_tests/rpl_special_charset.inc
index 51119b319d7..641aa483d32 100644
--- a/mysql-test/extra/rpl_tests/rpl_special_charset.inc
+++ b/mysql-test/extra/rpl_tests/rpl_special_charset.inc
@@ -20,7 +20,7 @@
# then set default's client character set(latin1) as client's character set.
###############################################################################
--source include/master-slave.inc
-call mtr.add_suppression("Cannot use utf16 as character_set_client");
+call mtr.add_suppression("'utf16' can not be used as client character set");
CREATE TABLE t1(i VARCHAR(20));
INSERT INTO t1 VALUES (0xFFFF);
--sync_slave_with_master
diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result
index 2edacb6c7e9..1e39c03696f 100644
--- a/mysql-test/r/cast.result
+++ b/mysql-test/r/cast.result
@@ -583,7 +583,7 @@ show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`cast(1 as unsigned)` int(1) unsigned NOT NULL,
- `cast(1 as signed)` int(1) NOT NULL,
+ `cast(1 as signed)` int(2) NOT NULL,
`cast(1 as double(5,2))` double(5,2) DEFAULT NULL,
`cast(1 as decimal(5,3))` decimal(5,3) NOT NULL,
`cast("A" as binary)` varbinary(1) NOT NULL,
@@ -822,3 +822,74 @@ utf8_bin
select collation(cast("a" as char(10) binary ascii));
collation(cast("a" as char(10) binary ascii))
latin1_bin
+#
+# MDEV-11030 Assertion `precision > 0' failed in decimal_bin_size
+#
+SELECT * FROM (SELECT IFNULL(CONVERT(NULL, UNSIGNED), NULL)) sq;
+IFNULL(CONVERT(NULL, UNSIGNED), NULL)
+NULL
+CREATE TABLE t1 AS SELECT IFNULL(CONVERT(NULL, UNSIGNED), NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `IFNULL(CONVERT(NULL, UNSIGNED), NULL)` decimal(1,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 AS SELECT COALESCE(CONVERT(NULL, UNSIGNED), NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `COALESCE(CONVERT(NULL, UNSIGNED), NULL)` decimal(1,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 AS SELECT CASE WHEN TRUE THEN CONVERT(NULL, UNSIGNED) ELSE NULL END;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `CASE WHEN TRUE THEN CONVERT(NULL, UNSIGNED) ELSE NULL END` decimal(1,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 AS SELECT IFNULL(CONVERT(NULL,SIGNED),CONVERT(NULL,UNSIGNED)) AS a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` decimal(1,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 AS SELECT
+-1,
+CONVERT(NULL,SIGNED),
+CONCAT(CONVERT(NULL,SIGNED)),
+1,
+CONVERT(NULL,UNSIGNED),
+CONCAT(CONVERT(NULL,UNSIGNED));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `-1` int(2) NOT NULL,
+ `CONVERT(NULL,SIGNED)` int(2) DEFAULT NULL,
+ `CONCAT(CONVERT(NULL,SIGNED))` varchar(2) DEFAULT NULL,
+ `1` int(1) NOT NULL,
+ `CONVERT(NULL,UNSIGNED)` int(1) unsigned DEFAULT NULL,
+ `CONCAT(CONVERT(NULL,UNSIGNED))` varchar(1) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 AS SELECT
+CONVERT('',SIGNED),
+CONCAT(CONVERT('',SIGNED)),
+CONVERT('',UNSIGNED),
+CONCAT(CONVERT('',UNSIGNED));
+Warnings:
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: ''
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `CONVERT('',SIGNED)` int(2) NOT NULL,
+ `CONCAT(CONVERT('',SIGNED))` varchar(2) NOT NULL,
+ `CONVERT('',UNSIGNED)` int(1) unsigned NOT NULL,
+ `CONCAT(CONVERT('',UNSIGNED))` varchar(1) NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index f9ac0dd4c7f..08fbd05ab58 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -1912,6 +1912,13 @@ end|
create table t1 as select f1();
ERROR 42S02: Table 'test.t1' doesn't exist
drop function f1;
+#
+# MDEV-10274 Bundling insert with create statement
+# for table with unsigned Decimal primary key issues warning 1194
+#
+create table t1(ID decimal(2,1) unsigned NOT NULL, PRIMARY KEY (ID))engine=memory
+select 2.1 ID;
+drop table t1;
End of 5.5 tests
create table t1;
ERROR 42000: A table must have at least 1 column
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index 0ac76e91c21..b6eb6076895 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -4576,6 +4576,16 @@ SELECT CHAR_LENGTH(TRIM(BOTH 0x00 FROM _ucs2 0x0061));
CHAR_LENGTH(TRIM(BOTH 0x00 FROM _ucs2 0x0061))
1
#
+# MDEV-11685: sql_mode can't be set with non-ascii connection charset
+#
+SET character_set_connection=ucs2;
+SET sql_mode='NO_ENGINE_SUBSTITUTION';
+SELECT @@sql_mode;
+@@sql_mode
+NO_ENGINE_SUBSTITUTION
+SET sql_mode=DEFAULT;
+SET NAMES utf8;
+#
# End of 5.5 tests
#
#
diff --git a/mysql-test/r/ctype_ucs2_def.result b/mysql-test/r/ctype_ucs2_def.result
index 5ca7d1689d2..9d8f5181103 100644
--- a/mysql-test/r/ctype_ucs2_def.result
+++ b/mysql-test/r/ctype_ucs2_def.result
@@ -1,4 +1,4 @@
-call mtr.add_suppression("Cannot use ucs2 as character_set_client");
+call mtr.add_suppression("'ucs2' can not be used as client character set");
show variables like 'collation_server';
Variable_name Value
collation_server ucs2_unicode_ci
diff --git a/mysql-test/r/ctype_ucs2_query_cache.result b/mysql-test/r/ctype_ucs2_query_cache.result
index 9a7580324c1..eba7f2fb0fc 100644
--- a/mysql-test/r/ctype_ucs2_query_cache.result
+++ b/mysql-test/r/ctype_ucs2_query_cache.result
@@ -1,4 +1,4 @@
-call mtr.add_suppression("Cannot use ucs2 as character_set_client");
+call mtr.add_suppression("'ucs2' can not be used as client character set");
#
# Start of 5.5 tests
#
diff --git a/mysql-test/r/ctype_utf16.result b/mysql-test/r/ctype_utf16.result
index 09ba94bd12d..32deafae3b7 100644
--- a/mysql-test/r/ctype_utf16.result
+++ b/mysql-test/r/ctype_utf16.result
@@ -1584,6 +1584,16 @@ ERROR HY000: Invalid utf16 character string: 'DE9899'
DO LPAD(_utf16 0x0061 COLLATE utf16_unicode_ci, 10000, 0x0061DE989999);
ERROR HY000: Invalid utf16 character string: 'DE9899'
#
+# MDEV-11685: sql_mode can't be set with non-ascii connection charset
+#
+SET character_set_connection=utf16;
+SET sql_mode='NO_ENGINE_SUBSTITUTION';
+SELECT @@sql_mode;
+@@sql_mode
+NO_ENGINE_SUBSTITUTION
+SET sql_mode=DEFAULT;
+SET NAMES utf8;
+#
# End of 5.5 tests
#
#
diff --git a/mysql-test/r/ctype_utf16_def.result b/mysql-test/r/ctype_utf16_def.result
index 9d3d110fc99..98b6f7d913d 100644
--- a/mysql-test/r/ctype_utf16_def.result
+++ b/mysql-test/r/ctype_utf16_def.result
@@ -1,4 +1,4 @@
-call mtr.add_suppression("Cannot use utf16 as character_set_client");
+call mtr.add_suppression("'utf16' can not be used as client character set");
SHOW VARIABLES LIKE 'collation_server';
Variable_name Value
collation_server utf16_general_ci
diff --git a/mysql-test/r/ctype_utf32.result b/mysql-test/r/ctype_utf32.result
index f5365dd0c31..de4c111ec4b 100644
--- a/mysql-test/r/ctype_utf32.result
+++ b/mysql-test/r/ctype_utf32.result
@@ -1668,6 +1668,16 @@ c
Warnings:
Warning 1300 Invalid utf32 character string: '\xFF\xFF\x00\x00'
#
+# MDEV-11685: sql_mode can't be set with non-ascii connection charset
+#
+SET character_set_connection=utf32;
+SET sql_mode='NO_ENGINE_SUBSTITUTION';
+SELECT @@sql_mode;
+@@sql_mode
+NO_ENGINE_SUBSTITUTION
+SET sql_mode=DEFAULT;
+SET NAMES utf8;
+#
# End of 5.5 tests
#
#
diff --git a/mysql-test/r/events_slowlog.result b/mysql-test/r/events_slowlog.result
new file mode 100644
index 00000000000..7de5925bc0f
--- /dev/null
+++ b/mysql-test/r/events_slowlog.result
@@ -0,0 +1,13 @@
+set @event_scheduler_save= @@global.event_scheduler;
+set @slow_query_log_save= @@global.slow_query_log;
+set global event_scheduler= on;
+set global slow_query_log= on;
+set global long_query_time=0.2;
+create table t1 (i int);
+insert into t1 values (0);
+create event ev on schedule at CURRENT_TIMESTAMP + INTERVAL 1 second do update t1 set i=1+sleep(0.5);
+FOUND /update t1 set i=1/ in mysqld-slow.log
+drop table t1;
+set global event_scheduler= @event_scheduler_save;
+set global slow_query_log= @slow_query_log_save;
+set global long_query_time= @@session.long_query_time;
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index 4d0a2a021f9..d5d8deca3fb 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -2765,6 +2765,12 @@ id date1 date2 DATE_ADD(a.date1,INTERVAL -10 DAY) TO_DAYS(a.date1)-10
18 2010-10-13 2010-10-03 2010-10-03 734413
DROP TABLE t1;
#
+# MDEV-10524 Assertion `arg1_int >= 0' failed in Item_func_additive_op::result_precision()
+#
+SELECT 1 MOD ADDTIME( '13:58:57', '00:00:01' ) + 2;
+1 MOD ADDTIME( '13:58:57', '00:00:01' ) + 2
+3
+#
# Start of 10.0 tests
#
#
diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result
index 0450622411a..6a3ea839535 100644
--- a/mysql-test/r/index_merge_innodb.result
+++ b/mysql-test/r/index_merge_innodb.result
@@ -799,3 +799,32 @@ a b c
9 d d
DROP TABLE t1;
set optimizer_switch= @optimizer_switch_save;
+#
+# MDEV-10927: Crash When Using sort_union Optimization
+#
+set @tmp_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='index_merge_sort_intersection=on';
+SET SESSION sort_buffer_size = 1024;
+create table t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col1 int(11) NOT NULL,
+col2 int(11) NOT NULL,
+col3 int(11) NOT NULL,
+key2 int(11) NOT NULL,
+col4 int(11) NOT NULL,
+key1 int(11) NOT NULL,
+PRIMARY KEY (pk),
+KEY key1 (key1),
+KEY key2 (key2)
+) ENGINE=InnoDB AUTO_INCREMENT=12860259 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
+create table t2(a int);
+insert into t2 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t3(a int);
+insert into t3 select A.a + B.a* 10 + C.a * 100 + D.a*1000 from t2 A, t2 B, t2 C, t2 D;
+insert into t1 (key1, key2, col1,col2,col3,col4)
+select a,a, a,a,a,a from t3;
+SELECT sum(col1) FROM t1 FORCE INDEX (key1,key2) WHERE (key1 between 10 and 8191+10) or (key2= 5);
+sum(col1)
+33632261
+drop table t1,t2,t3;
+set optimizer_switch=@tmp_optimizer_switch;
diff --git a/mysql-test/r/information_schema_part.result b/mysql-test/r/information_schema_part.result
index e0a0f28dec6..91720d12ac4 100644
--- a/mysql-test/r/information_schema_part.result
+++ b/mysql-test/r/information_schema_part.result
@@ -151,3 +151,11 @@ select create_options from information_schema.tables where table_schema="test";
create_options
partitioned
drop table t1;
+#
+# MDEV-11353 - Identical logical conditions
+#
+CREATE TABLE t1(a INT) CHECKSUM=1 SELECT 1;
+SELECT CHECKSUM FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1';
+CHECKSUM
+3036305396
+DROP TABLE t1;
diff --git a/mysql-test/r/insert_update.result b/mysql-test/r/insert_update.result
index 1987c5c0559..e8e6e16fe5a 100644
--- a/mysql-test/r/insert_update.result
+++ b/mysql-test/r/insert_update.result
@@ -242,14 +242,16 @@ ERROR 42S22: Unknown column 'a' in 'field list'
DROP TABLE t1,t2;
SET SQL_MODE = 'TRADITIONAL';
CREATE TABLE t1 (a INT PRIMARY KEY, b INT NOT NULL);
+INSERT INTO t1 VALUES (1,1);
INSERT INTO t1 (a) VALUES (1);
ERROR HY000: Field 'b' doesn't have a default value
INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE a = b;
ERROR HY000: Field 'b' doesn't have a default value
+INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE b = a;
INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE b = b;
-ERROR HY000: Field 'b' doesn't have a default value
SELECT * FROM t1;
a b
+1 1
DROP TABLE t1;
CREATE TABLE t1 (f1 INT AUTO_INCREMENT PRIMARY KEY,
f2 VARCHAR(5) NOT NULL UNIQUE);
diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result
index 74e64d92856..6a8581e0605 100644
--- a/mysql-test/r/join_cache.result
+++ b/mysql-test/r/join_cache.result
@@ -5755,11 +5755,13 @@ LEFT JOIN t2 c1 ON c1.parent_id = t.id AND c1.col2 = "val"
LEFT JOIN t2 c23 ON c23.parent_id = t.id AND c23.col2 = "val"
LEFT JOIN t2 c24 ON c24.parent_id = t.id AND c24.col2 = "val"
LEFT JOIN t2 c25 ON c25.parent_id = t.id AND c25.col2 = "val"
+ LEFT JOIN t2 c26 ON c26.parent_id = t.id AND c26.col2 = "val"
+ LEFT JOIN t2 c27 ON c27.parent_id = t.id AND c27.col2 = "val"
ORDER BY
col1;
id col1
-select timestampdiff(second, @init_time, now()) <= 1;
-timestampdiff(second, @init_time, now()) <= 1
+select timestampdiff(second, @init_time, now()) <= 5;
+timestampdiff(second, @init_time, now()) <= 5
1
set join_cache_level=2;
set @init_time:=now();
@@ -5791,11 +5793,13 @@ LEFT JOIN t2 c1 ON c1.parent_id = t.id AND c1.col2 = "val"
LEFT JOIN t2 c23 ON c23.parent_id = t.id AND c23.col2 = "val"
LEFT JOIN t2 c24 ON c24.parent_id = t.id AND c24.col2 = "val"
LEFT JOIN t2 c25 ON c25.parent_id = t.id AND c25.col2 = "val"
+ LEFT JOIN t2 c26 ON c26.parent_id = t.id AND c26.col2 = "val"
+ LEFT JOIN t2 c27 ON c27.parent_id = t.id AND c27.col2 = "val"
ORDER BY
col1;
id col1
-select timestampdiff(second, @init_time, now()) <= 1;
-timestampdiff(second, @init_time, now()) <= 1
+select timestampdiff(second, @init_time, now()) <= 5;
+timestampdiff(second, @init_time, now()) <= 5
1
EXPLAIN
SELECT t.*
@@ -5826,6 +5830,8 @@ LEFT JOIN t2 c1 ON c1.parent_id = t.id AND c1.col2 = "val"
LEFT JOIN t2 c23 ON c23.parent_id = t.id AND c23.col2 = "val"
LEFT JOIN t2 c24 ON c24.parent_id = t.id AND c24.col2 = "val"
LEFT JOIN t2 c25 ON c25.parent_id = t.id AND c25.col2 = "val"
+ LEFT JOIN t2 c26 ON c26.parent_id = t.id AND c26.col2 = "val"
+ LEFT JOIN t2 c27 ON c27.parent_id = t.id AND c27.col2 = "val"
ORDER BY
col1;
id select_type table type possible_keys key key_len ref rows Extra
@@ -5855,6 +5861,8 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE c23 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE c24 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE c25 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE c26 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE c27 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
set join_buffer_size=default;
set join_cache_level = default;
DROP TABLE t1,t2;
diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result
index d21402a336a..c865fcef53f 100644
--- a/mysql-test/r/loaddata.result
+++ b/mysql-test/r/loaddata.result
@@ -537,7 +537,7 @@ disconnect con1;
# Bug#11765139 58069: LOAD DATA INFILE: VALGRIND REPORTS INVALID MEMORY READS AND WRITES WITH U
#
CREATE TABLE t1(f1 INT);
-SELECT 0xE1C330 INTO OUTFILE 't1.dat';
+SELECT 0xE1BB30 INTO OUTFILE 't1.dat';
LOAD DATA INFILE 't1.dat' IGNORE INTO TABLE t1 CHARACTER SET utf8;
DROP TABLE t1;
#
@@ -562,12 +562,24 @@ FIELDS TERMINATED BY 't' LINES TERMINATED BY '';
Got one of the listed errors
SET @@sql_mode= @old_mode;
DROP TABLE t1;
-
#
-# Bug#23080148 - Backport of Bug#20683959.
-# Bug#20683959 LOAD DATA INFILE IGNORES A SPECIFIC ROW SILENTLY
-# UNDER DB CHARSET IS UTF8.
+# MDEV-11079 Regression: LOAD DATA INFILE lost BLOB support using utf8 load files
+#
+CREATE TABLE t1 (a mediumblob NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+LOAD DATA INFILE '../../std_data/loaddata/mdev-11079.txt' INTO TABLE t1 CHARSET utf8 FIELDS TERMINATED BY ';' ENCLOSED BY '"' ESCAPED BY '\\' LINES TERMINATED BY '\n';
+SELECT HEX(a) FROM t1;
+HEX(a)
+25AAABAC
+DROP TABLE t1;
#
+# MDEV-11631 LOAD DATA INFILE fails to load data with an escape character followed by a multi-byte character
+#
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8);
+LOAD DATA INFILE '../../std_data/loaddata/mdev-11631.txt' INTO TABLE t1 CHARACTER SET utf8;
+SELECT HEX(a) FROM t1;
+HEX(a)
+C3A4
+DROP TABLE t1;
CREATE DATABASE d1 CHARSET latin1;
USE d1;
CREATE TABLE t1 (val TEXT);
diff --git a/mysql-test/r/log_slow.result b/mysql-test/r/log_slow.result
index 383ad10ba66..16a59ece0ac 100644
--- a/mysql-test/r/log_slow.result
+++ b/mysql-test/r/log_slow.result
@@ -70,9 +70,9 @@ sleep(0.5)
select count(*) FROM mysql.slow_log;
count(*)
1
-truncate mysql.slow_log;
set @@long_query_time=default;
set global slow_query_log= @org_slow_query_log;
set @@log_slow_filter=default;
set @@log_slow_verbosity=default;
set global log_output= default;
+truncate mysql.slow_log;
diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result
index 203921ce08f..2b62252a129 100644
--- a/mysql-test/r/mysqld--help.result
+++ b/mysql-test/r/mysqld--help.result
@@ -461,6 +461,10 @@ The following options may be given as the first argument:
--max-seeks-for-key=#
Limit assumed max number of seeks when looking up rows
based on a key
+ --max-session-mem-used=#
+ Amount of memory a single user session is allowed to
+ allocate. This limits the value of the session variable
+ MEM_USED
--max-sort-length=# The number of bytes to use when sorting BLOB or TEXT
values (only the first max_sort_length bytes of each
value are used; the rest are ignored)
@@ -1311,6 +1315,7 @@ max-prepared-stmt-count 16382
max-recursive-iterations 18446744073709551615
max-relay-log-size 1073741824
max-seeks-for-key 18446744073709551615
+max-session-mem-used 9223372036854775807
max-sort-length 1024
max-sp-recursion-depth 0
max-statement-time 0
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index b4d78ac8347..5ba8d827cd8 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -2935,6 +2935,17 @@ t2 A, t2 B
where A.b = B.b
order by A.col2, B.col2 limit 10, 1000000;
drop table t1,t2,t3;
+#
+# mdev-10705 : long order by list that can be skipped
+#
+SELECT 1
+UNION
+( SELECT 2
+ORDER BY NULL, @a0 := 3, @a1 := 3, @a2 := 3, @a3 := 3, @a4 := 3,
+@a5 := 3, @a6 := 3, @a7 := 3, @a8 := 3, @a9 := 3, @a10 := 3 );
+1
+1
+2
End of 5.5 tests
#
# MDEV-5884: EXPLAIN UPDATE ... ORDER BY LIMIT shows wrong #rows
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index dee15c3b451..be8835bfe01 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -7165,6 +7165,17 @@ NULL
drop view v2;
drop table t1,t2;
#
+# MDEV-10386 Assertion `fixed == 1' failed in virtual String* Item_func_conv_charset::val_str(String*)
+#
+CREATE TABLE t1 (f1 CHAR(3) CHARACTER SET utf8 NULL, f2 CHAR(3) CHARACTER SET latin1 NULL);
+INSERT INTO t1 VALUES ('foo','bar');
+SELECT * FROM t1 WHERE f2 >= SOME ( SELECT f1 FROM t1 );
+f1 f2
+SELECT * FROM t1 WHERE f2 <= SOME ( SELECT f1 FROM t1 );
+f1 f2
+foo bar
+DROP TABLE t1;
+#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
# with UNION in ALL subquery
#
diff --git a/mysql-test/r/subselect2.result b/mysql-test/r/subselect2.result
index e87f4b9b451..069a19c4001 100644
--- a/mysql-test/r/subselect2.result
+++ b/mysql-test/r/subselect2.result
@@ -348,4 +348,49 @@ where t1.a = t2.a and ( t1.a = ( select min(a) from t1 ) or 0 );
a a a
FRA FRA FRA
drop table t1,t2,t3;
+#
+# MDEV-10148: Database crashes in the query to the View
+#
+CREATE TABLE t1 (
+key_code INT(11) NOT NULL,
+value_string VARCHAR(50) NULL DEFAULT NULL,
+PRIMARY KEY (key_code)
+) COLLATE='utf8_general_ci' ENGINE=InnoDB ;
+CREATE TABLE t2 (
+key_code INT(11) NOT NULL,
+target_date DATE NULL DEFAULT NULL,
+PRIMARY KEY (key_code)
+) COLLATE='utf8_general_ci' ENGINE=InnoDB ;
+CREATE TABLE t3 (
+now_date DATE NOT NULL,
+PRIMARY KEY (now_date)
+) COLLATE='utf8_general_ci' ENGINE=InnoDB ;
+CREATE VIEW v1
+AS
+SELECT
+B.key_code,
+B.target_date
+FROM
+t2 B INNER JOIN t3 C ON
+B.target_date = C.now_date
+;
+SET @s = 'SELECT A.* FROM t1 A WHERE A.key_code IN (SELECT key_code FROM v1)';
+PREPARE stmt FROM @s;
+EXECUTE stmt;
+key_code value_string
+EXECUTE stmt;
+key_code value_string
+DEALLOCATE PREPARE stmt;
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
set optimizer_switch=@subselect2_test_tmp;
+create table t1 (a int);
+create table t2 (a int);
+create table t3(a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t2 select a from t1;
+insert into t3 select a from t1;
+select null in (select a from t1 where a < out3.a union select a from t2 where
+(select a from t3) +1 < out3.a+1) from t3 out3;
+ERROR 21000: Subquery returns more than 1 row
+drop table t1, t2, t3;
diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result
index 792ce657ba0..dd1c29ba2ca 100644
--- a/mysql-test/r/subselect4.result
+++ b/mysql-test/r/subselect4.result
@@ -2401,5 +2401,44 @@ SELECT x FROM t1 WHERE id > (SELECT MAX(id) - 1000 FROM t1) ORDER BY x LIMIT 1;
x
0
drop table t1;
+#
+# MDEV-7691: Assertion `outer_context || !*from_field || *from_field == not_found_field' ...
+#
+set optimizer_switch=default;
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (4),(6);
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1),(8);
+PREPARE stmt FROM "
+SELECT * FROM t2
+HAVING 0 IN (
+ SELECT a FROM t1
+ WHERE a IN (
+ SELECT a FROM t1
+ WHERE b = a
+ )
+)
+";
+EXECUTE stmt;
+b
+EXECUTE stmt;
+b
+# Alternative test case, without HAVING
+CREATE TABLE t3 (i INT) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (4),(6);
+PREPARE stmt FROM "
+SELECT * FROM t3 AS t10
+WHERE EXISTS (
+ SELECT * FROM t3 AS t20 WHERE t10.i IN (
+ SELECT i FROM t3
+ )
+)";
+EXECUTE stmt;
+i
+6
+EXECUTE stmt;
+i
+6
+drop table t1, t2, t3;
SET optimizer_switch= @@global.optimizer_switch;
set @@tmp_table_size= @@global.tmp_table_size;
diff --git a/mysql-test/r/subselect_no_exists_to_in.result b/mysql-test/r/subselect_no_exists_to_in.result
index 7f6ff7a6a16..f8657642dc0 100644
--- a/mysql-test/r/subselect_no_exists_to_in.result
+++ b/mysql-test/r/subselect_no_exists_to_in.result
@@ -7165,6 +7165,17 @@ NULL
drop view v2;
drop table t1,t2;
#
+# MDEV-10386 Assertion `fixed == 1' failed in virtual String* Item_func_conv_charset::val_str(String*)
+#
+CREATE TABLE t1 (f1 CHAR(3) CHARACTER SET utf8 NULL, f2 CHAR(3) CHARACTER SET latin1 NULL);
+INSERT INTO t1 VALUES ('foo','bar');
+SELECT * FROM t1 WHERE f2 >= SOME ( SELECT f1 FROM t1 );
+f1 f2
+SELECT * FROM t1 WHERE f2 <= SOME ( SELECT f1 FROM t1 );
+f1 f2
+foo bar
+DROP TABLE t1;
+#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
# with UNION in ALL subquery
#
diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result
index 6a17f8c8bf5..2ecd4a70b73 100644
--- a/mysql-test/r/subselect_no_mat.result
+++ b/mysql-test/r/subselect_no_mat.result
@@ -7158,6 +7158,17 @@ NULL
drop view v2;
drop table t1,t2;
#
+# MDEV-10386 Assertion `fixed == 1' failed in virtual String* Item_func_conv_charset::val_str(String*)
+#
+CREATE TABLE t1 (f1 CHAR(3) CHARACTER SET utf8 NULL, f2 CHAR(3) CHARACTER SET latin1 NULL);
+INSERT INTO t1 VALUES ('foo','bar');
+SELECT * FROM t1 WHERE f2 >= SOME ( SELECT f1 FROM t1 );
+f1 f2
+SELECT * FROM t1 WHERE f2 <= SOME ( SELECT f1 FROM t1 );
+f1 f2
+foo bar
+DROP TABLE t1;
+#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
# with UNION in ALL subquery
#
diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result
index c37fc66613f..0005556e51c 100644
--- a/mysql-test/r/subselect_no_opts.result
+++ b/mysql-test/r/subselect_no_opts.result
@@ -7156,6 +7156,17 @@ NULL
drop view v2;
drop table t1,t2;
#
+# MDEV-10386 Assertion `fixed == 1' failed in virtual String* Item_func_conv_charset::val_str(String*)
+#
+CREATE TABLE t1 (f1 CHAR(3) CHARACTER SET utf8 NULL, f2 CHAR(3) CHARACTER SET latin1 NULL);
+INSERT INTO t1 VALUES ('foo','bar');
+SELECT * FROM t1 WHERE f2 >= SOME ( SELECT f1 FROM t1 );
+f1 f2
+SELECT * FROM t1 WHERE f2 <= SOME ( SELECT f1 FROM t1 );
+f1 f2
+foo bar
+DROP TABLE t1;
+#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
# with UNION in ALL subquery
#
diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result
index 0fec9524dd5..0c1183e90ac 100644
--- a/mysql-test/r/subselect_no_scache.result
+++ b/mysql-test/r/subselect_no_scache.result
@@ -7171,6 +7171,17 @@ NULL
drop view v2;
drop table t1,t2;
#
+# MDEV-10386 Assertion `fixed == 1' failed in virtual String* Item_func_conv_charset::val_str(String*)
+#
+CREATE TABLE t1 (f1 CHAR(3) CHARACTER SET utf8 NULL, f2 CHAR(3) CHARACTER SET latin1 NULL);
+INSERT INTO t1 VALUES ('foo','bar');
+SELECT * FROM t1 WHERE f2 >= SOME ( SELECT f1 FROM t1 );
+f1 f2
+SELECT * FROM t1 WHERE f2 <= SOME ( SELECT f1 FROM t1 );
+f1 f2
+foo bar
+DROP TABLE t1;
+#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
# with UNION in ALL subquery
#
diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result
index 6b45582eb45..82eb7ed60a2 100644
--- a/mysql-test/r/subselect_no_semijoin.result
+++ b/mysql-test/r/subselect_no_semijoin.result
@@ -7156,6 +7156,17 @@ NULL
drop view v2;
drop table t1,t2;
#
+# MDEV-10386 Assertion `fixed == 1' failed in virtual String* Item_func_conv_charset::val_str(String*)
+#
+CREATE TABLE t1 (f1 CHAR(3) CHARACTER SET utf8 NULL, f2 CHAR(3) CHARACTER SET latin1 NULL);
+INSERT INTO t1 VALUES ('foo','bar');
+SELECT * FROM t1 WHERE f2 >= SOME ( SELECT f1 FROM t1 );
+f1 f2
+SELECT * FROM t1 WHERE f2 <= SOME ( SELECT f1 FROM t1 );
+f1 f2
+foo bar
+DROP TABLE t1;
+#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
# with UNION in ALL subquery
#
diff --git a/mysql-test/r/trigger_no_defaults-11698.result b/mysql-test/r/trigger_no_defaults-11698.result
new file mode 100644
index 00000000000..40546cee41d
--- /dev/null
+++ b/mysql-test/r/trigger_no_defaults-11698.result
@@ -0,0 +1,22 @@
+set sql_mode='strict_all_tables';
+create table t1 (a int not null, b int);
+insert t1 (b) values (1);
+ERROR HY000: Field 'a' doesn't have a default value
+create trigger trgi before insert on t1 for each row
+case new.b
+when 10 then
+set new.a = new.b;
+when 30 then
+set new.a = new.a;
+else
+do 1;
+end case|
+insert t1 (b) values (10);
+insert t1 (b) values (20);
+ERROR HY000: Field 'a' doesn't have a default value
+insert t1 (b) values (30);
+select * from t1;
+a b
+10 10
+0 30
+drop table t1;
diff --git a/mysql-test/r/trigger_null-8605.result b/mysql-test/r/trigger_null-8605.result
index b187fc19554..10315988708 100644
--- a/mysql-test/r/trigger_null-8605.result
+++ b/mysql-test/r/trigger_null-8605.result
@@ -354,3 +354,13 @@ show columns from t1;
Field Type Null Key Default Extra
a int(11) NO PRI NULL
drop table t1;
+create table t1 (
+pk int primary key,
+i int,
+v1 int as (i) virtual,
+v2 int as (i) virtual
+);
+create trigger tr before update on t1 for each row set @a = 1;
+insert into t1 (pk, i) values (null, null);
+ERROR 23000: Column 'pk' cannot be null
+drop table t1;
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index adaaf084a3d..8712519350d 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -1233,12 +1233,9 @@ a b
select * from ((select * from t1 limit 1) union (select * from t1 limit 1)) a;
a b
1 a
-2 b
select * from ((select * from t1 limit 1) union (select * from t1 limit 1) union (select * from t1 limit 1)) a;
a b
1 a
-2 b
-3 c
select * from ((((select * from t1))) union (select * from t1) union (select * from t1)) a;
a b
1 a
@@ -1621,7 +1618,6 @@ NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort
Warnings:
Note 1003 select NULL AS `a` from `test`.`t1` union select NULL AS `a` from `test`.`t1` order by `a`
DROP TABLE t1;
-End of 5.0 tests
#
# Bug#32858: Error: "Incorrect usage of UNION and INTO" does not take
# subselects into account
@@ -1736,6 +1732,16 @@ a
6
7
8
+(select a from t1 where false) UNION (select a from t1) limit 8;
+a
+10
+2
+3
+4
+5
+6
+7
+8
drop table t1;
#
# Bug#11765255 58201:
@@ -2031,6 +2037,25 @@ bbbb
dddd
drop table t1;
#
+# MDEV-10172: UNION query returns incorrect rows outside
+# conditional evaluation
+#
+create table t1 (d datetime not null primary key);
+insert into t1(d) values ('2016-06-01'),('2016-06-02'),('2016-06-03'),('2016-06-04');
+select * from
+(
+select * from t1 where d between '2016-06-02' and '2016-06-05'
+ union
+(select * from t1 where d < '2016-06-05' order by d desc limit 1)
+) onlyJun2toJun4
+order by d;
+d
+2016-06-02 00:00:00
+2016-06-03 00:00:00
+2016-06-04 00:00:00
+drop table t1;
+End of 5.0 tests
+#
# WL#1763 Avoid creating temporary table in UNION ALL
#
EXPLAIN SELECT 1 UNION ALL SELECT 1 LIMIT 1 OFFSET 1;
diff --git a/mysql-test/std_data/bug20683959loaddata.txt b/mysql-test/std_data/bug20683959loaddata.txt
deleted file mode 100644
index 1878cc78879..00000000000
--- a/mysql-test/std_data/bug20683959loaddata.txt
+++ /dev/null
@@ -1 +0,0 @@
-Ã"RT @niouzechun: é˜âˆšõ€®ç¹ä¸Šãƒ£ç¹æ–õ€‡³ç¹§ï½¨ç¹ï½³ç¹ç‰™è€³ç¸ºï½ªç¹§è–™â–¡ç¸ºä»£ï½Œç¸ºï½©ç¸²âˆšã„ç¹ï½³ç¹ä¸Šãƒ£ç¹æ–õ€‡³ç¹§ï½¨ç¹ï½³ç¹å³¨ï½„諠ィ蜉õ€”Žå™ªç¸ºï½ªç¸ºé¡˜ï½©ï½±ç¹§åµâ‰ ç¸ºï½¾ç¹§é¡”ゥ肴・オ逧õ€‹–↓鞫ょå™ç¸ºåŠ±â†‘縺õ€‹šç‚Šé€•ï½±ç¸ºï½¯ç¸²âˆ«æ¨Ÿèž³æº˜õ€­èŽ ï½ºé€•æº˜õ€®è“コ譛ャ逧õ€‹–↓縺õ€‘Žâˆªç¸ºä¸Šï¼žç¸ºä¹â†‘縺õ€‹–ï¼ è³æ¦Šï½¹ï½³é²å³¨â–¡ç¸ºç¤¼ç‚Šè³æ¦Šï½°ï½½ç¸º ç¸ºè‹“セ帙>
diff --git a/mysql-test/std_data/loaddata/mdev-11079.txt b/mysql-test/std_data/loaddata/mdev-11079.txt
new file mode 100644
index 00000000000..a792f984d5f
--- /dev/null
+++ b/mysql-test/std_data/loaddata/mdev-11079.txt
@@ -0,0 +1 @@
+"%ª«¬"
diff --git a/mysql-test/std_data/loaddata/mdev-11631.txt b/mysql-test/std_data/loaddata/mdev-11631.txt
new file mode 100644
index 00000000000..87b824b71ae
--- /dev/null
+++ b/mysql-test/std_data/loaddata/mdev-11631.txt
@@ -0,0 +1 @@
+\ä
diff --git a/mysql-test/suite/binlog_encryption/rpl_special_charset.result b/mysql-test/suite/binlog_encryption/rpl_special_charset.result
index 218ced9b8ea..b947cf3484d 100644
--- a/mysql-test/suite/binlog_encryption/rpl_special_charset.result
+++ b/mysql-test/suite/binlog_encryption/rpl_special_charset.result
@@ -1,6 +1,6 @@
include/master-slave.inc
[connection master]
-call mtr.add_suppression("Cannot use utf16 as character_set_client");
+call mtr.add_suppression("'utf16' can not be used as client character set");
CREATE TABLE t1(i VARCHAR(20));
INSERT INTO t1 VALUES (0xFFFF);
connection slave;
diff --git a/mysql-test/suite/encryption/disabled.def b/mysql-test/suite/encryption/disabled.def
index c2f41b70d03..d92d3495cb8 100644
--- a/mysql-test/suite/encryption/disabled.def
+++ b/mysql-test/suite/encryption/disabled.def
@@ -10,5 +10,5 @@
#
##############################################################################
-innodb_scrub_background : MDEV-8139 background scrubbing does not work reliably
-innodb_scrub : MDEV-8139 occasional corruption of delete_3.ibd page 2
+innodb_scrub : MDEV-8139 scrubbing does not work reliably
+innodb_scrub_background : MDEV-8139 scrubbing does not work reliably
diff --git a/mysql-test/suite/encryption/r/innodb_lotoftables.result b/mysql-test/suite/encryption/r/innodb_lotoftables.result
index aea50a1fa67..cf5724b527a 100644
--- a/mysql-test/suite/encryption/r/innodb_lotoftables.result
+++ b/mysql-test/suite/encryption/r/innodb_lotoftables.result
@@ -86,47 +86,47 @@ Innodb_pages0_read 3
# Restart Success!
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 1
+Innodb_pages0_read 303
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 1
+Innodb_pages0_read 303
use test;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 1
+Innodb_pages0_read 303
use innodb_encrypted_1;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 1
+Innodb_pages0_read 303
use innodb_encrypted_2;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 1
+Innodb_pages0_read 303
use innodb_encrypted_3;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 1
+Innodb_pages0_read 303
use innodb_encrypted_1;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 1
+Innodb_pages0_read 303
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 101
+Innodb_pages0_read 303
use innodb_encrypted_2;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 101
+Innodb_pages0_read 303
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 201
+Innodb_pages0_read 303
use innodb_encrypted_3;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 201
+Innodb_pages0_read 303
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 301
+Innodb_pages0_read 303
SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%';
COUNT(*)
100
diff --git a/mysql-test/suite/funcs_2/t/innodb_charset.test b/mysql-test/suite/funcs_2/t/innodb_charset.test
index b77bacfc01c..da4dea44ad7 100644
--- a/mysql-test/suite/funcs_2/t/innodb_charset.test
+++ b/mysql-test/suite/funcs_2/t/innodb_charset.test
@@ -6,6 +6,7 @@
# Checking of other prerequisites is in charset_master.test #
################################################################################
+--source include/no_valgrind_without_big.inc
--source include/have_innodb.inc
let $engine_type= InnoDB;
diff --git a/mysql-test/suite/galera/r/galera_var_cluster_address.result b/mysql-test/suite/galera/r/galera_var_cluster_address.result
index ef75cf21a79..92790cc9a6a 100644
--- a/mysql-test/suite/galera/r/galera_var_cluster_address.result
+++ b/mysql-test/suite/galera/r/galera_var_cluster_address.result
@@ -43,5 +43,9 @@ CALL mtr.add_suppression("failed to open gcomm backend connection: 110: failed t
CALL mtr.add_suppression("Failed to open backend connection: -110 \\(Connection timed out\\)");
CALL mtr.add_suppression("gcs connect failed: Connection timed out");
CALL mtr.add_suppression("WSREP: wsrep::connect\\(foo://\\) failed: 7");
+<<<<<<< HEAD
disconnect node_2;
disconnect node_1;
+=======
+# End of test
+>>>>>>> origin/10.1
diff --git a/mysql-test/suite/galera/suite.pm b/mysql-test/suite/galera/suite.pm
index 2da2b3ad503..151e7b7cbe9 100644
--- a/mysql-test/suite/galera/suite.pm
+++ b/mysql-test/suite/galera/suite.pm
@@ -67,6 +67,7 @@ push @::global_suppressions,
qr|WSREP: gcs_caused\(\) returned .*|,
qr|WSREP: Protocol violation. JOIN message sender .* is not in state transfer \(SYNCED\). Message ignored.|,
qr(WSREP: Action message in non-primary configuration from member [0-9]*),
+ qr(WSREP: discarding established .*),
);
diff --git a/mysql-test/suite/galera/t/galera_var_cluster_address.test b/mysql-test/suite/galera/t/galera_var_cluster_address.test
index 4e5d138ae0a..740c38765f6 100644
--- a/mysql-test/suite/galera/t/galera_var_cluster_address.test
+++ b/mysql-test/suite/galera/t/galera_var_cluster_address.test
@@ -9,6 +9,7 @@
--let $node_1=node_1
--let $node_2=node_2
--source include/auto_increment_offset_save.inc
+
#
# Set to invalid value
#
@@ -73,3 +74,4 @@ CALL mtr.add_suppression("WSREP: wsrep::connect\\(foo://\\) failed: 7");
--source include/auto_increment_offset_restore.inc
--source include/galera_end.inc
+--echo # End of test
diff --git a/mysql-test/suite/innodb/include/ibd_convert.pl b/mysql-test/suite/innodb/include/ibd_convert.pl
new file mode 100644
index 00000000000..32eef96fd23
--- /dev/null
+++ b/mysql-test/suite/innodb/include/ibd_convert.pl
@@ -0,0 +1,25 @@
+#!/usr/bin/perl
+# Convert tablespace flags to the format understood by MariaDB 10.1.0..10.1.20,
+# with the assumption that the flags were correct.
+
+sub convert_to_mariadb_101
+{
+ my ($file, $page_size) = @_;
+ open(FILE, "+<", $file) or die "Unable to open $file\n";
+ sysread(FILE, $_, $page_size)==$page_size||die "Unable to read $file\n";
+ sysseek(FILE, 0, 0)||die "Unable to seek $file\n";
+
+ # FIL_PAGE_DATA + FSP_SPACE_FLAGS = 38 + 16 = 54 bytes from the start
+ my($flags) = unpack "x[54]N", $_;
+ my $badflags = ($flags & 0x3f);
+ my $compression_level=6;
+ $badflags |= 1<<6|$compression_level<<7 if ($flags & 1 << 16);
+ $badflags |= ($flags & 15 << 6) << 7; # PAGE_SSIZE
+
+ substr ($_, 54, 4) = pack("N", $badflags);
+ # Replace the innodb_checksum_algorithm=none checksum
+ substr ($_, 0, 4) = pack("N", 0xdeadbeef);
+ substr ($_, $page_size - 8, 4) = pack("N", 0xdeadbeef);
+ syswrite(FILE, $_, $page_size)==$page_size||die "Unable to write $file\n";
+ close(FILE);
+}
diff --git a/mysql-test/suite/innodb/r/101_compatibility.result b/mysql-test/suite/innodb/r/101_compatibility.result
new file mode 100644
index 00000000000..f9cc8c288ca
--- /dev/null
+++ b/mysql-test/suite/innodb/r/101_compatibility.result
@@ -0,0 +1,48 @@
+#
+# MDEV-11623 MariaDB 10.1 fails to start datadir created with
+# MariaDB 10.0/MySQL 5.6 using innodb-page-size!=16K
+#
+call mtr.add_suppression("InnoDB: adjusting FSP_SPACE_FLAGS of tablespace");
+SET GLOBAL innodb_file_per_table=1;
+SET GLOBAL innodb_file_format=Barracuda;
+CREATE TABLE tr(a INT)ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+CREATE TABLE tc(a INT)ENGINE=InnoDB ROW_FORMAT=COMPACT;
+CREATE TABLE td(a INT)ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+CREATE TABLE tz(a INT)ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1;
+CREATE TABLE tdd(a INT) ENGINE=InnoDB, DATA DIRECTORY='MYSQL_TMP_DIR';
+CREATE TABLE tp(a INT) ENGINE=InnoDB page_compressed=1;
+CREATE TABLE ti(a INT) ENGINE=InnoDB;
+FLUSH TABLES ti FOR EXPORT;
+backup: ti
+UNLOCK TABLES;
+ALTER TABLE ti DISCARD TABLESPACE;
+restore: ti .ibd and .cfg files
+ALTER TABLE ti IMPORT TABLESPACE;
+BEGIN;
+INSERT INTO tr VALUES(1);
+INSERT INTO tc VALUES(1);
+INSERT INTO td VALUES(1);
+INSERT INTO tz VALUES(1);
+INSERT INTO tdd VALUES(1);
+INSERT INTO tp VALUES(1);
+INSERT INTO ti VALUES(1);
+# Kill the server
+CHECK TABLE tr,tc,td,tz,tdd,tp,ti;
+Table Op Msg_type Msg_text
+test.tr check status OK
+test.tc check status OK
+test.td check status OK
+test.tz check status OK
+test.tdd check status OK
+test.tp check status OK
+test.ti check status OK
+CHECK TABLE tr,tc,td,tz,tdd,tp,ti;
+Table Op Msg_type Msg_text
+test.tr check status OK
+test.tc check status OK
+test.td check status OK
+test.tz check status OK
+test.tdd check status OK
+test.tp check status OK
+test.ti check status OK
+DROP TABLE tr,tc,td,tz,tdd,tp,ti;
diff --git a/mysql-test/suite/innodb/r/doublewrite.result b/mysql-test/suite/innodb/r/doublewrite.result
index aa96a5f2d93..6b913f49972 100644
--- a/mysql-test/suite/innodb/r/doublewrite.result
+++ b/mysql-test/suite/innodb/r/doublewrite.result
@@ -39,6 +39,8 @@ set global innodb_buf_flush_list_now = 1;
# Kill the server
# Make the first page (page_no=0) of the user tablespace
# full of zeroes.
+#
+# MDEV-11623: Use old FSP_SPACE_FLAGS in the doublewrite buffer.
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
diff --git a/mysql-test/suite/innodb/r/group_commit_crash.result b/mysql-test/suite/innodb/r/group_commit_crash.result
index 80a780ba2c5..f07df897453 100644
--- a/mysql-test/suite/innodb/r/group_commit_crash.result
+++ b/mysql-test/suite/innodb/r/group_commit_crash.result
@@ -1,4 +1,3 @@
-call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
CREATE TABLE t1(a CHAR(255),
b CHAR(255),
c CHAR(255),
diff --git a/mysql-test/suite/innodb/r/group_commit_crash_no_optimize_thread.result b/mysql-test/suite/innodb/r/group_commit_crash_no_optimize_thread.result
index 06fdeaef6a7..2cd9f01d7ed 100644
--- a/mysql-test/suite/innodb/r/group_commit_crash_no_optimize_thread.result
+++ b/mysql-test/suite/innodb/r/group_commit_crash_no_optimize_thread.result
@@ -1,4 +1,3 @@
-call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
CREATE TABLE t1(a CHAR(255),
b CHAR(255),
c CHAR(255),
diff --git a/mysql-test/suite/innodb/r/innodb-alter-tempfile.result b/mysql-test/suite/innodb/r/innodb-alter-tempfile.result
index 3cc973ca3a3..ce13ad0978b 100644
--- a/mysql-test/suite/innodb/r/innodb-alter-tempfile.result
+++ b/mysql-test/suite/innodb/r/innodb-alter-tempfile.result
@@ -4,10 +4,6 @@
# Temporary tablename will be unique. This makes sure that future
# in-place ALTERs of the same table will not be blocked due to
# temporary tablename.
-call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed
-");
-call mtr.add_suppression("InnoDB: file read of space .* page .*");
-call mtr.add_suppression("InnoDB: Trying to recover it from the doublewrite buffer.");
# Crash the server in ha_innobase::commit_inplace_alter_table()
CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=innodb;
SET debug='d,innodb_alter_commit_crash_before_commit';
diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-debug-zip.result b/mysql-test/suite/innodb/r/innodb-wl5522-debug-zip.result
index ab6bf0c808e..c130e042c9b 100644
--- a/mysql-test/suite/innodb/r/innodb-wl5522-debug-zip.result
+++ b/mysql-test/suite/innodb/r/innodb-wl5522-debug-zip.result
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
call mtr.add_suppression("InnoDB: Tablespace for table .* is set as discarded.");
call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* because the .ibd file is missing. Please refer to .* for how to resolve the issue.");
call mtr.add_suppression("InnoDB: Error: Tablespace flags .* corrupted unused .*");
@@ -5,6 +6,19 @@ call mtr.add_suppression("InnoDB: Tablespace flags: .* corrupted in file: .* ")
call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file .*");
call mtr.add_suppression("InnoDB: Page for tablespace .* ");
flush tables;
+=======
+call mtr.add_suppression("InnoDB: Page for tablespace ");
+call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=0x");
+FLUSH TABLES;
+SET GLOBAL innodb_file_per_table = 1;
+SELECT @@innodb_file_per_table;
+@@innodb_file_per_table
+1
+SET GLOBAL innodb_file_format = `Barracuda`;
+SELECT @@innodb_file_format;
+@@innodb_file_format
+Barracuda
+>>>>>>> origin/10.1
SET SESSION innodb_strict_mode=1;
CREATE DATABASE test_wl5522;
CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb
@@ -546,7 +560,11 @@ ERROR HY000: Tablespace has been discarded for table `t1`
restore: t1 .ibd and .cfg files
SET SESSION debug_dbug="+d,fsp_flags_is_valid_failure";
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
+<<<<<<< HEAD
ERROR HY000: Internal error: Cannot reset LSNs in table `test_wl5522`.`t1` : Unsupported
+=======
+ERROR HY000: Internal error: Cannot reset LSNs in table '"test_wl5522"."t1"' : Data structure corruption
+>>>>>>> origin/10.1
SET SESSION debug_dbug="-d,fsp_flags_is_valid_failure";
DROP TABLE test_wl5522.t1;
unlink: t1.ibd
diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result
index 8327ef36909..11a21b205aa 100644
--- a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result
+++ b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result
@@ -8,7 +8,12 @@ call mtr.add_suppression("InnoDB: Tablespace for table .* is set as discarded.")
call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .*");
call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file .*");
call mtr.add_suppression("InnoDB: Page for tablespace .* ");
+<<<<<<< HEAD
flush tables;
+=======
+call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=");
+FLUSH TABLES;
+>>>>>>> origin/10.1
SET GLOBAL innodb_file_per_table = 1;
SELECT @@innodb_file_per_table;
@@innodb_file_per_table
@@ -921,7 +926,11 @@ ERROR HY000: Tablespace has been discarded for table `t1`
restore: t1 .ibd and .cfg files
SET SESSION debug_dbug="+d,fsp_flags_is_valid_failure";
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
+<<<<<<< HEAD
ERROR HY000: Internal error: Cannot reset LSNs in table `test_wl5522`.`t1` : Unsupported
+=======
+ERROR HY000: Internal error: Cannot reset LSNs in table '"test_wl5522"."t1"' : Data structure corruption
+>>>>>>> origin/10.1
SET SESSION debug_dbug="-d,fsp_flags_is_valid_failure";
DROP TABLE test_wl5522.t1;
unlink: t1.ibd
diff --git a/mysql-test/suite/innodb/r/innodb_bug14147491.result b/mysql-test/suite/innodb/r/innodb_bug14147491.result
index cf960e3a6ee..a11b5bc0857 100644
--- a/mysql-test/suite/innodb/r/innodb_bug14147491.result
+++ b/mysql-test/suite/innodb/r/innodb_bug14147491.result
@@ -1,4 +1,21 @@
+<<<<<<< HEAD
CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ROW_FORMAT=COMPACT ENGINE=InnoDB;
+=======
+call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed.*");
+CALL mtr.add_suppression("InnoDB: Error: Unable to read tablespace .* page no .* into the buffer pool after 100 attempts");
+CALL mtr.add_suppression("InnoDB: Database page corruption on disk or a failed");
+CALL mtr.add_suppression("InnoDB: Space .* file test/t1 read of page .*");
+CALL mtr.add_suppression("InnoDB: You may have to recover from a backup.");
+CALL mtr.add_suppression("InnoDB: It is also possible that your operatingsystem has corrupted its own file cache.");
+CALL mtr.add_suppression("InnoDB: and rebooting your computer removes the error.");
+CALL mtr.add_suppression("InnoDB: If the corrupt page is an index page you can also try to");
+CALL mtr.add_suppression("InnoDB: fix the corruption by dumping, dropping, and reimporting");
+CALL mtr.add_suppression("InnoDB: the corrupt table. You can use CHECK");
+CALL mtr.add_suppression("InnoDB: TABLE to scan your table for corruption.");
+CALL mtr.add_suppression("InnoDB: See also .* about forcing recovery.");
+# Create and populate the table to be corrupted
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB;
+>>>>>>> origin/10.1
INSERT INTO t1 (b) VALUES ('corrupt me');
INSERT INTO t1 (b) VALUES ('corrupt me');
# Backup the t1.ibd before corrupting
diff --git a/mysql-test/suite/innodb/r/xa_recovery.result b/mysql-test/suite/innodb/r/xa_recovery.result
index 666a65f8ee1..43049e85a2b 100644
--- a/mysql-test/suite/innodb/r/xa_recovery.result
+++ b/mysql-test/suite/innodb/r/xa_recovery.result
@@ -1,4 +1,3 @@
-call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
connect con1,localhost,root;
@@ -8,8 +7,12 @@ XA END 'x';
XA PREPARE 'x';
connection default;
call mtr.add_suppression("Found 1 prepared XA transactions");
+<<<<<<< HEAD
disconnect con1;
connect con1,localhost,root;
+=======
+# Kill the server
+>>>>>>> origin/10.1
SELECT * FROM t1 LOCK IN SHARE MODE;
connection default;
disconnect con1;
diff --git a/mysql-test/suite/innodb/t/101_compatibility.test b/mysql-test/suite/innodb/t/101_compatibility.test
new file mode 100644
index 00000000000..125a559c1cb
--- /dev/null
+++ b/mysql-test/suite/innodb/t/101_compatibility.test
@@ -0,0 +1,101 @@
+--source include/have_innodb.inc
+--source include/not_embedded.inc
+
+-- echo #
+-- echo # MDEV-11623 MariaDB 10.1 fails to start datadir created with
+-- echo # MariaDB 10.0/MySQL 5.6 using innodb-page-size!=16K
+-- echo #
+
+# This is actually testing the opposite: starting the fixed 10.1 with
+# buggy 10.1 files (by manually converting the flags in the files).
+
+call mtr.add_suppression("InnoDB: adjusting FSP_SPACE_FLAGS of tablespace");
+SET GLOBAL innodb_file_per_table=1;
+SET GLOBAL innodb_file_format=Barracuda;
+let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
+let MYSQLD_DATADIR=`select @@datadir`;
+
+CREATE TABLE tr(a INT)ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+CREATE TABLE tc(a INT)ENGINE=InnoDB ROW_FORMAT=COMPACT;
+CREATE TABLE td(a INT)ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+--disable_warnings
+CREATE TABLE tz(a INT)ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1;
+--enable_warnings
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+EVAL CREATE TABLE tdd(a INT) ENGINE=InnoDB, DATA DIRECTORY='$MYSQL_TMP_DIR';
+
+CREATE TABLE tp(a INT) ENGINE=InnoDB page_compressed=1;
+CREATE TABLE ti(a INT) ENGINE=InnoDB;
+FLUSH TABLES ti FOR EXPORT;
+perl;
+do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+ib_backup_tablespaces("test", "ti");
+EOF
+UNLOCK TABLES;
+ALTER TABLE ti DISCARD TABLESPACE;
+perl;
+do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+ib_discard_tablespaces("test", "ti");
+ib_restore_tablespaces("test", "ti");
+do "$ENV{MTR_SUITE_DIR}/include/ibd_convert.pl";
+my $ps = $ENV{INNODB_PAGE_SIZE};
+my $dd = $ENV{MYSQLD_DATADIR};
+convert_to_mariadb_101("$dd/test/ti.ibd", $ps);
+EOF
+
+ALTER TABLE ti IMPORT TABLESPACE;
+
+BEGIN;
+INSERT INTO tr VALUES(1);
+INSERT INTO tc VALUES(1);
+INSERT INTO td VALUES(1);
+INSERT INTO tz VALUES(1);
+INSERT INTO tdd VALUES(1);
+INSERT INTO tp VALUES(1);
+INSERT INTO ti VALUES(1);
+
+--source include/kill_mysqld.inc
+
+perl;
+do "$ENV{MTR_SUITE_DIR}/include/ibd_convert.pl";
+my $ps = $ENV{INNODB_PAGE_SIZE};
+my $dd = $ENV{MYSQLD_DATADIR};
+
+convert_to_mariadb_101("$dd/ibdata1", $ps);
+convert_to_mariadb_101("$dd/test/tr.ibd", $ps);
+convert_to_mariadb_101("$dd/test/tc.ibd", $ps);
+convert_to_mariadb_101("$dd/test/td.ibd", $ps);
+convert_to_mariadb_101("$dd/test/tz.ibd", 1024) if $ps<32768;
+convert_to_mariadb_101("$dd/test/tp.ibd", $ps);
+convert_to_mariadb_101("$dd/test/ti.ibd", $ps);
+convert_to_mariadb_101("$ENV{MYSQL_TMP_DIR}/test/tdd.ibd", $ps);
+EOF
+
+--source include/start_mysqld.inc
+CHECK TABLE tr,tc,td,tz,tdd,tp,ti;
+--source include/shutdown_mysqld.inc
+
+perl;
+do "$ENV{MTR_SUITE_DIR}/include/ibd_convert.pl";
+my $ps = $ENV{INNODB_PAGE_SIZE};
+my $dd = $ENV{MYSQLD_DATADIR};
+
+convert_to_mariadb_101("$dd/ibdata1", $ps);
+convert_to_mariadb_101("$dd/test/tr.ibd", $ps);
+convert_to_mariadb_101("$dd/test/tc.ibd", $ps);
+convert_to_mariadb_101("$dd/test/td.ibd", $ps);
+convert_to_mariadb_101("$dd/test/tz.ibd", 1024) if $ps<32768;
+convert_to_mariadb_101("$dd/test/tp.ibd", $ps);
+convert_to_mariadb_101("$dd/test/ti.ibd", $ps);
+convert_to_mariadb_101("$ENV{MYSQL_TMP_DIR}/test/tdd.ibd", $ps);
+EOF
+
+--let $restart_parameters=--innodb-read-only
+--source include/start_mysqld.inc
+CHECK TABLE tr,tc,td,tz,tdd,tp,ti;
+--source include/shutdown_mysqld.inc
+
+--let $restart_parameters=
+--source include/start_mysqld.inc
+DROP TABLE tr,tc,td,tz,tdd,tp,ti;
diff --git a/mysql-test/suite/innodb/t/doublewrite.test b/mysql-test/suite/innodb/t/doublewrite.test
index e1984319cb7..fc61061c907 100644
--- a/mysql-test/suite/innodb/t/doublewrite.test
+++ b/mysql-test/suite/innodb/t/doublewrite.test
@@ -13,11 +13,19 @@ SET GLOBAL innodb_fast_shutdown = 0;
--source include/restart_mysqld.inc
--disable_query_log
+<<<<<<< HEAD
call mtr.add_suppression("InnoDB: Database page [0-9]+:1 contained only zeroes.");
call mtr.add_suppression("Header page consists of zero bytes");
call mtr.add_suppression("Checksum mismatch in datafile");
call mtr.add_suppression("but the innodb_page_size start-up parameter is");
call mtr.add_suppression("Database page corruption");
+=======
+call mtr.add_suppression("space header page consists of zero bytes.*test.t1");
+call mtr.add_suppression("checksum mismatch in tablespace.*test.t1");
+call mtr.add_suppression("Current page size .* != page size on page");
+call mtr.add_suppression("innodb-page-size mismatch in tablespace.*test.t1");
+call mtr.add_suppression("Trying to recover page.*from the doublewrite buffer");
+>>>>>>> origin/10.1
--enable_query_log
let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
@@ -65,14 +73,48 @@ set global innodb_buf_flush_list_now = 1;
--echo # Make the first page (page_no=0) of the user tablespace
--echo # full of zeroes.
+--echo #
+--echo # MDEV-11623: Use old FSP_SPACE_FLAGS in the doublewrite buffer.
+
perl;
use IO::Handle;
my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd";
+my $page_size = $ENV{INNODB_PAGE_SIZE};
+my $page;
open(FILE, "+<", $fname) or die;
-FILE->autoflush(1);
-binmode FILE;
-print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'});
+sysread(FILE, $page, $page_size)==$page_size||die "Unable to read $name\n";
+sysseek(FILE, 0, 0)||die "Unable to seek $fname\n";
+die unless syswrite(FILE, chr(0) x $page_size, $page_size) == $page_size;
close FILE;
+
+open(FILE, "+<", "$ENV{MYSQLD_DATADIR}ibdata1")||die "cannot open ibdata1\n";
+sysseek(FILE, 6 * $page_size - 190, 0)||die "Unable to seek ibdata1\n";
+sysread(FILE, $_, 12) == 12||die "Unable to read TRX_SYS\n";
+my($magic,$d1,$d2)=unpack "NNN", $_;
+die "magic=$magic, $d1, $d2\n" unless $magic == 536853855 && $d2 >= $d1 + 64;
+sysseek(FILE, $d1 * $page_size, 0)||die "Unable to seek ibdata1\n";
+# Find the page in the doublewrite buffer
+for (my $d = $d1; $d < $d2 + 64; $d++)
+{
+ sysread(FILE, $_, $page_size)==$page_size||die "Cannot read doublewrite\n";
+ next unless $_ eq $page;
+ sysseek(FILE, $d * $page_size, 0)||die "Unable to seek ibdata1\n";
+ # Write buggy MariaDB 10.1.x FSP_SPACE_FLAGS to the doublewrite buffer
+ my($flags) = unpack "x[54]N", $_;
+ my $badflags = ($flags & 0x3f);
+ my $compression_level=6;
+ $badflags |= 1<<6|$compression_level<<7 if ($flags & 1 << 16);
+ $badflags |= ($flags & 15 << 6) << 7; # PAGE_SSIZE
+
+ substr ($_, 54, 4) = pack("N", $badflags);
+ # Replace the innodb_checksum_algorithm=none checksum
+ substr ($_, 0, 4) = pack("N", 0xdeadbeef);
+ substr ($_, $page_size - 8, 4) = pack("N", 0xdeadbeef);
+ syswrite(FILE, $_, $page_size)==$page_size||die;
+ close(FILE);
+ exit 0;
+}
+die "Did not find the page in the doublewrite buffer ($d1,$d2)\n";
EOF
--source include/start_mysqld.inc
diff --git a/mysql-test/suite/innodb/t/group_commit_crash.test b/mysql-test/suite/innodb/t/group_commit_crash.test
index cad349819bd..7ad0d9d1e74 100644
--- a/mysql-test/suite/innodb/t/group_commit_crash.test
+++ b/mysql-test/suite/innodb/t/group_commit_crash.test
@@ -9,8 +9,6 @@
--source include/have_debug.inc
--source include/have_log_bin.inc
-call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
-
let $file_format_max=`SELECT @@innodb_file_format_max`;
CREATE TABLE t1(a CHAR(255),
b CHAR(255),
diff --git a/mysql-test/suite/innodb/t/group_commit_crash_no_optimize_thread.test b/mysql-test/suite/innodb/t/group_commit_crash_no_optimize_thread.test
index 8d1f460b64b..9dc2557e687 100644
--- a/mysql-test/suite/innodb/t/group_commit_crash_no_optimize_thread.test
+++ b/mysql-test/suite/innodb/t/group_commit_crash_no_optimize_thread.test
@@ -9,8 +9,6 @@
--source include/have_debug.inc
--source include/have_log_bin.inc
-call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
-
let $file_format_max=`SELECT @@innodb_file_format_max`;
CREATE TABLE t1(a CHAR(255),
b CHAR(255),
diff --git a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test
index e1e736fc678..ec1ea35f1cf 100644
--- a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test
+++ b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test
@@ -20,13 +20,6 @@
--echo # in-place ALTERs of the same table will not be blocked due to
--echo # temporary tablename.
-# As we intentionally crash below, there could be partially written
-# pages that are then recovered from the doublewrite buffer
-call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed
-");
-call mtr.add_suppression("InnoDB: file read of space .* page .*");
-call mtr.add_suppression("InnoDB: Trying to recover it from the doublewrite buffer.");
-
let datadir= `select @@datadir`;
--let $_server_id= `SELECT @@server_id`
diff --git a/mysql-test/suite/innodb/t/innodb-wl5522-debug-zip.test b/mysql-test/suite/innodb/t/innodb-wl5522-debug-zip.test
index 3b71bd802ef..c4e9b60e833 100644
--- a/mysql-test/suite/innodb/t/innodb-wl5522-debug-zip.test
+++ b/mysql-test/suite/innodb/t/innodb-wl5522-debug-zip.test
@@ -17,6 +17,7 @@
# allow test to run only when innodb-page-size=16
--source include/have_innodb_16k.inc
+<<<<<<< HEAD
call mtr.add_suppression("InnoDB: Tablespace for table .* is set as discarded.");
call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* because the .ibd file is missing. Please refer to .* for how to resolve the issue.");
call mtr.add_suppression("InnoDB: Error: Tablespace flags .* corrupted unused .*");
@@ -24,6 +25,11 @@ call mtr.add_suppression("InnoDB: Tablespace flags: .* corrupted in file: .* ")
call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file .*");
call mtr.add_suppression("InnoDB: Page for tablespace .* ");
flush tables;
+=======
+call mtr.add_suppression("InnoDB: Page for tablespace ");
+call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=0x");
+FLUSH TABLES;
+>>>>>>> origin/10.1
let MYSQLD_DATADIR =`SELECT @@datadir`;
let $pathfix=/: '.*test_wl5522.*t1.ibd'/: 'test_wl5522_t1.ibd'/;
diff --git a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test
index e537f5c0fc3..533637a3568 100644
--- a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test
+++ b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test
@@ -25,7 +25,12 @@ call mtr.add_suppression("InnoDB: Tablespace for table .* is set as discarded.")
call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .*");
call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file .*");
call mtr.add_suppression("InnoDB: Page for tablespace .* ");
+<<<<<<< HEAD
flush tables;
+=======
+call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=");
+FLUSH TABLES;
+>>>>>>> origin/10.1
let MYSQLD_DATADIR =`SELECT @@datadir`;
let $innodb_file_per_table = `SELECT @@innodb_file_per_table`;
diff --git a/mysql-test/suite/innodb/t/innodb_bug14147491.test b/mysql-test/suite/innodb/t/innodb_bug14147491.test
index c73571af6dd..a7705df381b 100644
--- a/mysql-test/suite/innodb/t/innodb_bug14147491.test
+++ b/mysql-test/suite/innodb/t/innodb_bug14147491.test
@@ -17,6 +17,7 @@ source include/not_encrypted.inc;
# if compiler set up
source include/not_windows.inc;
+<<<<<<< HEAD
--disable_query_log
CALL mtr.add_suppression("\\[ERROR\\] \\[FATAL\\] InnoDB: Unable to read page \\[page id: space=.*, page number=.*\\] into the buffer pool after 100 attempts");
CALL mtr.add_suppression("\\[ERROR\\] InnoDB: Database page corruption on disk or a failed");
@@ -24,6 +25,23 @@ CALL mtr.add_suppression("\\[ERROR\\] InnoDB: Database page corruption on disk o
CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ROW_FORMAT=COMPACT ENGINE=InnoDB;
+=======
+CALL mtr.add_suppression("InnoDB: Error: Unable to read tablespace .* page no .* into the buffer pool after 100 attempts");
+CALL mtr.add_suppression("InnoDB: Database page corruption on disk or a failed");
+CALL mtr.add_suppression("InnoDB: Space .* file test/t1 read of page .*");
+CALL mtr.add_suppression("InnoDB: You may have to recover from a backup.");
+CALL mtr.add_suppression("InnoDB: It is also possible that your operatingsystem has corrupted its own file cache.");
+CALL mtr.add_suppression("InnoDB: and rebooting your computer removes the error.");
+CALL mtr.add_suppression("InnoDB: If the corrupt page is an index page you can also try to");
+CALL mtr.add_suppression("InnoDB: fix the corruption by dumping, dropping, and reimporting");
+CALL mtr.add_suppression("InnoDB: the corrupt table. You can use CHECK");
+CALL mtr.add_suppression("InnoDB: TABLE to scan your table for corruption.");
+CALL mtr.add_suppression("InnoDB: See also .* about forcing recovery.");
+
+
+--echo # Create and populate the table to be corrupted
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB;
+>>>>>>> origin/10.1
INSERT INTO t1 (b) VALUES ('corrupt me');
--disable_query_log
--let $i = 10
diff --git a/mysql-test/suite/innodb/t/xa_recovery.test b/mysql-test/suite/innodb/t/xa_recovery.test
index 32373d63d14..9f25e4d1f30 100644
--- a/mysql-test/suite/innodb/t/xa_recovery.test
+++ b/mysql-test/suite/innodb/t/xa_recovery.test
@@ -12,11 +12,6 @@ if (`select plugin_auth_version <= "5.6.24" from information_schema.plugins wher
FLUSH TABLES;
--enable_query_log
-#
-# We kill server belown with timeout 0 that is not fully safe
-#
-call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
-
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
connect (con1,localhost,root);
@@ -25,15 +20,8 @@ connection default;
call mtr.add_suppression("Found 1 prepared XA transactions");
-# Kill and restart the server.
--- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--- shutdown_server 0
--- source include/wait_until_disconnected.inc
-
--- exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--- enable_reconnect
--- source include/wait_until_connected_again.inc
--- disable_reconnect
+--source include/kill_mysqld.inc
+--source include/start_mysqld.inc
disconnect con1;
connect (con1,localhost,root);
diff --git a/mysql-test/suite/rpl/r/rpl_gtid_crash.result b/mysql-test/suite/rpl/r/rpl_gtid_crash.result
index 00cae145673..7b6e95bf718 100644
--- a/mysql-test/suite/rpl/r/rpl_gtid_crash.result
+++ b/mysql-test/suite/rpl/r/rpl_gtid_crash.result
@@ -4,7 +4,6 @@ connection server_1;
call mtr.add_suppression("Checking table:");
call mtr.add_suppression("client is using or hasn't closed the table properly");
call mtr.add_suppression("Table .* is marked as crashed and should be repaired");
-call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
flush tables;
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB;
diff --git a/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result b/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result
index 5c3bcf9070c..63c2b13540c 100644
--- a/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result
+++ b/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result
@@ -1,15 +1,26 @@
include/master-slave.inc
[connection master]
-
---Setup Section --
set timestamp=1000000000;
+<<<<<<< HEAD
DROP TABLE IF EXISTS t1,t2,t3;
connection master;
+=======
+>>>>>>> origin/10.1
CREATE TABLE t1(word VARCHAR(20));
CREATE TABLE t2(id INT AUTO_INCREMENT NOT NULL PRIMARY KEY);
CREATE TABLE t3(c1 INT NOT NULL PRIMARY KEY, c2 LONGBLOB, c3 TIMESTAMP, c4 TEXT, c5 FLOAT);
-
----Test1 check table load --
+INSERT INTO t1 VALUES ("abirvalg");
+LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1;
+LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1;
+LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1;
+LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1;
+LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1;
+set @d1 = 'dd1';
+set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1);
+set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1);
+set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1);
+---Test 1 check table load --
SELECT COUNT(*) from t1;
COUNT(*)
351
@@ -74,9 +85,7 @@ c1 c3 c4 c5
connection master;
insert into t1 values ("Alas");
flush logs;
-
--- Test 1 Dump binlog to file --
-
--- Test 1 delete tables, clean master and slave --
DROP TABLE t1;
DROP TABLE t2;
@@ -90,10 +99,12 @@ connection slave;
reset slave;
start slave;
include/wait_for_slave_to_start.inc
+<<<<<<< HEAD
connection master;
+=======
+>>>>>>> origin/10.1
--- Test 1 Load from Dump binlog file --
-
--- Test 1 Check Load Results --
SELECT COUNT(*) from t1;
COUNT(*)
@@ -156,8 +167,11 @@ c1 c3 c4 c5
3 2006-02-22 00:00:00 Tested in Texas 6.6
4 2006-02-22 00:00:00 Tested in Texas 8.8
5 2006-02-22 00:00:00 Tested in Texas 11
+<<<<<<< HEAD
connection master;
+=======
+>>>>>>> origin/10.1
--- Test 2 position test --
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
@@ -167,8 +181,13 @@ ROLLBACK/*!*/;
use `test`/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
+<<<<<<< HEAD
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/;
+=======
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=1342177280/*!*/;
+>>>>>>> origin/10.1
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
@@ -181,7 +200,6 @@ DELIMITER ;
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
-
--- Test 3 First Remote test --
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
@@ -191,16 +209,18 @@ ROLLBACK/*!*/;
use `test`/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
+<<<<<<< HEAD
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/;
+=======
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=1342177280/*!*/;
+>>>>>>> origin/10.1
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
-DROP TABLE IF EXISTS `t1`,`t2`,`t3` /* generated by server */
-/*!*/;
-SET TIMESTAMP=1000000000/*!*/;
CREATE TABLE t1(word VARCHAR(20))
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
@@ -214,7 +234,6 @@ DELIMITER ;
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
-
--- Test 4 Second Remote test --
DROP TABLE t1;
DROP TABLE t2;
@@ -290,8 +309,11 @@ c1 c3 c4 c5
3 2006-02-22 00:00:00 Tested in Texas 6.6
4 2006-02-22 00:00:00 Tested in Texas 8.8
5 2006-02-22 00:00:00 Tested in Texas 11
+<<<<<<< HEAD
connection master;
+=======
+>>>>>>> origin/10.1
--- Test 5 LOAD DATA --
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
@@ -302,7 +324,6 @@ DELIMITER ;
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
-
--- Test 6 reading stdin --
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
@@ -312,16 +333,18 @@ ROLLBACK/*!*/;
use `test`/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
+<<<<<<< HEAD
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/;
+=======
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=1342177280/*!*/;
+>>>>>>> origin/10.1
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
-DROP TABLE IF EXISTS `t1`,`t2`,`t3` /* generated by server */
-/*!*/;
-SET TIMESTAMP=1000000000/*!*/;
CREATE TABLE t1(word VARCHAR(20))
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
@@ -335,7 +358,6 @@ DELIMITER ;
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
-
--- Test 7 reading stdin w/position --
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
@@ -345,8 +367,13 @@ ROLLBACK/*!*/;
use `test`/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
+<<<<<<< HEAD
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/;
+=======
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=1342177280/*!*/;
+>>>>>>> origin/10.1
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
@@ -359,7 +386,6 @@ DELIMITER ;
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
-
--- Test 8 switch internal charset --
connection slave;
stop slave;
@@ -400,18 +426,25 @@ HEX(f)
select HEX(f) from t5;
HEX(f)
835C
-
--- Test cleanup --
+<<<<<<< HEAD
connection master;
connection slave;
connection master;
DROP TABLE IF EXISTS t1;
+=======
+DROP TABLE t1, t2, t3, t04, t05, t4, t5;
+>>>>>>> origin/10.1
CREATE TABLE t1 (a INT NOT NULL KEY, b INT);
INSERT INTO t1 VALUES(1,1);
SELECT * FROM t1;
a b
1 1
FLUSH LOGS;
+<<<<<<< HEAD
DROP TABLE IF EXISTS t1, t2, t3, t04, t05, t4, t5;
connection slave;
+=======
+DROP TABLE t1;
+>>>>>>> origin/10.1
include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_special_charset.result b/mysql-test/suite/rpl/r/rpl_special_charset.result
index 218ced9b8ea..b947cf3484d 100644
--- a/mysql-test/suite/rpl/r/rpl_special_charset.result
+++ b/mysql-test/suite/rpl/r/rpl_special_charset.result
@@ -1,6 +1,6 @@
include/master-slave.inc
[connection master]
-call mtr.add_suppression("Cannot use utf16 as character_set_client");
+call mtr.add_suppression("'utf16' can not be used as client character set");
CREATE TABLE t1(i VARCHAR(20));
INSERT INTO t1 VALUES (0xFFFF);
connection slave;
diff --git a/mysql-test/suite/rpl/r/rpl_strict_password_validation.result b/mysql-test/suite/rpl/r/rpl_strict_password_validation.result
new file mode 100644
index 00000000000..071d730fa72
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_strict_password_validation.result
@@ -0,0 +1,13 @@
+include/master-slave.inc
+[connection master]
+install soname "simple_password_check";
+select @@strict_password_validation;
+@@strict_password_validation
+1
+create user foo1 identified by password '11111111111111111111111111111111111111111';
+set password for foo1 = PASSWORD('PLAINtext-password!!99');
+drop user foo1;
+create user foo1 identified by password '11111111111111111111111111111111111111111';
+ERROR HY000: The MariaDB server is running with the --strict-password-validation option so it cannot execute this statement
+uninstall plugin simple_password_check;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_gtid_crash.test b/mysql-test/suite/rpl/t/rpl_gtid_crash.test
index df3ba9a3420..b81cbd38cd3 100644
--- a/mysql-test/suite/rpl/t/rpl_gtid_crash.test
+++ b/mysql-test/suite/rpl/t/rpl_gtid_crash.test
@@ -12,11 +12,6 @@
call mtr.add_suppression("Checking table:");
call mtr.add_suppression("client is using or hasn't closed the table properly");
call mtr.add_suppression("Table .* is marked as crashed and should be repaired");
-# We have seen this warning a couple of times in Buildbot. Since we crash the
-# server deliberately, it seems possible that we could in rare cases crash in
-# the middle of a page write. The page is recovered from the doublewrite
-# buffer ("[Note] InnoDB: Recovered the page from the doublewrite buffer.").
-call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
flush tables;
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
diff --git a/mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test b/mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test
index a44cc18c0ed..678679f0cf1 100644
--- a/mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test
+++ b/mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test
@@ -4,44 +4,27 @@
# Purpose: To test changes to mysqlbinlog for row based bin logs #
# We are using .opt file since we need small binlog size #
##################################################################
-# Include Section
-# Make sure that we have row based bin log
-- source include/have_binlog_format_row.inc
-# Embedded server doesn't support binlogging
-- source include/not_embedded.inc
-# This test requires the cp932 charset compiled in
-- source include/have_cp932.inc
-# Slow test, don't run during staging part
--- source include/not_staging.inc
-
-- source include/master-slave.inc
-# Setup Section
-# we need this for getting fixed timestamps inside of this test
-
---disable_query_log
-select "---Setup Section --" as "";
-set sql_mode="";
---enable_query_log
+--echo ---Setup Section --
+# we need this for getting fixed timestamps inside of this test
set timestamp=1000000000;
---disable_warnings
-DROP TABLE IF EXISTS t1,t2,t3;
---enable_warnings
-
-connection master;
CREATE TABLE t1(word VARCHAR(20));
CREATE TABLE t2(id INT AUTO_INCREMENT NOT NULL PRIMARY KEY);
---let $position= query_get_value(SHOW MASTER STATUS, Position, 1)
+--let position= query_get_value(SHOW MASTER STATUS, Position, 1)
CREATE TABLE t3(c1 INT NOT NULL PRIMARY KEY, c2 LONGBLOB, c3 TIMESTAMP, c4 TEXT, c5 FLOAT);
---let $stop_position=query_get_value(SHOW MASTER STATUS, Position, 1)
---let $stop_position1=`select $stop_position - 1`
---let $binlog_start_pos=query_get_value(SHOW BINLOG EVENTS LIMIT 1, End_log_pos, 1)
+--let stop_position=query_get_value(SHOW MASTER STATUS, Position, 1)
+--let stop_position1=`select $stop_position - 1`
+--let binlog_start_pos=query_get_value(SHOW BINLOG EVENTS LIMIT 1, End_log_pos, 1)
+
# Test Section
# Lets start by putting some data into the tables.
---disable_query_log
INSERT INTO t1 VALUES ("abirvalg");
LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1;
LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1;
@@ -55,7 +38,8 @@ set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1);
set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1);
set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1);
-let $count=500;
+--disable_query_log
+let count=500;
while ($count)
{
INSERT INTO t2 VALUES (NULL);
@@ -64,10 +48,7 @@ while ($count)
}
--enable_query_log
-
---disable_query_log
-select "---Test1 check table load --" as "";
---enable_query_log
+--echo ---Test 1 check table load --
# Lets Check the tables on the Master
SELECT COUNT(*) from t1;
@@ -96,34 +77,26 @@ insert into t1 values ("Alas");
flush logs;
# delimiters are for easier debugging in future
---disable_query_log
-select "--- Test 1 Dump binlog to file --" as "";
---enable_query_log
+--echo --- Test 1 Dump binlog to file --
#
# Prepare local temporary file to recreate what we have currently.
-let $MYSQLD_DATADIR= `select @@datadir;`;
+let MYSQLD_DATADIR= `select @@datadir;`;
--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/master.sql
--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000002 >> $MYSQLTEST_VARDIR/tmp/master.sql
# Now that we have our file, lets get rid of the current database.
# Cleanup the master and the slave and try to recreate.
---disable_query_log
-select "--- Test 1 delete tables, clean master and slave --" as "";
---enable_query_log
+--echo --- Test 1 delete tables, clean master and slave --
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
sync_slave_with_master;
-#we expect STOP SLAVE to produce a warning as the slave is stopped
-#(the server was started with skip-slave-start)
---disable_warnings
stop slave;
--source include/wait_for_slave_to_stop.inc
---enable_warnings
connection master;
reset master;
connection slave;
@@ -133,15 +106,11 @@ start slave;
connection master;
# We should be clean at this point, now we will run in the file from above.
---disable_query_log
-select "--- Test 1 Load from Dump binlog file --" as "";
---enable_query_log
+--echo --- Test 1 Load from Dump binlog file --
--exec $MYSQL -e "source $MYSQLTEST_VARDIR/tmp/master.sql"
---disable_query_log
-select "--- Test 1 Check Load Results --" as "";
---enable_query_log
+--echo --- Test 1 Check Load Results --
# Lets Check the tables on the Master
SELECT COUNT(*) from t1;
@@ -169,28 +138,20 @@ remove_file $MYSQLTEST_VARDIR/tmp/master.sql;
# this test for start-position option
# By setting this position to 416, we should only get the create of t3
---disable_query_log
-select "--- Test 2 position test --" as "";
---enable_query_log
-let $MYSQLD_DATADIR= `select @@datadir;`;
+--echo --- Test 2 position test --
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --start-position=$position --stop-position=$stop_position $MYSQLD_DATADIR/master-bin.000001
# These are tests for remote binlog.
# They should return the same as previous test.
---disable_query_log
-select "--- Test 3 First Remote test --" as "";
---enable_query_log
+--echo --- Test 3 First Remote test --
# This is broken now
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --stop-position=$stop_position --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
---disable_query_log
-select "--- Test 4 Second Remote test --" as "";
---enable_query_log
+--echo --- Test 4 Second Remote test --
--exec $MYSQL_BINLOG --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 > $MYSQLTEST_VARDIR/tmp/remote.sql
-
--exec $MYSQL_BINLOG --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 >> $MYSQLTEST_VARDIR/tmp/remote.sql
# Now that we have our file, lets get rid of the current database.
@@ -202,13 +163,8 @@ DROP TABLE t3;
sync_slave_with_master;
-#we expect STOP SLAVE to produce a warning as the slave is stopped
-#(the server was started with skip-slave-start)
-
---disable_warnings
stop slave;
--source include/wait_for_slave_to_stop.inc
---enable_warnings
connection master;
reset master;
connection slave;
@@ -252,40 +208,26 @@ connection master;
# transactions. /Matz
# LOAD DATA
---disable_query_log
-select "--- Test 5 LOAD DATA --" as "";
---enable_query_log
+--echo --- Test 5 LOAD DATA --
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --stop-position=$binlog_start_pos --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002
# Bug#7853 (mysqlbinlog does not accept input from stdin)
---disable_query_log
-select "--- Test 6 reading stdin --" as "";
---enable_query_log
-let $MYSQLD_DATADIR= `select @@datadir;`;
+--echo --- Test 6 reading stdin --
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--exec $MYSQL_BINLOG --short-form --stop-position=$stop_position1 - < $MYSQLD_DATADIR/master-bin.000001
---disable_query_log
-select "--- Test 7 reading stdin w/position --" as "";
---enable_query_log
+--echo --- Test 7 reading stdin w/position --
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--exec $MYSQL_BINLOG --short-form --start-position=$position --stop-position=$stop_position - < $MYSQLD_DATADIR/master-bin.000001
# Bug#16217 (mysql client did not know how not switch its internal charset)
---disable_query_log
-select "--- Test 8 switch internal charset --" as "";
---enable_query_log
+--echo --- Test 8 switch internal charset --
sync_slave_with_master;
-#we expect STOP SLAVE to produce a warning as the slave is stopped
-#(the server was started with skip-slave-start)
-
---disable_warnings
stop slave;
--source include/wait_for_slave_to_stop.inc
---enable_warnings
connection master;
reset master;
connection slave;
@@ -298,7 +240,6 @@ create table t4 (f text character set utf8);
create table t5 (f text character set cp932);
--exec $MYSQL --default-character-set=utf8 test -e "insert into t4 values(_utf8'ソ')"
--exec $MYSQL --default-character-set=cp932 test -e "insert into t5 values(_cp932'ƒ\');"
-let $MYSQLD_DATADIR= `select @@datadir;`;
flush logs;
rename table t4 to t04, t5 to t05;
--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 | $MYSQL --default-character-set=utf8
@@ -315,42 +256,30 @@ select HEX(f) from t4;
select HEX(f) from t05;
select HEX(f) from t5;
---disable_query_log
-select "--- Test cleanup --" as "";
---enable_query_log
+--echo --- Test cleanup --
# clean up
connection master;
sync_slave_with_master;
connection master;
+DROP TABLE t1, t2, t3, t04, t05, t4, t5;
# BUG#17654 also test mysqlbinlog to ensure it can read the binlog from a remote server
# and ensure that the results are the same as if read from a file (the same file).
---disable_warnings
-DROP TABLE IF EXISTS t1;
---enable_warnings
-
CREATE TABLE t1 (a INT NOT NULL KEY, b INT);
-
INSERT INTO t1 VALUES(1,1);
-
SELECT * FROM t1;
-
-let $MYSQLD_DATADIR= `select @@datadir;`;
-
FLUSH LOGS;
--exec $MYSQL_BINLOG --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 > $MYSQLTEST_VARDIR/tmp/remote.sql
--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/local.sql
--diff_files $MYSQLTEST_VARDIR/tmp/local.sql $MYSQLTEST_VARDIR/tmp/remote.sql
-
--remove_file $MYSQLTEST_VARDIR/tmp/remote.sql
-
--remove_file $MYSQLTEST_VARDIR/tmp/local.sql
+DROP TABLE t1;
-DROP TABLE IF EXISTS t1, t2, t3, t04, t05, t4, t5;
sync_slave_with_master;
# End of 4.1 tests
diff --git a/mysql-test/suite/rpl/t/rpl_strict_password_validation.test b/mysql-test/suite/rpl/t/rpl_strict_password_validation.test
new file mode 100644
index 00000000000..c4dda1e1269
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_strict_password_validation.test
@@ -0,0 +1,24 @@
+if (!$SIMPLE_PASSWORD_CHECK_SO) {
+ skip No SIMPLE_PASSWORD_CHECK plugin;
+}
+
+--source include/master-slave.inc
+
+
+--connection slave
+install soname "simple_password_check";
+select @@strict_password_validation;
+
+--connection master
+create user foo1 identified by password '11111111111111111111111111111111111111111';
+set password for foo1 = PASSWORD('PLAINtext-password!!99');
+drop user foo1;
+--sync_slave_with_master
+
+--connection slave
+--error ER_OPTION_PREVENTS_STATEMENT
+create user foo1 identified by password '11111111111111111111111111111111111111111';
+
+uninstall plugin simple_password_check;
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
index b4c7b2cc1fb..1d9dda94eaa 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
@@ -2204,6 +2204,20 @@ NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST OFF,ON
READ_ONLY NO
COMMAND_LINE_ARGUMENT OPTIONAL
+VARIABLE_NAME INNODB_STATS_INCLUDE_DELETE_MARKED
+SESSION_VALUE NULL
+GLOBAL_VALUE OFF
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE OFF
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE BOOLEAN
+VARIABLE_COMMENT Scan delete marked records for persistent stat
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
+ENUM_VALUE_LIST OFF,ON
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME INNODB_STATS_METHOD
SESSION_VALUE NULL
GLOBAL_VALUE nulls_equal
@@ -2626,7 +2640,11 @@ READ_ONLY NO
COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME INNODB_VERSION
SESSION_VALUE NULL
+<<<<<<< HEAD
GLOBAL_VALUE 5.7.14
+=======
+GLOBAL_VALUE 5.6.35
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE NULL
VARIABLE_SCOPE GLOBAL
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff
index 0f34179a16d..08408b83e74 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff
@@ -1,5 +1,10 @@
+<<<<<<< HEAD
--- suite/sys_vars/r/sysvars_server_embedded.result
+++ suite/sys_vars/r/sysvars_server_embedded.reject
+=======
+--- sysvars_server_embedded.result
++++ sysvars_server_embedded,32bit.result~
+>>>>>>> origin/10.1
@@ -57,7 +57,7 @@
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE 1
@@ -485,7 +490,11 @@
VARIABLE_COMMENT Maximum stored procedure recursion depth
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 255
+<<<<<<< HEAD
@@ -2073,7 +2073,7 @@
+=======
+@@ -2059,7 +2059,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 32
VARIABLE_SCOPE SESSION
@@ -494,7 +503,11 @@
VARIABLE_COMMENT Unused, will be removed.
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -2101,7 +2101,7 @@
+=======
+@@ -2087,7 +2087,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 4294967295
VARIABLE_SCOPE GLOBAL
@@ -503,7 +516,11 @@
VARIABLE_COMMENT After this many write locks, allow some read locks to run in between
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -2115,7 +2115,7 @@
+=======
+@@ -2101,7 +2101,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1024
VARIABLE_SCOPE GLOBAL
@@ -512,7 +529,11 @@
VARIABLE_COMMENT Unused
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2129,7 +2129,7 @@
+=======
+@@ -2115,7 +2115,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 8
VARIABLE_SCOPE GLOBAL
@@ -521,7 +542,11 @@
VARIABLE_COMMENT Unused
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 1024
+<<<<<<< HEAD
@@ -2143,7 +2143,7 @@
+=======
+@@ -2129,7 +2129,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 0
VARIABLE_SCOPE SESSION
@@ -530,7 +555,11 @@
VARIABLE_COMMENT Don't write queries to slow log that examine fewer rows than that
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -2157,7 +2157,7 @@
+=======
+@@ -2143,7 +2143,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 262144
VARIABLE_SCOPE SESSION
@@ -539,7 +568,11 @@
VARIABLE_COMMENT Size of buffer to use when using MRR with range access
NUMERIC_MIN_VALUE 8192
NUMERIC_MAX_VALUE 2147483647
+<<<<<<< HEAD
@@ -2171,10 +2171,10 @@
+=======
+@@ -2157,10 +2157,10 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 256
VARIABLE_SCOPE SESSION
@@ -552,7 +585,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -2185,7 +2185,7 @@
+=======
+@@ -2171,7 +2171,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1024
VARIABLE_SCOPE GLOBAL
@@ -561,7 +598,11 @@
VARIABLE_COMMENT Block size to be used for MyISAM index pages
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 16384
+<<<<<<< HEAD
@@ -2199,7 +2199,7 @@
+=======
+@@ -2185,7 +2185,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 6
VARIABLE_SCOPE GLOBAL
@@ -570,7 +611,11 @@
VARIABLE_COMMENT Default pointer size to be used for MyISAM tables
NUMERIC_MIN_VALUE 2
NUMERIC_MAX_VALUE 7
+<<<<<<< HEAD
@@ -2209,9 +2209,9 @@
+=======
+@@ -2195,9 +2195,9 @@
+>>>>>>> origin/10.1
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME MYISAM_MAX_SORT_FILE_SIZE
SESSION_VALUE NULL
@@ -582,7 +627,11 @@
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Don't use the fast sort index method to created index if the temporary file would get bigger than this
+<<<<<<< HEAD
@@ -2223,14 +2223,14 @@
+=======
+@@ -2209,14 +2209,14 @@
+>>>>>>> origin/10.1
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME MYISAM_MMAP_SIZE
SESSION_VALUE NULL
@@ -600,7 +649,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY YES
+<<<<<<< HEAD
@@ -2255,10 +2255,10 @@
+=======
+@@ -2241,10 +2241,10 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1
VARIABLE_SCOPE SESSION
@@ -613,7 +666,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -2272,7 +2272,7 @@
+=======
+@@ -2258,7 +2258,7 @@
+>>>>>>> origin/10.1
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE
NUMERIC_MIN_VALUE 4096
@@ -622,7 +679,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -2325,7 +2325,7 @@
+=======
+@@ -2311,7 +2311,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 16384
VARIABLE_SCOPE SESSION
@@ -631,7 +692,11 @@
VARIABLE_COMMENT Buffer length for TCP/IP and socket communication
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2339,7 +2339,7 @@
+=======
+@@ -2325,7 +2325,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 30
VARIABLE_SCOPE SESSION
@@ -640,7 +705,11 @@
VARIABLE_COMMENT Number of seconds to wait for more data from a connection before aborting the read
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 31536000
+<<<<<<< HEAD
@@ -2353,7 +2353,7 @@
+=======
+@@ -2339,7 +2339,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 10
VARIABLE_SCOPE SESSION
@@ -649,7 +718,11 @@
VARIABLE_COMMENT If a read on a communication port is interrupted, retry this many times before giving up
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -2367,7 +2367,7 @@
+=======
+@@ -2353,7 +2353,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 60
VARIABLE_SCOPE SESSION
@@ -658,7 +731,11 @@
VARIABLE_COMMENT Number of seconds to wait for a block to be written to a connection before aborting the write
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 31536000
+<<<<<<< HEAD
@@ -2437,7 +2437,7 @@
+=======
+@@ -2423,7 +2423,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1
VARIABLE_SCOPE SESSION
@@ -667,7 +744,11 @@
VARIABLE_COMMENT Controls the heuristic(s) applied during query optimization to prune less-promising partial plans from the optimizer search space. Meaning: 0 - do not apply any heuristic, thus perform exhaustive search; 1 - prune plans based on number of retrieved rows
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 1
+<<<<<<< HEAD
@@ -2451,7 +2451,7 @@
+=======
+@@ -2437,7 +2437,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 62
VARIABLE_SCOPE SESSION
@@ -675,8 +756,13 @@
+VARIABLE_TYPE INT UNSIGNED
VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value
NUMERIC_MIN_VALUE 0
+<<<<<<< HEAD
NUMERIC_MAX_VALUE 62
@@ -2465,7 +2465,7 @@
+=======
+ NUMERIC_MAX_VALUE 63
+@@ -2451,7 +2451,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 100
VARIABLE_SCOPE SESSION
@@ -685,7 +771,11 @@
VARIABLE_COMMENT Controls number of record samples to check condition selectivity
NUMERIC_MIN_VALUE 10
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -2493,7 +2493,7 @@
+=======
+@@ -2479,7 +2479,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1
VARIABLE_SCOPE SESSION
@@ -694,7 +784,11 @@
VARIABLE_COMMENT Controls selectivity of which conditions the optimizer takes into account to calculate cardinality of a partial join when it searches for the best execution plan Meaning: 1 - use selectivity of index backed range conditions to calculate the cardinality of a partial join if the last joined table is accessed by full table scan or an index scan, 2 - use selectivity of index backed range conditions to calculate the cardinality of a partial join in any case, 3 - additionally always use selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join, 4 - use histograms to calculate selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join.5 - additionally use selectivity of certain non-range predicates calculated on record samples
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 5
+<<<<<<< HEAD
@@ -2521,7 +2521,7 @@
+=======
+@@ -2507,7 +2507,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -703,7 +797,11 @@
VARIABLE_COMMENT Maximum number of instrumented user@host accounts. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2535,7 +2535,7 @@
+=======
+@@ -2521,7 +2521,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -712,7 +810,11 @@
VARIABLE_COMMENT Size of the statement digest. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 200
+<<<<<<< HEAD
@@ -2549,7 +2549,7 @@
+=======
+@@ -2535,7 +2535,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -721,7 +823,11 @@
VARIABLE_COMMENT Number of rows in EVENTS_STAGES_HISTORY_LONG. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2563,7 +2563,7 @@
+=======
+@@ -2549,7 +2549,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -730,7 +836,11 @@
VARIABLE_COMMENT Number of rows per thread in EVENTS_STAGES_HISTORY. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1024
+<<<<<<< HEAD
@@ -2577,7 +2577,7 @@
+=======
+@@ -2563,7 +2563,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -739,7 +849,11 @@
VARIABLE_COMMENT Number of rows in EVENTS_STATEMENTS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2591,7 +2591,7 @@
+=======
+@@ -2577,7 +2577,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -748,7 +862,11 @@
VARIABLE_COMMENT Number of rows per thread in EVENTS_STATEMENTS_HISTORY. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1024
+<<<<<<< HEAD
@@ -2605,7 +2605,7 @@
+=======
+@@ -2591,7 +2591,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -757,7 +875,11 @@
VARIABLE_COMMENT Number of rows in EVENTS_WAITS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2619,7 +2619,7 @@
+=======
+@@ -2605,7 +2605,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -766,7 +888,11 @@
VARIABLE_COMMENT Number of rows per thread in EVENTS_WAITS_HISTORY. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1024
+<<<<<<< HEAD
@@ -2633,7 +2633,7 @@
+=======
+@@ -2619,7 +2619,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -775,7 +901,11 @@
VARIABLE_COMMENT Maximum number of instrumented hosts. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2647,7 +2647,7 @@
+=======
+@@ -2633,7 +2633,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 80
VARIABLE_SCOPE GLOBAL
@@ -784,7 +914,11 @@
VARIABLE_COMMENT Maximum number of condition instruments.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 256
+<<<<<<< HEAD
@@ -2661,7 +2661,7 @@
+=======
+@@ -2647,7 +2647,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -793,7 +927,11 @@
VARIABLE_COMMENT Maximum number of instrumented condition objects. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2675,7 +2675,7 @@
+=======
+@@ -2661,7 +2661,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1024
VARIABLE_SCOPE GLOBAL
@@ -802,7 +940,11 @@
VARIABLE_COMMENT Maximum length considered for digest text, when stored in performance_schema tables.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2689,7 +2689,7 @@
+=======
+@@ -2675,7 +2675,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 50
VARIABLE_SCOPE GLOBAL
@@ -811,7 +953,11 @@
VARIABLE_COMMENT Maximum number of file instruments.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 256
+<<<<<<< HEAD
@@ -2703,7 +2703,7 @@
+=======
+@@ -2689,7 +2689,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 32768
VARIABLE_SCOPE GLOBAL
@@ -820,7 +966,11 @@
VARIABLE_COMMENT Maximum number of opened instrumented files.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2717,7 +2717,7 @@
+=======
+@@ -2703,7 +2703,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -829,7 +979,11 @@
VARIABLE_COMMENT Maximum number of instrumented files. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2731,7 +2731,7 @@
+=======
+@@ -2717,7 +2717,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 200
VARIABLE_SCOPE GLOBAL
@@ -838,7 +992,11 @@
VARIABLE_COMMENT Maximum number of mutex instruments.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 256
+<<<<<<< HEAD
@@ -2745,7 +2745,7 @@
+=======
+@@ -2731,7 +2731,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -847,7 +1005,11 @@
VARIABLE_COMMENT Maximum number of instrumented MUTEX objects. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 104857600
+<<<<<<< HEAD
@@ -2759,7 +2759,7 @@
+=======
+@@ -2745,7 +2745,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 40
VARIABLE_SCOPE GLOBAL
@@ -856,7 +1018,11 @@
VARIABLE_COMMENT Maximum number of rwlock instruments.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 256
+<<<<<<< HEAD
@@ -2773,7 +2773,7 @@
+=======
+@@ -2759,7 +2759,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -865,7 +1031,11 @@
VARIABLE_COMMENT Maximum number of instrumented RWLOCK objects. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 104857600
+<<<<<<< HEAD
@@ -2787,7 +2787,7 @@
+=======
+@@ -2773,7 +2773,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 10
VARIABLE_SCOPE GLOBAL
@@ -874,7 +1044,11 @@
VARIABLE_COMMENT Maximum number of socket instruments.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 256
+<<<<<<< HEAD
@@ -2801,7 +2801,7 @@
+=======
+@@ -2787,7 +2787,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -883,7 +1057,11 @@
VARIABLE_COMMENT Maximum number of opened instrumented sockets. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2815,7 +2815,7 @@
+=======
+@@ -2801,7 +2801,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 150
VARIABLE_SCOPE GLOBAL
@@ -892,7 +1070,11 @@
VARIABLE_COMMENT Maximum number of stage instruments.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 256
+<<<<<<< HEAD
@@ -2829,7 +2829,7 @@
+=======
+@@ -2815,7 +2815,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 185
VARIABLE_SCOPE GLOBAL
@@ -901,7 +1083,11 @@
VARIABLE_COMMENT Maximum number of statement instruments.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 256
+<<<<<<< HEAD
@@ -2843,7 +2843,7 @@
+=======
+@@ -2829,7 +2829,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -910,7 +1096,11 @@
VARIABLE_COMMENT Maximum number of opened instrumented tables. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2857,7 +2857,7 @@
+=======
+@@ -2843,7 +2843,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -919,7 +1109,11 @@
VARIABLE_COMMENT Maximum number of instrumented tables. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2871,7 +2871,7 @@
+=======
+@@ -2857,7 +2857,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 50
VARIABLE_SCOPE GLOBAL
@@ -928,7 +1122,11 @@
VARIABLE_COMMENT Maximum number of thread instruments.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 256
+<<<<<<< HEAD
@@ -2885,7 +2885,7 @@
+=======
+@@ -2871,7 +2871,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -937,7 +1135,11 @@
VARIABLE_COMMENT Maximum number of instrumented threads. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2899,7 +2899,7 @@
+=======
+@@ -2885,7 +2885,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -946,7 +1148,11 @@
VARIABLE_COMMENT Size of session attribute string buffer per thread. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2913,7 +2913,7 @@
+=======
+@@ -2899,7 +2899,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 100
VARIABLE_SCOPE GLOBAL
@@ -955,7 +1161,11 @@
VARIABLE_COMMENT Maximum number of rows in SETUP_ACTORS.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 1024
+<<<<<<< HEAD
@@ -2927,7 +2927,7 @@
+=======
+@@ -2913,7 +2913,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 100
VARIABLE_SCOPE GLOBAL
@@ -964,7 +1174,11 @@
VARIABLE_COMMENT Maximum number of rows in SETUP_OBJECTS.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2941,7 +2941,7 @@
+=======
+@@ -2927,7 +2927,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -973,7 +1187,11 @@
VARIABLE_COMMENT Maximum number of instrumented users. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -3011,7 +3011,7 @@
+=======
+@@ -2997,7 +2997,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 32768
VARIABLE_SCOPE SESSION
@@ -982,7 +1200,11 @@
VARIABLE_COMMENT The size of the buffer that is allocated when preloading indexes
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 1073741824
+<<<<<<< HEAD
@@ -3039,7 +3039,7 @@
+=======
+@@ -3025,7 +3025,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 15
VARIABLE_SCOPE SESSION
@@ -991,7 +1213,11 @@
VARIABLE_COMMENT Limit of query profiling memory
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 100
+<<<<<<< HEAD
@@ -3053,7 +3053,7 @@
+=======
+@@ -3039,7 +3039,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 5
VARIABLE_SCOPE SESSION
@@ -1000,7 +1226,24 @@
VARIABLE_COMMENT Seconds between sending progress reports to the client for time-consuming statements. Set to 0 to disable progress reporting.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -3123,7 +3123,7 @@
+=======
+@@ -3095,10 +3095,10 @@
+ GLOBAL_VALUE_ORIGIN COMPILE-TIME
+ DEFAULT_VALUE 0
+ VARIABLE_SCOPE SESSION ONLY
+-VARIABLE_TYPE BIGINT UNSIGNED
++VARIABLE_TYPE INT UNSIGNED
+ VARIABLE_COMMENT This variable is for internal server use
+ NUMERIC_MIN_VALUE 0
+-NUMERIC_MAX_VALUE 18446744073709551615
++NUMERIC_MAX_VALUE 4294967295
+ NUMERIC_BLOCK_SIZE 1
+ ENUM_VALUE_LIST NULL
+ READ_ONLY NO
+@@ -3109,7 +3109,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 16384
VARIABLE_SCOPE SESSION
@@ -1009,7 +1252,11 @@
VARIABLE_COMMENT Allocation block size for query parsing and execution
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -3137,7 +3137,7 @@
+=======
+@@ -3123,7 +3123,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1048576
VARIABLE_SCOPE GLOBAL
@@ -1018,7 +1265,11 @@
VARIABLE_COMMENT Don't cache results that are bigger than this
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -3151,7 +3151,7 @@
+=======
+@@ -3137,7 +3137,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 4096
VARIABLE_SCOPE GLOBAL
@@ -1027,7 +1278,11 @@
VARIABLE_COMMENT The minimum size for blocks allocated by the query cache
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -3168,7 +3168,7 @@
+=======
+@@ -3154,7 +3154,7 @@
+>>>>>>> origin/10.1
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT The memory allocated to store results from old queries
NUMERIC_MIN_VALUE 0
@@ -1036,7 +1291,11 @@
NUMERIC_BLOCK_SIZE 1024
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -3221,7 +3221,7 @@
+=======
+@@ -3207,7 +3207,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 24576
VARIABLE_SCOPE SESSION
@@ -1045,7 +1304,11 @@
VARIABLE_COMMENT Persistent buffer for query parsing and execution
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -3235,7 +3235,7 @@
+=======
+@@ -3221,7 +3221,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 4096
VARIABLE_SCOPE SESSION
@@ -1054,7 +1317,11 @@
VARIABLE_COMMENT Allocation block size for storing ranges during optimization
NUMERIC_MIN_VALUE 4096
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -3249,7 +3249,7 @@
+=======
+@@ -3235,7 +3235,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 131072
VARIABLE_SCOPE SESSION
@@ -1063,7 +1330,11 @@
VARIABLE_COMMENT Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value
NUMERIC_MIN_VALUE 8192
NUMERIC_MAX_VALUE 2147483647
+<<<<<<< HEAD
@@ -3277,7 +3277,7 @@
+=======
+@@ -3263,7 +3263,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 262144
VARIABLE_SCOPE SESSION
@@ -1072,7 +1343,11 @@
VARIABLE_COMMENT When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 2147483647
+<<<<<<< HEAD
@@ -3291,10 +3291,10 @@
+=======
+@@ -3277,10 +3277,10 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 8388608
VARIABLE_SCOPE SESSION
@@ -1085,7 +1360,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -3333,7 +3333,7 @@
+=======
+@@ -3319,7 +3319,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE 1
VARIABLE_SCOPE SESSION
@@ -1094,7 +1373,11 @@
VARIABLE_COMMENT Uniquely identifies the server instance in the community of replication partners
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -3431,7 +3431,7 @@
+=======
+@@ -3417,7 +3417,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1073741824
VARIABLE_SCOPE GLOBAL
@@ -1103,7 +1386,11 @@
VARIABLE_COMMENT The maximum packet length to sent successfully from the master to slave.
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 1073741824
+<<<<<<< HEAD
@@ -3445,7 +3445,7 @@
+=======
+@@ -3431,7 +3431,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 2
VARIABLE_SCOPE GLOBAL
@@ -1112,7 +1399,11 @@
VARIABLE_COMMENT If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 31536000
+<<<<<<< HEAD
@@ -3504,7 +3504,7 @@
+=======
+@@ -3490,7 +3490,7 @@
+>>>>>>> origin/10.1
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Each thread that needs to do a sort allocates a buffer of this size
NUMERIC_MIN_VALUE 1024
@@ -1121,7 +1412,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -3795,7 +3795,7 @@
+=======
+@@ -3767,7 +3767,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 256
VARIABLE_SCOPE GLOBAL
@@ -1130,7 +1425,11 @@
VARIABLE_COMMENT The soft upper limit for number of cached stored routines for one connection.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 524288
+<<<<<<< HEAD
@@ -3865,7 +3865,7 @@
+=======
+@@ -3837,7 +3837,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 400
VARIABLE_SCOPE GLOBAL
@@ -1139,7 +1438,11 @@
VARIABLE_COMMENT The number of cached table definitions
NUMERIC_MIN_VALUE 400
NUMERIC_MAX_VALUE 524288
+<<<<<<< HEAD
@@ -3879,7 +3879,7 @@
+=======
+@@ -3851,7 +3851,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 2000
VARIABLE_SCOPE GLOBAL
@@ -1148,16 +1451,26 @@
VARIABLE_COMMENT The number of cached open tables
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -3893,7 +3893,7 @@
GLOBAL_VALUE_ORIGIN AUTO
DEFAULT_VALUE 256
+=======
+@@ -3865,7 +3865,7 @@
+ GLOBAL_VALUE_ORIGIN COMPILE-TIME
+ DEFAULT_VALUE 0
+>>>>>>> origin/10.1
VARIABLE_SCOPE GLOBAL
-VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_TYPE INT UNSIGNED
VARIABLE_COMMENT How many threads we should keep in a cache for reuse. These are freed after 5 minutes of idle time
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 16384
+<<<<<<< HEAD
@@ -3907,7 +3907,7 @@
+=======
+@@ -3879,7 +3879,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 10
VARIABLE_SCOPE GLOBAL
@@ -1166,7 +1479,11 @@
VARIABLE_COMMENT Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.This variable has no effect, and is deprecated. It will be removed in a future release.
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 512
+<<<<<<< HEAD
@@ -4022,7 +4022,7 @@
+=======
+@@ -3994,7 +3994,7 @@
+>>>>>>> origin/10.1
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MySQL will automatically convert it to an on-disk MyISAM or Aria table
NUMERIC_MIN_VALUE 1024
@@ -1175,7 +1492,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -4033,7 +4033,7 @@
+=======
+@@ -4005,7 +4005,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 8192
VARIABLE_SCOPE SESSION
@@ -1184,7 +1505,11 @@
VARIABLE_COMMENT Allocation block size for transactions to be stored in binary log
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 134217728
+<<<<<<< HEAD
@@ -4047,7 +4047,7 @@
+=======
+@@ -4019,7 +4019,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 4096
VARIABLE_SCOPE SESSION
@@ -1193,7 +1518,11 @@
VARIABLE_COMMENT Persistent buffer for transactions to be stored in binary log
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 134217728
+<<<<<<< HEAD
@@ -4145,7 +4145,7 @@
+=======
+@@ -4117,7 +4117,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 28800
VARIABLE_SCOPE SESSION
@@ -1202,7 +1531,11 @@
VARIABLE_COMMENT The number of seconds the server waits for activity on a connection before closing it
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 31536000
+<<<<<<< HEAD
@@ -4249,7 +4249,7 @@
+=======
+@@ -4221,7 +4221,7 @@
+>>>>>>> origin/10.1
COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME OPEN_FILES_LIMIT
VARIABLE_SCOPE GLOBAL
@@ -1211,7 +1544,11 @@
VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -4262,7 +4262,7 @@
+=======
+@@ -4234,7 +4234,7 @@
+>>>>>>> origin/10.1
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes
NUMERIC_MIN_VALUE 0
@@ -1220,7 +1557,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -4272,7 +4272,7 @@
+=======
+@@ -4244,7 +4244,7 @@
+>>>>>>> origin/10.1
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes
NUMERIC_MIN_VALUE 0
@@ -1229,7 +1570,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -4357,7 +4357,7 @@
+=======
+@@ -4329,7 +4329,7 @@
+>>>>>>> origin/10.1
VARIABLE_NAME LOG_TC_SIZE
GLOBAL_VALUE_ORIGIN AUTO
VARIABLE_SCOPE GLOBAL
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
index f37ca909836..968312124dc 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
@@ -2053,6 +2053,20 @@ NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME MAX_SESSION_MEM_USED
+SESSION_VALUE 9223372036854775807
+GLOBAL_VALUE 9223372036854775807
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE 9223372036854775807
+VARIABLE_SCOPE SESSION
+VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_COMMENT Amount of memory a single user session is allowed to allocate. This limits the value of the session variable MEM_USED
+NUMERIC_MIN_VALUE 8192
+NUMERIC_MAX_VALUE 18446744073709551615
+NUMERIC_BLOCK_SIZE 1
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME MAX_SORT_LENGTH
SESSION_VALUE 1024
GLOBAL_VALUE 1024
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff
index 88216992587..d21a195a07d 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff
@@ -1,5 +1,10 @@
+<<<<<<< HEAD
--- suite/sys_vars/r/sysvars_server_notembedded.result 2016-11-03 17:27:47.664855681 +0100
+++ suite/sys_vars/r/sysvars_server_notembedded.reject 2016-11-03 17:23:05.686196749 +0100
+=======
+--- sysvars_server_notembedded.result
++++ sysvars_server_notembedded,32bit.result~
+>>>>>>> origin/10.1
@@ -57,7 +57,7 @@
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE 1
@@ -485,7 +490,11 @@
VARIABLE_COMMENT Maximum stored procedure recursion depth
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 255
+<<<<<<< HEAD
@@ -2297,7 +2297,7 @@
+=======
+@@ -2255,7 +2255,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 32
VARIABLE_SCOPE SESSION
@@ -494,7 +503,11 @@
VARIABLE_COMMENT Unused, will be removed.
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -2325,7 +2325,7 @@
+=======
+@@ -2283,7 +2283,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 4294967295
VARIABLE_SCOPE GLOBAL
@@ -503,7 +516,11 @@
VARIABLE_COMMENT After this many write locks, allow some read locks to run in between
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -2339,7 +2339,7 @@
+=======
+@@ -2297,7 +2297,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1024
VARIABLE_SCOPE GLOBAL
@@ -512,7 +529,11 @@
VARIABLE_COMMENT Unused
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2353,7 +2353,7 @@
+=======
+@@ -2311,7 +2311,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 8
VARIABLE_SCOPE GLOBAL
@@ -521,7 +542,11 @@
VARIABLE_COMMENT Unused
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 1024
+<<<<<<< HEAD
@@ -2367,7 +2367,7 @@
+=======
+@@ -2325,7 +2325,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 0
VARIABLE_SCOPE SESSION
@@ -530,7 +555,11 @@
VARIABLE_COMMENT Don't write queries to slow log that examine fewer rows than that
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -2381,7 +2381,7 @@
+=======
+@@ -2339,7 +2339,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 262144
VARIABLE_SCOPE SESSION
@@ -539,7 +568,11 @@
VARIABLE_COMMENT Size of buffer to use when using MRR with range access
NUMERIC_MIN_VALUE 8192
NUMERIC_MAX_VALUE 2147483647
+<<<<<<< HEAD
@@ -2395,10 +2395,10 @@
+=======
+@@ -2353,10 +2353,10 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 256
VARIABLE_SCOPE SESSION
@@ -552,7 +585,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -2409,7 +2409,7 @@
+=======
+@@ -2367,7 +2367,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1024
VARIABLE_SCOPE GLOBAL
@@ -561,7 +598,11 @@
VARIABLE_COMMENT Block size to be used for MyISAM index pages
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 16384
+<<<<<<< HEAD
@@ -2423,7 +2423,7 @@
+=======
+@@ -2381,7 +2381,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 6
VARIABLE_SCOPE GLOBAL
@@ -570,7 +611,11 @@
VARIABLE_COMMENT Default pointer size to be used for MyISAM tables
NUMERIC_MIN_VALUE 2
NUMERIC_MAX_VALUE 7
+<<<<<<< HEAD
@@ -2433,9 +2433,9 @@
+=======
+@@ -2391,9 +2391,9 @@
+>>>>>>> origin/10.1
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME MYISAM_MAX_SORT_FILE_SIZE
SESSION_VALUE NULL
@@ -582,7 +627,11 @@
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Don't use the fast sort index method to created index if the temporary file would get bigger than this
+<<<<<<< HEAD
@@ -2447,14 +2447,14 @@
+=======
+@@ -2405,14 +2405,14 @@
+>>>>>>> origin/10.1
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME MYISAM_MMAP_SIZE
SESSION_VALUE NULL
@@ -600,7 +649,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY YES
+<<<<<<< HEAD
@@ -2479,10 +2479,10 @@
+=======
+@@ -2437,10 +2437,10 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1
VARIABLE_SCOPE SESSION
@@ -613,7 +666,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -2496,7 +2496,7 @@
+=======
+@@ -2454,7 +2454,7 @@
+>>>>>>> origin/10.1
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE
NUMERIC_MIN_VALUE 4096
@@ -622,7 +679,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -2549,7 +2549,7 @@
+=======
+@@ -2507,7 +2507,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 16384
VARIABLE_SCOPE SESSION
@@ -631,7 +692,11 @@
VARIABLE_COMMENT Buffer length for TCP/IP and socket communication
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2563,7 +2563,7 @@
+=======
+@@ -2521,7 +2521,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 30
VARIABLE_SCOPE SESSION
@@ -640,7 +705,11 @@
VARIABLE_COMMENT Number of seconds to wait for more data from a connection before aborting the read
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 31536000
+<<<<<<< HEAD
@@ -2577,7 +2577,7 @@
+=======
+@@ -2535,7 +2535,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 10
VARIABLE_SCOPE SESSION
@@ -649,7 +718,11 @@
VARIABLE_COMMENT If a read on a communication port is interrupted, retry this many times before giving up
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -2591,7 +2591,7 @@
+=======
+@@ -2549,7 +2549,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 60
VARIABLE_SCOPE SESSION
@@ -658,7 +731,11 @@
VARIABLE_COMMENT Number of seconds to wait for a block to be written to a connection before aborting the write
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 31536000
+<<<<<<< HEAD
@@ -2661,7 +2661,7 @@
+=======
+@@ -2619,7 +2619,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1
VARIABLE_SCOPE SESSION
@@ -667,7 +744,11 @@
VARIABLE_COMMENT Controls the heuristic(s) applied during query optimization to prune less-promising partial plans from the optimizer search space. Meaning: 0 - do not apply any heuristic, thus perform exhaustive search; 1 - prune plans based on number of retrieved rows
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 1
+<<<<<<< HEAD
@@ -2675,7 +2675,7 @@
+=======
+@@ -2633,7 +2633,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 62
VARIABLE_SCOPE SESSION
@@ -675,8 +756,13 @@
+VARIABLE_TYPE INT UNSIGNED
VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value
NUMERIC_MIN_VALUE 0
+<<<<<<< HEAD
NUMERIC_MAX_VALUE 62
@@ -2689,7 +2689,7 @@
+=======
+ NUMERIC_MAX_VALUE 63
+@@ -2647,7 +2647,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 100
VARIABLE_SCOPE SESSION
@@ -685,7 +771,11 @@
VARIABLE_COMMENT Controls number of record samples to check condition selectivity
NUMERIC_MIN_VALUE 10
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -2717,7 +2717,7 @@
+=======
+@@ -2675,7 +2675,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1
VARIABLE_SCOPE SESSION
@@ -694,7 +784,11 @@
VARIABLE_COMMENT Controls selectivity of which conditions the optimizer takes into account to calculate cardinality of a partial join when it searches for the best execution plan Meaning: 1 - use selectivity of index backed range conditions to calculate the cardinality of a partial join if the last joined table is accessed by full table scan or an index scan, 2 - use selectivity of index backed range conditions to calculate the cardinality of a partial join in any case, 3 - additionally always use selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join, 4 - use histograms to calculate selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join.5 - additionally use selectivity of certain non-range predicates calculated on record samples
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 5
+<<<<<<< HEAD
@@ -2745,7 +2745,7 @@
+=======
+@@ -2703,7 +2703,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -703,7 +797,11 @@
VARIABLE_COMMENT Maximum number of instrumented user@host accounts. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2759,7 +2759,7 @@
+=======
+@@ -2717,7 +2717,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -712,7 +810,11 @@
VARIABLE_COMMENT Size of the statement digest. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 200
+<<<<<<< HEAD
@@ -2773,7 +2773,7 @@
+=======
+@@ -2731,7 +2731,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -721,7 +823,11 @@
VARIABLE_COMMENT Number of rows in EVENTS_STAGES_HISTORY_LONG. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2787,7 +2787,7 @@
+=======
+@@ -2745,7 +2745,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -730,7 +836,11 @@
VARIABLE_COMMENT Number of rows per thread in EVENTS_STAGES_HISTORY. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1024
+<<<<<<< HEAD
@@ -2801,7 +2801,7 @@
+=======
+@@ -2759,7 +2759,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -739,7 +849,11 @@
VARIABLE_COMMENT Number of rows in EVENTS_STATEMENTS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2815,7 +2815,7 @@
+=======
+@@ -2773,7 +2773,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -748,7 +862,11 @@
VARIABLE_COMMENT Number of rows per thread in EVENTS_STATEMENTS_HISTORY. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1024
+<<<<<<< HEAD
@@ -2829,7 +2829,7 @@
+=======
+@@ -2787,7 +2787,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -757,7 +875,11 @@
VARIABLE_COMMENT Number of rows in EVENTS_WAITS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2843,7 +2843,7 @@
+=======
+@@ -2801,7 +2801,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -766,7 +888,11 @@
VARIABLE_COMMENT Number of rows per thread in EVENTS_WAITS_HISTORY. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1024
+<<<<<<< HEAD
@@ -2857,7 +2857,7 @@
+=======
+@@ -2815,7 +2815,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -775,7 +901,11 @@
VARIABLE_COMMENT Maximum number of instrumented hosts. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2871,7 +2871,7 @@
+=======
+@@ -2829,7 +2829,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 80
VARIABLE_SCOPE GLOBAL
@@ -784,7 +914,11 @@
VARIABLE_COMMENT Maximum number of condition instruments.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 256
+<<<<<<< HEAD
@@ -2885,7 +2885,7 @@
+=======
+@@ -2843,7 +2843,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -793,7 +927,11 @@
VARIABLE_COMMENT Maximum number of instrumented condition objects. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2899,7 +2899,7 @@
+=======
+@@ -2857,7 +2857,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1024
VARIABLE_SCOPE GLOBAL
@@ -802,7 +940,11 @@
VARIABLE_COMMENT Maximum length considered for digest text, when stored in performance_schema tables.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2913,7 +2913,7 @@
+=======
+@@ -2871,7 +2871,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 50
VARIABLE_SCOPE GLOBAL
@@ -811,7 +953,11 @@
VARIABLE_COMMENT Maximum number of file instruments.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 256
+<<<<<<< HEAD
@@ -2927,7 +2927,7 @@
+=======
+@@ -2885,7 +2885,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 32768
VARIABLE_SCOPE GLOBAL
@@ -820,7 +966,11 @@
VARIABLE_COMMENT Maximum number of opened instrumented files.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2941,7 +2941,7 @@
+=======
+@@ -2899,7 +2899,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -829,7 +979,11 @@
VARIABLE_COMMENT Maximum number of instrumented files. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -2955,7 +2955,7 @@
+=======
+@@ -2913,7 +2913,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 200
VARIABLE_SCOPE GLOBAL
@@ -838,7 +992,11 @@
VARIABLE_COMMENT Maximum number of mutex instruments.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 256
+<<<<<<< HEAD
@@ -2969,7 +2969,7 @@
+=======
+@@ -2927,7 +2927,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -847,7 +1005,11 @@
VARIABLE_COMMENT Maximum number of instrumented MUTEX objects. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 104857600
+<<<<<<< HEAD
@@ -2983,7 +2983,7 @@
+=======
+@@ -2941,7 +2941,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 40
VARIABLE_SCOPE GLOBAL
@@ -856,7 +1018,11 @@
VARIABLE_COMMENT Maximum number of rwlock instruments.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 256
+<<<<<<< HEAD
@@ -2997,7 +2997,7 @@
+=======
+@@ -2955,7 +2955,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -865,7 +1031,11 @@
VARIABLE_COMMENT Maximum number of instrumented RWLOCK objects. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 104857600
+<<<<<<< HEAD
@@ -3011,7 +3011,7 @@
+=======
+@@ -2969,7 +2969,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 10
VARIABLE_SCOPE GLOBAL
@@ -874,7 +1044,11 @@
VARIABLE_COMMENT Maximum number of socket instruments.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 256
+<<<<<<< HEAD
@@ -3025,7 +3025,7 @@
+=======
+@@ -2983,7 +2983,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -883,7 +1057,11 @@
VARIABLE_COMMENT Maximum number of opened instrumented sockets. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -3039,7 +3039,7 @@
+=======
+@@ -2997,7 +2997,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 150
VARIABLE_SCOPE GLOBAL
@@ -892,7 +1070,11 @@
VARIABLE_COMMENT Maximum number of stage instruments.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 256
+<<<<<<< HEAD
@@ -3053,7 +3053,7 @@
+=======
+@@ -3011,7 +3011,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 185
VARIABLE_SCOPE GLOBAL
@@ -901,7 +1083,11 @@
VARIABLE_COMMENT Maximum number of statement instruments.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 256
+<<<<<<< HEAD
@@ -3067,7 +3067,7 @@
+=======
+@@ -3025,7 +3025,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -910,7 +1096,11 @@
VARIABLE_COMMENT Maximum number of opened instrumented tables. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -3081,7 +3081,7 @@
+=======
+@@ -3039,7 +3039,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -919,7 +1109,11 @@
VARIABLE_COMMENT Maximum number of instrumented tables. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -3095,7 +3095,7 @@
+=======
+@@ -3053,7 +3053,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 50
VARIABLE_SCOPE GLOBAL
@@ -928,7 +1122,11 @@
VARIABLE_COMMENT Maximum number of thread instruments.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 256
+<<<<<<< HEAD
@@ -3109,7 +3109,7 @@
+=======
+@@ -3067,7 +3067,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -937,7 +1135,11 @@
VARIABLE_COMMENT Maximum number of instrumented threads. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -3123,7 +3123,7 @@
+=======
+@@ -3081,7 +3081,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -946,7 +1148,11 @@
VARIABLE_COMMENT Size of session attribute string buffer per thread. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -3137,7 +3137,7 @@
+=======
+@@ -3095,7 +3095,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 100
VARIABLE_SCOPE GLOBAL
@@ -955,7 +1161,11 @@
VARIABLE_COMMENT Maximum number of rows in SETUP_ACTORS.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 1024
+<<<<<<< HEAD
@@ -3151,7 +3151,7 @@
+=======
+@@ -3109,7 +3109,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 100
VARIABLE_SCOPE GLOBAL
@@ -964,7 +1174,11 @@
VARIABLE_COMMENT Maximum number of rows in SETUP_OBJECTS.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -3165,7 +3165,7 @@
+=======
+@@ -3123,7 +3123,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE -1
VARIABLE_SCOPE GLOBAL
@@ -973,7 +1187,11 @@
VARIABLE_COMMENT Maximum number of instrumented users. Use 0 to disable, -1 for automated sizing.
NUMERIC_MIN_VALUE -1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -3235,7 +3235,7 @@
+=======
+@@ -3193,7 +3193,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 32768
VARIABLE_SCOPE SESSION
@@ -982,7 +1200,11 @@
VARIABLE_COMMENT The size of the buffer that is allocated when preloading indexes
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 1073741824
+<<<<<<< HEAD
@@ -3263,7 +3263,7 @@
+=======
+@@ -3221,7 +3221,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 15
VARIABLE_SCOPE SESSION
@@ -991,7 +1213,11 @@
VARIABLE_COMMENT Limit of query profiling memory
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 100
+<<<<<<< HEAD
@@ -3277,7 +3277,7 @@
+=======
+@@ -3235,7 +3235,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 5
VARIABLE_SCOPE SESSION
@@ -1000,7 +1226,24 @@
VARIABLE_COMMENT Seconds between sending progress reports to the client for time-consuming statements. Set to 0 to disable progress reporting.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -3347,7 +3347,7 @@
+=======
+@@ -3291,10 +3291,10 @@
+ GLOBAL_VALUE_ORIGIN COMPILE-TIME
+ DEFAULT_VALUE 0
+ VARIABLE_SCOPE SESSION ONLY
+-VARIABLE_TYPE BIGINT UNSIGNED
++VARIABLE_TYPE INT UNSIGNED
+ VARIABLE_COMMENT This variable is for internal server use
+ NUMERIC_MIN_VALUE 0
+-NUMERIC_MAX_VALUE 18446744073709551615
++NUMERIC_MAX_VALUE 4294967295
+ NUMERIC_BLOCK_SIZE 1
+ ENUM_VALUE_LIST NULL
+ READ_ONLY NO
+@@ -3305,7 +3305,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 16384
VARIABLE_SCOPE SESSION
@@ -1009,7 +1252,11 @@
VARIABLE_COMMENT Allocation block size for query parsing and execution
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -3361,7 +3361,7 @@
+=======
+@@ -3319,7 +3319,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1048576
VARIABLE_SCOPE GLOBAL
@@ -1018,7 +1265,11 @@
VARIABLE_COMMENT Don't cache results that are bigger than this
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -3375,7 +3375,7 @@
+=======
+@@ -3333,7 +3333,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 4096
VARIABLE_SCOPE GLOBAL
@@ -1027,7 +1278,11 @@
VARIABLE_COMMENT The minimum size for blocks allocated by the query cache
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -3392,7 +3392,7 @@
+=======
+@@ -3350,7 +3350,7 @@
+>>>>>>> origin/10.1
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT The memory allocated to store results from old queries
NUMERIC_MIN_VALUE 0
@@ -1036,7 +1291,11 @@
NUMERIC_BLOCK_SIZE 1024
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -3445,7 +3445,7 @@
+=======
+@@ -3403,7 +3403,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 24576
VARIABLE_SCOPE SESSION
@@ -1045,7 +1304,11 @@
VARIABLE_COMMENT Persistent buffer for query parsing and execution
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -3459,7 +3459,7 @@
+=======
+@@ -3417,7 +3417,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 4096
VARIABLE_SCOPE SESSION
@@ -1054,6 +1317,7 @@
VARIABLE_COMMENT Allocation block size for storing ranges during optimization
NUMERIC_MIN_VALUE 4096
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -3476,7 +3476,7 @@
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Maximum speed(KB/s) to read binlog from master (0 = no limit)
@@ -1064,6 +1328,9 @@
ENUM_VALUE_LIST NULL
READ_ONLY NO
@@ -3487,7 +3487,7 @@
+=======
+@@ -3431,7 +3431,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 131072
VARIABLE_SCOPE SESSION
@@ -1072,7 +1339,11 @@
VARIABLE_COMMENT Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value
NUMERIC_MIN_VALUE 8192
NUMERIC_MAX_VALUE 2147483647
+<<<<<<< HEAD
@@ -3515,7 +3515,7 @@
+=======
+@@ -3459,7 +3459,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 262144
VARIABLE_SCOPE SESSION
@@ -1081,7 +1352,11 @@
VARIABLE_COMMENT When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 2147483647
+<<<<<<< HEAD
@@ -3795,10 +3795,10 @@
+=======
+@@ -3739,10 +3739,10 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 8388608
VARIABLE_SCOPE SESSION
@@ -1094,7 +1369,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -3837,7 +3837,7 @@
+=======
+@@ -3781,7 +3781,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE 1
VARIABLE_SCOPE SESSION
@@ -1103,7 +1382,11 @@
VARIABLE_COMMENT Uniquely identifies the server instance in the community of replication partners
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -4019,7 +4019,7 @@
+=======
+@@ -3907,7 +3907,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 0
VARIABLE_SCOPE GLOBAL
@@ -1112,7 +1395,11 @@
VARIABLE_COMMENT Maximum number of parallel threads to use on slave for events in a single replication domain. When using multiple domains, this can be used to limit a single domain from grabbing all threads and thus stalling other domains. The default of 0 means to allow a domain to grab as many threads as it wants, up to the value of slave_parallel_threads.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 16383
+<<<<<<< HEAD
@@ -4061,7 +4061,7 @@
+=======
+@@ -3949,7 +3949,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1073741824
VARIABLE_SCOPE GLOBAL
@@ -1121,7 +1408,11 @@
VARIABLE_COMMENT The maximum packet length to sent successfully from the master to slave.
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 1073741824
+<<<<<<< HEAD
@@ -4089,7 +4089,7 @@
+=======
+@@ -3977,7 +3977,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 131072
VARIABLE_SCOPE GLOBAL
@@ -1130,7 +1421,11 @@
VARIABLE_COMMENT Limit on how much memory SQL threads should use per parallel replication thread when reading ahead in the relay log looking for opportunities for parallel replication. Only used when --slave-parallel-threads > 0.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 2147483647
+<<<<<<< HEAD
@@ -4117,7 +4117,7 @@
+=======
+@@ -4005,7 +4005,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 0
VARIABLE_SCOPE GLOBAL
@@ -1139,6 +1434,7 @@
VARIABLE_COMMENT If non-zero, number of threads to spawn to apply in parallel events on the slave that were group-committed on the master or were logged with GTID in different replication domains. Note that these threads are in addition to the IO and SQL threads, which are always created by a replication slave
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 16383
+<<<<<<< HEAD
@@ -4131,7 +4131,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 0
@@ -1149,6 +1445,9 @@
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 16383
@@ -4187,7 +4187,7 @@
+=======
+@@ -4061,7 +4061,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 10
VARIABLE_SCOPE GLOBAL
@@ -1157,7 +1456,11 @@
VARIABLE_COMMENT Number of times the slave SQL thread will retry a transaction in case it failed with a deadlock or elapsed lock wait timeout, before giving up and stopping
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -4215,7 +4215,7 @@
+=======
+@@ -4089,7 +4089,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 2
VARIABLE_SCOPE GLOBAL
@@ -1166,7 +1469,11 @@
VARIABLE_COMMENT If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 31536000
+<<<<<<< HEAD
@@ -4274,7 +4274,7 @@
+=======
+@@ -4148,7 +4148,7 @@
+>>>>>>> origin/10.1
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Each thread that needs to do a sort allocates a buffer of this size
NUMERIC_MIN_VALUE 1024
@@ -1175,7 +1482,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -4579,7 +4579,7 @@
+=======
+@@ -4439,7 +4439,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 256
VARIABLE_SCOPE GLOBAL
@@ -1184,7 +1495,11 @@
VARIABLE_COMMENT The soft upper limit for number of cached stored routines for one connection.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 524288
+<<<<<<< HEAD
@@ -4677,7 +4677,7 @@
+=======
+@@ -4537,7 +4537,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN AUTO
DEFAULT_VALUE 400
VARIABLE_SCOPE GLOBAL
@@ -1193,7 +1508,11 @@
VARIABLE_COMMENT The number of cached table definitions
NUMERIC_MIN_VALUE 400
NUMERIC_MAX_VALUE 524288
+<<<<<<< HEAD
@@ -4691,7 +4691,7 @@
+=======
+@@ -4551,7 +4551,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 2000
VARIABLE_SCOPE GLOBAL
@@ -1202,16 +1521,26 @@
VARIABLE_COMMENT The number of cached open tables
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 1048576
+<<<<<<< HEAD
@@ -4719,7 +4719,7 @@
GLOBAL_VALUE_ORIGIN AUTO
DEFAULT_VALUE 256
+=======
+@@ -4565,7 +4565,7 @@
+ GLOBAL_VALUE_ORIGIN COMPILE-TIME
+ DEFAULT_VALUE 0
+>>>>>>> origin/10.1
VARIABLE_SCOPE GLOBAL
-VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_TYPE INT UNSIGNED
VARIABLE_COMMENT How many threads we should keep in a cache for reuse. These are freed after 5 minutes of idle time
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 16384
+<<<<<<< HEAD
@@ -4733,7 +4733,7 @@
+=======
+@@ -4579,7 +4579,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 10
VARIABLE_SCOPE GLOBAL
@@ -1220,7 +1549,11 @@
VARIABLE_COMMENT Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.This variable has no effect, and is deprecated. It will be removed in a future release.
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 512
+<<<<<<< HEAD
@@ -4946,7 +4946,7 @@
+=======
+@@ -4764,7 +4764,7 @@
+>>>>>>> origin/10.1
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MySQL will automatically convert it to an on-disk MyISAM or Aria table
NUMERIC_MIN_VALUE 1024
@@ -1229,7 +1562,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -4957,7 +4957,7 @@
+=======
+@@ -4775,7 +4775,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 8192
VARIABLE_SCOPE SESSION
@@ -1238,7 +1575,11 @@
VARIABLE_COMMENT Allocation block size for transactions to be stored in binary log
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 134217728
+<<<<<<< HEAD
@@ -4971,7 +4971,7 @@
+=======
+@@ -4789,7 +4789,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 4096
VARIABLE_SCOPE SESSION
@@ -1247,7 +1588,11 @@
VARIABLE_COMMENT Persistent buffer for transactions to be stored in binary log
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 134217728
+<<<<<<< HEAD
@@ -5069,7 +5069,7 @@
+=======
+@@ -4887,7 +4887,7 @@
+>>>>>>> origin/10.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 28800
VARIABLE_SCOPE SESSION
@@ -1256,7 +1601,11 @@
VARIABLE_COMMENT The number of seconds the server waits for activity on a connection before closing it
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 31536000
+<<<<<<< HEAD
@@ -5173,7 +5173,7 @@
+=======
+@@ -4991,7 +4991,7 @@
+>>>>>>> origin/10.1
COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME OPEN_FILES_LIMIT
VARIABLE_SCOPE GLOBAL
@@ -1265,7 +1614,11 @@
VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
+<<<<<<< HEAD
@@ -5186,7 +5186,7 @@
+=======
+@@ -5004,7 +5004,7 @@
+>>>>>>> origin/10.1
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes
NUMERIC_MIN_VALUE 0
@@ -1274,7 +1627,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -5196,7 +5196,7 @@
+=======
+@@ -5014,7 +5014,7 @@
+>>>>>>> origin/10.1
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes
NUMERIC_MIN_VALUE 0
@@ -1283,7 +1640,11 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
+<<<<<<< HEAD
@@ -5281,7 +5281,7 @@
+=======
+@@ -5099,7 +5099,7 @@
+>>>>>>> origin/10.1
VARIABLE_NAME LOG_TC_SIZE
GLOBAL_VALUE_ORIGIN AUTO
VARIABLE_SCOPE GLOBAL
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
index 15373702057..9f006cbdb9b 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
@@ -2249,6 +2249,20 @@ NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME MAX_SESSION_MEM_USED
+SESSION_VALUE 9223372036854775807
+GLOBAL_VALUE 9223372036854775807
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE 9223372036854775807
+VARIABLE_SCOPE SESSION
+VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_COMMENT Amount of memory a single user session is allowed to allocate. This limits the value of the session variable MEM_USED
+NUMERIC_MIN_VALUE 8192
+NUMERIC_MAX_VALUE 18446744073709551615
+NUMERIC_BLOCK_SIZE 1
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME MAX_SORT_LENGTH
SESSION_VALUE 1024
GLOBAL_VALUE 1024
diff --git a/mysql-test/suite/sys_vars/t/sysvars_innodb.test b/mysql-test/suite/sys_vars/t/sysvars_innodb.test
index 38f248cb611..2abafda34c6 100644
--- a/mysql-test/suite/sys_vars/t/sysvars_innodb.test
+++ b/mysql-test/suite/sys_vars/t/sysvars_innodb.test
@@ -3,6 +3,11 @@
--source include/not_valgrind.inc
--source include/word_size.inc
+if (`select plugin_auth_version <= "5.6.34-79.1" from information_schema.plugins where plugin_name='innodb'`)
+{
+ --skip Not fixed in XtraDB as of 10.1.21-MariaDB or earlier
+}
+
--vertical_results
--replace_regex /^\/\S+/PATH/ /\.\//PATH/
select * from information_schema.system_variables
diff --git a/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc b/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc
index f807405d18d..80ce44a6024 100644
--- a/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc
+++ b/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc
@@ -110,7 +110,7 @@ drop table t1,t2;
drop procedure p1;
--echo #
---echo # Bug mdev-3845: values of virtual columns are not computed for triggers
+--echo # MDEV-3845 values of virtual columns are not computed for triggers
--echo #
CREATE TABLE t1 (
@@ -149,6 +149,7 @@ DROP TRIGGER t1_ins_aft;
DROP TRIGGER t1_del_bef;
DROP TABLE t1,t2;
+<<<<<<< HEAD
--echo #
--echo # Examine the number of times triggers are recalculated for updates
--echo #
@@ -280,4 +281,12 @@ select * from t1;
drop trigger t1_ins;
drop trigger t1_update;
+=======
+#
+# MDEV-11706 Assertion `is_stat_field || !table || (!table->write_set || bitmap_is_set(table->write_set, field_index) || (table->vcol_set && bitmap_is_set(table->vcol_set, field_index)))' failed in Field_time::store_TIME_with_warning
+#
+create table t1 (i int, t time not null, vt time(4) as (t) virtual);
+create trigger trg before update on t1 for each row set @a = 1;
+insert ignore into t1 (i) values (1);
+>>>>>>> origin/10.1
drop table t1;
diff --git a/mysql-test/suite/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result
index a917159249b..8a0cb3162f7 100644
--- a/mysql-test/suite/vcol/r/vcol_misc.result
+++ b/mysql-test/suite/vcol/r/vcol_misc.result
@@ -328,6 +328,13 @@ t1 CREATE TABLE `t1` (
`c1` varchar(50) COLLATE latin1_general_ci DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci
drop table t1;
+set sql_mode='no_zero_date';
+create table t1 (
+ts timestamp not null default current_timestamp,
+tsv timestamp as (adddate(ts, interval 1 day)) virtual
+);
+drop table t1;
+set sql_mode=default;
#
# Start of 10.1 tests
#
diff --git a/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result b/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result
index 0a82f1006e7..8d0521ebc34 100644
--- a/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result
+++ b/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result
@@ -86,7 +86,7 @@ a b c
drop table t1,t2;
drop procedure p1;
#
-# Bug mdev-3845: values of virtual columns are not computed for triggers
+# MDEV-3845 values of virtual columns are not computed for triggers
#
CREATE TABLE t1 (
a INTEGER UNSIGNED NULL DEFAULT NULL,
@@ -125,6 +125,7 @@ c
DROP TRIGGER t1_ins_aft;
DROP TRIGGER t1_del_bef;
DROP TABLE t1,t2;
+<<<<<<< HEAD
#
# Examine the number of times triggers are recalculated for updates
#
@@ -303,4 +304,11 @@ a b c blob_a blob_b blob_c
104 generated generated before update 104 generated generated before update
drop trigger t1_ins;
drop trigger t1_update;
+=======
+create table t1 (i int, t time not null, vt time(4) as (t) virtual);
+create trigger trg before update on t1 for each row set @a = 1;
+insert ignore into t1 (i) values (1);
+Warnings:
+Warning 1364 Field 't' doesn't have a default value
+>>>>>>> origin/10.1
drop table t1;
diff --git a/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result b/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result
index edafd474286..adcecbf3976 100644
--- a/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result
+++ b/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result
@@ -86,7 +86,7 @@ a b c
drop table t1,t2;
drop procedure p1;
#
-# Bug mdev-3845: values of virtual columns are not computed for triggers
+# MDEV-3845 values of virtual columns are not computed for triggers
#
CREATE TABLE t1 (
a INTEGER UNSIGNED NULL DEFAULT NULL,
@@ -125,6 +125,7 @@ c
DROP TRIGGER t1_ins_aft;
DROP TRIGGER t1_del_bef;
DROP TABLE t1,t2;
+<<<<<<< HEAD
#
# Examine the number of times triggers are recalculated for updates
#
@@ -303,4 +304,11 @@ a b c blob_a blob_b blob_c
104 generated generated before update 104 generated generated before update
drop trigger t1_ins;
drop trigger t1_update;
+=======
+create table t1 (i int, t time not null, vt time(4) as (t) virtual);
+create trigger trg before update on t1 for each row set @a = 1;
+insert ignore into t1 (i) values (1);
+Warnings:
+Warning 1364 Field 't' doesn't have a default value
+>>>>>>> origin/10.1
drop table t1;
diff --git a/mysql-test/suite/vcol/r/wrong_arena.result b/mysql-test/suite/vcol/r/wrong_arena.result
new file mode 100644
index 00000000000..172b59d6c4c
--- /dev/null
+++ b/mysql-test/suite/vcol/r/wrong_arena.result
@@ -0,0 +1,61 @@
+create table t1 (a datetime,
+# get_datetime_value
+b int as (a > 1), # Arg_comparator
+c int as (a in (1,2,3)), # in_datetime
+d int as ((a,a) in ((1,1),(2,1),(NULL,1))), # cmp_item_datetime
+# other issues
+e int as ((a,1) in ((1,1),(2,1),(NULL,1))) # cmp_item_row::alloc_comparators()
+);
+Warnings:
+Warning 1292 Incorrect datetime value: '1'
+Warning 1292 Incorrect datetime value: '2'
+Warning 1292 Incorrect datetime value: '3'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` datetime DEFAULT NULL,
+ `b` int(11) AS (a > 1) VIRTUAL,
+ `c` int(11) AS (a in (1,2,3)) VIRTUAL,
+ `d` int(11) AS ((a,a) in ((1,1),(2,1),(NULL,1))) VIRTUAL,
+ `e` int(11) AS ((a,1) in ((1,1),(2,1),(NULL,1))) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+Warnings:
+Warning 1292 Incorrect datetime value: '1'
+Warning 1292 Incorrect datetime value: '2'
+Warning 1292 Incorrect datetime value: '3'
+insert t1 (a) values ('2010-10-10 10:10:10');
+select * from t1;
+a b c d e
+2010-10-10 10:10:10 1 0 0 NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '1'
+Warning 1292 Incorrect datetime value: '1'
+Warning 1292 Incorrect datetime value: '2'
+Warning 1292 Incorrect datetime value: '1'
+Warning 1292 Incorrect datetime value: '1'
+Warning 1292 Incorrect datetime value: '2'
+select * from t1;
+a b c d e
+2010-10-10 10:10:10 1 0 0 NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '1'
+Warning 1292 Incorrect datetime value: '2'
+Warning 1292 Incorrect datetime value: '1'
+Warning 1292 Incorrect datetime value: '1'
+Warning 1292 Incorrect datetime value: '2'
+drop table t1;
+create table t1 (a datetime,
+b datetime as (least(a,1)) # Item_func_min_max::get_date
+);
+insert t1 (a) values ('2010-10-10 10:10:10');
+select * from t1;
+a b
+2010-10-10 10:10:10 0000-00-00 00:00:00
+Warnings:
+Warning 1292 Incorrect datetime value: '1'
+select * from t1;
+a b
+2010-10-10 10:10:10 0000-00-00 00:00:00
+Warnings:
+Warning 1292 Incorrect datetime value: '1'
+drop table t1;
diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test
index 2387000c3ef..8c9787d38f7 100644
--- a/mysql-test/suite/vcol/t/vcol_misc.test
+++ b/mysql-test/suite/vcol/t/vcol_misc.test
@@ -294,6 +294,17 @@ create table t1 (v1 varchar(255) as (c1) persistent, c1 varchar(50)) collate=lat
show create table t1;
drop table t1;
+#
+# MDEV-11527 Virtual columns do not get along well with NO_ZERO_DATE
+#
+set sql_mode='no_zero_date';
+create table t1 (
+ ts timestamp not null default current_timestamp,
+ tsv timestamp as (adddate(ts, interval 1 day)) virtual
+);
+drop table t1;
+set sql_mode=default;
+
--echo #
--echo # Start of 10.1 tests
diff --git a/mysql-test/suite/vcol/t/wrong_arena.test b/mysql-test/suite/vcol/t/wrong_arena.test
new file mode 100644
index 00000000000..484f1fe685d
--- /dev/null
+++ b/mysql-test/suite/vcol/t/wrong_arena.test
@@ -0,0 +1,35 @@
+#
+# This tests various issues when vcol items allocate memory (e.g. more items)
+# not in the TABLE::expr_arena.
+#
+
+#
+# MDEV-9690 concurrent queries with virtual columns crash in temporal code
+#
+create table t1 (a datetime,
+ # get_datetime_value
+ b int as (a > 1), # Arg_comparator
+ c int as (a in (1,2,3)), # in_datetime
+ d int as ((a,a) in ((1,1),(2,1),(NULL,1))), # cmp_item_datetime
+ # other issues
+ e int as ((a,1) in ((1,1),(2,1),(NULL,1))) # cmp_item_row::alloc_comparators()
+);
+show create table t1;
+connect con1, localhost, root;
+insert t1 (a) values ('2010-10-10 10:10:10');
+select * from t1;
+disconnect con1;
+connection default;
+select * from t1;
+drop table t1;
+
+connect con1, localhost, root;
+create table t1 (a datetime,
+ b datetime as (least(a,1)) # Item_func_min_max::get_date
+);
+insert t1 (a) values ('2010-10-10 10:10:10');
+select * from t1;
+disconnect con1;
+connection default;
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test
index 58f91571ebb..5316c12c857 100644
--- a/mysql-test/t/cast.test
+++ b/mysql-test/t/cast.test
@@ -472,3 +472,42 @@ select collation(cast("a" as char(10) ascii binary));
select collation(cast("a" as char(10) binary charset utf8));
select collation(cast("a" as char(10) binary ascii));
+--echo #
+--echo # MDEV-11030 Assertion `precision > 0' failed in decimal_bin_size
+--echo #
+
+SELECT * FROM (SELECT IFNULL(CONVERT(NULL, UNSIGNED), NULL)) sq;
+
+CREATE TABLE t1 AS SELECT IFNULL(CONVERT(NULL, UNSIGNED), NULL);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 AS SELECT COALESCE(CONVERT(NULL, UNSIGNED), NULL);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 AS SELECT CASE WHEN TRUE THEN CONVERT(NULL, UNSIGNED) ELSE NULL END;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 AS SELECT IFNULL(CONVERT(NULL,SIGNED),CONVERT(NULL,UNSIGNED)) AS a;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 AS SELECT
+ -1,
+ CONVERT(NULL,SIGNED),
+ CONCAT(CONVERT(NULL,SIGNED)),
+ 1,
+ CONVERT(NULL,UNSIGNED),
+ CONCAT(CONVERT(NULL,UNSIGNED));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 AS SELECT
+ CONVERT('',SIGNED),
+ CONCAT(CONVERT('',SIGNED)),
+ CONVERT('',UNSIGNED),
+ CONCAT(CONVERT('',UNSIGNED));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index 0be9537350b..6948dd667d1 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -1754,6 +1754,15 @@ DELIMITER ;|
create table t1 as select f1();
drop function f1;
+--echo #
+--echo # MDEV-10274 Bundling insert with create statement
+--echo # for table with unsigned Decimal primary key issues warning 1194
+--echo #
+
+create table t1(ID decimal(2,1) unsigned NOT NULL, PRIMARY KEY (ID))engine=memory
+ select 2.1 ID;
+drop table t1;
+
--echo End of 5.5 tests
#
diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
index cad82222ac7..5b8c2f74528 100644
--- a/mysql-test/t/ctype_ucs.test
+++ b/mysql-test/t/ctype_ucs.test
@@ -816,6 +816,14 @@ SELECT CHAR_LENGTH(TRIM(BOTH 0x0001 FROM _ucs2 0x0061));
SELECT CHAR_LENGTH(TRIM(BOTH 0x61 FROM _ucs2 0x0061));
SELECT CHAR_LENGTH(TRIM(BOTH 0x00 FROM _ucs2 0x0061));
+--echo #
+--echo # MDEV-11685: sql_mode can't be set with non-ascii connection charset
+--echo #
+SET character_set_connection=ucs2;
+SET sql_mode='NO_ENGINE_SUBSTITUTION';
+SELECT @@sql_mode;
+SET sql_mode=DEFAULT;
+SET NAMES utf8;
--echo #
--echo # End of 5.5 tests
diff --git a/mysql-test/t/ctype_ucs2_def.test b/mysql-test/t/ctype_ucs2_def.test
index be8e044f2e4..e297fa5ccf1 100644
--- a/mysql-test/t/ctype_ucs2_def.test
+++ b/mysql-test/t/ctype_ucs2_def.test
@@ -1,6 +1,6 @@
-- source include/have_ucs2.inc
-call mtr.add_suppression("Cannot use ucs2 as character_set_client");
+call mtr.add_suppression("'ucs2' can not be used as client character set");
#
# MySQL Bug#15276: MySQL ignores collation-server
diff --git a/mysql-test/t/ctype_ucs2_query_cache.test b/mysql-test/t/ctype_ucs2_query_cache.test
index acb39419751..ace826aec44 100644
--- a/mysql-test/t/ctype_ucs2_query_cache.test
+++ b/mysql-test/t/ctype_ucs2_query_cache.test
@@ -1,7 +1,7 @@
-- source include/have_query_cache.inc
-- source include/have_ucs2.inc
-call mtr.add_suppression("Cannot use ucs2 as character_set_client");
+call mtr.add_suppression("'ucs2' can not be used as client character set");
--echo #
--echo # Start of 5.5 tests
diff --git a/mysql-test/t/ctype_utf16.test b/mysql-test/t/ctype_utf16.test
index 3946da73f9b..c986309707e 100644
--- a/mysql-test/t/ctype_utf16.test
+++ b/mysql-test/t/ctype_utf16.test
@@ -796,6 +796,15 @@ DO RPAD(_utf16 0x0061 COLLATE utf16_unicode_ci, 10000, 0x0061DE989999);
DO LPAD(_utf16 0x0061 COLLATE utf16_unicode_ci, 10000, 0x0061DE989999);
--echo #
+--echo # MDEV-11685: sql_mode can't be set with non-ascii connection charset
+--echo #
+SET character_set_connection=utf16;
+SET sql_mode='NO_ENGINE_SUBSTITUTION';
+SELECT @@sql_mode;
+SET sql_mode=DEFAULT;
+SET NAMES utf8;
+
+--echo #
--echo # End of 5.5 tests
--echo #
diff --git a/mysql-test/t/ctype_utf16_def.test b/mysql-test/t/ctype_utf16_def.test
index fad61b057c3..0829cd53285 100644
--- a/mysql-test/t/ctype_utf16_def.test
+++ b/mysql-test/t/ctype_utf16_def.test
@@ -1,5 +1,5 @@
--source include/have_utf16.inc
-call mtr.add_suppression("Cannot use utf16 as character_set_client");
+call mtr.add_suppression("'utf16' can not be used as client character set");
#
# Bug #32391 Character sets: crash with --character-set-server
diff --git a/mysql-test/t/ctype_utf32.test b/mysql-test/t/ctype_utf32.test
index f364f1bd3a5..f113f046d42 100644
--- a/mysql-test/t/ctype_utf32.test
+++ b/mysql-test/t/ctype_utf32.test
@@ -895,6 +895,15 @@ SELECT CHAR_LENGTH(TRIM(BOTH 0x00 FROM _utf32 0x00000061));
select hex(lower(cast(0xffff0000 as char character set utf32))) as c;
--echo #
+--echo # MDEV-11685: sql_mode can't be set with non-ascii connection charset
+--echo #
+SET character_set_connection=utf32;
+SET sql_mode='NO_ENGINE_SUBSTITUTION';
+SELECT @@sql_mode;
+SET sql_mode=DEFAULT;
+SET NAMES utf8;
+
+--echo #
--echo # End of 5.5 tests
--echo #
diff --git a/mysql-test/t/events_slowlog.test b/mysql-test/t/events_slowlog.test
new file mode 100644
index 00000000000..9679714dba3
--- /dev/null
+++ b/mysql-test/t/events_slowlog.test
@@ -0,0 +1,28 @@
+--source include/not_embedded.inc
+#
+# MDEV-11552 Queries executed by event scheduler are written to slow log incorrectly or not written at all
+#
+set @event_scheduler_save= @@global.event_scheduler;
+set @slow_query_log_save= @@global.slow_query_log;
+
+set global event_scheduler= on;
+set global slow_query_log= on;
+set global long_query_time=0.2;
+
+create table t1 (i int);
+insert into t1 values (0);
+create event ev on schedule at CURRENT_TIMESTAMP + INTERVAL 1 second do update t1 set i=1+sleep(0.5);
+
+--let wait_condition= select i from t1 where i > 0
+--source include/wait_condition.inc
+
+--let SEARCH_FILE = `SELECT @@slow_query_log_file`
+--let SEARCH_PATTERN= update t1 set i=1
+--let SEARCH_RANGE= -1000
+--source include/search_pattern_in_file.inc
+
+drop table t1;
+
+set global event_scheduler= @event_scheduler_save;
+set global slow_query_log= @slow_query_log_save;
+set global long_query_time= @@session.long_query_time;
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 40a6c387448..5cfb7f7d05f 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -1672,6 +1672,11 @@ INSERT INTO t1 VALUES (18, '2010-10-13');
SELECT a.id,a.date1,FROM_DAYS(TO_DAYS(a.date1)-10) as date2, DATE_ADD(a.date1,INTERVAL -10 DAY),TO_DAYS(a.date1)-10 FROM t1 a ORDER BY a.id;
DROP TABLE t1;
+--echo #
+--echo # MDEV-10524 Assertion `arg1_int >= 0' failed in Item_func_additive_op::result_precision()
+--echo #
+SELECT 1 MOD ADDTIME( '13:58:57', '00:00:01' ) + 2;
+
--echo #
--echo # Start of 10.0 tests
diff --git a/mysql-test/t/index_merge_innodb.test b/mysql-test/t/index_merge_innodb.test
index 3a2601342ba..53ce3114b49 100644
--- a/mysql-test/t/index_merge_innodb.test
+++ b/mysql-test/t/index_merge_innodb.test
@@ -171,6 +171,37 @@ WHERE ( tb.b != ta.b OR tb.a = ta.a )
AND ( tb.b = ta.c OR tb.b = ta.b );
DROP TABLE t1;
-
set optimizer_switch= @optimizer_switch_save;
+--echo #
+--echo # MDEV-10927: Crash When Using sort_union Optimization
+--echo #
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='index_merge_sort_intersection=on';
+SET SESSION sort_buffer_size = 1024;
+
+create table t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col1 int(11) NOT NULL,
+col2 int(11) NOT NULL,
+col3 int(11) NOT NULL,
+key2 int(11) NOT NULL,
+col4 int(11) NOT NULL,
+key1 int(11) NOT NULL,
+PRIMARY KEY (pk),
+KEY key1 (key1),
+KEY key2 (key2)
+) ENGINE=InnoDB AUTO_INCREMENT=12860259 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
+
+create table t2(a int);
+insert into t2 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t3(a int);
+insert into t3 select A.a + B.a* 10 + C.a * 100 + D.a*1000 from t2 A, t2 B, t2 C, t2 D;
+
+insert into t1 (key1, key2, col1,col2,col3,col4)
+select a,a, a,a,a,a from t3;
+SELECT sum(col1) FROM t1 FORCE INDEX (key1,key2) WHERE (key1 between 10 and 8191+10) or (key2= 5);
+drop table t1,t2,t3;
+set optimizer_switch=@tmp_optimizer_switch;
diff --git a/mysql-test/t/information_schema_part.test b/mysql-test/t/information_schema_part.test
index f1415d12f79..ea88f364c07 100644
--- a/mysql-test/t/information_schema_part.test
+++ b/mysql-test/t/information_schema_part.test
@@ -131,3 +131,10 @@ drop table if exists t1;
create table t1 (f1 int key) partition by key(f1) partitions 2;
select create_options from information_schema.tables where table_schema="test";
drop table t1;
+
+--echo #
+--echo # MDEV-11353 - Identical logical conditions
+--echo #
+CREATE TABLE t1(a INT) CHECKSUM=1 SELECT 1;
+SELECT CHECKSUM FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1';
+DROP TABLE t1;
diff --git a/mysql-test/t/insert_update.test b/mysql-test/t/insert_update.test
index de38ae0b0d3..7234973eeb8 100644
--- a/mysql-test/t/insert_update.test
+++ b/mysql-test/t/insert_update.test
@@ -170,6 +170,7 @@ DROP TABLE t1,t2;
SET SQL_MODE = 'TRADITIONAL';
CREATE TABLE t1 (a INT PRIMARY KEY, b INT NOT NULL);
+INSERT INTO t1 VALUES (1,1);
--error ER_NO_DEFAULT_FOR_FIELD
INSERT INTO t1 (a) VALUES (1);
@@ -177,7 +178,10 @@ INSERT INTO t1 (a) VALUES (1);
--error ER_NO_DEFAULT_FOR_FIELD
INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE a = b;
---error ER_NO_DEFAULT_FOR_FIELD
+# this one is ok
+INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE b = a;
+
+# arguably the statement below should fail
INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE b = b;
SELECT * FROM t1;
diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test
index 019d8edde2f..5ee868b4177 100644
--- a/mysql-test/t/join_cache.test
+++ b/mysql-test/t/join_cache.test
@@ -3742,9 +3742,11 @@ FROM
LEFT JOIN t2 c23 ON c23.parent_id = t.id AND c23.col2 = "val"
LEFT JOIN t2 c24 ON c24.parent_id = t.id AND c24.col2 = "val"
LEFT JOIN t2 c25 ON c25.parent_id = t.id AND c25.col2 = "val"
+ LEFT JOIN t2 c26 ON c26.parent_id = t.id AND c26.col2 = "val"
+ LEFT JOIN t2 c27 ON c27.parent_id = t.id AND c27.col2 = "val"
ORDER BY
col1;
-select timestampdiff(second, @init_time, now()) <= 1;
+select timestampdiff(second, @init_time, now()) <= 5;
set join_cache_level=2;
@@ -3777,9 +3779,11 @@ FROM
LEFT JOIN t2 c23 ON c23.parent_id = t.id AND c23.col2 = "val"
LEFT JOIN t2 c24 ON c24.parent_id = t.id AND c24.col2 = "val"
LEFT JOIN t2 c25 ON c25.parent_id = t.id AND c25.col2 = "val"
+ LEFT JOIN t2 c26 ON c26.parent_id = t.id AND c26.col2 = "val"
+ LEFT JOIN t2 c27 ON c27.parent_id = t.id AND c27.col2 = "val"
ORDER BY
col1;
-select timestampdiff(second, @init_time, now()) <= 1;
+select timestampdiff(second, @init_time, now()) <= 5;
EXPLAIN
SELECT t.*
@@ -3810,6 +3814,8 @@ FROM
LEFT JOIN t2 c23 ON c23.parent_id = t.id AND c23.col2 = "val"
LEFT JOIN t2 c24 ON c24.parent_id = t.id AND c24.col2 = "val"
LEFT JOIN t2 c25 ON c25.parent_id = t.id AND c25.col2 = "val"
+ LEFT JOIN t2 c26 ON c26.parent_id = t.id AND c26.col2 = "val"
+ LEFT JOIN t2 c27 ON c27.parent_id = t.id AND c27.col2 = "val"
ORDER BY
col1;
diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test
index 7e529194303..4de7138e4dc 100644
--- a/mysql-test/t/loaddata.test
+++ b/mysql-test/t/loaddata.test
@@ -612,7 +612,7 @@ disconnect con1;
--echo #
CREATE TABLE t1(f1 INT);
-EVAL SELECT 0xE1C330 INTO OUTFILE 't1.dat';
+EVAL SELECT 0xE1BB30 INTO OUTFILE 't1.dat';
--disable_warnings
LOAD DATA INFILE 't1.dat' IGNORE INTO TABLE t1 CHARACTER SET utf8;
--enable_warnings
@@ -658,13 +658,25 @@ SET @@sql_mode= @old_mode;
--remove_file $MYSQLTEST_VARDIR/mysql
DROP TABLE t1;
---echo
+
--echo #
---echo # Bug#23080148 - Backport of Bug#20683959.
---echo # Bug#20683959 LOAD DATA INFILE IGNORES A SPECIFIC ROW SILENTLY
---echo # UNDER DB CHARSET IS UTF8.
+--echo # MDEV-11079 Regression: LOAD DATA INFILE lost BLOB support using utf8 load files
--echo #
+CREATE TABLE t1 (a mediumblob NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+LOAD DATA INFILE '../../std_data/loaddata/mdev-11079.txt' INTO TABLE t1 CHARSET utf8 FIELDS TERMINATED BY ';' ENCLOSED BY '"' ESCAPED BY '\\' LINES TERMINATED BY '\n';
+SELECT HEX(a) FROM t1;
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-11631 LOAD DATA INFILE fails to load data with an escape character followed by a multi-byte character
+--echo #
+
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8);
+LOAD DATA INFILE '../../std_data/loaddata/mdev-11631.txt' INTO TABLE t1 CHARACTER SET utf8;
+SELECT HEX(a) FROM t1;
+DROP TABLE t1;
+
CREATE DATABASE d1 CHARSET latin1;
USE d1;
CREATE TABLE t1 (val TEXT);
diff --git a/mysql-test/t/log_slow.test b/mysql-test/t/log_slow.test
index 8d5a09d7a94..56e35bd5a20 100644
--- a/mysql-test/t/log_slow.test
+++ b/mysql-test/t/log_slow.test
@@ -50,7 +50,6 @@ set global slow_query_log=1;
set global log_output='TABLE';
select sleep(0.5);
select count(*) FROM mysql.slow_log;
-truncate mysql.slow_log;
# Reset used variables
set @@long_query_time=default;
@@ -58,3 +57,4 @@ set global slow_query_log= @org_slow_query_log;
set @@log_slow_filter=default;
set @@log_slow_verbosity=default;
set global log_output= default;
+truncate mysql.slow_log;
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index 13c8db5a481..2d0c134a2d9 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -1945,6 +1945,16 @@ order by A.col2, B.col2 limit 10, 1000000;
drop table t1,t2,t3;
+--echo #
+--echo # mdev-10705 : long order by list that can be skipped
+--echo #
+
+SELECT 1
+UNION
+( SELECT 2
+ ORDER BY NULL, @a0 := 3, @a1 := 3, @a2 := 3, @a3 := 3, @a4 := 3,
+ @a5 := 3, @a6 := 3, @a7 := 3, @a8 := 3, @a9 := 3, @a10 := 3 );
+
--echo End of 5.5 tests
--echo #
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 77b9c305ac8..e02bf6aaecf 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -6015,6 +6015,17 @@ drop view v2;
drop table t1,t2;
--echo #
+--echo # MDEV-10386 Assertion `fixed == 1' failed in virtual String* Item_func_conv_charset::val_str(String*)
+--echo #
+
+CREATE TABLE t1 (f1 CHAR(3) CHARACTER SET utf8 NULL, f2 CHAR(3) CHARACTER SET latin1 NULL);
+INSERT INTO t1 VALUES ('foo','bar');
+SELECT * FROM t1 WHERE f2 >= SOME ( SELECT f1 FROM t1 );
+SELECT * FROM t1 WHERE f2 <= SOME ( SELECT f1 FROM t1 );
+DROP TABLE t1;
+
+
+--echo #
--echo # MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
--echo # with UNION in ALL subquery
--echo #
diff --git a/mysql-test/t/subselect2.test b/mysql-test/t/subselect2.test
index b3c1322184d..ae210b865a2 100644
--- a/mysql-test/t/subselect2.test
+++ b/mysql-test/t/subselect2.test
@@ -359,5 +359,55 @@ where t1.a = t2.a and ( t1.a = ( select min(a) from t1 ) or 0 );
drop table t1,t2,t3;
+--echo #
+--echo # MDEV-10148: Database crashes in the query to the View
+--echo #
+CREATE TABLE t1 (
+ key_code INT(11) NOT NULL,
+ value_string VARCHAR(50) NULL DEFAULT NULL,
+ PRIMARY KEY (key_code)
+) COLLATE='utf8_general_ci' ENGINE=InnoDB ;
+
+CREATE TABLE t2 (
+ key_code INT(11) NOT NULL,
+ target_date DATE NULL DEFAULT NULL,
+ PRIMARY KEY (key_code)
+) COLLATE='utf8_general_ci' ENGINE=InnoDB ;
+
+CREATE TABLE t3 (
+ now_date DATE NOT NULL,
+ PRIMARY KEY (now_date)
+) COLLATE='utf8_general_ci' ENGINE=InnoDB ;
+
+CREATE VIEW v1
+AS
+SELECT
+ B.key_code,
+ B.target_date
+FROM
+ t2 B INNER JOIN t3 C ON
+ B.target_date = C.now_date
+;
+SET @s = 'SELECT A.* FROM t1 A WHERE A.key_code IN (SELECT key_code FROM v1)';
+PREPARE stmt FROM @s;
+EXECUTE stmt; #1st time -> success
+EXECUTE stmt; #2nd time -> crash
+DEALLOCATE PREPARE stmt;
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
set optimizer_switch=@subselect2_test_tmp;
+#
+# Bug #23303485 : HANDLE_FATAL_SIGNAL (SIG=11) IN SUBSELECT_UNION_ENGINE::NO_ROWS
+#
+create table t1 (a int);
+create table t2 (a int);
+create table t3(a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t2 select a from t1;
+insert into t3 select a from t1;
+--error ER_SUBQUERY_NO_1_ROW
+select null in (select a from t1 where a < out3.a union select a from t2 where
+ (select a from t3) +1 < out3.a+1) from t3 out3;
+drop table t1, t2, t3;
diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test
index 4eb9701ee71..cb102f8319e 100644
--- a/mysql-test/t/subselect4.test
+++ b/mysql-test/t/subselect4.test
@@ -1956,5 +1956,46 @@ SELECT x FROM t1 WHERE id > (SELECT MAX(id) - 1000 FROM t1) ORDER BY x LIMIT 1;
drop table t1;
+--echo #
+--echo # MDEV-7691: Assertion `outer_context || !*from_field || *from_field == not_found_field' ...
+--echo #
+set optimizer_switch=default;
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (4),(6);
+
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1),(8);
+
+PREPARE stmt FROM "
+SELECT * FROM t2
+HAVING 0 IN (
+ SELECT a FROM t1
+ WHERE a IN (
+ SELECT a FROM t1
+ WHERE b = a
+ )
+)
+";
+
+EXECUTE stmt;
+EXECUTE stmt;
+
+--echo # Alternative test case, without HAVING
+CREATE TABLE t3 (i INT) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (4),(6);
+
+PREPARE stmt FROM "
+SELECT * FROM t3 AS t10
+WHERE EXISTS (
+ SELECT * FROM t3 AS t20 WHERE t10.i IN (
+ SELECT i FROM t3
+ )
+)";
+
+EXECUTE stmt;
+EXECUTE stmt;
+
+drop table t1, t2, t3;
+
SET optimizer_switch= @@global.optimizer_switch;
set @@tmp_table_size= @@global.tmp_table_size;
diff --git a/mysql-test/t/trigger_no_defaults-11698.test b/mysql-test/t/trigger_no_defaults-11698.test
new file mode 100644
index 00000000000..fab7845ad7d
--- /dev/null
+++ b/mysql-test/t/trigger_no_defaults-11698.test
@@ -0,0 +1,25 @@
+#
+# MDEV-11698 Old Bug possibly not fixed; BEFORE INSERT Trigger on NOT NULL
+#
+set sql_mode='strict_all_tables';
+create table t1 (a int not null, b int);
+--error ER_NO_DEFAULT_FOR_FIELD
+insert t1 (b) values (1);
+delimiter |;
+create trigger trgi before insert on t1 for each row
+ case new.b
+ when 10 then
+ set new.a = new.b;
+ when 30 then
+ set new.a = new.a;
+ else
+ do 1;
+ end case|
+delimiter ;|
+insert t1 (b) values (10);
+--error ER_NO_DEFAULT_FOR_FIELD
+insert t1 (b) values (20);
+# arguably the statement below should fail too
+insert t1 (b) values (30);
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/trigger_null-8605.test b/mysql-test/t/trigger_null-8605.test
index 748768a1849..34a57654b48 100644
--- a/mysql-test/t/trigger_null-8605.test
+++ b/mysql-test/t/trigger_null-8605.test
@@ -373,3 +373,17 @@ show columns from t1;
insert into t1 (a) values (3);
show columns from t1;
drop table t1;
+
+#
+# MDEV-11551 Server crashes in Field::is_real_null
+#
+create table t1 (
+ pk int primary key,
+ i int,
+ v1 int as (i) virtual,
+ v2 int as (i) virtual
+);
+create trigger tr before update on t1 for each row set @a = 1;
+--error ER_BAD_NULL_ERROR
+insert into t1 (pk, i) values (null, null);
+drop table t1;
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
index 151512515b9..e0c011e3d20 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/t/union.test
@@ -1057,7 +1057,6 @@ ORDER BY a;
DROP TABLE t1;
---echo End of 5.0 tests
-- echo #
-- echo # Bug#32858: Error: "Incorrect usage of UNION and INTO" does not take
-- echo # subselects into account
@@ -1160,6 +1159,8 @@ create table t1 (a int);
insert into t1 values (10),(10),(10),(2),(3),(4),(5),(6),(7),(8),(9),(1),(10);
--sorted_result
select a from t1 where false UNION select a from t1 limit 8;
+--sorted_result
+(select a from t1 where false) UNION (select a from t1) limit 8;
drop table t1;
--echo #
@@ -1385,6 +1386,26 @@ UNION
drop table t1;
+
+--echo #
+--echo # MDEV-10172: UNION query returns incorrect rows outside
+--echo # conditional evaluation
+--echo #
+
+create table t1 (d datetime not null primary key);
+insert into t1(d) values ('2016-06-01'),('2016-06-02'),('2016-06-03'),('2016-06-04');
+select * from
+(
+ select * from t1 where d between '2016-06-02' and '2016-06-05'
+ union
+ (select * from t1 where d < '2016-06-05' order by d desc limit 1)
+) onlyJun2toJun4
+order by d;
+drop table t1;
+
+--echo End of 5.0 tests
+
+
--echo #
--echo # WL#1763 Avoid creating temporary table in UNION ALL
--echo #
@@ -1486,4 +1507,3 @@ SELECT * FROM t1 t1_1 LEFT JOIN t1 t1_2 ON ( t1_2.b = t1_1.a )
WHERE t1_2.b NOT IN ( SELECT 4 UNION ALL SELECT 5 );
DROP TABLE t1;
-
diff --git a/mysql-test/unstable-tests b/mysql-test/unstable-tests
index 7b5c2756f11..42985e1d66d 100644
--- a/mysql-test/unstable-tests
+++ b/mysql-test/unstable-tests
@@ -23,66 +23,83 @@
#
##############################################################################
-main.alter_table : Modified in 10.1.19
-main.analyze_stmt_slow_query_log : MDEV-7558 - wrong result
-main.create : Modified in 10.1.20
+main.alter_table : Modified in 10.1.21
+main.alter_table_trans : MDEV-11805 - timeout
+main.analyze_stmt_slow_query_log : Modified in 10.1.21
+main.cast : Modified in 10.1.21
+main.create : Modified in 10.1.21
main.create_delayed : MDEV-10605 - failed with timeout
main.create_drop_binlog : Uses binlog_start_pos.inc modified in 10.1.20
-main.create_or_replace : Modified in 10.1.19
+main.ctype_ucs : Modified in 10.1.21
+main.ctype_ucs2_def : Modified in 10.1.21
+main.ctype_ucs2_query_cache : Modified in 10.1.21
+main.ctype_utf16 : Modified in 10.1.21
+main.ctype_utf16_def : Modified in 10.1.21
main.ctype_utf16le : MDEV-10675: timeout or extra warnings
+main.ctype_utf32 : Modified in 10.1.21
main.ctype_utf8 : Modified in 10.1.20
main.ctype_utf8mb4 : Modified in 10.1.20
main.default : Modified in 10.1.20
main.derived : Modified in 10.1.20
main.derived_view : Modified in 10.1.20
-main.drop : Modified in 10.1.19
main.events_restart : MDEV-11221: assertion failure
+main.events_slowlog : Added in 10.1.21
main.fulltext_charsets : Added in 10.1.20
-main.func_time : Modified in 10.1.20
+main.func_time : Modified in 10.1.21
main.group_by : Modified in 10.1.20
main.group_by_innodb : Modified in 10.1.20
main.host_cache_size_functionality : MDEV-10606 - sporadic failure on shutdown
main.index_intersect_innodb : MDEV-10643 - failed with timeout
-main.index_merge_innodb : MDEV-7142 - Wrong execution plan
-main.information_schema : Modified in 10.1.19
+main.index_merge_innodb : MDEV-7142 - Wrong execution plan, also modified in 10.1.21
+main.information_schema_part : Modified in 10.1.21
main.innodb_mysql_lock : MDEV-7861 - sporadic lock detection failure
+main.join_cache : Modified in 10.1.21
main.kill_processlist-6619 : MDEV-10793 - wrong result in processlist
-main.loaddata : Modified in 10.1.20
+main.loaddata : Modified in 10.1.21
+main.log_slow : Modified in 10.1.21
main.lowercase_fs_on : Uses search_pattern_in_file.inc modified in 10.1.20
main.mdev-504 : MDEV-10607 - sporadic "can't connect"
main.mdev375 : MDEV-10607 - sporadic "can't connect"
main.merge : MDEV-10607 - sporadic "can't connect"
-main.mysql : Modified in 10.1.19
-main.mysql_not_windows : Modified in 10.1.19
main.mysqlbinlog : Uses binlog_start_pos.inc modified in 10.1.20
main.mysqldump-max : Uses binlog_start_pos.inc modified in 10.1.20
-main.mysqldump-nl : Added in 10.1.19
-main.mysqltest : MDEV-9269 - fails on Alpha; also modified in 10.1.19
+main.mysqlslap : MDEV-11801 - timeout
+main.mysqltest : MDEV-9269 - fails on Alpha
main.named_pipe : Uses search_pattern_in_file.inc modified in 10.1.20
-main.null : Modified in 10.1.19
+main.order_by : Modified in 10.1.21
main.order_by_optimizer_innodb : MDEV-10683 - wrong execution plan
main.parser : Modified in 10.1.20
-main.pool_of_threads : MDEV-10100 - sporadic error on detecting max connections
+main.pool_of_threads : Modified in 10.1.21
main.ps : MDEV-11017 - sporadic wrong Prepared_stmt_count
main.selectivity : Modified in 10.1.20
-main.selectivity_innodb : Modified in 10.1.19
main.show_explain : MDEV-10674 - sporadic failure
-main.sp : Modified in 10.1.20
+main.signal_demo3 : MDEV-11720 - Thread stack overrun on labrador
+main.sp : Modified in 10.1.21
+main.sp-prelocking : Modified in 10.1.21
main.sp-security : MDEV-10607 - sporadic "can't connect"
main.stat_tables_par_innodb : MDEV-10515 - sporadic wrong results
main.statistics : Modified in 10.1.20
main.status : MDEV-8510 - sporadic wrong result
-main.subselect : Modified in 10.1.20
+main.subselect : Modified in 10.1.21
+main.subselect2 : Modified in 10.1.21
+main.subselect4 : Modified in 10.1.21
main.subselect_innodb : MDEV-10614 - sporadic wrong results
+main.subselect_no_exists_to_in : Uses subselect.test modified in 10.1.21
+main.subselect_no_mat : Uses subselect.test modified in 10.1.21
+main.subselect_no_opts : Uses subselect.test modified in 10.1.21
+main.subselect_no_scache : Uses subselect.test modified in 10.1.21
+main.subselect_no_semijoin : Uses subselect.test modified in 10.1.21
+main.trigger_null-8605 : Modified in 10.1.21
main.type_datetime_hires : MDEV-10687 - timeout
main.type_decimal : Modified in 10.1.20
-main.view : Uses search_pattern_in_file.inc modified in 10.1.20
+main.union : Modified in 10.1.21
+main.view : Modified in 10.1.21
main.wait_timeout_not_windows : Uses search_pattern_in_file.inc modified in 10.1.20
#----------------------------------------------------------------
archive.archive-big : MDEV-10615 - table is marked as crashed
-archive.discover : MDEV-10510 - table is marked as crashed
+archive.discover : MDEV-10510 - table is marked as crashed; modified in 10.1.21
#----------------------------------------------------------------
@@ -101,6 +118,8 @@ binlog_encryption.* : Added in 10.1.20
#----------------------------------------------------------------
+connect.jdbc : Modified in 10.1.21
+connect.jdbc_new : Modified in 10.1.21
connect.tbl : MDEV-9844, MDEV-10179 - sporadic crashes, valgrind warnings, wrong results
#----------------------------------------------------------------
@@ -115,27 +134,28 @@ encryption.filekeys_nofile : Uses search_pattern_in_file.inc mo
encryption.filekeys_syntax : Uses search_pattern_in_file.inc modified in 10.1.20
encryption.filekeys_tooshort : Uses search_pattern_in_file.inc modified in 10.1.20
encryption.filekeys_unencfile : Uses search_pattern_in_file.inc modified in 10.1.20
-encryption.innodb-bad-key-change : uses keys2.txt modified in 10.1.19
-encryption.innodb-bad-key-change2 : uses keys2.txt modified in 10.1.19
-encryption.innodb-bad-key-change3 : Uses search_pattern_in_file.inc modified in 10.1.20
-encryption.innodb-bad-key-change4 : uses keys2.txt modified in 10.1.19
-encryption.innodb-bad-key-change5 : uses keys2.txt modified in 10.1.19
-encryption.innodb-bad-key-shutdown : MDEV-9105 - valgrind warnings, assertion failures, and uses keys2.txt modified in 10.1.19
-encryption.innodb-discard-import : Uses search_pattern_in_file.inc modified in 10.1.20
-encryption.innodb_encryption_discard_import : MDEV-11218 - wrong result, also uses search_pattern_in_file.inc modified in 10.1.20
+encryption.innodb-bad-key-change3 : Modified in 10.1.21
+encryption.innodb-bad-key-shutdown : MDEV-9105 - valgrind warnings, assertion failures
+encryption.innodb-discard-import : Modified in 10.1.21
+encryption.innodb-discard-import-change : Modified in 10.1.21
+encryption.innodb_encryption_discard_import : MDEV-11218 - wrong result, also modified in 10.1.21
encryption.innodb_encryption_filekeys : MDEV-9962 - timeouts
+encryption.innodb_encryption-page-compression : MDEV-11420 - Trying to access missing tablespace
encryption.innodb_encryption_row_compressed : Uses search_pattern_in_file.inc modified in 10.1.20
encryption.innodb_first_page : MDEV-10689 - crashes
-encryption.innodb-log-encrypt : Uses search_pattern_in_file.inc modified in 10.1.20
-encryption.innodb_lotoftables : MDEV-11531 - InnoDB error
-encryption.innodb-missing-key : Added in 10.1.19
+encryption.innodb-log-encrypt : Modified in 10.1.21
+encryption.innodb_lotoftables : MDEV-11531 - InnoDB error, also modified in 10.1.21
+encryption.innodb-missing-key : MDEV-9359 - assertion failure
encryption.innodb_onlinealter_encryption : MDEV-10099 - wrong results; also uses search_pattern_in_file.inc modified in 10.1.20
encryption.innodb-page_encryption : MDEV-10641 - mutex problem
-encryption.innodb_page_encryption_key_change : uses keys2.txt modified in 10.1.19
+encryption.innodb_scrub : MDEV-8139, also was modified in 10.1.21
+encryption.innodb_scrub_background : MDEV_8139, also was modified in 10.1.21
+encryption.innodb_scrub_compressed : MDEV-8139; also was modified and re-enabled in 10.1.21
#----------------------------------------------------------------
-extra/binlog_tests.database : Modified in 10.1.19 (merge)
+engines/iuds.* : Not maintained in timely manner
+engines/funcs.* : Not maintained in timely manner
#----------------------------------------------------------------
@@ -147,51 +167,57 @@ federated.federated_transactions : MDEV-10617, MDEV-10417 - Wrong checksum, time
#----------------------------------------------------------------
funcs_1.processlist_val_no_prot : MDEV-11223 - Wrong result
+
+funcs_2.innodb_charset : Modified in 10.1.21
funcs_2.memory_charset : MDEV-10290 - Timeout
funcs_2.myisam_charset : MDEV-11535 - Timeout
#----------------------------------------------------------------
-galera.* : Added to default suites in 10.1.19
-
-galera.galera_var_dirty_reads : Modified in 10.1.20
+galera.galera_var_cluster_address : Modified in 10.1.21
+galera.galera_var_dirty_reads : Modified in 10.1.21
+galera.MW-284 : Modified in 10.1.21
galera.rpl_row_annotate : Uses binlog_start_pos.inc modified in 10.1.20
+galera_split_brain : Modified in 10.1.21
-galera_3nodes.* : Added to default suites in 10.1.19, MDEV-11490
+galera_3nodes.* : MDEV-11490 - Warnings not suppressed
#----------------------------------------------------------------
+innodb.101_compatibility : Added in 10.1.21
innodb.binlog_consistent : MDEV-10618 - Server fails to start; also uses binlog_start_pos.inc modified in 10.1.20
+innodb.doublewrite : Added in 10.1.21
innodb.group_commit_binlog_pos : Uses binlog_start_pos.inc modified in 10.1.20
innodb.group_commit_binlog_pos_no_optimize_thread : Uses binlog_start_pos.inc modified in 10.1.20
+innodb.group_commit_crash : Modified in 10.1.21
+innodb.group_commit_crash_no_optimize_thread : Modified in 10.1.21
innodb.innodb-alter-table : MDEV-10619 - Testcase timeout
-innodb.innodb-bug-14068765 : MDEV-9105 - valgrind warnings, assertion failures, also uses innodb-util.pl added in 10.1.19
-innodb.innodb-bug-14084530 : MDEV-9105 - valgrind warnings, assertion failures, also uses innodb-util.pl added in 10.1.19
+innodb.innodb-bug-14068765 : MDEV-9105 - valgrind warnings, assertion failures
+innodb.innodb-bug-14084530 : MDEV-9105 - valgrind warnings, assertion failures
+innodb.innodb_bug14147491 : MDEV-11808, also modified in 10.1.21
+innodb.innodb_bug14676111 : MDEV-11802 - wrong result
innodb.innodb_bug30423 : MDEV-7311 - Wrong number of rows in the plan
-innodb.innodb-change-buffer-recovery : Uses search_pattern_in_file.inc modified in 10.1.20
+innodb.innodb-change-buffer-recovery : Modified in 10.1.21
innodb.innodb_defragment_fill_factor : Modified in 10.1.20
innodb.innodb-lock-schedule-algorithm : Modified in 10.1.20
innodb.innodb-page_compression_zip : MDEV-10641 - mutex problem
innodb.innodb_stats : MDEV-10682 - wrong result
innodb.innodb_sys_semaphore_waits : MDEV-10331 - wrong result
-innodb.innodb-wl5522 : MDEV-9105 - valgrind warnings, assertion failures, also uses innodb-util.pl added in 10.1.19
-innodb.innodb-wl5522-1 : MDEV-9105 - valgrind warnings, assertion failures, also uses innodb-util.pl added in 10.1.19
-innodb.innodb-wl5522-debug : Modified in 10.1.19
-innodb.innodb-wl5522-debug-zip : Modified in 10.1.20
-innodb.innodb-wl5522-zip : MDEV-9105 - valgrind warnings, assertion failures, also uses innodb-util.pl added in 10.1.19
+innodb.innodb-wl5522 : MDEV-9105 - valgrind warnings, assertion failures
+innodb.innodb-wl5522-1 : MDEV-9105 - valgrind warnings, assertion failures
+innodb.innodb-wl5522-debug-zip : Modified in 10.1.21
+innodb.log_data_file_size : Added in 10.1.21
innodb.table_index_statistics : Added in 10.1.20
innodb.trigger : Modified in 10.1.20
-innodb.xa_recovery : Modified in 10.1.19
+innodb.xa_recovery : Modified in 10.1.21
#----------------------------------------------------------------
innodb_fts.create : Added in 10.1.20
-innodb_fts.innodb_fts_misc : MDEV-11233 - Crash on CREATE FULLTEXT INDEX
#----------------------------------------------------------------
maria.collations : Added in 10.1.20
-maria.encrypt-wrong-key : uses keys2.txt modified in 10.1.19
maria.maria-connect : Uses binlog_start_pos.inc modified in 10.1.20
#----------------------------------------------------------------
@@ -225,24 +251,26 @@ perfschema.func_file_io : MDEV-5708 - fails for s390x
perfschema.func_mutex : MDEV-5708 - fails for s390x
perfschema.setup_actors : MDEV-10679 - rare crash
perfschema.socket_summary_by_event_name_func : MDEV-10622 - Socket summary tables do not match
+perfschema.stage_mdl_global : MDEV-11803 - wrong result on slow builders
perfschema.threads_mysql : MDEV-10677 - sporadic wrong result
#----------------------------------------------------------------
+plugins.cracklib_password_check : MDEV-11650 - valgrind warnings
plugins.feedback_plugin_send : MDEV-7932 - ssl failed for url
plugins.server_audit : MDEV-9562 - crashes on sol10-sparc
plugins.thread_pool_server_audit : MDEV-9562 - crashes on sol10-sparc
-
+plugins.two_password_validations : MDEV-11650 - valgrind warnings
#----------------------------------------------------------------
roles.role_case_sensitive-10744 : Added in 10.1.20
roles.create_and_drop_role : Modified in 10.1.20
-roles.create_and_grant_role : MDEV-11533 - Extra grant in output
#----------------------------------------------------------------
rpl.last_insert_id : MDEV-10625 - warnings in error log
+rpl.rpl_alter_extra_persistent : Added in 10.1.21
rpl.rpl_auto_increment : MDEV-10417 - Fails on Mips
rpl.rpl_auto_increment_bug45679 : MDEV-10417 - Fails on Mips
rpl.rpl_auto_increment_update_failure : MDEV-10625 - warnings in error log
@@ -252,7 +280,6 @@ rpl.rpl_checksum_cache : MDEV-10626 - Testcase timeout
rpl.rpl_circular_for_4_hosts : MDEV-10627 - Testcase timeout
rpl.rpl_ddl : MDEV-10417 - Fails on Mips
rpl.rpl_domain_id_filter_restart : MDEV-10684 - Wrong result
-rpl.rpl_drop_db : Modified in 10.1.19
rpl.rpl_gtid_basic : MDEV-10681 - server startup problem
rpl.rpl_gtid_crash : MDEV-9501 - Warning: failed registering on master
rpl.rpl_gtid_errorlog : Uses search_pattern_in_file.inc modified in 10.1.20
@@ -260,6 +287,7 @@ rpl.rpl_gtid_master_promote : MDEV-10628 - Timeout in sync_with_master
rpl.rpl_gtid_mdev9033 : MDEV-10680 - warnings
rpl.rpl_gtid_stop_start : MDEV-10629 - Crash on shutdown
rpl.rpl_gtid_until : MDEV-10625 - warnings in error log
+rpl.rpl_heartbeat_basic : MDEV-11668 - wrong result
rpl.rpl_innodb_bug30888 : MDEV-10417 - Fails on Mips
rpl.rpl_insert : MDEV-9329 - Fails on Ubuntu/s390x
rpl.rpl_insert_delayed : MDEV-9329 - Fails on Ubuntu/s390x
@@ -278,17 +306,21 @@ rpl.rpl_password_boundaries : MDEV-11534 - Slave IO warnings
rpl.rpl_row_drop_create_temp_table : MDEV-10626 - Testcase timeout
rpl.rpl_row_flsh_tbls : Uses binlog_start_pos.inc modified in 10.1.20
rpl.rpl_row_log_innodb : MDEV-10688 - Wrong result
+rpl.rpl_row_mysqlbinlog : Modified in 10.1.21
rpl.rpl_row_sp001 : MDEV-9329 - Fails on Ubuntu/s390x
rpl.rpl_semi_sync : MDEV-11220 - Wrong result
+rpl.rpl_semi_sync_event_after_sync : MDEV-11806 - warnings
rpl.rpl_semi_sync_uninstall_plugin : MDEV-7140 - Wrong plugin status
+rpl.rpl_semi_sync_wait_point : MDEV-11807 - timeout in wait condition
rpl.rpl_show_slave_hosts : MDEV-10681 - server startup problem
rpl.rpl_skip_replication : MDEV-9268 - Fails with timeout in sync_slave_with_master on Alpha
rpl.rpl_slave_grp_exec : MDEV-10514 - Unexpected deadlock
+rpl.rpl_special_charset : Modified in 10.1.21
rpl.rpl_stm_flsh_tbls : Uses binlog_start_pos.inc modified in 10.1.20
rpl.rpl_stop_slave_error : Uses search_pattern_in_file.inc modified in 10.1.20
rpl.rpl_sync : MDEV-10633 - Database page corruption
rpl.rpl_temporary_error2 : MDEV-10634 - Wrong number of retries
-rpl.sec_behind_master-5114 : MDEV-8518 - Wrong value of Seconds_Behind_Master
+rpl.sec_behind_master-5114 : Modified in 10.1.21
#----------------------------------------------------------------
@@ -301,9 +333,11 @@ spider/bg.ha_part : MDEV-9329 - Fails on Ubuntu/s390x
spider/bg.spider_fixes : MDEV-7098, MDEV-9329 - Mutex problem, failures on s390x
spider/bg.vp_fixes : MDEV-9329 - Fails on Ubuntu/s390x
+spider/handler.* : MDEV-10987, MDEV-10990 - Tests have not been maintained
+
#----------------------------------------------------------------
-sphinx.* : MDEV-10985, MDEV-10986 - Tests have not been maintained
+sphinx.* : MDEV-10986 - Tests have not been maintained
#----------------------------------------------------------------
@@ -325,6 +359,7 @@ sys_vars.replicate_ignore_db_basic : Modified in 10.1.20
sys_vars.replicate_ignore_table_basic : Modified in 10.1.20
sys_vars.replicate_wild_do_table_basic : Modified in 10.1.20
sys_vars.replicate_wild_ignore_table_basic : Modified in 10.1.20
+sys_vars.rpl_init_slave_func : MDEV-10149 - wrong results
sys_vars.sysvars_innodb : MDEV-6958 - error-prone rdiffs
sys_vars.sysvars_server_embedded : MDEV-6958 - error-prone rdiffs
sys_vars.table_open_cache_instances_basic : Modified in 10.1.20
@@ -339,6 +374,7 @@ tokudb.table_index_statistics : Added in 10.1.20
tokudb_bugs.checkpoint_lock : MDEV-10637 - Wrong processlist output
tokudb_bugs.checkpoint_lock_3 : MDEV-10637 - Wrong processlist output
+tokudb_bugs.xa : MDEV-11804 - Lock wait timeout
tokudb_rpl.rpl_parallel_optimistic : Added in 10.1.20
tokudb_rpl.rpl_tokudb_rfr_partition_table : Added in 10.1.20
@@ -355,9 +391,7 @@ vcol.vcol_keys_innodb : MDEV-10639 - Testcase timeout
#----------------------------------------------------------------
wsrep.binlog_format : MDEV-11532 - WSREP has not yet prepared node
-wsrep.mdev_10186 : Modified in 10.1.19
#----------------------------------------------------------------
-wsrep_info.* : suite.pm modified in 10.1.19
wsrep_info.plugin : MDEV-11530 - Warnings; also modified in 10.1.20
diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp
index 20d4b124dd7..6bdbcab4530 100644
--- a/mysql-test/valgrind.supp
+++ b/mysql-test/valgrind.supp
@@ -950,6 +950,14 @@
fun:backtrace
}
+{
+ memory leak in mysqld_exit
+ Memcheck:Leak
+ fun:malloc
+ fun:_dl_close_worker
+ fun:_dl_close
+}
+
#
# Bug in Glibc 2.9: http://sourceware.org/bugzilla/show_bug.cgi?id=10391
# Fixed in latest Glibc, but suppressed here for running tests on hosts
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index 6c43c29a758..13ea8dd9f35 100644
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -50,7 +50,7 @@ IF (WIN32)
ENDIF()
IF(UNIX)
- SET (MYSYS_SOURCES ${MYSYS_SOURCES} my_addr_resolve.c)
+ SET (MYSYS_SOURCES ${MYSYS_SOURCES} my_addr_resolve.c my_setuser.c)
ENDIF()
IF(HAVE_ALARM)
diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c
index e533230106e..dc02d3896bd 100644
--- a/mysys/my_malloc.c
+++ b/mysys/my_malloc.c
@@ -48,7 +48,6 @@ static inline size_t malloc_size_and_flag(void *p, my_bool *is_thread_specific)
#define MALLOC_FIX_POINTER_FOR_FREE(p) (((char*) (p)) - MALLOC_PREFIX_SIZE)
#endif /* SAFEMALLOC */
-static MALLOC_SIZE_CB malloc_size_cb_func= NULL;
/**
Inform application that memory usage has changed
@@ -59,17 +58,19 @@ static MALLOC_SIZE_CB malloc_size_cb_func= NULL;
The type os size is long long, to be able to handle negative numbers to
decrement the memory usage
+
+ @return 0 - ok
+ 1 - failure, abort the allocation
*/
+static void dummy(long long size __attribute__((unused)),
+ my_bool is_thread_specific __attribute__((unused)))
+{}
-static void update_malloc_size(long long size, my_bool is_thread_specific)
-{
- if (malloc_size_cb_func)
- malloc_size_cb_func(size, is_thread_specific);
-}
+static MALLOC_SIZE_CB update_malloc_size= dummy;
void set_malloc_size_cb(MALLOC_SIZE_CB func)
{
- malloc_size_cb_func= func;
+ update_malloc_size= func ? func : dummy;
}
diff --git a/mysys/my_setuser.c b/mysys/my_setuser.c
new file mode 100644
index 00000000000..14ab04dd10f
--- /dev/null
+++ b/mysys/my_setuser.c
@@ -0,0 +1,82 @@
+#include <my_global.h>
+#include <m_string.h>
+#include <my_sys.h>
+#include <my_pthread.h>
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+
+struct passwd *my_check_user(const char *user, myf MyFlags)
+{
+ struct passwd *user_info;
+ uid_t user_id= geteuid();
+ DBUG_ENTER("my_check_user");
+
+ // Don't bother if we aren't superuser
+ if (user_id)
+ {
+ if (user)
+ {
+ /* Don't give a warning, if real user is same as given with --user */
+ user_info= getpwnam(user);
+ if (!user_info || user_id != user_info->pw_uid)
+ {
+ my_errno= EPERM;
+ if (MyFlags & MY_WME)
+ my_printf_error(my_errno, "One can only use the --user switch if "
+ "running as root", MYF(ME_JUST_WARNING|ME_NOREFRESH));
+ }
+ }
+ DBUG_RETURN(NULL);
+ }
+ if (!user)
+ {
+ if (MyFlags & MY_FAE)
+ {
+ my_errno= EINVAL;
+ my_printf_error(my_errno, "Please consult the Knowledge Base to find "
+ "out how to run mysqld as root!", MYF(ME_NOREFRESH));
+ }
+ DBUG_RETURN(NULL);
+ }
+ if (!strcmp(user,"root"))
+ DBUG_RETURN(NULL);
+
+ if (!(user_info= getpwnam(user)))
+ {
+ // Allow a numeric uid to be used
+ int err= 0;
+ user_id= my_strtoll10(user, NULL, &err);
+ if (err || !(user_info= getpwuid(user_id)))
+ {
+ my_errno= EINVAL;
+ my_printf_error(my_errno, "Can't change to run as user '%s'. Please "
+ "check that the user exists!", MYF(ME_NOREFRESH), user);
+ DBUG_RETURN(NULL);
+ }
+ }
+ DBUG_ASSERT(user_info);
+ DBUG_RETURN(user_info);
+}
+
+int my_set_user(const char *user, struct passwd *user_info, myf MyFlags)
+{
+ DBUG_ENTER("my_set_user");
+
+ DBUG_ASSERT(user_info != 0);
+#ifdef HAVE_INITGROUPS
+ initgroups(user, user_info->pw_gid);
+#endif
+ if (setgid(user_info->pw_gid) == -1 || setuid(user_info->pw_uid) == -1)
+ {
+ my_errno= errno;
+ if (MyFlags & MY_WME)
+ my_printf_error(errno, "Cannot change uid/gid (errno: %d)", MYF(ME_NOREFRESH),
+ errno);
+ DBUG_RETURN(my_errno);
+ }
+ DBUG_RETURN(0);
+}
diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c
index a06c0409cd6..95b9586a1c5 100644
--- a/plugin/server_audit/server_audit.c
+++ b/plugin/server_audit/server_audit.c
@@ -2843,6 +2843,7 @@ void __attribute__ ((constructor)) audit_plugin_so_init(void)
_mysql_plugin_declarations_[0].info= mysql_v4_descriptor;
use_event_data_for_disconnect= 1;
}
+ MYSQL_SYSVAR_NAME(loc_info).flags= PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC;
}
memset(locinfo_ini_value, 'O', sizeof(locinfo_ini_value)-1);
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index 3b48dad649c..f8f4859e627 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -35,11 +35,26 @@ force=0
in_rpm=0
ip_only=0
cross_bootstrap=0
+install_params=""
+auth_root_authentication_method=normal
+auth_root_socket_user='root'
usage()
{
cat <<EOF
Usage: $0 [OPTIONS]
+ --auth-root-authentication-method=normal|socket
+ Chooses the authentication method for the created initial
+ root user. The default is 'normal' to creates a root user
+ that can login without password, which can be insecure.
+ The alternative 'socket' allows only the system root user
+ to login as MariaDB root; this requires the unix socket
+ authentication plugin.
+ --auth-root-socket-user=user
+ Used with --auth-root-authentication-method=socket. It
+ specifies the name of the MariaDB root account, as well
+ as of the system account allowed to access it. Defaults
+ to 'root'.
--basedir=path The path to the MariaDB installation directory.
--builddir=path If using --srcdir with out-of-directory builds, you
will need to set this to the location of the build
@@ -60,6 +75,8 @@ Usage: $0 [OPTIONS]
--defaults-file=path Read only this configuration file.
--rpm For internal use. This option is used by RPM files
during the MariaDB installation process.
+ --skip-auth-anonymous-user
+ Do not install an unprivileged anonymous user.
--skip-name-resolve Use IP addresses rather than hostnames when creating
grant table entries. This option can be useful if
your DNS does not work.
@@ -142,6 +159,17 @@ parse_arguments()
#
# --windows is a deprecated alias
cross_bootstrap=1 ;;
+ --skip-auth-anonymous-user)
+ install_params="$install_params
+SET @skip_auth_anonymous=1;" ;;
+ --auth-root-authentication-method=normal)
+ auth_root_authentication_method=normal ;;
+ --auth-root-authentication-method=socket)
+ auth_root_authentication_method=socket ;;
+ --auth-root-authentication-method=*)
+ usage ;;
+ --auth-root-socket-user=*)
+ auth_root_socket_user="$(parse_arg "$arg")" ;;
*)
if test -n "$pick_args"
@@ -431,7 +459,17 @@ mysqld_install_cmd_line()
# Create the system and help tables by passing them to "mysqld --bootstrap"
s_echo "Installing MariaDB/MySQL system tables in '$ldata' ..."
-if { echo "use mysql;"; cat "$create_system_tables" "$create_system_tables2" "$fill_system_tables" "$fill_help_tables" "$maria_add_gis_sp"; } | eval "$filter_cmd_line" | mysqld_install_cmd_line > /dev/null
+case "$auth_root_authentication_method" in
+ normal)
+ install_params="$install_params
+SET @skip_auth_root_nopasswd=NULL;
+SET @auth_root_socket=NULL;" ;;
+ socket)
+ install_params="$install_params
+SET @skip_auth_root_nopasswd=1;
+SET @auth_root_socket='$auth_root_socket_user';" ;;
+esac
+if { echo "use mysql;$install_params"; cat "$create_system_tables" "$create_system_tables2" "$fill_system_tables" "$fill_help_tables" "$maria_add_gis_sp"; } | eval "$filter_cmd_line" | mysqld_install_cmd_line > /dev/null
then
s_echo "OK"
else
diff --git a/scripts/mysql_system_tables_data.sql b/scripts/mysql_system_tables_data.sql
index 075aafd5e3b..9556e7ba160 100644
--- a/scripts/mysql_system_tables_data.sql
+++ b/scripts/mysql_system_tables_data.sql
@@ -38,15 +38,24 @@ DROP TABLE tmp_db;
-- Fill "user" table with default users allowing root access
-- from local machine if "user" table didn't exist before
-CREATE TEMPORARY TABLE tmp_user LIKE user;
-INSERT INTO tmp_user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N', 'N','', 0);
-REPLACE INTO tmp_user SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0 FROM dual WHERE @current_hostname != 'localhost';
-REPLACE INTO tmp_user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0);
-REPLACE INTO tmp_user VALUES ('::1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N', '', 0);
-INSERT INTO tmp_user (host,user) VALUES ('localhost','');
-INSERT INTO tmp_user (host,user) SELECT @current_hostname,'' FROM dual WHERE @current_hostname != 'localhost';
-INSERT INTO user SELECT * FROM tmp_user WHERE @had_user_table=0;
-DROP TABLE tmp_user;
+CREATE TEMPORARY TABLE tmp_user_nopasswd LIKE user;
+CREATE TEMPORARY TABLE tmp_user_socket LIKE user;
+CREATE TEMPORARY TABLE tmp_user_anonymous LIKE user;
+-- Classic passwordless root account.
+INSERT INTO tmp_user_nopasswd VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N', 'N','', 0);
+REPLACE INTO tmp_user_nopasswd SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0 FROM dual WHERE @current_hostname != 'localhost';
+REPLACE INTO tmp_user_nopasswd VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0);
+REPLACE INTO tmp_user_nopasswd VALUES ('::1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N', '', 0);
+-- More secure root account using unix sucket auth.
+INSERT INTO tmp_user_socket VALUES ('localhost',IFNULL(@auth_root_socket, 'root'),'','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'unix_socket','','N', 'N','', 0);
+-- Anonymous user with no privileges.
+INSERT INTO tmp_user_anonymous (host,user) VALUES ('localhost','');
+INSERT INTO tmp_user_anonymous (host,user) SELECT @current_hostname,'' FROM dual WHERE @current_hostname != 'localhost';
+
+INSERT INTO user SELECT * FROM tmp_user_nopasswd WHERE @had_user_table=0 AND @skip_auth_root_nopasswd IS NULL;
+INSERT INTO user SELECT * FROM tmp_user_socket WHERE @had_user_table=0 AND @auth_root_socket IS NOT NULL;
+INSERT INTO user SELECT * FROM tmp_user_anonymous WHERE @had_user_table=0 AND @skip_auth_anonymous IS NULL;
+DROP TABLE tmp_user_nopasswd, tmp_user_socket, tmp_user_anonymous;
CREATE TEMPORARY TABLE tmp_proxies_priv LIKE proxies_priv;
INSERT INTO tmp_proxies_priv VALUES ('localhost', 'root', '', '', TRUE, '', now());
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
index 000271f7808..6fdd2138ee0 100644
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -132,6 +132,18 @@ my_which ()
return $ret # Success
}
+find_in_bin() {
+ if test -x "$MY_BASEDIR_VERSION/bin/$1"
+ then
+ echo "$MY_BASEDIR_VERSION/bin/$1"
+ elif test -x "@bindir@/$1"
+ then
+ echo "@bindir@/$1"
+ else
+ echo "$1"
+ fi
+}
+
log_generic () {
[ $dry_run -eq 1 ] && return
priority="$1"
@@ -141,7 +153,7 @@ log_generic () {
echo "$msg"
case $logging in
init) ;; # Just echo the message, don't save it anywhere
- file) echo "$msg" >> "$err_log" ;;
+ file) echo "$msg" | "$helper" "$user" log "$err_log" ;;
syslog) logger -t "$syslog_tag_mysqld_safe" -p "$priority" "$*" ;;
*)
echo "Internal program error (non-fatal):" \
@@ -161,7 +173,7 @@ log_notice () {
eval_log_error () {
local cmd="$1"
case $logging in
- file) cmd="$cmd >> "`shell_quote_string "$err_log"`" 2>&1" ;;
+ file) cmd="$cmd 2>&1 | "`shell_quote_string "$helper"`" $user log "`shell_quote_string "$err_log"` ;;
syslog)
# mysqld often prefixes its messages with a timestamp, which is
# redundant when logging to syslog (which adds its own timestamp)
@@ -282,7 +294,6 @@ parse_arguments() {
for arg do
val=`echo "$arg" | sed -e "s;--[^=]*=;;"`
case "$arg" in
- --crash[-_]script=*) CRASH_SCRIPT="$val" ;;
# these get passed explicitly to mysqld
--basedir=*) MY_BASEDIR_VERSION="$val" ;;
--datadir=*|--data=*) DATADIR="$val" ;;
@@ -311,6 +322,7 @@ parse_arguments() {
--core[-_]file[-_]size=*) core_file_size="$val" ;;
--ledir=*) ledir="$val" ;;
--malloc[-_]lib=*) set_malloc_lib "$val" ;;
+ --crash[-_]script=*) crash_script="$val" ;;
--mysqld=*) MYSQLD="$val" ;;
--mysqld[-_]version=*)
if test -n "$val"
@@ -498,15 +510,8 @@ set_malloc_lib() {
# First, try to find BASEDIR and ledir (where mysqld is)
#
-if echo '@pkgdatadir@' | grep '^@prefix@' > /dev/null
-then
- relpkgdata=`echo '@pkgdatadir@' | sed -e 's,^@prefix@,,' -e 's,^/,,' -e 's,^,./,'`
-else
- # pkgdatadir is not relative to prefix
- relpkgdata='@pkgdatadir@'
-fi
-
-MY_PWD=`pwd`
+MY_PWD=`dirname $0`
+MY_PWD=`cd "$MY_PWD"/.. && pwd`
# Check for the directories we would expect from a binary release install
if test -n "$MY_BASEDIR_VERSION" -a -d "$MY_BASEDIR_VERSION"
then
@@ -522,16 +527,16 @@ then
else
ledir="$MY_BASEDIR_VERSION/bin"
fi
-elif test -f "$relpkgdata"/english/errmsg.sys -a -x "$MY_PWD/bin/mysqld"
+elif test -x "$MY_PWD/bin/mysqld"
then
MY_BASEDIR_VERSION="$MY_PWD" # Where bin, share and data are
ledir="$MY_PWD/bin" # Where mysqld is
# Check for the directories we would expect from a source install
-elif test -f "$relpkgdata"/english/errmsg.sys -a -x "$MY_PWD/libexec/mysqld"
+elif test -x "$MY_PWD/libexec/mysqld"
then
MY_BASEDIR_VERSION="$MY_PWD" # Where libexec, share and var are
ledir="$MY_PWD/libexec" # Where mysqld is
-elif test -f "$relpkgdata"/english/errmsg.sys -a -x "$MY_PWD/sbin/mysqld"
+elif test -x "$MY_PWD/sbin/mysqld"
then
MY_BASEDIR_VERSION="$MY_PWD" # Where sbin, share and var are
ledir="$MY_PWD/sbin" # Where mysqld is
@@ -541,6 +546,8 @@ else
ledir='@libexecdir@'
fi
+helper=`find_in_bin mysqld_safe_helper`
+print_defaults=`find_in_bin my_print_defaults`
#
# Second, try to find the data directory
@@ -571,34 +578,15 @@ $MY_BASEDIR_VERSION/my.cnf"
fi
export MYSQL_HOME
-
-# Get first arguments from the my.cnf file, groups [mysqld] and [mysqld_safe]
-# and then merge with the command line arguments
-if test -x "$MY_BASEDIR_VERSION/bin/my_print_defaults"
-then
- print_defaults="$MY_BASEDIR_VERSION/bin/my_print_defaults"
-elif test -x `dirname $0`/my_print_defaults
-then
- print_defaults="`dirname $0`/my_print_defaults"
-elif test -x ./bin/my_print_defaults
-then
- print_defaults="./bin/my_print_defaults"
-elif test -x @bindir@/my_print_defaults
-then
- print_defaults="@bindir@/my_print_defaults"
-elif test -x @bindir@/mysql_print_defaults
-then
- print_defaults="@bindir@/mysql_print_defaults"
-else
- print_defaults="my_print_defaults"
-fi
-
append_arg_to_args () {
args="$args "`shell_quote_string "$1"`
}
args=
+# Get first arguments from the my.cnf file, groups [mysqld] and [mysqld_safe]
+# and then merge with the command line arguments
+
SET_USER=2
parse_arguments `$print_defaults $defaults --loose-verbose --mysqld`
if test $SET_USER -eq 2
@@ -707,11 +695,6 @@ then
log_notice "Logging to '$err_log'."
logging=file
- if [ ! -f "$err_log" ]; then # if error log already exists,
- touch "$err_log" # we just append. otherwise,
- chmod "$fmode" "$err_log" # fix the permissions here!
- fi
-
else
if [ -n "$syslog_tag" ]
then
@@ -731,11 +714,6 @@ then
then
USER_OPTION="--user=$user"
fi
- # Change the err log to the right user, if it is in use
- if [ $want_syslog -eq 0 ]; then
- touch "$err_log"
- chown $user "$err_log"
- fi
if test -n "$open_files"
then
ulimit -n $open_files
@@ -973,10 +951,6 @@ cmd="$cmd $args"
# Avoid 'nohup: ignoring input' warning
test -n "$NOHUP_NICENESS" && cmd="$cmd < /dev/null"
-# close stdout and stderr, everything goes to $logging now
-exec 1>&-
-exec 2>&-
-
log_notice "Starting $MYSQLD daemon with databases from $DATADIR"
# variable to track the current number of "fast" (a.k.a. subsecond) restarts
@@ -986,6 +960,15 @@ max_fast_restarts=5
# flag whether a usable sleep command exists
have_sleep=1
+# close stdout and stderr, everything goes to $logging now
+if expr "${-}" : '.*x' > /dev/null
+then
+ :
+else
+ exec 1>&-
+ exec 2>&-
+fi
+
# maximum number of wsrep restarts
max_wsrep_restarts=0
@@ -1014,13 +997,6 @@ do
else
eval_log_error "$cmd"
fi
-
- if [ $want_syslog -eq 0 -a ! -f "$err_log" ]; then
- touch "$err_log" # hypothetical: log was renamed but not
- chown $user "$err_log" # flushed yet. we'd recreate it with
- chmod "$fmode" "$err_log" # wrong owner next time we log, so set
- fi # it up correctly while we can!
-
end_time=`date +%M%S`
if test ! -f "$pid_file" # This is removed if normal shutdown
@@ -1098,9 +1074,9 @@ do
fi
log_notice "mysqld restarted"
- if test -n "$CRASH_SCRIPT"
+ if test -n "$crash_script"
then
- crash_script_output=`$CRASH_SCRIPT 2>&1`
+ crash_script_output=`$crash_script 2>&1`
log_error "$crash_script_output"
fi
done
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index c96060cd5df..ca4d93eb240 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -18,6 +18,7 @@
#include "sql_priv.h"
#include "unireg.h"
#include "sql_base.h" // close_thread_tables
+#include "sql_parse.h"
#include "event_db_repository.h"
#include "key.h" // key_copy
#include "sql_db.h" // get_default_db_collation
@@ -702,19 +703,17 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
restore_record(table, s->default_values); // Get default values for fields
- if (system_charset_info->cset->
- numchars(system_charset_info, parse_data->dbname.str,
- parse_data->dbname.str + parse_data->dbname.length) >
- table->field[ET_FIELD_DB]->char_length())
+ if (check_string_char_length(&parse_data->dbname, 0,
+ table->field[ET_FIELD_DB]->char_length(),
+ system_charset_info, 1))
{
my_error(ER_TOO_LONG_IDENT, MYF(0), parse_data->dbname.str);
goto end;
}
- if (system_charset_info->cset->
- numchars(system_charset_info, parse_data->name.str,
- parse_data->name.str + parse_data->name.length) >
- table->field[ET_FIELD_NAME]->char_length())
+ if (check_string_char_length(&parse_data->name, 0,
+ table->field[ET_FIELD_NAME]->char_length(),
+ system_charset_info, 1))
{
my_error(ER_TOO_LONG_IDENT, MYF(0), parse_data->name.str);
goto end;
diff --git a/sql/field.cc b/sql/field.cc
index ff8b948ef62..23a8ecd965d 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1371,12 +1371,15 @@ void Field_num::prepend_zeros(String *value) const
int diff;
if ((diff= (int) (field_length - value->length())) > 0)
{
- bmove_upp((uchar*) value->ptr()+field_length,
- (uchar*) value->ptr()+value->length(),
- value->length());
- bfill((uchar*) value->ptr(),diff,'0');
- value->length(field_length);
- (void) value->c_ptr_quick(); // Avoid warnings in purify
+ const bool error= value->realloc(field_length);
+ if (!error)
+ {
+ bmove_upp((uchar*) value->ptr()+field_length,
+ (uchar*) value->ptr()+value->length(),
+ value->length());
+ bfill((uchar*) value->ptr(),diff,'0');
+ value->length(field_length);
+ }
}
}
@@ -2309,9 +2312,10 @@ void Field::set_default()
{
if (default_value)
{
- table->in_use->reset_arena_for_cached_items(table->expr_arena);
+ Query_arena backup_arena;
+ table->in_use->set_n_backup_active_arena(table->expr_arena, &backup_arena);
(void) default_value->expr->save_in_field(this, 0);
- table->in_use->reset_arena_for_cached_items(0);
+ table->in_use->restore_active_arena(table->expr_arena, &backup_arena);
return;
}
/* Copy constant value stored in s->default_values */
@@ -10509,7 +10513,7 @@ Column_definition::Column_definition(THD *thd, Field *old_field,
if (length != 4)
{
char buff[sizeof("YEAR()") + MY_INT64_NUM_DECIMAL_DIGITS + 1];
- my_snprintf(buff, sizeof(buff), "YEAR(%lu)", length);
+ my_snprintf(buff, sizeof(buff), "YEAR(%llu)", length);
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_WARN_DEPRECATED_SYNTAX,
ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX),
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 6046693cba1..2283e6e3d0a 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -1672,7 +1672,7 @@ int merge_buffers(Sort_param *param, IO_CACHE *from_file,
if (!(error= (int) read_to_buffer(from_file, buffpek,
rec_length)))
{
- queue_remove(&queue,0);
+ (void) queue_remove_top(&queue);
reuse_freed_buff(&queue, buffpek, rec_length);
}
else if (error == -1)
diff --git a/sql/handler.cc b/sql/handler.cc
index f06c5d71a5e..9b1bf820f0c 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -4549,7 +4549,7 @@ void handler::get_dynamic_partition_info(PARTITION_STATS *stat_info,
stat_info->update_time= stats.update_time;
stat_info->check_time= stats.check_time;
stat_info->check_sum= 0;
- if (table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_OLD_CHECKSUM))
+ if (table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM))
stat_info->check_sum= checksum();
return;
}
diff --git a/sql/item.cc b/sql/item.cc
index 682f88317f1..7b657aeadc6 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -544,7 +544,14 @@ uint Item::decimal_precision() const
unsigned_flag);
return MY_MIN(prec, DECIMAL_MAX_PRECISION);
}
- return MY_MIN(max_char_length(), DECIMAL_MAX_PRECISION);
+ uint res= max_char_length();
+ /*
+ Return at least one decimal digit, even if Item::max_char_length()
+ returned 0. This is important to avoid attempts to create fields of types
+ INT(0) or DECIMAL(0,0) when converting NULL or empty strings to INT/DECIMAL:
+ CREATE TABLE t1 AS SELECT CONVERT(NULL,SIGNED) AS a;
+ */
+ return res ? MY_MIN(res, DECIMAL_MAX_PRECISION) : 1;
}
@@ -1182,7 +1189,8 @@ Item *Item_cache::safe_charset_converter(THD *thd, CHARSET_INFO *tocs)
if (conv == example)
return this;
Item_cache *cache;
- if (!conv || !(cache= new (thd->mem_root) Item_cache_str(thd, conv)))
+ if (!conv || conv->fix_fields(thd, (Item **) NULL) ||
+ !(cache= new (thd->mem_root) Item_cache_str(thd, conv)))
return NULL; // Safe conversion is not possible, or OEM
cache->setup(thd, conv);
cache->fixed= false; // Make Item::fix_fields() happy
@@ -2878,6 +2886,44 @@ void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref)
depended_from= NULL;
if (context)
{
+ bool need_change= false;
+ /*
+ Suppose there are nested selects:
+
+ select_id=1
+ select_id=2
+ select_id=3 <----+
+ select_id=4 -+
+ select_id=5 --+
+
+ Suppose, pullout operation has moved anything that had select_id=4 or 5
+ in to select_id=3.
+
+ If this Item_field had a name resolution context pointing into select_lex
+ with id=4 or id=5, it needs a new name resolution context.
+
+ However, it could also be that this object is a part of outer reference:
+ Item_ref(Item_field(field in select with select_id=1))).
+ - The Item_ref object has a context with select_id=5, and so needs a new
+ name resolution context.
+ - The Item_field object has a context with select_id=1, and doesn't need
+ a new name resolution context.
+
+ So, the following loop walks from Item_field's current context upwards.
+ If we find that the select we've been pulled out to is up there, we
+ create the new name resolution context. Otherwise, we don't.
+ */
+ for (Name_resolution_context *ct= context; ct; ct= ct->outer_context)
+ {
+ if (new_parent == ct->select_lex)
+ {
+ need_change= true;
+ break;
+ }
+ }
+ if (!need_change)
+ return;
+
Name_resolution_context *ctx= new Name_resolution_context();
if (context->select_lex == new_parent)
{
diff --git a/sql/item.h b/sql/item.h
index 1f3e0f02971..b6ece6dae69 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -3413,7 +3413,7 @@ class Item_blob :public Item_partition_func_safe_string
{
public:
Item_blob(THD *thd, const char *name_arg, uint length):
- Item_partition_func_safe_string(thd, name_arg, length, &my_charset_bin)
+ Item_partition_func_safe_string(thd, name_arg, strlen(name_arg), &my_charset_bin)
{ max_length= length; }
enum Type type() const { return TYPE_HOLDER; }
enum_field_types field_type() const { return MYSQL_TYPE_BLOB; }
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 2856cea0697..a3b9041aed4 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -610,7 +610,7 @@ int Arg_comparator::set_compare_func(Item_func_or_sum *item, Item_result type)
int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg,
Item **a1, Item **a2)
{
- thd= current_thd;
+ THD *thd= current_thd;
owner= owner_arg;
set_null= set_null && owner_arg;
a= a1;
@@ -742,12 +742,10 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
if (cache_arg && item->const_item() &&
!(item->type() == Item::CACHE_ITEM && item->cmp_type() == TIME_RESULT))
{
- Query_arena backup;
- Query_arena *save_arena= thd->switch_to_arena_for_cached_items(&backup);
- Item_cache_temporal *cache= new (thd->mem_root) Item_cache_temporal(thd, f_type);
- if (save_arena)
- thd->set_query_arena(save_arena);
+ if (!thd)
+ thd= current_thd;
+ Item_cache_temporal *cache= new (thd->mem_root) Item_cache_temporal(thd, f_type);
cache->store_packed(value, item);
*cache_arg= cache;
*item_arg= cache_arg;
@@ -782,12 +780,12 @@ int Arg_comparator::compare_temporal(enum_field_types type)
owner->null_value= 1;
/* Get DATE/DATETIME/TIME value of the 'a' item. */
- a_value= get_datetime_value(thd, &a, &a_cache, type, &a_is_null);
+ a_value= get_datetime_value(0, &a, &a_cache, type, &a_is_null);
if (a_is_null)
return -1;
/* Get DATE/DATETIME/TIME value of the 'b' item. */
- b_value= get_datetime_value(thd, &b, &b_cache, type, &b_is_null);
+ b_value= get_datetime_value(0, &b, &b_cache, type, &b_is_null);
if (b_is_null)
return -1;
@@ -805,10 +803,10 @@ int Arg_comparator::compare_e_temporal(enum_field_types type)
longlong a_value, b_value;
/* Get DATE/DATETIME/TIME value of the 'a' item. */
- a_value= get_datetime_value(thd, &a, &a_cache, type, &a_is_null);
+ a_value= get_datetime_value(0, &a, &a_cache, type, &a_is_null);
/* Get DATE/DATETIME/TIME value of the 'b' item. */
- b_value= get_datetime_value(thd, &b, &b_cache, type, &b_is_null);
+ b_value= get_datetime_value(0, &b, &b_cache, type, &b_is_null);
return a_is_null || b_is_null ? a_is_null == b_is_null
: a_value == b_value;
}
@@ -3742,7 +3740,7 @@ uchar *in_datetime::get_value(Item *item)
Item **tmp_item= lval_cache ? &lval_cache : &item;
enum_field_types f_type=
tmp_item[0]->field_type_for_temporal_comparison(warn_item);
- tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, f_type, &is_null);
+ tmp.val= get_datetime_value(0, &tmp_item, &lval_cache, f_type, &is_null);
if (item->null_value)
return 0;
tmp.unsigned_flag= 1L;
@@ -4007,7 +4005,7 @@ void cmp_item_datetime::store_value(Item *item)
Item **tmp_item= lval_cache ? &lval_cache : &item;
enum_field_types f_type=
tmp_item[0]->field_type_for_temporal_comparison(warn_item);
- value= get_datetime_value(thd, &tmp_item, &lval_cache, f_type, &is_null);
+ value= get_datetime_value(0, &tmp_item, &lval_cache, f_type, &is_null);
m_null_value= item->null_value;
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 7774663bd57..b1d25ba69fd 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -55,7 +55,6 @@ class Arg_comparator: public Sql_alloc
Arg_comparator *comparators; // used only for compare_row()
double precision;
/* Fields used in DATE/DATETIME comparison. */
- THD *thd;
Item *a_cache, *b_cache; // Cached values of a and b items
// when one of arguments is NULL.
int set_compare_func(Item_func_or_sum *owner, Item_result type);
@@ -70,12 +69,12 @@ public:
Arg_comparator(): m_compare_type(STRING_RESULT),
m_compare_collation(&my_charset_bin),
- set_null(TRUE), comparators(0), thd(0),
+ set_null(TRUE), comparators(0),
a_cache(0), b_cache(0) {};
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2),
m_compare_type(STRING_RESULT),
m_compare_collation(&my_charset_bin),
- set_null(TRUE), comparators(0), thd(0),
+ set_null(TRUE), comparators(0),
a_cache(0), b_cache(0) {};
public:
@@ -1268,14 +1267,13 @@ public:
class in_datetime :public in_longlong
{
public:
- THD *thd;
/* An item used to issue warnings. */
Item *warn_item;
/* Cache for the left item. */
Item *lval_cache;
in_datetime(THD *thd, Item *warn_item_arg, uint elements)
- :in_longlong(thd, elements), thd(current_thd), warn_item(warn_item_arg),
+ :in_longlong(thd, elements), warn_item(warn_item_arg),
lval_cache(0) {};
void set(uint pos,Item *item);
uchar *get_value(Item *item);
@@ -1445,14 +1443,13 @@ class cmp_item_datetime : public cmp_item_scalar
{
longlong value;
public:
- THD *thd;
/* Item used for issuing warnings. */
Item *warn_item;
/* Cache for the left item. */
Item *lval_cache;
cmp_item_datetime(Item *warn_item_arg)
- :thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
+ : warn_item(warn_item_arg), lval_cache(0) {}
void store_value(Item *item);
int cmp(Item *arg);
int compare(cmp_item *ci);
diff --git a/sql/item_func.cc b/sql/item_func.cc
index f6162b54806..2e0596da2d1 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2725,7 +2725,6 @@ void Item_func_min_max::fix_length_and_dec()
decimals=0;
max_length=0;
maybe_null=0;
- thd= current_thd;
Item_result tmp_cmp_type= args[0]->cmp_type();
uint string_type_count= 0;
uint temporal_type_count= 0;
@@ -2867,10 +2866,8 @@ bool Item_func_min_max::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
longlong res= args[i]->val_temporal_packed(Item_func_min_max::field_type());
/* Check if we need to stop (because of error or KILL) and stop the loop */
- if (thd->is_error() || args[i]->null_value)
- {
+ if (args[i]->null_value)
return (null_value= 1);
- }
if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0)
min_max= res;
diff --git a/sql/item_func.h b/sql/item_func.h
index d4314f7bd6a..08b1421cb1d 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -636,8 +636,15 @@ public:
}
void fix_length_and_dec()
{
- fix_char_length(MY_MIN(args[0]->max_char_length(),
- MY_INT64_NUM_DECIMAL_DIGITS));
+ uint32 char_length= MY_MIN(args[0]->max_char_length(),
+ MY_INT64_NUM_DECIMAL_DIGITS);
+ /*
+ args[0]->max_char_length() can return 0.
+ Reserve max_length to fit at least one character for one digit,
+ plus one character for the sign (if signed).
+ */
+ set_if_bigger(char_length, 1 + (unsigned_flag ? 0 : 1));
+ fix_char_length(char_length);
}
virtual void print(String *str, enum_query_type query_type);
uint decimal_precision() const { return args[0]->decimal_precision(); }
@@ -1156,7 +1163,6 @@ class Item_func_min_max :public Item_hybrid_func
{
String tmp_value;
int cmp_sign;
- THD *thd;
public:
Item_func_min_max(THD *thd, List<Item> &list, int cmp_sign_arg):
Item_hybrid_func(thd, list), cmp_sign(cmp_sign_arg)
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 89c663b5f16..94bc71ca889 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2002, 2015, Oracle and/or its affiliates.
- Copyright (c) 2010, 2015, MariaDB
+/* Copyright (c) 2002, 2016, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2016, MariaDB
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
@@ -3520,9 +3520,14 @@ bool subselect_union_engine::is_executed() const
bool subselect_union_engine::no_rows()
{
/* Check if we got any rows when reading UNION result from temp. table: */
- return MY_TEST(!(unit->fake_select_lex ?
- unit->fake_select_lex->join->send_records :
- ((select_union_direct *)(unit->get_union_result()))
+ if (unit->fake_select_lex)
+ {
+ JOIN *join= unit->fake_select_lex->join;
+ if (join)
+ return MY_TEST(!join->send_records);
+ return false;
+ }
+ return MY_TEST(!(((select_union_direct *)(unit->get_union_result()))
->send_records));
}
@@ -4897,9 +4902,9 @@ bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id)
result= result_sink;
/*
- If the subquery has blobs, or the total key lenght is bigger than
+ If the subquery has blobs, or the total key length is bigger than
some length, or the total number of key parts is more than the
- allowed maximum (currently MAX_REF_PARTS == 16), then the created
+ allowed maximum (currently MAX_REF_PARTS == 32), then the created
index cannot be used for lookups and we can't use hash semi
join. If this is the case, delete the temporary table since it
will not be used, and tell the caller we failed to initialize the
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 27ce83f3f2b..300ab0deb9e 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2012, Oracle and/or its affiliates.
- Copyright (c) 2009, 2016, MariaDB
+ Copyright (c) 2009, 2017, MariaDB
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
@@ -426,7 +426,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
{
if (!my_isspace(&my_charset_latin1,*val))
{
- make_truncated_value_warning(current_thd,
+ make_truncated_value_warning(current_thd,
Sql_condition::WARN_LEVEL_WARN,
val_begin, length,
cached_timestamp_type, NullS);
@@ -711,7 +711,7 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
{
longlong value;
const char *start= str;
- for (value=0; str != end && my_isdigit(cs, *str) ; str++)
+ for (value= 0; str != end && my_isdigit(cs, *str); str++)
value= value*10 + *str - '0';
msec_length= 6 - (str - start);
values[i]= value;
@@ -1464,8 +1464,9 @@ void Item_temporal_func::fix_length_and_dec()
/*
We set maybe_null to 1 as default as any bad argument with date or
time can get us to return NULL.
- */
+ */
maybe_null= (arg_count > 0);
+
if (decimals)
{
if (decimals == NOT_FIXED_DEC)
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 0af348ab453..e1a37a8bccf 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -7605,6 +7605,7 @@ Gtid_list_log_event::do_apply_event(rpl_group_info *rgi)
rli->abort_slave= true;
rli->stop_for_until= true;
}
+ free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC));
return ret;
}
diff --git a/sql/my_json_writer.cc b/sql/my_json_writer.cc
index d36fdd1192a..135ce353552 100644
--- a/sql/my_json_writer.cc
+++ b/sql/my_json_writer.cc
@@ -125,7 +125,7 @@ void Json_writer::start_element()
void Json_writer::add_ll(longlong val)
{
char buf[64];
- my_snprintf(buf, sizeof(buf), "%ld", val);
+ my_snprintf(buf, sizeof(buf), "%lld", val);
add_unquoted_str(buf);
}
@@ -135,16 +135,16 @@ void Json_writer::add_size(longlong val)
{
char buf[64];
if (val < 1024)
- my_snprintf(buf, sizeof(buf), "%ld", val);
+ my_snprintf(buf, sizeof(buf), "%lld", val);
else if (val < 1024*1024*16)
{
/* Values less than 16MB are specified in KB for precision */
- size_t len= my_snprintf(buf, sizeof(buf), "%ld", val/1024);
+ size_t len= my_snprintf(buf, sizeof(buf), "%lld", val/1024);
strcpy(buf + len, "Kb");
}
else
{
- size_t len= my_snprintf(buf, sizeof(buf), "%ld", val/(1024*1024));
+ size_t len= my_snprintf(buf, sizeof(buf), "%lld", val/(1024*1024));
strcpy(buf + len, "Mb");
}
add_str(buf);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 4b79ea43c7c..d30fa3e25c7 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2008, 2016, MariaDB
+ Copyright (c) 2008, 2017, MariaDB
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
@@ -130,10 +130,7 @@ extern "C" { // Because of SCO 3.2V4.2
#include <sysent.h>
#endif
#ifdef HAVE_PWD_H
-#include <pwd.h> // For getpwent
-#endif
-#ifdef HAVE_GRP_H
-#include <grp.h>
+#include <pwd.h> // For struct passwd
#endif
#include <my_net.h>
@@ -485,9 +482,7 @@ ulong opt_binlog_rows_event_max_size;
my_bool opt_master_verify_checksum= 0;
my_bool opt_slave_sql_verify_checksum= 1;
const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
-#ifdef HAVE_INITGROUPS
volatile sig_atomic_t calling_initgroups= 0; /**< Used in SIGSEGV handler. */
-#endif
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
uint mysqld_extra_port;
uint mysqld_port_timeout;
@@ -2421,59 +2416,18 @@ static void set_ports()
static struct passwd *check_user(const char *user)
{
-#if !defined(__WIN__)
- struct passwd *tmp_user_info;
- uid_t user_id= geteuid();
+ myf flags= 0;
+ if (global_system_variables.log_warnings)
+ flags|= MY_WME;
+ if (!opt_bootstrap && !opt_help)
+ flags|= MY_FAE;
- // Don't bother if we aren't superuser
- if (user_id)
- {
- if (user)
- {
- /* Don't give a warning, if real user is same as given with --user */
- /* purecov: begin tested */
- tmp_user_info= getpwnam(user);
- if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
- global_system_variables.log_warnings)
- sql_print_warning(
- "One can only use the --user switch if running as root\n");
- /* purecov: end */
- }
- return NULL;
- }
- if (!user)
- {
- if (!opt_bootstrap && !opt_help)
- {
- sql_print_error("Fatal error: Please consult the Knowledge Base "
- "to find out how to run mysqld as root!\n");
- unireg_abort(1);
- }
- return NULL;
- }
- /* purecov: begin tested */
- if (!strcmp(user,"root"))
- return NULL; // Avoid problem with dynamic libraries
+ struct passwd *tmp_user_info= my_check_user(user, MYF(flags));
- if (!(tmp_user_info= getpwnam(user)))
- {
- // Allow a numeric uid to be used
- const char *pos;
- for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ;
- if (*pos) // Not numeric id
- goto err;
- if (!(tmp_user_info= getpwuid(atoi(user))))
- goto err;
- }
+ if (!tmp_user_info && my_errno==EINVAL && (flags & MY_FAE))
+ unireg_abort(1);
return tmp_user_info;
- /* purecov: end */
-
-err:
- sql_print_error("Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user);
- unireg_abort(1);
-#endif
- return NULL;
}
static inline void allow_coredumps()
@@ -2490,10 +2444,6 @@ static inline void allow_coredumps()
static void set_user(const char *user, struct passwd *user_info_arg)
{
- /* purecov: begin tested */
-#if !defined(__WIN__)
- DBUG_ASSERT(user_info_arg != 0);
-#ifdef HAVE_INITGROUPS
/*
We can get a SIGSEGV when calling initgroups() on some systems when NSS
is configured to use LDAP and the server is statically linked. We set
@@ -2501,22 +2451,11 @@ static void set_user(const char *user, struct passwd *user_info_arg)
output a specific message to help the user resolve this problem.
*/
calling_initgroups= 1;
- initgroups((char*) user, user_info_arg->pw_gid);
+ int res= my_set_user(user, user_info_arg, MYF(MY_WME));
calling_initgroups= 0;
-#endif
- if (setgid(user_info_arg->pw_gid) == -1)
- {
- sql_perror("setgid");
+ if (res)
unireg_abort(1);
- }
- if (setuid(user_info_arg->pw_uid) == -1)
- {
- sql_perror("setuid");
- unireg_abort(1);
- }
allow_coredumps();
-#endif
- /* purecov: end */
}
@@ -4087,8 +4026,8 @@ extern "C" {
static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific)
{
THD *thd= current_thd;
-
- if (likely(is_thread_specific)) /* If thread specific memory */
+
+ if (is_thread_specific) /* If thread specific memory */
{
/*
When thread specfic is set, both mysqld_server_initialized and thd
@@ -4100,14 +4039,22 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific)
(longlong) thd->status_var.local_memory_used,
size));
thd->status_var.local_memory_used+= size;
+ if (thd->status_var.local_memory_used > (int64)thd->variables.max_mem_used &&
+ !thd->killed)
+ {
+ char buf[1024];
+ thd->killed= KILL_QUERY;
+ my_snprintf(buf, sizeof(buf), "--max-thread-mem-used=%llu",
+ thd->variables.max_mem_used);
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), buf);
+ }
DBUG_ASSERT((longlong) thd->status_var.local_memory_used >= 0 ||
!debug_assert_on_not_freed_memory);
}
else if (likely(thd))
{
DBUG_PRINT("info", ("global thd memory_used: %lld size: %lld",
- (longlong) thd->status_var.global_memory_used,
- size));
+ (longlong) thd->status_var.global_memory_used, size));
thd->status_var.global_memory_used+= size;
}
else
@@ -4580,19 +4527,24 @@ static int init_common_variables()
default_charset_info= default_collation;
}
/* Set collactions that depends on the default collation */
- global_system_variables.collation_server= default_charset_info;
- global_system_variables.collation_database= default_charset_info;
- global_system_variables.collation_connection= default_charset_info;
- global_system_variables.character_set_results= default_charset_info;
- if (default_charset_info->mbminlen > 1)
- {
- global_system_variables.character_set_client= &my_charset_latin1;
- sql_print_warning("Cannot use %s as character_set_client, %s will be used instead",
- default_charset_info->csname,
- global_system_variables.character_set_client->csname);
+ global_system_variables.collation_server= default_charset_info;
+ global_system_variables.collation_database= default_charset_info;
+ if (is_supported_parser_charset(default_charset_info))
+ {
+ global_system_variables.collation_connection= default_charset_info;
+ global_system_variables.character_set_results= default_charset_info;
+ global_system_variables.character_set_client= default_charset_info;
}
else
- global_system_variables.character_set_client= default_charset_info;
+ {
+ sql_print_warning("'%s' can not be used as client character set. "
+ "'%s' will be used as default client character set.",
+ default_charset_info->csname,
+ my_charset_latin1.csname);
+ global_system_variables.collation_connection= &my_charset_latin1;
+ global_system_variables.character_set_results= &my_charset_latin1;
+ global_system_variables.character_set_client= &my_charset_latin1;
+ }
if (!(character_set_filesystem=
get_charset_by_csname(character_set_filesystem_name,
diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc
index ad7fb873c68..dc90fcae576 100644
--- a/sql/signal_handler.cc
+++ b/sql/signal_handler.cc
@@ -156,7 +156,7 @@ extern "C" sig_handler handle_fatal_signal(int sig)
if (opt_stack_trace)
{
- my_safe_printf_stderr("Thread pointer: 0x%p\n", thd);
+ my_safe_printf_stderr("Thread pointer: %p\n", thd);
my_safe_printf_stderr("%s",
"Attempting backtrace. You can use the following "
"information to find out\n"
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 0b9b503aef3..251b829fb1d 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -523,12 +523,8 @@ check_routine_name(LEX_STRING *ident)
my_error(ER_SP_WRONG_NAME, MYF(0), ident->str);
return TRUE;
}
- if (check_string_char_length(ident, 0, NAME_CHAR_LEN,
- system_charset_info, 1))
- {
- my_error(ER_TOO_LONG_IDENT, MYF(0), ident->str);
+ if (check_ident_length(ident))
return TRUE;
- }
return FALSE;
}
@@ -3152,23 +3148,23 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
thd->query_length()) <= 0)
{
res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
+ bool log_slow= !res && thd->enable_slow_log;
- if (thd->get_stmt_da()->is_eof())
- {
- /* Finalize server status flags after executing a statement. */
+ /* Finalize server status flags after executing a statement. */
+ if (log_slow || thd->get_stmt_da()->is_eof())
thd->update_server_status();
+ if (thd->get_stmt_da()->is_eof())
thd->protocol->end_statement();
- }
query_cache_end_of_result(thd);
mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_STATUS,
- thd->get_stmt_da()->is_error() ?
- thd->get_stmt_da()->sql_errno() : 0,
- command_name[COM_QUERY].str);
+ thd->get_stmt_da()->is_error() ?
+ thd->get_stmt_da()->sql_errno() : 0,
+ command_name[COM_QUERY].str);
- if (!res && unlikely(thd->enable_slow_log))
+ if (log_slow)
log_slow_statement(thd);
}
else
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 4a3c9ae75e7..ada5ab1cd28 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -892,7 +892,7 @@ static my_bool do_validate(THD *, plugin_ref plugin, void *arg)
}
-static bool validate_password(LEX_USER *user)
+static bool validate_password(LEX_USER *user, THD *thd)
{
if (user->pwtext.length || !user->pwhash.length)
{
@@ -908,7 +908,8 @@ static bool validate_password(LEX_USER *user)
}
else
{
- if (strict_password_validation && has_validation_plugins())
+ if (!thd->slave_thread &&
+ strict_password_validation && has_validation_plugins())
{
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--strict-password-validation");
return true;
@@ -2748,7 +2749,7 @@ bool check_change_password(THD *thd, LEX_USER *user)
LEX_USER *real_user= get_current_user(thd, user);
if (fix_and_copy_user(real_user, user, thd) ||
- validate_password(real_user))
+ validate_password(real_user, thd))
return true;
*user= *real_user;
@@ -3463,7 +3464,7 @@ static int replace_user_table(THD *thd, TABLE *table, LEX_USER &combo,
}
if (!old_row_exists || combo.pwtext.length || combo.pwhash.length)
- if (!handle_as_role && validate_password(&combo))
+ if (!handle_as_role && validate_password(&combo, thd))
goto end;
/* Update table columns with new privileges */
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index ac4b8a45107..ff16e46a631 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2016, MariaDB
+ Copyright (c) 2010, 2017, MariaDB Corporation.
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
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 5c7cfdce657..f63ba4ed657 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2008, 2016, MariaDB
+ Copyright (c) 2008, 2017, MariaDB Corporation.
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
@@ -742,8 +742,8 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
#endif
{
ulong tmp;
+ bzero(&variables, sizeof(variables));
- mdl_context.init(this);
/*
We set THR_THD to temporally point to this THD to register all the
variables that allocates memory for this THD
@@ -753,8 +753,11 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
status_var.local_memory_used= sizeof(THD);
status_var.global_memory_used= 0;
variables.pseudo_thread_id= thread_id;
+ variables.max_mem_used= global_system_variables.max_mem_used;
main_da.init();
+ mdl_context.init(this);
+
/*
Pass nominal parameters to init_alloc_root only to ensure that
the destructor works OK in case of an error. The main_mem_root
@@ -800,7 +803,6 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
connection_name.str= 0;
connection_name.length= 0;
- bzero(&variables, sizeof(variables));
file_id = 0;
query_id= 0;
query_name_consts= 0;
@@ -916,7 +918,6 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
m_internal_handler= NULL;
m_binlog_invoker= INVOKER_NONE;
- arena_for_cached_items= 0;
memset(&invoker_user, 0, sizeof(invoker_user));
memset(&invoker_host, 0, sizeof(invoker_host));
prepare_derived_at_open= FALSE;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 3a7454e0a89..f68d75ef935 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -546,6 +546,7 @@ typedef struct system_variables
ulonglong sortbuff_size;
ulonglong group_concat_max_len;
ulonglong default_regex_flags;
+ ulonglong max_mem_used;
/**
Place holders to store Multi-source variables in sys_var.cc during
@@ -3991,27 +3992,7 @@ public:
}
}
-private:
- /*
- This reference points to the table arena when the expression
- for a virtual column is being evaluated
- */
- Query_arena *arena_for_cached_items;
-
public:
- void reset_arena_for_cached_items(Query_arena *new_arena)
- {
- arena_for_cached_items= new_arena;
- }
- Query_arena *switch_to_arena_for_cached_items(Query_arena *backup)
- {
- if (!arena_for_cached_items)
- return 0;
- set_n_backup_active_arena(arena_for_cached_items, backup);
- return backup;
- }
-
-
void clear_wakeup_ready() { wakeup_ready= false; }
/*
Sleep waiting for others to wake us up with signal_wakeup_ready().
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index fe6a101f999..e277a81624e 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2007, 2013, Oracle and/or its affiliates.
- Copyright (c) 2008, 2014, SkySQL Ab.
+ Copyright (c) 2008, 2017, MariaDB Corporation.
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
@@ -789,6 +789,7 @@ void update_global_user_stats(THD *thd, bool create_user, time_t now)
bool thd_init_client_charset(THD *thd, uint cs_number)
{
+ SV *gv=&global_system_variables;
CHARSET_INFO *cs;
/*
Use server character set and collation if
@@ -799,9 +800,10 @@ bool thd_init_client_charset(THD *thd, uint cs_number)
if (!opt_character_set_client_handshake ||
!(cs= get_charset(cs_number, MYF(0))))
{
- thd->update_charset(global_system_variables.character_set_client,
- global_system_variables.collation_connection,
- global_system_variables.character_set_results);
+ DBUG_ASSERT(is_supported_parser_charset(gv->character_set_client));
+ thd->update_charset(gv->character_set_client,
+ gv->collation_connection,
+ gv->character_set_results);
}
else
{
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 2f4c2d9a6f8..07066c4c504 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2010, Oracle and/or its affiliates.
- Copyright (c) 2010, 2015, MariaDB
+ Copyright (c) 2010, 2017, MariaDB Corporation.
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
@@ -1346,4 +1346,3 @@ bool multi_delete::send_eof()
}
return 0;
}
-
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index b9c1dcebee9..b9cc836e164 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2016, MariaDB
+ Copyright (c) 2010, 2017, MariaDB Corporation.
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
@@ -309,6 +309,32 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(0);
}
+static bool has_no_default_value(THD *thd, Field *field, TABLE_LIST *table_list)
+{
+ if ((field->flags & NO_DEFAULT_VALUE_FLAG) && field->real_type() != MYSQL_TYPE_ENUM)
+ {
+ bool view= false;
+ if (table_list)
+ {
+ table_list= table_list->top_table();
+ view= table_list->view != NULL;
+ }
+ if (view)
+ {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NO_DEFAULT_FOR_VIEW_FIELD,
+ ER_THD(thd, ER_NO_DEFAULT_FOR_VIEW_FIELD),
+ table_list->view_db.str, table_list->view_name.str);
+ }
+ else
+ {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NO_DEFAULT_FOR_FIELD,
+ ER_THD(thd, ER_NO_DEFAULT_FOR_FIELD), field->field_name);
+ }
+ return true;
+ }
+ return false;
+}
+
/**
Check if update fields are correct.
@@ -744,13 +770,10 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
DBUG_ASSERT(bulk_iterations > 0);
if (mysql_prepare_insert(thd, table_list, table, fields, values,
update_fields, update_values, duplic, &unused_conds,
- FALSE,
- (fields.elements || !value_count ||
- table_list->view != 0),
- !ignore && thd->is_strict_mode()))
+ FALSE))
goto abort;
- /* mysql_prepare_insert set table_list->table if it was not set */
+ /* mysql_prepare_insert sets table_list->table if it was not set */
table= table_list->table;
context= &thd->lex->select_lex.context;
@@ -879,6 +902,15 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
table->prepare_triggers_for_insert_stmt_or_event();
table->mark_columns_needed_for_insert();
+ if (fields.elements || !value_count || table_list->view != 0)
+ {
+ if (check_that_all_fields_are_given_values(thd, table, table_list))
+ {
+ error= 1;
+ goto values_loop_end;
+ }
+ }
+
if (table_list->prepare_where(thd, 0, TRUE) ||
table_list->prepare_check_option(thd))
error= 1;
@@ -973,6 +1005,23 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
}
}
+ /*
+ with triggers a field can get a value *conditionally*, so we have to repeat
+ has_no_default_value() check for every row
+ */
+ if (table->triggers &&
+ table->triggers->has_triggers(TRG_EVENT_INSERT, TRG_ACTION_BEFORE))
+ {
+ for (Field **f=table->field ; *f ; f++)
+ {
+ if (!(*f)->has_explicit_value() && has_no_default_value(thd, *f, table_list))
+ {
+ error= 1;
+ goto values_loop_end;
+ }
+ }
+ }
+
if ((res= table_list->view_check_option(thd,
(values_list.elements == 1 ?
0 :
@@ -1384,10 +1433,6 @@ static void prepare_for_positional_update(TABLE *table, TABLE_LIST *tables)
be taken from table_list->table)
where Where clause (for insert ... select)
select_insert TRUE if INSERT ... SELECT statement
- check_fields TRUE if need to check that all INSERT fields are
- given values.
- abort_on_warning whether to report if some INSERT field is not
- assigned as an error (TRUE) or as a warning (FALSE).
TODO (in far future)
In cases of:
@@ -1407,9 +1452,8 @@ static void prepare_for_positional_update(TABLE *table, TABLE_LIST *tables)
bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
TABLE *table, List<Item> &fields, List_item *values,
List<Item> &update_fields, List<Item> &update_values,
- enum_duplicates duplic,
- COND **where, bool select_insert,
- bool check_fields, bool abort_on_warning)
+ enum_duplicates duplic, COND **where,
+ bool select_insert)
{
SELECT_LEX *select_lex= &thd->lex->select_lex;
Name_resolution_context *context= &select_lex->context;
@@ -1481,17 +1525,6 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
check_insert_fields(thd, context->table_list, fields, *values,
!insert_into_view, 0, &map));
- if (!res && check_fields)
- {
- bool saved_abort_on_warning= thd->abort_on_warning;
- thd->abort_on_warning= abort_on_warning;
- res= check_that_all_fields_are_given_values(thd,
- table ? table :
- context->table_list->table,
- context->table_list);
- thd->abort_on_warning= saved_abort_on_warning;
- }
-
if (!res)
res= setup_fields(thd, Ref_ptr_array(),
update_values, MARK_COLUMNS_READ, 0, 0);
@@ -1927,8 +1960,8 @@ before_trg_err:
Check that all fields with arn't null_fields are used
******************************************************************************/
-int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
- TABLE_LIST *table_list)
+
+int check_that_all_fields_are_given_values(THD *thd, TABLE *entry, TABLE_LIST *table_list)
{
int err= 0;
MY_BITMAP *write_set= entry->write_set;
@@ -1936,32 +1969,8 @@ int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
for (Field **field=entry->field ; *field ; field++)
{
if (!bitmap_is_set(write_set, (*field)->field_index) &&
- ((*field)->flags & NO_DEFAULT_VALUE_FLAG) &&
- ((*field)->real_type() != MYSQL_TYPE_ENUM))
- {
- bool view= FALSE;
- if (table_list)
- {
- table_list= table_list->top_table();
- view= MY_TEST(table_list->view);
- }
- if (view)
- {
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_NO_DEFAULT_FOR_VIEW_FIELD,
- ER_THD(thd, ER_NO_DEFAULT_FOR_VIEW_FIELD),
- table_list->view_db.str,
- table_list->view_name.str);
- }
- else
- {
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_NO_DEFAULT_FOR_FIELD,
- ER_THD(thd, ER_NO_DEFAULT_FOR_FIELD),
- (*field)->field_name);
- }
- err= 1;
- }
+ has_no_default_value(thd, *field, table_list))
+ err=1;
}
return thd->abort_on_warning ? err : 0;
}
@@ -3430,9 +3439,8 @@ bool mysql_insert_select_prepare(THD *thd)
if (mysql_prepare_insert(thd, lex->query_tables,
lex->query_tables->table, lex->field_list, 0,
- lex->update_list, lex->value_list,
- lex->duplicates,
- &select_lex->where, TRUE, FALSE, FALSE))
+ lex->update_list, lex->value_list, lex->duplicates,
+ &select_lex->where, TRUE))
DBUG_RETURN(TRUE);
DBUG_ASSERT(select_lex->leaf_tables.elements != 0);
@@ -3519,8 +3527,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
{
bool saved_abort_on_warning= thd->abort_on_warning;
thd->abort_on_warning= !info.ignore && thd->is_strict_mode();
- res= check_that_all_fields_are_given_values(thd, table_list->table,
- table_list);
+ res= check_that_all_fields_are_given_values(thd, table_list->table, table_list);
thd->abort_on_warning= saved_abort_on_warning;
}
diff --git a/sql/sql_insert.h b/sql/sql_insert.h
index cbfc1ea9dcd..aea0dac6b0d 100644
--- a/sql/sql_insert.h
+++ b/sql/sql_insert.h
@@ -27,8 +27,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
List<Item> &fields, List_item *values,
List<Item> &update_fields,
List<Item> &update_values, enum_duplicates duplic,
- COND **where, bool select_insert,
- bool check_fields, bool abort_on_warning);
+ COND **where, bool select_insert);
bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
List<List_item> &values, List<Item> &update_fields,
List<Item> &update_values, enum_duplicates flag,
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index c028d49d620..491ed37e63a 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -4590,6 +4590,12 @@ bool st_select_lex::is_merged_child_of(st_select_lex *ancestor)
{
continue;
}
+
+ if (sl->master_unit()->derived &&
+ sl->master_unit()->derived->is_merged_derived())
+ {
+ continue;
+ }
all_merged= FALSE;
break;
}
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 6f0e97a61c9..138f5de11e9 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2016, MariaDB
+ Copyright (c) 2010, 2017, MariaDB Corporation.
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
@@ -1463,7 +1463,7 @@ READ_INFO::READ_INFO(THD *thd, File file_par, uint tot_length, CHARSET_INFO *cs,
stack= stack_pos= (int*) thd->alloc(sizeof(int) * length);
if (data.reserve(tot_length))
- error=1; /* purecov: inspected */
+ error= 1; /* purecov: inspected */
else
{
if (init_io_cache(&cache,(get_it_from_net) ? -1 : file, 0,
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 53482454491..11faaaef129 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5964,11 +5964,8 @@ end_with_restore_list:
}
case SQLCOM_SHOW_CREATE_TRIGGER:
{
- if (lex->spname->m_name.length > NAME_LEN)
- {
- my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str);
+ if (check_ident_length(&lex->spname->m_name))
goto error;
- }
#ifdef WITH_WSREP
if (WSREP_CLIENT(thd) && wsrep_sync_wait(thd)) goto error;
@@ -9668,6 +9665,18 @@ bool check_string_char_length(LEX_STRING *str, uint err_msg,
return TRUE;
}
+
+bool check_ident_length(LEX_STRING *ident)
+{
+ if (check_string_char_length(ident, 0, NAME_CHAR_LEN, system_charset_info, 1))
+ {
+ my_error(ER_TOO_LONG_IDENT, MYF(0), ident->str);
+ return 1;
+ }
+ return 0;
+}
+
+
C_MODE_START
/*
diff --git a/sql/sql_parse.h b/sql/sql_parse.h
index ad29bb2cdd3..d669f36acef 100644
--- a/sql/sql_parse.h
+++ b/sql/sql_parse.h
@@ -77,6 +77,7 @@ bool check_string_byte_length(LEX_STRING *str, uint err_msg,
bool check_string_char_length(LEX_STRING *str, uint err_msg,
uint max_char_length, CHARSET_INFO *cs,
bool no_error);
+bool check_ident_length(LEX_STRING *ident);
CHARSET_INFO* merge_charset_and_collation(CHARSET_INFO *cs, CHARSET_INFO *cl);
CHARSET_INFO *find_bin_collation(CHARSET_INFO *cs);
bool check_host_name(LEX_STRING *str);
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index d7a23a41002..853079dd36a 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1358,7 +1358,7 @@ static bool mysql_test_insert(Prepared_statement *stmt,
if (mysql_prepare_insert(thd, table_list, table_list->table,
fields, values, update_fields, update_values,
- duplic, &unused_conds, FALSE, FALSE, FALSE))
+ duplic, &unused_conds, FALSE))
goto error;
value_count= values->elements;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 2889e1e1549..899cd05f712 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016 Oracle and/or its affiliates.
- Copyright (c) 2009, 2016 MariaDB
+ Copyright (c) 2009, 2017 MariaDB Corporation.
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
@@ -788,10 +788,15 @@ JOIN::prepare(TABLE_LIST *tables_init,
if (mixed_implicit_grouping && tbl->table)
tbl->table->maybe_null= 1;
}
+
+ uint real_og_num= og_num;
+ if (skip_order_by &&
+ select_lex != select_lex->master_unit()->global_parameters())
+ real_og_num+= select_lex->order_list.elements;
if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num))
DBUG_RETURN(-1);
- if (select_lex->setup_ref_array(thd, og_num))
+ if (select_lex->setup_ref_array(thd, real_og_num))
DBUG_RETURN(-1);
ref_ptrs= ref_ptr_array_slice(0);
@@ -13010,9 +13015,12 @@ COND *Item_cond_and::build_equal_items(THD *thd,
COND_EQUAL cond_equal;
cond_equal.upper_levels= inherited;
+ if (check_stack_overrun(thd, STACK_MIN_SIZE, NULL))
+ return this; // Fatal error flag is set!
+
List<Item> eq_list;
List<Item> *cond_args= argument_list();
-
+
List_iterator<Item> li(*cond_args);
Item *item;
@@ -13022,7 +13030,7 @@ COND *Item_cond_and::build_equal_items(THD *thd,
that are subject to substitution by multiple equality items and
removing each such predicate from the conjunction after having
found/created a multiple equality whose inference the predicate is.
- */
+ */
while ((item= li++))
{
/*
@@ -17826,7 +17834,7 @@ do_select(JOIN *join, Procedure *procedure)
}
join->procedure= procedure;
- join->send_records=0;
+ join->duplicate_rows= join->send_records= 0;
if (join->only_const_tables() && !join->need_tmp)
{
Next_select_func end_select= setup_end_select_func(join, NULL);
@@ -17889,7 +17897,7 @@ do_select(JOIN *join, Procedure *procedure)
error= join->first_select(join,join_tab,1);
}
- join->thd->limit_found_rows= join->send_records;
+ join->thd->limit_found_rows= join->send_records - join->duplicate_rows;
if (error == NESTED_LOOP_NO_MORE_ROWS || join->thd->killed == ABORT_QUERY)
error= NESTED_LOOP_OK;
@@ -19503,10 +19511,14 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
}
if (join->do_send_rows)
{
- int error;
/* result < 0 if row was not accepted and should not be counted */
- if ((error= join->result->send_data(*fields)))
- DBUG_RETURN(error < 0 ? NESTED_LOOP_OK : NESTED_LOOP_ERROR);
+ if (int error= join->result->send_data(*fields))
+ {
+ if (error > 0)
+ DBUG_RETURN(NESTED_LOOP_ERROR);
+ // error < 0 => duplicate row
+ join->duplicate_rows++;
+ }
}
++join->send_records;
@@ -19652,7 +19664,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (error < 0)
{
/* Duplicate row, don't count */
- join->send_records--;
+ join->duplicate_rows++;
error= 0;
}
}
diff --git a/sql/sql_select.h b/sql/sql_select.h
index f3b59e5d20c..d043e3559f7 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1149,6 +1149,10 @@ public:
(if sql_calc_found_rows is used, LIMIT is ignored)
*/
ha_rows select_limit;
+ /*
+ Number of duplicate rows found in UNION.
+ */
+ ha_rows duplicate_rows;
/**
Used to fetch no more than given amount of rows per one
fetch operation of server side cursor.
@@ -1420,7 +1424,7 @@ public:
sort_and_group= 0;
first_record= 0;
do_send_rows= 1;
- send_records= 0;
+ duplicate_rows= send_records= 0;
found_records= 0;
fetch_limit= HA_POS_ERROR;
thd= thd_arg;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 2df3f4ef34a..eb66bc85549 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2016, MariaDB
+ Copyright (c) 2010, 2017, MariaDB Corporation.
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
@@ -3475,7 +3475,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
sql_field->pack_length= dup_field->pack_length;
sql_field->key_length= dup_field->key_length;
sql_field->decimals= dup_field->decimals;
- sql_field->create_length_to_internal_length();
sql_field->unireg_check= dup_field->unireg_check;
/*
We're making one field from two, the result field will have
@@ -3485,6 +3484,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (!(sql_field->flags & NOT_NULL_FLAG))
null_fields--;
sql_field->flags= dup_field->flags;
+ sql_field->create_length_to_internal_length();
sql_field->interval= dup_field->interval;
sql_field->vcol_info= dup_field->vcol_info;
it2.remove(); // Remove first (create) definition
@@ -3610,12 +3610,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
DBUG_RETURN(TRUE);
}
- if (check_string_char_length(&key->name, 0, NAME_CHAR_LEN,
- system_charset_info, 1))
- {
- my_error(ER_TOO_LONG_IDENT, MYF(0), key->name.str);
+ if (check_ident_length(&key->name))
DBUG_RETURN(TRUE);
- }
key_iterator2.rewind ();
if (key->type != Key::FOREIGN_KEY)
{
@@ -4130,7 +4126,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
}
if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
- !sql_field->default_value &&
+ !sql_field->default_value && !sql_field->vcol_info &&
is_timestamp_type(sql_field->sql_type) &&
(sql_field->flags & NOT_NULL_FLAG) &&
(type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index bd02289b135..f2ad2b3dc0a 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1,5 +1,6 @@
/*
Copyright (c) 2004, 2012, Oracle and/or its affiliates.
+ Copyright (c) 2017, MariaDB Corporation.
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
@@ -1206,7 +1207,7 @@ bool Table_triggers_list::prepare_record_accessors(TABLE *table)
(table->s->stored_fields != table->s->null_fields))
{
- int null_bytes= (table->s->stored_fields - table->s->null_fields + 7)/8;
+ int null_bytes= (table->s->fields - table->s->null_fields + 7)/8;
if (!(extra_null_bitmap= (uchar*)alloc_root(&table->mem_root, null_bytes)))
return 1;
if (!(record0_field= (Field **)alloc_root(&table->mem_root,
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index db2ef93204c..394fa713445 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -501,12 +501,8 @@ int mysql_create_function(THD *thd,udf_func *udf)
my_message(ER_UDF_NO_PATHS, ER_THD(thd, ER_UDF_NO_PATHS), MYF(0));
DBUG_RETURN(1);
}
- if (check_string_char_length(&udf->name, 0, NAME_CHAR_LEN,
- system_charset_info, 1))
- {
- my_error(ER_TOO_LONG_IDENT, MYF(0), udf->name.str);
+ if (check_ident_length(&udf->name))
DBUG_RETURN(1);
- }
tables.init_one_table(STRING_WITH_LEN("mysql"), STRING_WITH_LEN("func"),
"func", TL_WRITE);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index ff4a5e12e56..7a5fb1c4fbf 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -5195,6 +5195,8 @@ part_name:
{
partition_info *part_info= Lex->part_info;
partition_element *p_elem= part_info->curr_part_elem;
+ if (check_ident_length(&$1))
+ MYSQL_YYABORT;
p_elem->partition_name= $1.str;
}
;
@@ -5499,7 +5501,11 @@ sub_part_definition:
sub_name:
ident_or_text
- { Lex->part_info->curr_part_elem->partition_name= $1.str; }
+ {
+ if (check_ident_length(&$1))
+ MYSQL_YYABORT;
+ Lex->part_info->curr_part_elem->partition_name= $1.str;
+ }
;
opt_part_options:
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index bdfedc30d46..17b1aedd4f1 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2002, 2015, Oracle and/or its affiliates.
- Copyright (c) 2012, 2016, MariaDB Corporation
+ Copyright (c) 2012, 2017, MariaDB Corporation.
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
@@ -641,6 +641,7 @@ static bool check_cs_client(sys_var *self, THD *thd, set_var *var)
if (check_charset_not_null(self, thd, var))
return true;
+ // Currently, UCS-2 cannot be used as a client character set
if (!is_supported_parser_charset((CHARSET_INFO *)(var->save_result.ptr)))
return true;
@@ -5468,6 +5469,13 @@ static Sys_var_ulong Sys_log_tc_size(
BLOCK_SIZE(my_getpagesize()));
#endif
+static Sys_var_ulonglong Sys_max_thread_mem(
+ "max_session_mem_used", "Amount of memory a single user session "
+ "is allowed to allocate. This limits the value of the "
+ "session variable MEM_USED", SESSION_VAR(max_mem_used),
+ CMD_LINE(REQUIRED_ARG), VALID_RANGE(8192, ULONGLONG_MAX),
+ DEFAULT(LONGLONG_MAX), BLOCK_SIZE(1));
+
#ifndef EMBEDDED_LIBRARY
static Sys_var_sesvartrack Sys_track_session_sys_vars(
diff --git a/sql/sys_vars.ic b/sql/sys_vars.ic
index c7f148afd39..780450b484b 100644
--- a/sql/sys_vars.ic
+++ b/sql/sys_vars.ic
@@ -1347,7 +1347,7 @@ public:
if (var->value->result_type() == STRING_RESULT)
{
- if (!(res=var->value->val_str(&str)))
+ if (!(res=var->value->val_str_ascii(&str)))
return true;
else
{
diff --git a/sql/table.cc b/sql/table.cc
index 4242b870d55..04f827646a3 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2008, 2016, MariaDB
+ Copyright (c) 2008, 2017, MariaDB Corporation.
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
@@ -7347,12 +7347,12 @@ int TABLE::update_virtual_fields(enum_vcol_update_mode update_mode)
DBUG_PRINT("enter", ("update_mode: %d", update_mode));
Field **vfield_ptr, *vf;
Turn_errors_to_warnings_handler Suppress_errors;
- int error;
+ Query_arena backup_arena;
+ int error= 0;
bool handler_pushed= 0;
DBUG_ASSERT(vfield);
- error= 0;
- in_use->reset_arena_for_cached_items(expr_arena);
+ in_use->set_n_backup_active_arena(expr_arena, &backup_arena);
/* When reading or deleting row, ignore errors from virtual columns */
if (update_mode == VCOL_UPDATE_FOR_READ ||
@@ -7362,6 +7362,7 @@ int TABLE::update_virtual_fields(enum_vcol_update_mode update_mode)
in_use->push_internal_handler(&Suppress_errors);
handler_pushed= 1;
}
+
/* Iterate over virtual fields in the table */
for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
{
@@ -7435,7 +7436,7 @@ int TABLE::update_virtual_fields(enum_vcol_update_mode update_mode)
}
if (handler_pushed)
in_use->pop_internal_handler();
- in_use->reset_arena_for_cached_items(0);
+ in_use->restore_active_arena(expr_arena, &backup_arena);
/* Return 1 only of we got a fatal error, not a warning */
DBUG_RETURN(in_use->is_error());
@@ -7443,13 +7444,14 @@ int TABLE::update_virtual_fields(enum_vcol_update_mode update_mode)
int TABLE::update_virtual_field(Field *vf)
{
+ Query_arena backup_arena;
DBUG_ENTER("TABLE::update_virtual_field");
- in_use->reset_arena_for_cached_items(expr_arena);
+ in_use->set_n_backup_active_arena(expr_arena, &backup_arena);
bitmap_clear_all(&tmp_set);
vf->vcol_info->expr->walk(&Item::update_vcol_processor, 0, &tmp_set);
vf->vcol_info->expr->save_in_field(vf, 0);
- in_use->reset_arena_for_cached_items(0);
+ in_use->restore_active_arena(expr_arena, &backup_arena);
DBUG_RETURN(0);
}
@@ -7478,10 +7480,11 @@ int TABLE::update_default_fields(bool update_command, bool ignore_errors)
{
DBUG_ENTER("TABLE::update_default_fields");
Field **field_ptr;
+ Query_arena backup_arena;
int res= 0;
DBUG_ASSERT(default_field);
- in_use->reset_arena_for_cached_items(expr_arena);
+ in_use->set_n_backup_active_arena(expr_arena, &backup_arena);
/* Iterate over fields with default functions in the table */
for (field_ptr= default_field; *field_ptr ; field_ptr++)
@@ -7509,7 +7512,7 @@ int TABLE::update_default_fields(bool update_command, bool ignore_errors)
res= 0;
}
}
- in_use->reset_arena_for_cached_items(0);
+ in_use->restore_active_arena(expr_arena, &backup_arena);
DBUG_RETURN(res);
}
diff --git a/storage/connect/ApacheInterface.java b/storage/connect/ApacheInterface.java
index b4c8a4e9885..47b46dc0506 100644
--- a/storage/connect/ApacheInterface.java
+++ b/storage/connect/ApacheInterface.java
@@ -35,7 +35,10 @@ public class ApacheInterface extends JdbcInterface {
ds.setPassword(parms[3]);
pool.put(url, ds);
} // endif ds
-
+
+ // if (parms.length > 4 && parms[4] != null)
+ // ds.setConnectionProperties(parms[4]);
+
// Get a connection from the data source
conn = ds.getConnection();
diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt
index 95d88538119..ce6de424421 100644
--- a/storage/connect/CMakeLists.txt
+++ b/storage/connect/CMakeLists.txt
@@ -20,25 +20,25 @@ SET(CONNECT_SOURCES
ha_connect.cc connect.cc user_connect.cc mycat.cc
fmdlex.c osutil.c plugutil.c rcmsg.c rcmsg.h
array.cpp blkfil.cpp colblk.cpp csort.cpp
-filamap.cpp filamdbf.cpp filamfix.cpp filamtxt.cpp filamvct.cpp filamzip.cpp
+filamap.cpp filamdbf.cpp filamfix.cpp filamgz.cpp filamtxt.cpp
filter.cpp json.cpp jsonudf.cpp maputil.cpp myconn.cpp myutil.cpp plgdbutl.cpp
reldef.cpp tabcol.cpp tabdos.cpp tabfix.cpp tabfmt.cpp tabjson.cpp table.cpp
tabmul.cpp tabmysql.cpp taboccur.cpp tabpivot.cpp tabsys.cpp tabtbl.cpp tabutil.cpp
-tabvct.cpp tabvir.cpp tabxcl.cpp valblk.cpp value.cpp xindex.cpp xobject.cpp
+tabvir.cpp tabxcl.cpp valblk.cpp value.cpp xindex.cpp xobject.cpp
array.h blkfil.h block.h catalog.h checklvl.h colblk.h connect.h csort.h
-engmsg.h filamap.h filamdbf.h filamfix.h filamtxt.h filamvct.h filamzip.h
+engmsg.h filamap.h filamdbf.h filamfix.h filamgz.h filamtxt.h
filter.h global.h ha_connect.h inihandl.h json.h jsonudf.h maputil.h msgid.h
mycat.h myconn.h myutil.h os.h osutil.h plgcnx.h plgdbsem.h preparse.h reldef.h
resource.h tabcol.h tabdos.h tabfix.h tabfmt.h tabjson.h tabmul.h tabmysql.h
-taboccur.h tabpivot.h tabsys.h tabtbl.h tabutil.h tabvct.h tabvir.h tabxcl.h
+taboccur.h tabpivot.h tabsys.h tabtbl.h tabutil.h tabvir.h tabxcl.h
user_connect.h valblk.h value.h xindex.h xobject.h xtable.h)
#
# Definitions that are shared for all OSes
#
add_definitions( -DMARIADB -DFORCE_INIT_OF_VARS -Dconnect_EXPORTS)
-add_definitions( -DHUGE_SUPPORT -DZIP_SUPPORT -DPIVOT_SUPPORT )
+add_definitions( -DHUGE_SUPPORT -DGZ_SUPPORT -DPIVOT_SUPPORT )
#
@@ -90,6 +90,18 @@ ENDIF(UNIX)
#
+# VCT: the VEC format might be not supported in future versions
+#
+
+OPTION(CONNECT_WITH_VCT "Compile CONNECT storage engine with VCT support" ON)
+
+IF(CONNECT_WITH_VCT)
+ SET(CONNECT_SOURCES ${CONNECT_SOURCES} filamvct.cpp tabvct.cpp filamvct.h tabvct.h)
+ add_definitions(-DVCT_SUPPORT)
+ENDIF(CONNECT_WITH_VCT)
+
+
+#
# XML
#
@@ -236,9 +248,9 @@ ENDIF(CONNECT_WITH_ODBC)
# JDBC
#
IF(APPLE)
- OPTION(CONNECT_WITH_JDBC "some comment" OFF)
+ OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine without JDBC support" OFF)
ELSE()
- OPTION(CONNECT_WITH_JDBC "some comment" ON)
+ OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON)
ENDIF()
IF(CONNECT_WITH_JDBC)
@@ -252,18 +264,33 @@ IF(CONNECT_WITH_JDBC)
SET(CONNECT_SOURCES ${CONNECT_SOURCES}
jdbconn.cpp tabjdbc.cpp jdbconn.h tabjdbc.h jdbccat.h
JdbcInterface.java ApacheInterface.java MariadbInterface.java
- MysqlInterface.java OracleInterface.java PostgresqlInterface.java)
+ MysqlInterface.java OracleInterface.java PostgresqlInterface.java
+ JavaWrappers.jar)
# TODO: Find how to compile and install the java wrapper classes
# Find required libraries and include directories
SET (JAVA_SOURCES JdbcInterface.java)
add_jar(JdbcInterface ${JAVA_SOURCES})
- install_jar(JdbcInterface DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
+ install_jar(JdbcInterface DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
+ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/JavaWrappers.jar
+ DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
add_definitions(-DJDBC_SUPPORT)
ELSE()
SET(JDBC_LIBRARY "")
ENDIF()
ENDIF(CONNECT_WITH_JDBC)
+#
+# ZIP
+#
+
+OPTION(CONNECT_WITH_ZIP "Compile CONNECT storage engine with ZIP support" ON)
+
+IF(CONNECT_WITH_ZIP)
+ SET(CONNECT_SOURCES ${CONNECT_SOURCES} filamzip.cpp tabzip.cpp unzip.c ioapi.c zip.c
+ filamzip.h tabzip.h ioapi.h unzip.h zip.h)
+ add_definitions(-DZIP_SUPPORT -DNOCRYPT)
+ENDIF(CONNECT_WITH_ZIP)
+
#
# XMAP
diff --git a/storage/connect/JavaWrappers.jar b/storage/connect/JavaWrappers.jar
new file mode 100644
index 00000000000..8c01c364a3f
--- /dev/null
+++ b/storage/connect/JavaWrappers.jar
Binary files differ
diff --git a/storage/connect/JdbcInterface.java b/storage/connect/JdbcInterface.java
index 34af8c4e013..a1b1360e6ea 100644
--- a/storage/connect/JdbcInterface.java
+++ b/storage/connect/JdbcInterface.java
@@ -82,6 +82,9 @@ public class JdbcInterface {
System.out.println("URL=" + parms[1]);
CheckURL(parms[1], null);
+
+ // This is required for drivers using context class loaders
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
if (parms[2] != null && !parms[2].isEmpty()) {
if (DEBUG)
@@ -220,6 +223,19 @@ public class JdbcInterface {
} // end of SetTimestampParm
+ public int SetNullParm(int i, int typ) {
+ int rc = 0;
+
+ try {
+ pstmt.setNull(i, typ);
+ } catch (Exception e) {
+ SetErrmsg(e);
+ rc = -1;
+ } // end try/catch
+
+ return rc;
+ } // end of SetNullParm
+
public int ExecutePrep() {
int n = -3;
diff --git a/storage/connect/domdoc.cpp b/storage/connect/domdoc.cpp
index 64a0a172956..eb9660b439d 100644
--- a/storage/connect/domdoc.cpp
+++ b/storage/connect/domdoc.cpp
@@ -89,30 +89,43 @@ DOMDOC::DOMDOC(char *nsl, char *nsdf, char *enc, PFBLOCK fp)
/******************************************************************/
/* Initialize XML parser and check library compatibility. */
/******************************************************************/
-bool DOMDOC::Initialize(PGLOBAL g)
- {
- if (TestHr(g, CoInitialize(NULL)))
+bool DOMDOC::Initialize(PGLOBAL g, char *entry, bool zipped)
+{
+ if (zipped && InitZip(g, entry))
+ return true;
+
+ if (TestHr(g, CoInitialize(NULL)))
return true;
if (TestHr(g, Docp.CreateInstance("msxml2.domdocument")))
return true;
return MakeNSlist(g);
- } // end of Initialize
+} // end of Initialize
/******************************************************************/
/* Parse the XML file and construct node tree in memory. */
/******************************************************************/
-bool DOMDOC::ParseFile(char *fn)
- {
- // Load the document
+bool DOMDOC::ParseFile(PGLOBAL g, char *fn)
+{
+ bool b;
+
Docp->async = false;
- if (!(bool)Docp->load((_bstr_t)fn))
+ if (zip) {
+ // Parse an in memory document
+ char *xdoc = GetMemDoc(g, fn);
+
+ b = (xdoc) ? (bool)Docp->loadXML((_bstr_t)xdoc) : false;
+ } else
+ // Load the document
+ b = (bool)Docp->load((_bstr_t)fn);
+
+ if (!b)
return true;
return false;
- } // end of ParseFile
+} // end of ParseFile
/******************************************************************/
/* Create or reuse an Xblock for this document. */
@@ -239,6 +252,7 @@ int DOMDOC::DumpDoc(PGLOBAL g, char *ofn)
void DOMDOC::CloseDoc(PGLOBAL g, PFBLOCK xp)
{
CloseXMLFile(g, xp, false);
+ CloseZip();
} // end of Close
/* ----------------------- class DOMNODE ------------------------ */
@@ -616,13 +630,13 @@ PXNODE DOMNODELIST::GetItem(PGLOBAL g, int n, PXNODE np)
/* Reset the pointer on the deleted item. */
/******************************************************************/
bool DOMNODELIST::DropItem(PGLOBAL g, int n)
- {
- if (Listp == NULL || Listp->length <= n)
- return true;
+{
+ if (Listp == NULL || Listp->length < n)
+ return true;
//Listp->item[n] = NULL; La propriété n'a pas de méthode 'set'
return false;
- } // end of DeleteItem
+} // end of DeleteItem
/* ----------------------- class DOMATTR ------------------------ */
diff --git a/storage/connect/domdoc.h b/storage/connect/domdoc.h
index 2cffec499e2..cfec98a9422 100644
--- a/storage/connect/domdoc.h
+++ b/storage/connect/domdoc.h
@@ -37,8 +37,8 @@ class DOMDOC : public XMLDOCUMENT {
virtual void SetNofree(bool b) {} // Only libxml2
// Methods
- virtual bool Initialize(PGLOBAL g);
- virtual bool ParseFile(char *fn);
+ virtual bool Initialize(PGLOBAL g, char *entry, bool zipped);
+ virtual bool ParseFile(PGLOBAL g, char *fn);
virtual bool NewDoc(PGLOBAL g, char *ver);
virtual void AddComment(PGLOBAL g, char *com);
virtual PXNODE GetRoot(PGLOBAL g);
diff --git a/storage/connect/filamap.cpp b/storage/connect/filamap.cpp
index c6b4585a839..94c562a9981 100644
--- a/storage/connect/filamap.cpp
+++ b/storage/connect/filamap.cpp
@@ -87,7 +87,7 @@ int MAPFAM::GetFileLength(PGLOBAL g)
{
int len;
- len = (To_Fb) ? To_Fb->Length : TXTFAM::GetFileLength(g);
+ len = (To_Fb && To_Fb->Count) ? To_Fb->Length : TXTFAM::GetFileLength(g);
if (trace)
htrc("Mapped file length=%d\n", len);
@@ -319,11 +319,13 @@ int MAPFAM::SkipRecord(PGLOBAL g, bool header)
/***********************************************************************/
int MAPFAM::ReadBuffer(PGLOBAL g)
{
- int len;
+ int rc, len;
// Are we at the end of the memory
- if (Mempos >= Top)
- return RC_EF;
+ if (Mempos >= Top)
+ if ((rc = GetNext(g)) != RC_OK)
+ return rc;
+
if (!Placed) {
/*******************************************************************/
@@ -341,8 +343,10 @@ int MAPFAM::ReadBuffer(PGLOBAL g)
/*******************************************************************/
switch (Tdbp->TestBlock(g)) {
case RC_EF:
- return RC_EF;
- case RC_NF:
+ if ((rc = GetNext(g)) != RC_OK)
+ return rc;
+
+ case RC_NF:
// Skip this record
if ((rc = SkipRecord(g, false)) != RC_OK)
return rc;
@@ -498,7 +502,7 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
void MAPFAM::CloseTableFile(PGLOBAL g, bool)
{
PlugCloseFile(g, To_Fb);
- To_Fb = NULL; // To get correct file size in Cardinality
+//To_Fb = NULL; // To get correct file size in Cardinality
if (trace)
htrc("MAP Close: closing %s count=%d\n",
@@ -569,7 +573,7 @@ int MBKFAM::GetRowID(void)
/***********************************************************************/
int MBKFAM::ReadBuffer(PGLOBAL g)
{
- int len;
+ int rc, len;
/*********************************************************************/
/* Sequential block reading when Placed is not true. */
@@ -577,8 +581,10 @@ int MBKFAM::ReadBuffer(PGLOBAL g)
if (Placed) {
Placed = false;
} else if (Mempos >= Top) { // Are we at the end of the memory
- return RC_EF;
- } else if (++CurNum < Nrec) {
+ if ((rc = GetNext(g)) != RC_OK)
+ return rc;
+
+ } else if (++CurNum < Nrec) {
Fpos = Mempos;
} else {
/*******************************************************************/
@@ -588,7 +594,8 @@ int MBKFAM::ReadBuffer(PGLOBAL g)
next:
if (++CurBlk >= Block)
- return RC_EF;
+ if ((rc = GetNext(g)) != RC_OK)
+ return rc;
/*******************************************************************/
/* Before reading a new block, check whether block optimization */
@@ -596,8 +603,11 @@ int MBKFAM::ReadBuffer(PGLOBAL g)
/*******************************************************************/
switch (Tdbp->TestBlock(g)) {
case RC_EF:
- return RC_EF;
- case RC_NF:
+ if ((rc = GetNext(g)) != RC_OK)
+ return rc;
+
+ break;
+ case RC_NF:
goto next;
} // endswitch rc
@@ -697,14 +707,18 @@ int MPXFAM::InitDelete(PGLOBAL, int fpos, int)
/***********************************************************************/
int MPXFAM::ReadBuffer(PGLOBAL g)
{
+ int rc;
+
/*********************************************************************/
/* Sequential block reading when Placed is not true. */
/*********************************************************************/
if (Placed) {
Placed = false;
} else if (Mempos >= Top) { // Are we at the end of the memory
- return RC_EF;
- } else if (++CurNum < Nrec) {
+ if ((rc = GetNext(g)) != RC_OK)
+ return rc;
+
+ } else if (++CurNum < Nrec) {
Fpos = Mempos;
} else {
/*******************************************************************/
@@ -714,7 +728,7 @@ int MPXFAM::ReadBuffer(PGLOBAL g)
next:
if (++CurBlk >= Block)
- return RC_EF;
+ return GetNext(g);
/*******************************************************************/
/* Before reading a new block, check whether block optimization */
@@ -722,8 +736,11 @@ int MPXFAM::ReadBuffer(PGLOBAL g)
/*******************************************************************/
switch (Tdbp->TestBlock(g)) {
case RC_EF:
- return RC_EF;
- case RC_NF:
+ if ((rc = GetNext(g)) != RC_OK)
+ return rc;
+
+ break;
+ case RC_NF:
goto next;
} // endswitch rc
diff --git a/storage/connect/filamap.h b/storage/connect/filamap.h
index b9c8ad965fd..774eb8b91b3 100644
--- a/storage/connect/filamap.h
+++ b/storage/connect/filamap.h
@@ -41,7 +41,8 @@ class DllExport MAPFAM : public TXTFAM {
virtual int SkipRecord(PGLOBAL g, bool header);
virtual bool OpenTableFile(PGLOBAL g);
virtual bool DeferReading(void) {return false;}
- virtual int ReadBuffer(PGLOBAL g);
+ virtual int GetNext(PGLOBAL g) {return RC_EF;}
+ virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g, bool abort);
diff --git a/storage/connect/filamgz.cpp b/storage/connect/filamgz.cpp
new file mode 100644
index 00000000000..07242ea633c
--- /dev/null
+++ b/storage/connect/filamgz.cpp
@@ -0,0 +1,1426 @@
+/************ File AM GZ C++ Program Source Code File (.CPP) ***********/
+/* PROGRAM NAME: FILAMGZ */
+/* ------------- */
+/* Version 1.5 */
+/* */
+/* COPYRIGHT: */
+/* ---------- */
+/* (C) Copyright to the author Olivier BERTRAND 2005-2016 */
+/* */
+/* WHAT THIS PROGRAM DOES: */
+/* ----------------------- */
+/* This program are the ZLIB compressed files classes. */
+/* */
+/***********************************************************************/
+
+/***********************************************************************/
+/* Include relevant MariaDB header file. */
+/***********************************************************************/
+#include "my_global.h"
+#if defined(__WIN__)
+#include <io.h>
+#include <fcntl.h>
+#if defined(__BORLANDC__)
+#define __MFC_COMPAT__ // To define min/max as macro
+#endif
+//#include <windows.h>
+#else // !__WIN__
+#if defined(UNIX)
+#include <errno.h>
+#else // !UNIX
+#include <io.h>
+#endif
+#include <fcntl.h>
+#endif // !__WIN__
+
+/***********************************************************************/
+/* Include application header files: */
+/* global.h is header containing all global declarations. */
+/* plgdbsem.h is header containing the DB application declarations. */
+/* tabdos.h is header containing the TABDOS class declarations. */
+/***********************************************************************/
+#include "global.h"
+#include "plgdbsem.h"
+//#include "catalog.h"
+//#include "reldef.h"
+//#include "xobject.h"
+//#include "kindex.h"
+#include "filamtxt.h"
+#include "tabdos.h"
+#if defined(UNIX)
+#include "osutil.h"
+#endif
+
+/***********************************************************************/
+/* This define prepares ZLIB function declarations. */
+/***********************************************************************/
+//#define ZLIB_DLL
+
+#include "filamgz.h"
+
+/***********************************************************************/
+/* DB static variables. */
+/***********************************************************************/
+extern int num_read, num_there, num_eq[]; // Statistics
+
+/* ------------------------------------------------------------------- */
+
+/***********************************************************************/
+/* Implementation of the GZFAM class. */
+/***********************************************************************/
+GZFAM::GZFAM(PGZFAM txfp) : TXTFAM(txfp)
+ {
+ Zfile = txfp->Zfile;
+ Zpos = txfp->Zpos;
+ } // end of GZFAM copy constructor
+
+/***********************************************************************/
+/* Zerror: Error function for gz calls. */
+/* gzerror returns the error message for the last error which occurred*/
+/* on the given compressed file. errnum is set to zlib error number. */
+/* If an error occurred in the file system and not in the compression */
+/* library, errnum is set to Z_ERRNO and the application may consult */
+/* errno to get the exact error code. */
+/***********************************************************************/
+int GZFAM::Zerror(PGLOBAL g)
+ {
+ int errnum;
+
+ strcpy(g->Message, gzerror(Zfile, &errnum));
+
+ if (errnum == Z_ERRNO)
+#if defined(__WIN__)
+ sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(NULL));
+#else // !__WIN__
+ sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno));
+#endif // !__WIN__
+
+ return (errnum == Z_STREAM_END) ? RC_EF : RC_FX;
+ } // end of Zerror
+
+/***********************************************************************/
+/* Reset: reset position values at the beginning of file. */
+/***********************************************************************/
+void GZFAM::Reset(void)
+ {
+ TXTFAM::Reset();
+//gzrewind(Zfile); // Useful ?????
+ Zpos = 0;
+ } // end of Reset
+
+/***********************************************************************/
+/* GZ GetFileLength: returns an estimate of what would be the */
+/* uncompressed file size in number of bytes. */
+/***********************************************************************/
+int GZFAM::GetFileLength(PGLOBAL g)
+ {
+ int len = TXTFAM::GetFileLength(g);
+
+ if (len > 0)
+ // Estimate size reduction to a max of 6
+ len *= 6;
+
+ return len;
+ } // end of GetFileLength
+
+/***********************************************************************/
+/* GZ Access Method opening routine. */
+/***********************************************************************/
+bool GZFAM::OpenTableFile(PGLOBAL g)
+ {
+ char opmode[4], filename[_MAX_PATH];
+ MODE mode = Tdbp->GetMode();
+
+ switch (mode) {
+ case MODE_READ:
+ strcpy(opmode, "r");
+ break;
+ case MODE_UPDATE:
+ /*****************************************************************/
+ /* Updating GZ files not implemented yet. */
+ /*****************************************************************/
+ strcpy(g->Message, MSG(UPD_ZIP_NOT_IMP));
+ return true;
+ case MODE_DELETE:
+ if (!Tdbp->GetNext()) {
+ // Store the number of deleted lines
+ DelRows = Cardinality(g);
+
+ // This will erase the entire file
+ strcpy(opmode, "w");
+// Block = 0; // For ZBKFAM
+// Last = Nrec; // For ZBKFAM
+ Tdbp->ResetSize();
+ } else {
+ sprintf(g->Message, MSG(NO_PART_DEL), "GZ");
+ return true;
+ } // endif filter
+
+ break;
+ case MODE_INSERT:
+ strcpy(opmode, "a+");
+ break;
+ default:
+ sprintf(g->Message, MSG(BAD_OPEN_MODE), mode);
+ return true;
+ } // endswitch Mode
+
+ /*********************************************************************/
+ /* Open according to logical input/output mode required. */
+ /* Use specific zlib functions. */
+ /* Treat files as binary. */
+ /*********************************************************************/
+ strcat(opmode, "b");
+ Zfile = gzopen(PlugSetPath(filename, To_File, Tdbp->GetPath()), opmode);
+
+ if (Zfile == NULL) {
+ sprintf(g->Message, MSG(GZOPEN_ERROR),
+ opmode, (int)errno, filename);
+ strcat(strcat(g->Message, ": "), strerror(errno));
+ return (mode == MODE_READ && errno == ENOENT)
+ ? PushWarning(g, Tdbp) : true;
+ } // endif Zfile
+
+ /*********************************************************************/
+ /* Something to be done here. >>>>>>>> NOT DONE <<<<<<<< */
+ /*********************************************************************/
+//To_Fb = dbuserp->Openlist; // Keep track of File block
+
+ /*********************************************************************/
+ /* Allocate the line buffer. */
+ /*********************************************************************/
+ return AllocateBuffer(g);
+ } // end of OpenTableFile
+
+/***********************************************************************/
+/* Allocate the line buffer. For mode Delete a bigger buffer has to */
+/* be allocated because is it also used to move lines into the file. */
+/***********************************************************************/
+bool GZFAM::AllocateBuffer(PGLOBAL g)
+ {
+ MODE mode = Tdbp->GetMode();
+
+ Buflen = Lrecl + 2; // Lrecl does not include CRLF
+//Buflen *= ((Mode == MODE_DELETE) ? DOS_BUFF_LEN : 1); NIY
+
+ if (trace)
+ htrc("SubAllocating a buffer of %d bytes\n", Buflen);
+
+ To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);
+
+ if (mode == MODE_INSERT) {
+ /*******************************************************************/
+ /* For Insert buffer must be prepared. */
+ /*******************************************************************/
+ memset(To_Buf, ' ', Buflen);
+ To_Buf[Buflen - 2] = '\n';
+ To_Buf[Buflen - 1] = '\0';
+ } // endif Insert
+
+ return false;
+ } // end of AllocateBuffer
+
+/***********************************************************************/
+/* GetRowID: return the RowID of last read record. */
+/***********************************************************************/
+int GZFAM::GetRowID(void)
+ {
+ return Rows;
+ } // end of GetRowID
+
+/***********************************************************************/
+/* GetPos: return the position of last read record. */
+/***********************************************************************/
+int GZFAM::GetPos(void)
+ {
+ return (int)Zpos;
+ } // end of GetPos
+
+/***********************************************************************/
+/* GetNextPos: return the position of next record. */
+/***********************************************************************/
+int GZFAM::GetNextPos(void)
+ {
+ return gztell(Zfile);
+ } // end of GetNextPos
+
+/***********************************************************************/
+/* SetPos: Replace the table at the specified position. */
+/***********************************************************************/
+bool GZFAM::SetPos(PGLOBAL g, int pos __attribute__((unused)))
+ {
+ sprintf(g->Message, MSG(NO_SETPOS_YET), "GZ");
+ return true;
+#if 0
+ Fpos = pos;
+
+ if (fseek(Stream, Fpos, SEEK_SET)) {
+ sprintf(g->Message, MSG(FSETPOS_ERROR), Fpos);
+ return true;
+ } // endif
+
+ Placed = true;
+ return false;
+#endif // 0
+ } // end of SetPos
+
+/***********************************************************************/
+/* Record file position in case of UPDATE or DELETE. */
+/***********************************************************************/
+bool GZFAM::RecordPos(PGLOBAL)
+ {
+ Zpos = gztell(Zfile);
+ return false;
+ } // end of RecordPos
+
+/***********************************************************************/
+/* Skip one record in file. */
+/***********************************************************************/
+int GZFAM::SkipRecord(PGLOBAL g, bool header)
+ {
+ // Skip this record
+ if (gzeof(Zfile))
+ return RC_EF;
+ else if (gzgets(Zfile, To_Buf, Buflen) == Z_NULL)
+ return Zerror(g);
+
+ if (header)
+ RecordPos(g);
+
+ return RC_OK;
+ } // end of SkipRecord
+
+/***********************************************************************/
+/* ReadBuffer: Read one line from a compressed text file. */
+/***********************************************************************/
+int GZFAM::ReadBuffer(PGLOBAL g)
+ {
+ char *p;
+ int rc;
+
+ if (!Zfile)
+ return RC_EF;
+
+ if (!Placed) {
+ /*******************************************************************/
+ /* Record file position in case of UPDATE or DELETE. */
+ /*******************************************************************/
+ next:
+ if (RecordPos(g))
+ return RC_FX;
+
+ CurBlk = Rows++; // Update RowID
+
+ /*******************************************************************/
+ /* Check whether optimization on ROWID */
+ /* can be done, as well as for join as for local filtering. */
+ /*******************************************************************/
+ switch (Tdbp->TestBlock(g)) {
+ case RC_EF:
+ return RC_EF;
+ case RC_NF:
+ // Skip this record
+ if ((rc = SkipRecord(g, FALSE)) != RC_OK)
+ return rc;
+
+ goto next;
+ } // endswitch rc
+
+ } else
+ Placed = false;
+
+ if (gzeof(Zfile)) {
+ rc = RC_EF;
+ } else if (gzgets(Zfile, To_Buf, Buflen) != Z_NULL) {
+ p = To_Buf + strlen(To_Buf) - 1;
+
+ if (*p == '\n')
+ *p = '\0'; // Eliminate ending new-line character
+
+ if (*(--p) == '\r')
+ *p = '\0'; // Eliminate eventuel carriage return
+
+ strcpy(Tdbp->GetLine(), To_Buf);
+ IsRead = true;
+ rc = RC_OK;
+ num_read++;
+ } else
+ rc = Zerror(g);
+
+ if (trace > 1)
+ htrc(" Read: '%s' rc=%d\n", To_Buf, rc);
+
+ return rc;
+ } // end of ReadBuffer
+
+/***********************************************************************/
+/* WriteDB: Data Base write routine for ZDOS access method. */
+/* Update is not possible without using a temporary file (NIY). */
+/***********************************************************************/
+int GZFAM::WriteBuffer(PGLOBAL g)
+ {
+ /*********************************************************************/
+ /* Prepare the write buffer. */
+ /*********************************************************************/
+ strcat(strcpy(To_Buf, Tdbp->GetLine()), CrLf);
+
+ /*********************************************************************/
+ /* Now start the writing process. */
+ /*********************************************************************/
+ if (gzputs(Zfile, To_Buf) < 0)
+ return Zerror(g);
+
+ return RC_OK;
+ } // end of WriteBuffer
+
+/***********************************************************************/
+/* Data Base delete line routine for ZDOS access method. (NIY) */
+/***********************************************************************/
+int GZFAM::DeleteRecords(PGLOBAL g, int)
+ {
+ strcpy(g->Message, MSG(NO_ZIP_DELETE));
+ return RC_FX;
+ } // end of DeleteRecords
+
+/***********************************************************************/
+/* Data Base close routine for DOS access method. */
+/***********************************************************************/
+void GZFAM::CloseTableFile(PGLOBAL, bool)
+ {
+ int rc = gzclose(Zfile);
+
+ if (trace)
+ htrc("GZ CloseDB: closing %s rc=%d\n", To_File, rc);
+
+ Zfile = NULL; // So we can know whether table is open
+//To_Fb->Count = 0; // Avoid double closing by PlugCloseAll
+ } // end of CloseTableFile
+
+/***********************************************************************/
+/* Rewind routine for GZ access method. */
+/***********************************************************************/
+void GZFAM::Rewind(void)
+ {
+ gzrewind(Zfile);
+ } // end of Rewind
+
+/* ------------------------------------------------------------------- */
+
+/***********************************************************************/
+/* Constructors. */
+/***********************************************************************/
+ZBKFAM::ZBKFAM(PDOSDEF tdp) : GZFAM(tdp)
+ {
+ Blocked = true;
+ Block = tdp->GetBlock();
+ Last = tdp->GetLast();
+ Nrec = tdp->GetElemt();
+ CurLine = NULL;
+ NxtLine = NULL;
+ Closing = false;
+ BlkPos = tdp->GetTo_Pos();
+ } // end of ZBKFAM standard constructor
+
+ZBKFAM::ZBKFAM(PZBKFAM txfp) : GZFAM(txfp)
+ {
+ CurLine = txfp->CurLine;
+ NxtLine = txfp->NxtLine;
+ Closing = txfp->Closing;
+ } // end of ZBKFAM copy constructor
+
+/***********************************************************************/
+/* Use BlockTest to reduce the table estimated size. */
+/***********************************************************************/
+int ZBKFAM::MaxBlkSize(PGLOBAL g, int)
+ {
+ int rc = RC_OK, savcur = CurBlk;
+ int size;
+
+ // Roughly estimate the table size as the sum of blocks
+ // that can contain good rows
+ for (size = 0, CurBlk = 0; CurBlk < Block; CurBlk++)
+ if ((rc = Tdbp->TestBlock(g)) == RC_OK)
+ size += (CurBlk == Block - 1) ? Last : Nrec;
+ else if (rc == RC_EF)
+ break;
+
+ CurBlk = savcur;
+ return size;
+ } // end of MaxBlkSize
+
+/***********************************************************************/
+/* ZBK Cardinality: returns table cardinality in number of rows. */
+/* This function can be called with a null argument to test the */
+/* availability of Cardinality implementation (1 yes, 0 no). */
+/***********************************************************************/
+int ZBKFAM::Cardinality(PGLOBAL g)
+ {
+ return (g) ? (int)((Block - 1) * Nrec + Last) : 1;
+ } // end of Cardinality
+
+/***********************************************************************/
+/* Allocate the line buffer. For mode Delete a bigger buffer has to */
+/* be allocated because is it also used to move lines into the file. */
+/***********************************************************************/
+bool ZBKFAM::AllocateBuffer(PGLOBAL g)
+ {
+ Buflen = Nrec * (Lrecl + 2);
+ CurLine = To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);
+
+ if (Tdbp->GetMode() == MODE_INSERT) {
+ // Set values so Block and Last can be recalculated
+ if (Last == Nrec) {
+ CurBlk = Block;
+ Rbuf = Nrec; // To be used by WriteDB
+ } else {
+ // The last block must be completed
+ CurBlk = Block - 1;
+ Rbuf = Nrec - Last; // To be used by WriteDB
+ } // endif Last
+
+ } // endif Insert
+
+ return false;
+ } // end of AllocateBuffer
+
+/***********************************************************************/
+/* GetRowID: return the RowID of last read record. */
+/***********************************************************************/
+int ZBKFAM::GetRowID(void)
+ {
+ return CurNum + Nrec * CurBlk + 1;
+ } // end of GetRowID
+
+/***********************************************************************/
+/* GetPos: return the position of last read record. */
+/***********************************************************************/
+int ZBKFAM::GetPos(void)
+ {
+ return CurNum + Nrec * CurBlk; // Computed file index
+ } // end of GetPos
+
+/***********************************************************************/
+/* Record file position in case of UPDATE or DELETE. */
+/* Not used yet for fixed tables. */
+/***********************************************************************/
+bool ZBKFAM::RecordPos(PGLOBAL /*g*/)
+ {
+//strcpy(g->Message, "RecordPos not implemented for gz blocked tables");
+//return true;
+ return RC_OK;
+ } // end of RecordPos
+
+/***********************************************************************/
+/* Skip one record in file. */
+/***********************************************************************/
+int ZBKFAM::SkipRecord(PGLOBAL /*g*/, bool)
+ {
+//strcpy(g->Message, "SkipRecord not implemented for gz blocked tables");
+//return RC_FX;
+ return RC_OK;
+ } // end of SkipRecord
+
+/***********************************************************************/
+/* ReadBuffer: Read one line from a compressed text file. */
+/***********************************************************************/
+int ZBKFAM::ReadBuffer(PGLOBAL g)
+ {
+ int n, skip, rc = RC_OK;
+
+ /*********************************************************************/
+ /* Sequential reading when Placed is not true. */
+ /*********************************************************************/
+ if (++CurNum < Rbuf) {
+ CurLine = NxtLine;
+
+ // Get the position of the next line in the buffer
+ while (*NxtLine++ != '\n') ;
+
+ // Set caller line buffer
+ n = NxtLine - CurLine - Ending;
+ memcpy(Tdbp->GetLine(), CurLine, n);
+ Tdbp->GetLine()[n] = '\0';
+ return RC_OK;
+ } else if (Rbuf < Nrec && CurBlk != -1)
+ return RC_EF;
+
+ /*********************************************************************/
+ /* New block. */
+ /*********************************************************************/
+ CurNum = 0;
+ skip = 0;
+
+ next:
+ if (++CurBlk >= Block)
+ return RC_EF;
+
+ /*********************************************************************/
+ /* Before using the new block, check whether block optimization */
+ /* can be done, as well as for join as for local filtering. */
+ /*********************************************************************/
+ switch (Tdbp->TestBlock(g)) {
+ case RC_EF:
+ return RC_EF;
+ case RC_NF:
+ skip++;
+ goto next;
+ } // endswitch rc
+
+ if (skip)
+ // Skip blocks rejected by block optimization
+ for (int i = CurBlk - skip; i < CurBlk; i++) {
+ BlkLen = BlkPos[i + 1] - BlkPos[i];
+
+ if (gzseek(Zfile, (z_off_t)BlkLen, SEEK_CUR) < 0)
+ return Zerror(g);
+
+ } // endfor i
+
+ BlkLen = BlkPos[CurBlk + 1] - BlkPos[CurBlk];
+
+ if (!(n = gzread(Zfile, To_Buf, BlkLen))) {
+ rc = RC_EF;
+ } else if (n > 0) {
+ // Get the position of the current line
+ CurLine = To_Buf;
+
+ // Now get the position of the next line
+ for (NxtLine = CurLine; *NxtLine++ != '\n';) ;
+
+ // Set caller line buffer
+ n = NxtLine - CurLine - Ending;
+ memcpy(Tdbp->GetLine(), CurLine, n);
+ Tdbp->GetLine()[n] = '\0';
+ Rbuf = (CurBlk == Block - 1) ? Last : Nrec;
+ IsRead = true;
+ rc = RC_OK;
+ num_read++;
+ } else
+ rc = Zerror(g);
+
+ return rc;
+ } // end of ReadBuffer
+
+/***********************************************************************/
+/* WriteDB: Data Base write routine for ZDOS access method. */
+/* Update is not possible without using a temporary file (NIY). */
+/***********************************************************************/
+int ZBKFAM::WriteBuffer(PGLOBAL g)
+ {
+ /*********************************************************************/
+ /* Prepare the write buffer. */
+ /*********************************************************************/
+ if (!Closing)
+ strcat(strcpy(CurLine, Tdbp->GetLine()), CrLf);
+
+ /*********************************************************************/
+ /* In Insert mode, blocs are added sequentialy to the file end. */
+ /* Note: Update mode is not handled for gz files. */
+ /*********************************************************************/
+ if (++CurNum == Rbuf) {
+ /*******************************************************************/
+ /* New block, start the writing process. */
+ /*******************************************************************/
+ BlkLen = CurLine + strlen(CurLine) - To_Buf;
+
+ if (gzwrite(Zfile, To_Buf, BlkLen) != BlkLen ||
+ gzflush(Zfile, Z_FULL_FLUSH)) {
+ Closing = true;
+ return Zerror(g);
+ } // endif gzwrite
+
+ Rbuf = Nrec;
+ CurBlk++;
+ CurNum = 0;
+ CurLine = To_Buf;
+ } else
+ CurLine += strlen(CurLine);
+
+ return RC_OK;
+ } // end of WriteBuffer
+
+/***********************************************************************/
+/* Data Base delete line routine for ZBK access method. */
+/* Implemented only for total deletion of the table, which is done */
+/* by opening the file in mode "wb". */
+/***********************************************************************/
+int ZBKFAM::DeleteRecords(PGLOBAL g, int irc)
+ {
+ if (irc == RC_EF) {
+ LPCSTR name = Tdbp->GetName();
+ PDOSDEF defp = (PDOSDEF)Tdbp->GetDef();
+
+ defp->SetBlock(0);
+ defp->SetLast(Nrec);
+
+ if (!defp->SetIntCatInfo("Blocks", 0) ||
+ !defp->SetIntCatInfo("Last", 0)) {
+ sprintf(g->Message, MSG(UPDATE_ERROR), "Header");
+ return RC_FX;
+ } else
+ return RC_OK;
+
+ } else
+ return irc;
+
+ } // end of DeleteRecords
+
+/***********************************************************************/
+/* Data Base close routine for ZBK access method. */
+/***********************************************************************/
+void ZBKFAM::CloseTableFile(PGLOBAL g, bool)
+ {
+ int rc = RC_OK;
+
+ if (Tdbp->GetMode() == MODE_INSERT) {
+ LPCSTR name = Tdbp->GetName();
+ PDOSDEF defp = (PDOSDEF)Tdbp->GetDef();
+
+ if (CurNum && !Closing) {
+ // Some more inserted lines remain to be written
+ Last = (Nrec - Rbuf) + CurNum;
+ Block = CurBlk + 1;
+ Rbuf = CurNum--;
+ Closing = true;
+ rc = WriteBuffer(g);
+ } else if (Rbuf == Nrec) {
+ Last = Nrec;
+ Block = CurBlk;
+ } // endif CurNum
+
+ if (rc != RC_FX) {
+ defp->SetBlock(Block);
+ defp->SetLast(Last);
+ defp->SetIntCatInfo("Blocks", Block);
+ defp->SetIntCatInfo("Last", Last);
+ } // endif
+
+ gzclose(Zfile);
+ } else if (Tdbp->GetMode() == MODE_DELETE) {
+ rc = DeleteRecords(g, RC_EF);
+ gzclose(Zfile);
+ } else
+ rc = gzclose(Zfile);
+
+ if (trace)
+ htrc("GZ CloseDB: closing %s rc=%d\n", To_File, rc);
+
+ Zfile = NULL; // So we can know whether table is open
+//To_Fb->Count = 0; // Avoid double closing by PlugCloseAll
+ } // end of CloseTableFile
+
+/***********************************************************************/
+/* Rewind routine for ZBK access method. */
+/***********************************************************************/
+void ZBKFAM::Rewind(void)
+ {
+ gzrewind(Zfile);
+ CurBlk = -1;
+ CurNum = Rbuf;
+ } // end of Rewind
+
+/* ------------------------------------------------------------------- */
+
+/***********************************************************************/
+/* Constructors. */
+/***********************************************************************/
+ZIXFAM::ZIXFAM(PDOSDEF tdp) : ZBKFAM(tdp)
+ {
+//Block = tdp->GetBlock();
+//Last = tdp->GetLast();
+ Nrec = (tdp->GetElemt()) ? tdp->GetElemt() : DOS_BUFF_LEN;
+ Blksize = Nrec * Lrecl;
+ } // end of ZIXFAM standard constructor
+
+/***********************************************************************/
+/* ZIX Cardinality: returns table cardinality in number of rows. */
+/* This function can be called with a null argument to test the */
+/* availability of Cardinality implementation (1 yes, 0 no). */
+/***********************************************************************/
+int ZIXFAM::Cardinality(PGLOBAL g)
+ {
+ if (Last)
+ return (g) ? (int)((Block - 1) * Nrec + Last) : 1;
+ else // Last and Block not defined, cannot do it yet
+ return 0;
+
+ } // end of Cardinality
+
+/***********************************************************************/
+/* Allocate the line buffer. For mode Delete a bigger buffer has to */
+/* be allocated because is it also used to move lines into the file. */
+/***********************************************************************/
+bool ZIXFAM::AllocateBuffer(PGLOBAL g)
+ {
+ Buflen = Blksize;
+ To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);
+
+ if (Tdbp->GetMode() == MODE_INSERT) {
+ /*******************************************************************/
+ /* For Insert the buffer must be prepared. */
+ /*******************************************************************/
+ memset(To_Buf, ' ', Buflen);
+
+ if (Tdbp->GetFtype() < 2)
+ // if not binary, the file is physically a text file
+ for (int len = Lrecl; len <= Buflen; len += Lrecl) {
+#if defined(__WIN__)
+ To_Buf[len - 2] = '\r';
+#endif // __WIN__
+ To_Buf[len - 1] = '\n';
+ } // endfor len
+
+ // Set values so Block and Last can be recalculated
+ if (Last == Nrec) {
+ CurBlk = Block;
+ Rbuf = Nrec; // To be used by WriteDB
+ } else {
+ // The last block must be completed
+ CurBlk = Block - 1;
+ Rbuf = Nrec - Last; // To be used by WriteDB
+ } // endif Last
+
+ } // endif Insert
+
+ return false;
+ } // end of AllocateBuffer
+
+/***********************************************************************/
+/* ReadBuffer: Read one line from a compressed text file. */
+/***********************************************************************/
+int ZIXFAM::ReadBuffer(PGLOBAL g)
+ {
+ int n, rc = RC_OK;
+
+ /*********************************************************************/
+ /* Sequential reading when Placed is not true. */
+ /*********************************************************************/
+ if (++CurNum < Rbuf) {
+ Tdbp->IncLine(Lrecl); // Used by DOSCOL functions
+ return RC_OK;
+ } else if (Rbuf < Nrec && CurBlk != -1)
+ return RC_EF;
+
+ /*********************************************************************/
+ /* New block. */
+ /*********************************************************************/
+ CurNum = 0;
+ Tdbp->SetLine(To_Buf);
+
+ int skip = 0;
+
+ next:
+ if (++CurBlk >= Block)
+ return RC_EF;
+
+ /*********************************************************************/
+ /* Before using the new block, check whether block optimization */
+ /* can be done, as well as for join as for local filtering. */
+ /*********************************************************************/
+ switch (Tdbp->TestBlock(g)) {
+ case RC_EF:
+ return RC_EF;
+ case RC_NF:
+ skip++;
+ goto next;
+ } // endswitch rc
+
+ if (skip)
+ // Skip blocks rejected by block optimization
+ for (int i = 0; i < skip; i++) {
+ if (gzseek(Zfile, (z_off_t)Buflen, SEEK_CUR) < 0)
+ return Zerror(g);
+
+ } // endfor i
+
+ if (!(n = gzread(Zfile, To_Buf, Buflen))) {
+ rc = RC_EF;
+ } else if (n > 0) {
+ Rbuf = n / Lrecl;
+ IsRead = true;
+ rc = RC_OK;
+ num_read++;
+ } else
+ rc = Zerror(g);
+
+ return rc;
+ } // end of ReadBuffer
+
+/***********************************************************************/
+/* WriteDB: Data Base write routine for ZDOS access method. */
+/* Update is not possible without using a temporary file (NIY). */
+/***********************************************************************/
+int ZIXFAM::WriteBuffer(PGLOBAL g)
+ {
+ /*********************************************************************/
+ /* In Insert mode, blocs are added sequentialy to the file end. */
+ /* Note: Update mode is not handled for gz files. */
+ /*********************************************************************/
+ if (++CurNum == Rbuf) {
+ /*******************************************************************/
+ /* New block, start the writing process. */
+ /*******************************************************************/
+ BlkLen = Rbuf * Lrecl;
+
+ if (gzwrite(Zfile, To_Buf, BlkLen) != BlkLen ||
+ gzflush(Zfile, Z_FULL_FLUSH)) {
+ Closing = true;
+ return Zerror(g);
+ } // endif gzwrite
+
+ Rbuf = Nrec;
+ CurBlk++;
+ CurNum = 0;
+ Tdbp->SetLine(To_Buf);
+ } else
+ Tdbp->IncLine(Lrecl); // Used by FIXCOL functions
+
+ return RC_OK;
+ } // end of WriteBuffer
+
+/* --------------------------- Class ZLBFAM -------------------------- */
+
+/***********************************************************************/
+/* Constructors. */
+/***********************************************************************/
+ZLBFAM::ZLBFAM(PDOSDEF tdp) : BLKFAM(tdp)
+ {
+ Zstream = NULL;
+ Zbuffer = NULL;
+ Zlenp = NULL;
+ Optimized = tdp->IsOptimized();
+ } // end of ZLBFAM standard constructor
+
+ZLBFAM::ZLBFAM(PZLBFAM txfp) : BLKFAM(txfp)
+ {
+ Zstream = txfp->Zstream;
+ Zbuffer = txfp->Zbuffer;
+ Zlenp = txfp->Zlenp;
+ Optimized = txfp->Optimized;
+ } // end of ZLBFAM (dummy?) copy constructor
+
+/***********************************************************************/
+/* ZLB GetFileLength: returns an estimate of what would be the */
+/* uncompressed file size in number of bytes. */
+/***********************************************************************/
+int ZLBFAM::GetFileLength(PGLOBAL g)
+ {
+ int len = (Optimized) ? BlkPos[Block] : BLKFAM::GetFileLength(g);
+
+ if (len > 0)
+ // Estimate size reduction to a max of 5
+ len *= 5;
+
+ return len;
+ } // end of GetFileLength
+
+/***********************************************************************/
+/* Allocate the line buffer. For mode Delete a bigger buffer has to */
+/* be allocated because is it also used to move lines into the file. */
+/***********************************************************************/
+bool ZLBFAM::AllocateBuffer(PGLOBAL g)
+ {
+ char *msg;
+ int n, zrc;
+
+#if 0
+ if (!Optimized && Tdbp->NeedIndexing(g)) {
+ strcpy(g->Message, MSG(NOP_ZLIB_INDEX));
+ return TRUE;
+ } // endif indexing
+#endif // 0
+
+#if defined(NOLIB)
+ if (!zlib && LoadZlib()) {
+ sprintf(g->Message, MSG(DLL_LOAD_ERROR), GetLastError(), "zlib.dll");
+ return TRUE;
+ } // endif zlib
+#endif
+
+ BLKFAM::AllocateBuffer(g);
+//Buflen = Nrec * (Lrecl + 2);
+//Rbuf = Nrec;
+
+ // Allocate the compressed buffer
+ n = Buflen + 16; // ?????????????????????????????????
+ Zlenp = (int*)PlugSubAlloc(g, NULL, n);
+ Zbuffer = (Byte*)(Zlenp + 1);
+
+ // Allocate and initialize the Z stream
+ Zstream = (z_streamp)PlugSubAlloc(g, NULL, sizeof(z_stream));
+ Zstream->zalloc = (alloc_func)0;
+ Zstream->zfree = (free_func)0;
+ Zstream->opaque = (voidpf)0;
+ Zstream->next_in = NULL;
+ Zstream->avail_in = 0;
+
+ if (Tdbp->GetMode() == MODE_READ) {
+ msg = "inflateInit";
+ zrc = inflateInit(Zstream);
+ } else {
+ msg = "deflateInit";
+ zrc = deflateInit(Zstream, Z_DEFAULT_COMPRESSION);
+ } // endif Mode
+
+ if (zrc != Z_OK) {
+ if (Zstream->msg)
+ sprintf(g->Message, "%s error: %s", msg, Zstream->msg);
+ else
+ sprintf(g->Message, "%s error: %d", msg, zrc);
+
+ return TRUE;
+ } // endif zrc
+
+ if (Tdbp->GetMode() == MODE_INSERT) {
+ // Write the file header block
+ if (Last == Nrec) {
+ CurBlk = Block;
+ CurNum = 0;
+
+ if (!GetFileLength(g)) {
+ // Write the zlib header as an extra block
+ strcpy(To_Buf, "PlugDB");
+ BlkLen = strlen("PlugDB") + 1;
+
+ if (WriteCompressedBuffer(g))
+ return TRUE;
+
+ } // endif void file
+
+ } else {
+ // In mode insert, if Last != Nrec, last block must be updated
+ CurBlk = Block - 1;
+ CurNum = Last;
+
+ strcpy(g->Message, MSG(NO_PAR_BLK_INS));
+ return TRUE;
+ } // endif Last
+
+ } else { // MODE_READ
+ // First thing to do is to read the header block
+ void *rdbuf;
+
+ if (Optimized) {
+ BlkLen = BlkPos[0];
+ rdbuf = Zlenp;
+ } else {
+ // Get the stored length from the file itself
+ if (fread(Zlenp, sizeof(int), 1, Stream) != 1)
+ return FALSE; // Empty file
+
+ BlkLen = *Zlenp;
+ rdbuf = Zbuffer;
+ } // endif Optimized
+
+ switch (ReadCompressedBuffer(g, rdbuf)) {
+ case RC_EF:
+ return FALSE;
+ case RC_FX:
+#if defined(UNIX)
+ sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno));
+#else
+ sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL));
+#endif
+ case RC_NF:
+ return TRUE;
+ } // endswitch
+
+ // Some old tables can have PlugDB in their header
+ if (strcmp(To_Buf, "PlugDB")) {
+ sprintf(g->Message, MSG(BAD_HEADER), Tdbp->GetFile(g));
+ return TRUE;
+ } // endif strcmp
+
+ } // endif Mode
+
+ return FALSE;
+ } // end of AllocateBuffer
+
+/***********************************************************************/
+/* GetPos: return the position of last read record. */
+/***********************************************************************/
+int ZLBFAM::GetPos(void)
+ {
+ return (Optimized) ? (CurNum + Nrec * CurBlk) : Fpos;
+ } // end of GetPos
+
+/***********************************************************************/
+/* GetNextPos: should not be called for this class. */
+/***********************************************************************/
+int ZLBFAM::GetNextPos(void)
+ {
+ if (Optimized) {
+ assert(FALSE);
+ return 0;
+ } else
+ return ftell(Stream);
+
+ } // end of GetNextPos
+
+/***********************************************************************/
+/* SetPos: Replace the table at the specified position. */
+/***********************************************************************/
+bool ZLBFAM::SetPos(PGLOBAL g, int pos __attribute__((unused)))
+ {
+ sprintf(g->Message, MSG(NO_SETPOS_YET), "GZ");
+ return true;
+#if 0 // All this must be checked
+ if (pos < 0) {
+ strcpy(g->Message, MSG(INV_REC_POS));
+ return true;
+ } // endif recpos
+
+ CurBlk = pos / Nrec;
+ CurNum = pos % Nrec;
+#if defined(_DEBUG)
+ num_eq[(CurBlk == OldBlk) ? 1 : 0]++;
+#endif
+
+ // Indicate the table position was externally set
+ Placed = true;
+ return false;
+#endif // 0
+ } // end of SetPos
+
+/***********************************************************************/
+/* ReadBuffer: Read one line for a text file. */
+/***********************************************************************/
+int ZLBFAM::ReadBuffer(PGLOBAL g)
+ {
+ int n;
+ void *rdbuf;
+
+ /*********************************************************************/
+ /* Sequential reading when Placed is not true. */
+ /*********************************************************************/
+ if (Placed) {
+ Placed = FALSE;
+ } else if (++CurNum < Rbuf) {
+ CurLine = NxtLine;
+
+ // Get the position of the next line in the buffer
+ if (Tdbp->GetFtype() == RECFM_VAR)
+ while (*NxtLine++ != '\n') ;
+ else
+ NxtLine += Lrecl;
+
+ // Set caller line buffer
+ n = NxtLine - CurLine - ((Tdbp->GetFtype() == RECFM_BIN) ? 0 : Ending);
+ memcpy(Tdbp->GetLine(), CurLine, n);
+ Tdbp->GetLine()[n] = '\0';
+ return RC_OK;
+ } else if (Rbuf < Nrec && CurBlk != -1) {
+ CurNum--; // To have a correct Last value when optimizing
+ return RC_EF;
+ } else {
+ /*******************************************************************/
+ /* New block. */
+ /*******************************************************************/
+ CurNum = 0;
+
+ next:
+ if (++CurBlk >= Block)
+ return RC_EF;
+
+ /*******************************************************************/
+ /* Before reading a new block, check whether block optimization */
+ /* can be done, as well as for join as for local filtering. */
+ /*******************************************************************/
+ if (Optimized) switch (Tdbp->TestBlock(g)) {
+ case RC_EF:
+ return RC_EF;
+ case RC_NF:
+ goto next;
+ } // endswitch rc
+
+ } // endif's
+
+ if (OldBlk == CurBlk)
+ goto ok; // Block is already there
+
+ if (Optimized) {
+ // Store the position of next block
+ Fpos = BlkPos[CurBlk];
+
+ // fseek is required only in non sequential reading
+ if (CurBlk != OldBlk + 1)
+ if (fseek(Stream, Fpos, SEEK_SET)) {
+ sprintf(g->Message, MSG(FSETPOS_ERROR), Fpos);
+ return RC_FX;
+ } // endif fseek
+
+ // Calculate the length of block to read
+ BlkLen = BlkPos[CurBlk + 1] - Fpos;
+ rdbuf = Zlenp;
+ } else { // !Optimized
+ if (CurBlk != OldBlk + 1) {
+ strcpy(g->Message, MSG(INV_RAND_ACC));
+ return RC_FX;
+ } else
+ Fpos = ftell(Stream); // Used when optimizing
+
+ // Get the stored length from the file itself
+ if (fread(Zlenp, sizeof(int), 1, Stream) != 1) {
+ if (feof(Stream))
+ return RC_EF;
+
+ goto err;
+ } // endif fread
+
+ BlkLen = *Zlenp;
+ rdbuf = Zbuffer;
+ } // endif Optimized
+
+ // Read the next block
+ switch (ReadCompressedBuffer(g, rdbuf)) {
+ case RC_FX: goto err;
+ case RC_NF: return RC_FX;
+ case RC_EF: return RC_EF;
+ default: Rbuf = (CurBlk == Block - 1) ? Last : Nrec;
+ } // endswitch ReadCompressedBuffer
+
+ ok:
+ if (Tdbp->GetFtype() == RECFM_VAR) {
+ int i;
+
+ // Get the position of the current line
+ for (i = 0, CurLine = To_Buf; i < CurNum; i++)
+ while (*CurLine++ != '\n') ; // What about Unix ???
+
+ // Now get the position of the next line
+ for (NxtLine = CurLine; *NxtLine++ != '\n';) ;
+
+ // Set caller line buffer
+ n = NxtLine - CurLine - Ending;
+ } else {
+ CurLine = To_Buf + CurNum * Lrecl;
+ NxtLine = CurLine + Lrecl;
+ n = Lrecl - ((Tdbp->GetFtype() == RECFM_BIN) ? 0 : Ending);
+ } // endif Ftype
+
+ memcpy(Tdbp->GetLine(), CurLine, n);
+ Tdbp->GetLine()[n] = '\0';
+
+ OldBlk = CurBlk; // Last block actually read
+ IsRead = TRUE; // Is read indeed
+ return RC_OK;
+
+ err:
+#if defined(UNIX)
+ sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno));
+#else
+ sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL));
+#endif
+ return RC_FX;
+ } // end of ReadBuffer
+
+/***********************************************************************/
+/* Read and decompress a block from the stream. */
+/***********************************************************************/
+int ZLBFAM::ReadCompressedBuffer(PGLOBAL g, void *rdbuf)
+ {
+ if (fread(rdbuf, 1, (size_t)BlkLen, Stream) == (unsigned)BlkLen) {
+ int zrc;
+
+ num_read++;
+
+ if (Optimized && BlkLen != signed(*Zlenp + sizeof(int))) {
+ sprintf(g->Message, MSG(BAD_BLK_SIZE), CurBlk + 1);
+ return RC_NF;
+ } // endif BlkLen
+
+ // HERE WE MUST INFLATE THE BLOCK
+ Zstream->next_in = Zbuffer;
+ Zstream->avail_in = (uInt)(*Zlenp);
+ Zstream->next_out = (Byte*)To_Buf;
+ Zstream->avail_out = Buflen;
+ zrc = inflate(Zstream, Z_SYNC_FLUSH);
+
+ if (zrc != Z_OK) {
+ if (Zstream->msg)
+ sprintf(g->Message, MSG(FUNC_ERR_S), "inflate", Zstream->msg);
+ else
+ sprintf(g->Message, MSG(FUNCTION_ERROR), "inflate", (int)zrc);
+
+ return RC_NF;
+ } // endif zrc
+
+ } else if (feof(Stream)) {
+ return RC_EF;
+ } else
+ return RC_FX;
+
+ return RC_OK;
+ } // end of ReadCompressedBuffer
+
+/***********************************************************************/
+/* WriteBuffer: File write routine for DOS access method. */
+/* Update is directly written back into the file, */
+/* with this (fast) method, record size cannot change. */
+/***********************************************************************/
+int ZLBFAM::WriteBuffer(PGLOBAL g)
+ {
+ assert (Tdbp->GetMode() == MODE_INSERT);
+
+ /*********************************************************************/
+ /* Prepare the write buffer. */
+ /*********************************************************************/
+ if (!Closing) {
+ if (Tdbp->GetFtype() == RECFM_BIN)
+ memcpy(CurLine, Tdbp->GetLine(), Lrecl);
+ else
+ strcat(strcpy(CurLine, Tdbp->GetLine()), CrLf);
+
+#if defined(_DEBUG)
+ if (Tdbp->GetFtype() == RECFM_FIX &&
+ (signed)strlen(CurLine) != Lrecl + (signed)strlen(CrLf)) {
+ strcpy(g->Message, MSG(BAD_LINE_LEN));
+ Closing = TRUE;
+ return RC_FX;
+ } // endif Lrecl
+#endif // _DEBUG
+ } // endif Closing
+
+ /*********************************************************************/
+ /* In Insert mode, blocs are added sequentialy to the file end. */
+ /*********************************************************************/
+ if (++CurNum != Rbuf) {
+ if (Tdbp->GetFtype() == RECFM_VAR)
+ CurLine += strlen(CurLine);
+ else
+ CurLine += Lrecl;
+
+ return RC_OK; // We write only full blocks
+ } // endif CurNum
+
+ // HERE WE MUST DEFLATE THE BLOCK
+ if (Tdbp->GetFtype() == RECFM_VAR)
+ NxtLine = CurLine + strlen(CurLine);
+ else
+ NxtLine = CurLine + Lrecl;
+
+ BlkLen = NxtLine - To_Buf;
+
+ if (WriteCompressedBuffer(g)) {
+ Closing = TRUE; // To tell CloseDB about a Write error
+ return RC_FX;
+ } // endif WriteCompressedBuffer
+
+ CurBlk++;
+ CurNum = 0;
+ CurLine = To_Buf;
+ return RC_OK;
+ } // end of WriteBuffer
+
+/***********************************************************************/
+/* Compress the buffer and write the deflated output to stream. */
+/***********************************************************************/
+bool ZLBFAM::WriteCompressedBuffer(PGLOBAL g)
+ {
+ int zrc;
+
+ Zstream->next_in = (Byte*)To_Buf;
+ Zstream->avail_in = (uInt)BlkLen;
+ Zstream->next_out = Zbuffer;
+ Zstream->avail_out = Buflen + 16;
+ Zstream->total_out = 0;
+ zrc = deflate(Zstream, Z_FULL_FLUSH);
+
+ if (zrc != Z_OK) {
+ if (Zstream->msg)
+ sprintf(g->Message, MSG(FUNC_ERR_S), "deflate", Zstream->msg);
+ else
+ sprintf(g->Message, MSG(FUNCTION_ERROR), "deflate", (int)zrc);
+
+ return TRUE;
+ } else
+ *Zlenp = Zstream->total_out;
+
+ // Now start the writing process.
+ BlkLen = *Zlenp + sizeof(int);
+
+ if (fwrite(Zlenp, 1, BlkLen, Stream) != (size_t)BlkLen) {
+ sprintf(g->Message, MSG(FWRITE_ERROR), strerror(errno));
+ return TRUE;
+ } // endif size
+
+ return FALSE;
+ } // end of WriteCompressedBuffer
+
+/***********************************************************************/
+/* Table file close routine for DOS access method. */
+/***********************************************************************/
+void ZLBFAM::CloseTableFile(PGLOBAL g, bool)
+ {
+ int rc = RC_OK;
+
+ if (Tdbp->GetMode() == MODE_INSERT) {
+ LPCSTR name = Tdbp->GetName();
+ PDOSDEF defp = (PDOSDEF)Tdbp->GetDef();
+
+ // Closing is True if last Write was in error
+ if (CurNum && !Closing) {
+ // Some more inserted lines remain to be written
+ Last = (Nrec - Rbuf) + CurNum;
+ Block = CurBlk + 1;
+ Rbuf = CurNum--;
+ Closing = TRUE;
+ rc = WriteBuffer(g);
+ } else if (Rbuf == Nrec) {
+ Last = Nrec;
+ Block = CurBlk;
+ } // endif CurNum
+
+ if (rc != RC_FX) {
+ defp->SetBlock(Block);
+ defp->SetLast(Last);
+ defp->SetIntCatInfo("Blocks", Block);
+ defp->SetIntCatInfo("Last", Last);
+ } // endif
+
+ fclose(Stream);
+ } else
+ rc = fclose(Stream);
+
+ if (trace)
+ htrc("ZLB CloseTableFile: closing %s mode=%d rc=%d\n",
+ To_File, Tdbp->GetMode(), rc);
+
+ Stream = NULL; // So we can know whether table is open
+ To_Fb->Count = 0; // Avoid double closing by PlugCloseAll
+
+ if (Tdbp->GetMode() == MODE_READ)
+ rc = inflateEnd(Zstream);
+ else
+ rc = deflateEnd(Zstream);
+
+ } // end of CloseTableFile
+
+/***********************************************************************/
+/* Rewind routine for ZLIB access method. */
+/***********************************************************************/
+void ZLBFAM::Rewind(void)
+ {
+ // We must be positioned after the header block
+ if (CurBlk >= 0) { // Nothing to do if no block read yet
+ if (!Optimized) { // If optimized, fseek will be done in ReadBuffer
+ size_t st;
+
+ rewind(Stream);
+
+ if (!(st = fread(Zlenp, sizeof(int), 1, Stream)) && trace)
+ htrc("fread error %d in Rewind", errno);
+
+ fseek(Stream, *Zlenp + sizeof(int), SEEK_SET);
+ OldBlk = -1;
+ } // endif Optimized
+
+ CurBlk = -1;
+ CurNum = Rbuf;
+ } // endif CurBlk
+
+//OldBlk = -1;
+//Rbuf = 0; commented out in case we reuse last read block
+ } // end of Rewind
+
+/* ------------------------ End of GzFam ---------------------------- */
diff --git a/storage/connect/filamgz.h b/storage/connect/filamgz.h
new file mode 100644
index 00000000000..d667fdddcc2
--- /dev/null
+++ b/storage/connect/filamgz.h
@@ -0,0 +1,170 @@
+/*************** FilAmGz H Declares Source Code File (.H) **************/
+/* Name: FILAMGZ.H Version 1.3 */
+/* */
+/* (C) Copyright to the author Olivier BERTRAND 2005-2016 */
+/* */
+/* This file contains the GZIP access method classes declares. */
+/***********************************************************************/
+#ifndef __FILAMGZ_H
+#define __FILAMGZ_H
+
+#include "zlib.h"
+
+typedef class GZFAM *PGZFAM;
+typedef class ZBKFAM *PZBKFAM;
+typedef class ZIXFAM *PZIXFAM;
+typedef class ZLBFAM *PZLBFAM;
+
+/***********************************************************************/
+/* This is the access method class declaration for not optimized */
+/* variable record length files compressed using the gzip library */
+/* functions. File is accessed record by record (row). */
+/***********************************************************************/
+class DllExport GZFAM : public TXTFAM {
+// friend class DOSCOL;
+ public:
+ // Constructor
+ GZFAM(PDOSDEF tdp) : TXTFAM(tdp) {Zfile = NULL; Zpos = 0;}
+ GZFAM(PGZFAM txfp);
+
+ // Implementation
+ virtual AMT GetAmType(void) {return TYPE_AM_GZ;}
+ virtual int GetPos(void);
+ virtual int GetNextPos(void);
+ virtual PTXF Duplicate(PGLOBAL g)
+ {return (PTXF)new(g) GZFAM(this);}
+
+ // Methods
+ virtual void Reset(void);
+ virtual int GetFileLength(PGLOBAL g);
+ virtual int Cardinality(PGLOBAL g) {return (g) ? -1 : 0;}
+ virtual int MaxBlkSize(PGLOBAL g, int s) {return s;}
+ virtual bool AllocateBuffer(PGLOBAL g);
+ virtual int GetRowID(void);
+ virtual bool RecordPos(PGLOBAL g);
+ virtual bool SetPos(PGLOBAL g, int recpos);
+ virtual int SkipRecord(PGLOBAL g, bool header);
+ virtual bool OpenTableFile(PGLOBAL g);
+ virtual int ReadBuffer(PGLOBAL g);
+ virtual int WriteBuffer(PGLOBAL g);
+ virtual int DeleteRecords(PGLOBAL g, int irc);
+ virtual void CloseTableFile(PGLOBAL g, bool abort);
+ virtual void Rewind(void);
+
+ protected:
+ int Zerror(PGLOBAL g); // GZ error function
+
+ // Members
+ gzFile Zfile; // Points to GZ file structure
+ z_off_t Zpos; // Uncompressed file position
+ }; // end of class GZFAM
+
+/***********************************************************************/
+/* This is the access method class declaration for optimized variable */
+/* record length files compressed using the gzip library functions. */
+/* The File is accessed by block (requires an opt file). */
+/***********************************************************************/
+class DllExport ZBKFAM : public GZFAM {
+ public:
+ // Constructor
+ ZBKFAM(PDOSDEF tdp);
+ ZBKFAM(PZBKFAM txfp);
+
+ // Implementation
+ virtual int GetPos(void);
+ virtual int GetNextPos(void) {return 0;}
+ virtual PTXF Duplicate(PGLOBAL g)
+ {return (PTXF)new(g) ZBKFAM(this);}
+
+ // Methods
+ virtual int Cardinality(PGLOBAL g);
+ virtual int MaxBlkSize(PGLOBAL g, int s);
+ virtual bool AllocateBuffer(PGLOBAL g);
+ virtual int GetRowID(void);
+ virtual bool RecordPos(PGLOBAL g);
+ virtual int SkipRecord(PGLOBAL g, bool header);
+ virtual int ReadBuffer(PGLOBAL g);
+ virtual int WriteBuffer(PGLOBAL g);
+ virtual int DeleteRecords(PGLOBAL g, int irc);
+ virtual void CloseTableFile(PGLOBAL g, bool abort);
+ virtual void Rewind(void);
+
+ protected:
+ // Members
+ char *CurLine; // Position of current line in buffer
+ char *NxtLine; // Position of Next line in buffer
+ bool Closing; // True when closing on Insert
+ }; // end of class ZBKFAM
+
+/***********************************************************************/
+/* This is the access method class declaration for fixed record */
+/* length files compressed using the gzip library functions. */
+/* The file is always accessed by block. */
+/***********************************************************************/
+class DllExport ZIXFAM : public ZBKFAM {
+ public:
+ // Constructor
+ ZIXFAM(PDOSDEF tdp);
+ ZIXFAM(PZIXFAM txfp) : ZBKFAM(txfp) {}
+
+ // Implementation
+ virtual int GetNextPos(void) {return 0;}
+ virtual PTXF Duplicate(PGLOBAL g)
+ {return (PTXF)new(g) ZIXFAM(this);}
+
+ // Methods
+ virtual int Cardinality(PGLOBAL g);
+ virtual bool AllocateBuffer(PGLOBAL g);
+ virtual int ReadBuffer(PGLOBAL g);
+ virtual int WriteBuffer(PGLOBAL g);
+
+ protected:
+ // No additional Members
+ }; // end of class ZIXFAM
+
+/***********************************************************************/
+/* This is the DOS/UNIX Access Method class declaration for PlugDB */
+/* fixed/variable files compressed using the zlib library functions. */
+/* Physically these are written and read using the same technique */
+/* than blocked variable files, only the contain of each block is */
+/* compressed using the deflate zlib function. The purpose of this */
+/* specific format is to have a fast mechanism for direct access of */
+/* records so blocked optimization is fast and direct access (joins) */
+/* is allowed. Note that the block length is written ahead of each */
+/* block to enable reading when optimization file is not available. */
+/***********************************************************************/
+class DllExport ZLBFAM : public BLKFAM {
+ public:
+ // Constructor
+ ZLBFAM(PDOSDEF tdp);
+ ZLBFAM(PZLBFAM txfp);
+
+ // Implementation
+ virtual AMT GetAmType(void) {return TYPE_AM_ZLIB;}
+ virtual int GetPos(void);
+ virtual int GetNextPos(void);
+ virtual PTXF Duplicate(PGLOBAL g)
+ {return (PTXF)new(g) ZLBFAM(this);}
+ inline void SetOptimized(bool b) {Optimized = b;}
+
+ // Methods
+ virtual int GetFileLength(PGLOBAL g);
+ virtual bool SetPos(PGLOBAL g, int recpos);
+ virtual bool AllocateBuffer(PGLOBAL g);
+ virtual int ReadBuffer(PGLOBAL g);
+ virtual int WriteBuffer(PGLOBAL g);
+ virtual void CloseTableFile(PGLOBAL g, bool abort);
+ virtual void Rewind(void);
+
+ protected:
+ bool WriteCompressedBuffer(PGLOBAL g);
+ int ReadCompressedBuffer(PGLOBAL g, void *rdbuf);
+
+ // Members
+ z_streamp Zstream; // Compression/decompression stream
+ Byte *Zbuffer; // Compressed block buffer
+ int *Zlenp; // Pointer to block length
+ bool Optimized; // true when opt file is available
+ }; // end of class ZLBFAM
+
+#endif // __FILAMGZ_H
diff --git a/storage/connect/filamzip.cpp b/storage/connect/filamzip.cpp
index d9834e56dcd..22fe95aebad 100644
--- a/storage/connect/filamzip.cpp
+++ b/storage/connect/filamzip.cpp
@@ -1,35 +1,29 @@
/*********** File AM Zip C++ Program Source Code File (.CPP) ***********/
/* PROGRAM NAME: FILAMZIP */
/* ------------- */
-/* Version 1.5 */
+/* Version 1.0 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 2005-2015 */
+/* (C) Copyright to the author Olivier BERTRAND 2016 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
-/* This program are the ZLIB compressed files classes. */
+/* This program are the ZIP file access method classes. */
/* */
/***********************************************************************/
/***********************************************************************/
-/* Include relevant MariaDB header file. */
+/* Include relevant sections of the System header files. */
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
-#include <io.h>
-#include <fcntl.h>
-#if defined(__BORLANDC__)
-#define __MFC_COMPAT__ // To define min/max as macro
-#endif
-//#include <windows.h>
-#else // !__WIN__
+#if !defined(__WIN__)
#if defined(UNIX)
#include <errno.h>
-#else // !UNIX
+#include <unistd.h>
+#else // !UNIX
#include <io.h>
-#endif
+#endif // !UNIX
#include <fcntl.h>
#endif // !__WIN__
@@ -37,1390 +31,592 @@
/* Include application header files: */
/* global.h is header containing all global declarations. */
/* plgdbsem.h is header containing the DB application declarations. */
-/* tabdos.h is header containing the TABDOS class declarations. */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
-//#include "catalog.h"
-//#include "reldef.h"
-//#include "xobject.h"
-//#include "kindex.h"
-#include "filamtxt.h"
-#include "tabdos.h"
-#if defined(UNIX)
#include "osutil.h"
-#endif
-
-/***********************************************************************/
-/* This define prepares ZLIB function declarations. */
-/***********************************************************************/
-//#define ZLIB_DLL
-
+#include "filamtxt.h"
+#include "tabfmt.h"
+//#include "tabzip.h"
#include "filamzip.h"
-/***********************************************************************/
-/* DB static variables. */
-/***********************************************************************/
-extern int num_read, num_there, num_eq[]; // Statistics
-
-/* ------------------------------------------------------------------- */
+/* -------------------------- class ZIPUTIL -------------------------- */
/***********************************************************************/
-/* Implementation of the ZIPFAM class. */
+/* Constructors. */
/***********************************************************************/
-ZIPFAM::ZIPFAM(PZIPFAM txfp) : TXTFAM(txfp)
- {
- Zfile = txfp->Zfile;
- Zpos = txfp->Zpos;
- } // end of ZIPFAM copy constructor
+ZIPUTIL::ZIPUTIL(PSZ tgt, bool mul)
+{
+ zipfile = NULL;
+ target = tgt;
+ fp = NULL;
+ memory = NULL;
+ size = 0;
+ entryopen = false;
+ multiple = mul;
+ memset(fn, 0, sizeof(fn));
+
+ // Init the case mapping table.
+#if defined(__WIN__)
+ for (int i = 0; i < 256; ++i) mapCaseTable[i] = toupper(i);
+#else
+ for (int i = 0; i < 256; ++i) mapCaseTable[i] = i;
+#endif
+} // end of ZIPUTIL standard constructor
+
+#if 0
+ZIPUTIL::ZIPUTIL(PZIPUTIL zutp)
+{
+ zipfile = zutp->zipfile;
+ target = zutp->target;
+ fp = zutp->fp;
+ finfo = zutp->finfo;
+ entryopen = zutp->entryopen;
+ multiple = zutp->multiple;
+ for (int i = 0; i < 256; ++i) mapCaseTable[i] = zutp->mapCaseTable[i];
+} // end of ZIPUTIL copy constructor
+#endif // 0
/***********************************************************************/
-/* Zerror: Error function for gz calls. */
-/* gzerror returns the error message for the last error which occurred*/
-/* on the given compressed file. errnum is set to zlib error number. */
-/* If an error occurred in the file system and not in the compression */
-/* library, errnum is set to Z_ERRNO and the application may consult */
-/* errno to get the exact error code. */
+/* This code is the copyright property of Alessandro Felice Cantatore. */
+/* http://xoomer.virgilio.it/acantato/dev/wildcard/wildmatch.html */
/***********************************************************************/
-int ZIPFAM::Zerror(PGLOBAL g)
- {
- int errnum;
+bool ZIPUTIL::WildMatch(PSZ pat, PSZ str) {
+ PSZ s, p;
+ bool star = FALSE;
- strcpy(g->Message, gzerror(Zfile, &errnum));
+loopStart:
+ for (s = str, p = pat; *s; ++s, ++p) {
+ switch (*p) {
+ case '?':
+ if (*s == '.') goto starCheck;
+ break;
+ case '*':
+ star = TRUE;
+ str = s, pat = p;
+ if (!*++pat) return TRUE;
+ goto loopStart;
+ default:
+ if (mapCaseTable[(unsigned)*s] != mapCaseTable[(unsigned)*p])
+ goto starCheck;
+ break;
+ } /* endswitch */
+ } /* endfor */
+ if (*p == '*') ++p;
+ return (!*p);
- if (errnum == Z_ERRNO)
-#if defined(__WIN__)
- sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(NULL));
-#else // !__WIN__
- sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno));
-#endif // !__WIN__
-
- return (errnum == Z_STREAM_END) ? RC_EF : RC_FX;
- } // end of Zerror
+starCheck:
+ if (!star) return FALSE;
+ str++;
+ goto loopStart;
+} // end of WildMatch
/***********************************************************************/
-/* Reset: reset position values at the beginning of file. */
+/* open a zip file. */
+/* param: filename path and the filename of the zip file to open. */
+/* return: true if open, false otherwise. */
/***********************************************************************/
-void ZIPFAM::Reset(void)
- {
- TXTFAM::Reset();
-//gzrewind(Zfile); // Useful ?????
- Zpos = 0;
- } // end of Reset
+bool ZIPUTIL::open(PGLOBAL g, char *filename)
+{
+ if (!zipfile && !(zipfile = unzOpen64(filename)))
+ sprintf(g->Message, "Zipfile open error on %s", filename);
+
+ return (zipfile == NULL);
+} // end of open
/***********************************************************************/
-/* ZIP GetFileLength: returns an estimate of what would be the */
-/* uncompressed file size in number of bytes. */
+/* Close the zip file. */
/***********************************************************************/
-int ZIPFAM::GetFileLength(PGLOBAL g)
- {
- int len = TXTFAM::GetFileLength(g);
+void ZIPUTIL::close()
+{
+ if (zipfile) {
+ closeEntry();
+ unzClose(zipfile);
+ zipfile = NULL;
+ } // endif zipfile
- if (len > 0)
- // Estimate size reduction to a max of 6
- len *= 6;
-
- return len;
- } // end of GetFileLength
+} // end of close
/***********************************************************************/
-/* ZIP Access Method opening routine. */
+/* Find next entry matching target pattern. */
/***********************************************************************/
-bool ZIPFAM::OpenTableFile(PGLOBAL g)
- {
- char opmode[4], filename[_MAX_PATH];
- MODE mode = Tdbp->GetMode();
-
- switch (mode) {
- case MODE_READ:
- strcpy(opmode, "r");
- break;
- case MODE_UPDATE:
- /*****************************************************************/
- /* Updating ZIP files not implemented yet. */
- /*****************************************************************/
- strcpy(g->Message, MSG(UPD_ZIP_NOT_IMP));
- return true;
- case MODE_DELETE:
- if (!Tdbp->GetNext()) {
- // Store the number of deleted lines
- DelRows = Cardinality(g);
-
- // This will erase the entire file
- strcpy(opmode, "w");
-// Block = 0; // For ZBKFAM
-// Last = Nrec; // For ZBKFAM
- Tdbp->ResetSize();
- } else {
- sprintf(g->Message, MSG(NO_PART_DEL), "ZIP");
- return true;
- } // endif filter
-
- break;
- case MODE_INSERT:
- strcpy(opmode, "a+");
- break;
- default:
- sprintf(g->Message, MSG(BAD_OPEN_MODE), mode);
- return true;
- } // endswitch Mode
-
- /*********************************************************************/
- /* Open according to logical input/output mode required. */
- /* Use specific zlib functions. */
- /* Treat files as binary. */
- /*********************************************************************/
- strcat(opmode, "b");
- Zfile = gzopen(PlugSetPath(filename, To_File, Tdbp->GetPath()), opmode);
-
- if (Zfile == NULL) {
- sprintf(g->Message, MSG(GZOPEN_ERROR),
- opmode, (int)errno, filename);
- strcat(strcat(g->Message, ": "), strerror(errno));
- return (mode == MODE_READ && errno == ENOENT)
- ? PushWarning(g, Tdbp) : true;
- } // endif Zfile
-
- /*********************************************************************/
- /* Something to be done here. >>>>>>>> NOT DONE <<<<<<<< */
- /*********************************************************************/
-//To_Fb = dbuserp->Openlist; // Keep track of File block
-
- /*********************************************************************/
- /* Allocate the line buffer. */
- /*********************************************************************/
- return AllocateBuffer(g);
- } // end of OpenTableFile
+int ZIPUTIL::findEntry(PGLOBAL g, bool next)
+{
+ int rc;
-/***********************************************************************/
-/* Allocate the line buffer. For mode Delete a bigger buffer has to */
-/* be allocated because is it also used to move lines into the file. */
-/***********************************************************************/
-bool ZIPFAM::AllocateBuffer(PGLOBAL g)
- {
- MODE mode = Tdbp->GetMode();
+ do {
+ if (next) {
+ rc = unzGoToNextFile(zipfile);
- Buflen = Lrecl + 2; // Lrecl does not include CRLF
-//Buflen *= ((Mode == MODE_DELETE) ? DOS_BUFF_LEN : 1); NIY
+ if (rc == UNZ_END_OF_LIST_OF_FILE)
+ return RC_EF;
+ else if (rc != UNZ_OK) {
+ sprintf(g->Message, "unzGoToNextFile rc = %d", rc);
+ return RC_FX;
+ } // endif rc
- if (trace)
- htrc("SubAllocating a buffer of %d bytes\n", Buflen);
+ } // endif next
- To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);
+ if (target && *target) {
+ rc = unzGetCurrentFileInfo(zipfile, NULL, fn, sizeof(fn),
+ NULL, 0, NULL, 0);
+ if (rc == UNZ_OK) {
+ if (WildMatch(target, fn))
+ return RC_OK;
- if (mode == MODE_INSERT) {
- /*******************************************************************/
- /* For Insert buffer must be prepared. */
- /*******************************************************************/
- memset(To_Buf, ' ', Buflen);
- To_Buf[Buflen - 2] = '\n';
- To_Buf[Buflen - 1] = '\0';
- } // endif Insert
+ } else {
+ sprintf(g->Message, "GetCurrentFileInfo rc = %d", rc);
+ return RC_FX;
+ } // endif rc
- return false;
- } // end of AllocateBuffer
+ } else
+ return RC_OK;
-/***********************************************************************/
-/* GetRowID: return the RowID of last read record. */
-/***********************************************************************/
-int ZIPFAM::GetRowID(void)
- {
- return Rows;
- } // end of GetRowID
+ next = true;
+ } while (true);
-/***********************************************************************/
-/* GetPos: return the position of last read record. */
-/***********************************************************************/
-int ZIPFAM::GetPos(void)
- {
- return (int)Zpos;
- } // end of GetPos
+ strcpy(g->Message, "FindNext logical error");
+ return RC_FX;
+} // end of FindEntry
-/***********************************************************************/
-/* GetNextPos: return the position of next record. */
-/***********************************************************************/
-int ZIPFAM::GetNextPos(void)
- {
- return gztell(Zfile);
- } // end of GetNextPos
/***********************************************************************/
-/* SetPos: Replace the table at the specified position. */
+/* Get the next used entry. */
/***********************************************************************/
-bool ZIPFAM::SetPos(PGLOBAL g, int pos __attribute__((unused)))
- {
- sprintf(g->Message, MSG(NO_SETPOS_YET), "ZIP");
- return true;
-#if 0
- Fpos = pos;
+int ZIPUTIL::nextEntry(PGLOBAL g)
+{
+ if (multiple) {
+ int rc;
- if (fseek(Stream, Fpos, SEEK_SET)) {
- sprintf(g->Message, MSG(FSETPOS_ERROR), Fpos);
- return true;
- } // endif
+ closeEntry();
- Placed = true;
- return false;
-#endif // 0
- } // end of SetPos
+ if ((rc = findEntry(g, true)) != RC_OK)
+ return rc;
-/***********************************************************************/
-/* Record file position in case of UPDATE or DELETE. */
-/***********************************************************************/
-bool ZIPFAM::RecordPos(PGLOBAL)
- {
- Zpos = gztell(Zfile);
- return false;
- } // end of RecordPos
+ if (openEntry(g))
+ return RC_FX;
-/***********************************************************************/
-/* Skip one record in file. */
-/***********************************************************************/
-int ZIPFAM::SkipRecord(PGLOBAL g, bool header)
- {
- // Skip this record
- if (gzeof(Zfile))
- return RC_EF;
- else if (gzgets(Zfile, To_Buf, Buflen) == Z_NULL)
- return Zerror(g);
+ return RC_OK;
+ } else
+ return RC_EF;
- if (header)
- RecordPos(g);
+} // end of nextEntry
- return RC_OK;
- } // end of SkipRecord
/***********************************************************************/
-/* ReadBuffer: Read one line from a compressed text file. */
+/* OpenTableFile: Open a DOS/UNIX table file from a ZIP file. */
/***********************************************************************/
-int ZIPFAM::ReadBuffer(PGLOBAL g)
- {
- char *p;
- int rc;
-
- if (!Zfile)
- return RC_EF;
-
- if (!Placed) {
- /*******************************************************************/
- /* Record file position in case of UPDATE or DELETE. */
- /*******************************************************************/
- next:
- if (RecordPos(g))
- return RC_FX;
-
- CurBlk = Rows++; // Update RowID
-
- /*******************************************************************/
- /* Check whether optimization on ROWID */
- /* can be done, as well as for join as for local filtering. */
- /*******************************************************************/
- switch (Tdbp->TestBlock(g)) {
- case RC_EF:
- return RC_EF;
- case RC_NF:
- // Skip this record
- if ((rc = SkipRecord(g, FALSE)) != RC_OK)
- return rc;
-
- goto next;
- } // endswitch rc
-
- } else
- Placed = false;
-
- if (gzeof(Zfile)) {
- rc = RC_EF;
- } else if (gzgets(Zfile, To_Buf, Buflen) != Z_NULL) {
- p = To_Buf + strlen(To_Buf) - 1;
-
- if (*p == '\n')
- *p = '\0'; // Eliminate ending new-line character
-
- if (*(--p) == '\r')
- *p = '\0'; // Eliminate eventuel carriage return
-
- strcpy(Tdbp->GetLine(), To_Buf);
- IsRead = true;
- rc = RC_OK;
- num_read++;
- } else
- rc = Zerror(g);
-
- if (trace > 1)
- htrc(" Read: '%s' rc=%d\n", To_Buf, rc);
-
- return rc;
- } // end of ReadBuffer
+bool ZIPUTIL::OpenTable(PGLOBAL g, MODE mode, char *fn)
+{
+ /*********************************************************************/
+ /* The file will be decompressed into virtual memory. */
+ /*********************************************************************/
+ if (mode == MODE_READ || mode == MODE_ANY) {
+ bool b = open(g, fn);
-/***********************************************************************/
-/* WriteDB: Data Base write routine for ZDOS access method. */
-/* Update is not possible without using a temporary file (NIY). */
-/***********************************************************************/
-int ZIPFAM::WriteBuffer(PGLOBAL g)
- {
- /*********************************************************************/
- /* Prepare the write buffer. */
- /*********************************************************************/
- strcat(strcpy(To_Buf, Tdbp->GetLine()), CrLf);
-
- /*********************************************************************/
- /* Now start the writing process. */
- /*********************************************************************/
- if (gzputs(Zfile, To_Buf) < 0)
- return Zerror(g);
-
- return RC_OK;
- } // end of WriteBuffer
+ if (!b) {
+ int rc;
-/***********************************************************************/
-/* Data Base delete line routine for ZDOS access method. (NIY) */
-/***********************************************************************/
-int ZIPFAM::DeleteRecords(PGLOBAL g, int)
- {
- strcpy(g->Message, MSG(NO_ZIP_DELETE));
- return RC_FX;
- } // end of DeleteRecords
+ if (target && *target) {
+ if (!multiple) {
+ rc = unzLocateFile(zipfile, target, 0);
-/***********************************************************************/
-/* Data Base close routine for DOS access method. */
-/***********************************************************************/
-void ZIPFAM::CloseTableFile(PGLOBAL, bool)
- {
- int rc = gzclose(Zfile);
+ if (rc == UNZ_END_OF_LIST_OF_FILE) {
+ sprintf(g->Message, "Target file %s not in %s", target, fn);
+ return true;
+ } else if (rc != UNZ_OK) {
+ sprintf(g->Message, "unzLocateFile rc=%d", rc);
+ return true;
+ } // endif's rc
- if (trace)
- htrc("ZIP CloseDB: closing %s rc=%d\n", To_File, rc);
+ } else {
+ if ((rc = findEntry(g, false)) == RC_FX)
+ return true;
+ else if (rc == RC_EF) {
+ sprintf(g->Message, "No match of %s in %s", target, fn);
+ return true;
+ } // endif rc
- Zfile = NULL; // So we can know whether table is open
-//To_Fb->Count = 0; // Avoid double closing by PlugCloseAll
- } // end of CloseTableFile
+ } // endif multiple
-/***********************************************************************/
-/* Rewind routine for ZIP access method. */
-/***********************************************************************/
-void ZIPFAM::Rewind(void)
- {
- gzrewind(Zfile);
- } // end of Rewind
+ } // endif target
-/* ------------------------------------------------------------------- */
+ if (openEntry(g))
+ return true;
-/***********************************************************************/
-/* Constructors. */
-/***********************************************************************/
-ZBKFAM::ZBKFAM(PDOSDEF tdp) : ZIPFAM(tdp)
- {
- Blocked = true;
- Block = tdp->GetBlock();
- Last = tdp->GetLast();
- Nrec = tdp->GetElemt();
- CurLine = NULL;
- NxtLine = NULL;
- Closing = false;
- BlkPos = tdp->GetTo_Pos();
- } // end of ZBKFAM standard constructor
-
-ZBKFAM::ZBKFAM(PZBKFAM txfp) : ZIPFAM(txfp)
- {
- CurLine = txfp->CurLine;
- NxtLine = txfp->NxtLine;
- Closing = txfp->Closing;
- } // end of ZBKFAM copy constructor
+ if (size > 0) {
+ /*******************************************************************/
+ /* Link a Fblock. This make possible to automatically close it */
+ /* in case of error g->jump. */
+ /*******************************************************************/
+ PDBUSER dbuserp = (PDBUSER)g->Activityp->Aptr;
-/***********************************************************************/
-/* Use BlockTest to reduce the table estimated size. */
-/***********************************************************************/
-int ZBKFAM::MaxBlkSize(PGLOBAL g, int)
- {
- int rc = RC_OK, savcur = CurBlk;
- int size;
-
- // Roughly estimate the table size as the sum of blocks
- // that can contain good rows
- for (size = 0, CurBlk = 0; CurBlk < Block; CurBlk++)
- if ((rc = Tdbp->TestBlock(g)) == RC_OK)
- size += (CurBlk == Block - 1) ? Last : Nrec;
- else if (rc == RC_EF)
- break;
-
- CurBlk = savcur;
- return size;
- } // end of MaxBlkSize
+ fp = (PFBLOCK)PlugSubAlloc(g, NULL, sizeof(FBLOCK));
+ fp->Type = TYPE_FB_ZIP;
+ fp->Fname = PlugDup(g, fn);
+ fp->Next = dbuserp->Openlist;
+ dbuserp->Openlist = fp;
+ fp->Count = 1;
+ fp->Length = size;
+ fp->Memory = memory;
+ fp->Mode = mode;
+ fp->File = this;
+ fp->Handle = 0;
+ } // endif fp
-/***********************************************************************/
-/* ZBK Cardinality: returns table cardinality in number of rows. */
-/* This function can be called with a null argument to test the */
-/* availability of Cardinality implementation (1 yes, 0 no). */
-/***********************************************************************/
-int ZBKFAM::Cardinality(PGLOBAL g)
- {
- return (g) ? (int)((Block - 1) * Nrec + Last) : 1;
- } // end of Cardinality
+ } else
+ return true;
-/***********************************************************************/
-/* Allocate the line buffer. For mode Delete a bigger buffer has to */
-/* be allocated because is it also used to move lines into the file. */
-/***********************************************************************/
-bool ZBKFAM::AllocateBuffer(PGLOBAL g)
- {
- Buflen = Nrec * (Lrecl + 2);
- CurLine = To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);
-
- if (Tdbp->GetMode() == MODE_INSERT) {
- // Set values so Block and Last can be recalculated
- if (Last == Nrec) {
- CurBlk = Block;
- Rbuf = Nrec; // To be used by WriteDB
- } else {
- // The last block must be completed
- CurBlk = Block - 1;
- Rbuf = Nrec - Last; // To be used by WriteDB
- } // endif Last
-
- } // endif Insert
-
- return false;
- } // end of AllocateBuffer
+ } else {
+ strcpy(g->Message, "Only READ mode supported for ZIP files");
+ return true;
+ } // endif mode
-/***********************************************************************/
-/* GetRowID: return the RowID of last read record. */
-/***********************************************************************/
-int ZBKFAM::GetRowID(void)
- {
- return CurNum + Nrec * CurBlk + 1;
- } // end of GetRowID
+ return false;
+} // end of OpenTableFile
/***********************************************************************/
-/* GetPos: return the position of last read record. */
+/* Open target in zip file. */
/***********************************************************************/
-int ZBKFAM::GetPos(void)
- {
- return CurNum + Nrec * CurBlk; // Computed file index
- } // end of GetPos
+bool ZIPUTIL::openEntry(PGLOBAL g)
+{
+ int rc;
-/***********************************************************************/
-/* Record file position in case of UPDATE or DELETE. */
-/* Not used yet for fixed tables. */
-/***********************************************************************/
-bool ZBKFAM::RecordPos(PGLOBAL /*g*/)
- {
-//strcpy(g->Message, "RecordPos not implemented for zip blocked tables");
-//return true;
- return RC_OK;
- } // end of RecordPos
+ rc = unzGetCurrentFileInfo(zipfile, &finfo, fn, sizeof(fn),
+ NULL, 0, NULL, 0);
-/***********************************************************************/
-/* Skip one record in file. */
-/***********************************************************************/
-int ZBKFAM::SkipRecord(PGLOBAL /*g*/, bool)
- {
-//strcpy(g->Message, "SkipRecord not implemented for zip blocked tables");
-//return RC_FX;
- return RC_OK;
- } // end of SkipRecord
+ if (rc != UNZ_OK) {
+ sprintf(g->Message, "unzGetCurrentFileInfo64 rc=%d", rc);
+ return true;
+ } else if ((rc = unzOpenCurrentFile(zipfile)) != UNZ_OK) {
+ sprintf(g->Message, "unzOpen fn=%s rc=%d", fn, rc);
+ return true;
+ } // endif rc
-/***********************************************************************/
-/* ReadBuffer: Read one line from a compressed text file. */
-/***********************************************************************/
-int ZBKFAM::ReadBuffer(PGLOBAL g)
- {
- int n, skip, rc = RC_OK;
-
- /*********************************************************************/
- /* Sequential reading when Placed is not true. */
- /*********************************************************************/
- if (++CurNum < Rbuf) {
- CurLine = NxtLine;
-
- // Get the position of the next line in the buffer
- while (*NxtLine++ != '\n') ;
-
- // Set caller line buffer
- n = NxtLine - CurLine - Ending;
- memcpy(Tdbp->GetLine(), CurLine, n);
- Tdbp->GetLine()[n] = '\0';
- return RC_OK;
- } else if (Rbuf < Nrec && CurBlk != -1)
- return RC_EF;
-
- /*********************************************************************/
- /* New block. */
- /*********************************************************************/
- CurNum = 0;
- skip = 0;
-
- next:
- if (++CurBlk >= Block)
- return RC_EF;
-
- /*********************************************************************/
- /* Before using the new block, check whether block optimization */
- /* can be done, as well as for join as for local filtering. */
- /*********************************************************************/
- switch (Tdbp->TestBlock(g)) {
- case RC_EF:
- return RC_EF;
- case RC_NF:
- skip++;
- goto next;
- } // endswitch rc
-
- if (skip)
- // Skip blocks rejected by block optimization
- for (int i = CurBlk - skip; i < CurBlk; i++) {
- BlkLen = BlkPos[i + 1] - BlkPos[i];
-
- if (gzseek(Zfile, (z_off_t)BlkLen, SEEK_CUR) < 0)
- return Zerror(g);
-
- } // endfor i
-
- BlkLen = BlkPos[CurBlk + 1] - BlkPos[CurBlk];
-
- if (!(n = gzread(Zfile, To_Buf, BlkLen))) {
- rc = RC_EF;
- } else if (n > 0) {
- // Get the position of the current line
- CurLine = To_Buf;
-
- // Now get the position of the next line
- for (NxtLine = CurLine; *NxtLine++ != '\n';) ;
-
- // Set caller line buffer
- n = NxtLine - CurLine - Ending;
- memcpy(Tdbp->GetLine(), CurLine, n);
- Tdbp->GetLine()[n] = '\0';
- Rbuf = (CurBlk == Block - 1) ? Last : Nrec;
- IsRead = true;
- rc = RC_OK;
- num_read++;
- } else
- rc = Zerror(g);
-
- return rc;
- } // end of ReadBuffer
+ size = finfo.uncompressed_size;
+ memory = new char[size + 1];
-/***********************************************************************/
-/* WriteDB: Data Base write routine for ZDOS access method. */
-/* Update is not possible without using a temporary file (NIY). */
-/***********************************************************************/
-int ZBKFAM::WriteBuffer(PGLOBAL g)
- {
- /*********************************************************************/
- /* Prepare the write buffer. */
- /*********************************************************************/
- if (!Closing)
- strcat(strcpy(CurLine, Tdbp->GetLine()), CrLf);
-
- /*********************************************************************/
- /* In Insert mode, blocs are added sequentialy to the file end. */
- /* Note: Update mode is not handled for zip files. */
- /*********************************************************************/
- if (++CurNum == Rbuf) {
- /*******************************************************************/
- /* New block, start the writing process. */
- /*******************************************************************/
- BlkLen = CurLine + strlen(CurLine) - To_Buf;
-
- if (gzwrite(Zfile, To_Buf, BlkLen) != BlkLen ||
- gzflush(Zfile, Z_FULL_FLUSH)) {
- Closing = true;
- return Zerror(g);
- } // endif gzwrite
-
- Rbuf = Nrec;
- CurBlk++;
- CurNum = 0;
- CurLine = To_Buf;
- } else
- CurLine += strlen(CurLine);
-
- return RC_OK;
- } // end of WriteBuffer
+ if ((rc = unzReadCurrentFile(zipfile, memory, size)) < 0) {
+ sprintf(g->Message, "unzReadCurrentFile rc = %d", rc);
+ unzCloseCurrentFile(zipfile);
+ free(memory);
+ memory = NULL;
+ entryopen = false;
+ } else {
+ memory[size] = 0; // Required by some table types (XML)
+ entryopen = true;
+ } // endif rc
+
+ if (trace)
+ htrc("Openning entry%s %s\n", fn, (entryopen) ? "oked" : "failed");
+
+ return !entryopen;
+} // end of openEntry
+
+/***********************************************************************/
+/* Close the zip file. */
+/***********************************************************************/
+void ZIPUTIL::closeEntry()
+{
+ if (entryopen) {
+ unzCloseCurrentFile(zipfile);
+ entryopen = false;
+ } // endif entryopen
+
+ if (memory) {
+ free(memory);
+ memory = NULL;
+ } // endif memory
+
+} // end of closeEntry
+
+/* -------------------------- class ZIPFAM --------------------------- */
/***********************************************************************/
-/* Data Base delete line routine for ZBK access method. */
-/* Implemented only for total deletion of the table, which is done */
-/* by opening the file in mode "wb". */
+/* Constructors. */
/***********************************************************************/
-int ZBKFAM::DeleteRecords(PGLOBAL g, int irc)
- {
- if (irc == RC_EF) {
- LPCSTR name = Tdbp->GetName();
- PDOSDEF defp = (PDOSDEF)Tdbp->GetDef();
-
- defp->SetBlock(0);
- defp->SetLast(Nrec);
+ZIPFAM::ZIPFAM(PDOSDEF tdp) : MAPFAM(tdp)
+{
+ zutp = NULL;
+ target = tdp->GetEntry();
+ mul = tdp->GetMul();
+} // end of ZIPFAM standard constructor
- if (!defp->SetIntCatInfo("Blocks", 0) ||
- !defp->SetIntCatInfo("Last", 0)) {
- sprintf(g->Message, MSG(UPDATE_ERROR), "Header");
- return RC_FX;
- } else
- return RC_OK;
+ZIPFAM::ZIPFAM(PZIPFAM txfp) : MAPFAM(txfp)
+{
+ zutp = txfp->zutp;
+ target = txfp->target;
+ mul = txfp->mul;
+} // end of ZIPFAM copy constructor
- } else
- return irc;
-
- } // end of DeleteRecords
+ZIPFAM::ZIPFAM(PDOSDEF tdp, PZPXFAM txfp) : MAPFAM(tdp)
+{
+ zutp = txfp->zutp;
+ target = txfp->target;
+ mul = txfp->mul;
+} // end of ZIPFAM constructor used in ResetTableOpt
/***********************************************************************/
-/* Data Base close routine for ZBK access method. */
+/* ZIP GetFileLength: returns file size in number of bytes. */
/***********************************************************************/
-void ZBKFAM::CloseTableFile(PGLOBAL g, bool)
- {
- int rc = RC_OK;
-
- if (Tdbp->GetMode() == MODE_INSERT) {
- LPCSTR name = Tdbp->GetName();
- PDOSDEF defp = (PDOSDEF)Tdbp->GetDef();
-
- if (CurNum && !Closing) {
- // Some more inserted lines remain to be written
- Last = (Nrec - Rbuf) + CurNum;
- Block = CurBlk + 1;
- Rbuf = CurNum--;
- Closing = true;
- rc = WriteBuffer(g);
- } else if (Rbuf == Nrec) {
- Last = Nrec;
- Block = CurBlk;
- } // endif CurNum
-
- if (rc != RC_FX) {
- defp->SetBlock(Block);
- defp->SetLast(Last);
- defp->SetIntCatInfo("Blocks", Block);
- defp->SetIntCatInfo("Last", Last);
- } // endif
-
- gzclose(Zfile);
- } else if (Tdbp->GetMode() == MODE_DELETE) {
- rc = DeleteRecords(g, RC_EF);
- gzclose(Zfile);
- } else
- rc = gzclose(Zfile);
-
- if (trace)
- htrc("ZIP CloseDB: closing %s rc=%d\n", To_File, rc);
-
- Zfile = NULL; // So we can know whether table is open
-//To_Fb->Count = 0; // Avoid double closing by PlugCloseAll
- } // end of CloseTableFile
+int ZIPFAM::GetFileLength(PGLOBAL g)
+{
+ int len = (zutp && zutp->entryopen) ? Top - Memory
+ : TXTFAM::GetFileLength(g) * 3;
-/***********************************************************************/
-/* Rewind routine for ZBK access method. */
-/***********************************************************************/
-void ZBKFAM::Rewind(void)
- {
- gzrewind(Zfile);
- CurBlk = -1;
- CurNum = Rbuf;
- } // end of Rewind
+ if (trace)
+ htrc("Zipped file length=%d\n", len);
-/* ------------------------------------------------------------------- */
+ return len;
+} // end of GetFileLength
/***********************************************************************/
-/* Constructors. */
+/* ZIP Cardinality: return the number of rows if possible. */
/***********************************************************************/
-ZIXFAM::ZIXFAM(PDOSDEF tdp) : ZBKFAM(tdp)
- {
-//Block = tdp->GetBlock();
-//Last = tdp->GetLast();
- Nrec = (tdp->GetElemt()) ? tdp->GetElemt() : DOS_BUFF_LEN;
- Blksize = Nrec * Lrecl;
- } // end of ZIXFAM standard constructor
+int ZIPFAM::Cardinality(PGLOBAL g)
+{
+ if (!g)
+ return 1;
-/***********************************************************************/
-/* ZIX Cardinality: returns table cardinality in number of rows. */
-/* This function can be called with a null argument to test the */
-/* availability of Cardinality implementation (1 yes, 0 no). */
-/***********************************************************************/
-int ZIXFAM::Cardinality(PGLOBAL g)
- {
- if (Last)
- return (g) ? (int)((Block - 1) * Nrec + Last) : 1;
- else // Last and Block not defined, cannot do it yet
- return 0;
+ int card = -1;
+ int len = GetFileLength(g);
- } // end of Cardinality
+ card = (len / (int)Lrecl) * 2; // Estimated ???
+ return card;
+} // end of Cardinality
/***********************************************************************/
-/* Allocate the line buffer. For mode Delete a bigger buffer has to */
-/* be allocated because is it also used to move lines into the file. */
+/* OpenTableFile: Open a DOS/UNIX table file from a ZIP file. */
/***********************************************************************/
-bool ZIXFAM::AllocateBuffer(PGLOBAL g)
- {
- Buflen = Blksize;
- To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);
-
- if (Tdbp->GetMode() == MODE_INSERT) {
- /*******************************************************************/
- /* For Insert the buffer must be prepared. */
- /*******************************************************************/
- memset(To_Buf, ' ', Buflen);
-
- if (Tdbp->GetFtype() < 2)
- // if not binary, the file is physically a text file
- for (int len = Lrecl; len <= Buflen; len += Lrecl) {
-#if defined(__WIN__)
- To_Buf[len - 2] = '\r';
-#endif // __WIN__
- To_Buf[len - 1] = '\n';
- } // endfor len
-
- // Set values so Block and Last can be recalculated
- if (Last == Nrec) {
- CurBlk = Block;
- Rbuf = Nrec; // To be used by WriteDB
- } else {
- // The last block must be completed
- CurBlk = Block - 1;
- Rbuf = Nrec - Last; // To be used by WriteDB
- } // endif Last
-
- } // endif Insert
-
- return false;
- } // end of AllocateBuffer
+bool ZIPFAM::OpenTableFile(PGLOBAL g)
+{
+ char filename[_MAX_PATH];
+ MODE mode = Tdbp->GetMode();
-/***********************************************************************/
-/* ReadBuffer: Read one line from a compressed text file. */
-/***********************************************************************/
-int ZIXFAM::ReadBuffer(PGLOBAL g)
- {
- int n, rc = RC_OK;
-
- /*********************************************************************/
- /* Sequential reading when Placed is not true. */
- /*********************************************************************/
- if (++CurNum < Rbuf) {
- Tdbp->IncLine(Lrecl); // Used by DOSCOL functions
- return RC_OK;
- } else if (Rbuf < Nrec && CurBlk != -1)
- return RC_EF;
-
- /*********************************************************************/
- /* New block. */
- /*********************************************************************/
- CurNum = 0;
- Tdbp->SetLine(To_Buf);
-
- int skip = 0;
-
- next:
- if (++CurBlk >= Block)
- return RC_EF;
-
- /*********************************************************************/
- /* Before using the new block, check whether block optimization */
- /* can be done, as well as for join as for local filtering. */
- /*********************************************************************/
- switch (Tdbp->TestBlock(g)) {
- case RC_EF:
- return RC_EF;
- case RC_NF:
- skip++;
- goto next;
- } // endswitch rc
-
- if (skip)
- // Skip blocks rejected by block optimization
- for (int i = 0; i < skip; i++) {
- if (gzseek(Zfile, (z_off_t)Buflen, SEEK_CUR) < 0)
- return Zerror(g);
-
- } // endfor i
-
- if (!(n = gzread(Zfile, To_Buf, Buflen))) {
- rc = RC_EF;
- } else if (n > 0) {
- Rbuf = n / Lrecl;
- IsRead = true;
- rc = RC_OK;
- num_read++;
- } else
- rc = Zerror(g);
-
- return rc;
- } // end of ReadBuffer
+ /*********************************************************************/
+ /* Allocate the ZIP utility class. */
+ /*********************************************************************/
+ zutp = new(g) ZIPUTIL(target, mul);
-/***********************************************************************/
-/* WriteDB: Data Base write routine for ZDOS access method. */
-/* Update is not possible without using a temporary file (NIY). */
-/***********************************************************************/
-int ZIXFAM::WriteBuffer(PGLOBAL g)
- {
- /*********************************************************************/
- /* In Insert mode, blocs are added sequentialy to the file end. */
- /* Note: Update mode is not handled for zip files. */
- /*********************************************************************/
- if (++CurNum == Rbuf) {
- /*******************************************************************/
- /* New block, start the writing process. */
- /*******************************************************************/
- BlkLen = Rbuf * Lrecl;
-
- if (gzwrite(Zfile, To_Buf, BlkLen) != BlkLen ||
- gzflush(Zfile, Z_FULL_FLUSH)) {
- Closing = true;
- return Zerror(g);
- } // endif gzwrite
-
- Rbuf = Nrec;
- CurBlk++;
- CurNum = 0;
- Tdbp->SetLine(To_Buf);
- } else
- Tdbp->IncLine(Lrecl); // Used by FIXCOL functions
-
- return RC_OK;
- } // end of WriteBuffer
-
-/* --------------------------- Class ZLBFAM -------------------------- */
+ // We used the file name relative to recorded datapath
+ PlugSetPath(filename, To_File, Tdbp->GetPath());
-/***********************************************************************/
-/* Constructors. */
-/***********************************************************************/
-ZLBFAM::ZLBFAM(PDOSDEF tdp) : BLKFAM(tdp)
- {
- Zstream = NULL;
- Zbuffer = NULL;
- Zlenp = NULL;
- Optimized = tdp->IsOptimized();
- } // end of ZLBFAM standard constructor
-
-ZLBFAM::ZLBFAM(PZLBFAM txfp) : BLKFAM(txfp)
- {
- Zstream = txfp->Zstream;
- Zbuffer = txfp->Zbuffer;
- Zlenp = txfp->Zlenp;
- Optimized = txfp->Optimized;
- } // end of ZLBFAM (dummy?) copy constructor
+ if (!zutp->OpenTable(g, mode, filename)) {
+ // The pseudo "buffer" is here the entire real buffer
+ Fpos = Mempos = Memory = zutp->memory;
+ Top = Memory + zutp->size;
+ To_Fb = zutp->fp; // Useful when closing
+ } else
+ return true;
+
+ return false;
+ } // end of OpenTableFile
/***********************************************************************/
-/* ZLB GetFileLength: returns an estimate of what would be the */
-/* uncompressed file size in number of bytes. */
+/* GetNext: go to next entry. */
/***********************************************************************/
-int ZLBFAM::GetFileLength(PGLOBAL g)
- {
- int len = (Optimized) ? BlkPos[Block] : BLKFAM::GetFileLength(g);
+int ZIPFAM::GetNext(PGLOBAL g)
+{
+ int rc = zutp->nextEntry(g);
- if (len > 0)
- // Estimate size reduction to a max of 5
- len *= 5;
+ if (rc != RC_OK)
+ return rc;
- return len;
- } // end of GetFileLength
+ Mempos = Memory = zutp->memory;
+ Top = Memory + zutp->size;
+ return RC_OK;
+} // end of GetNext
+#if 0
/***********************************************************************/
-/* Allocate the line buffer. For mode Delete a bigger buffer has to */
-/* be allocated because is it also used to move lines into the file. */
+/* ReadBuffer: Read one line for a ZIP file. */
/***********************************************************************/
-bool ZLBFAM::AllocateBuffer(PGLOBAL g)
- {
- char *msg;
- int n, zrc;
+int ZIPFAM::ReadBuffer(PGLOBAL g)
+{
+ int rc, len;
-#if 0
- if (!Optimized && Tdbp->NeedIndexing(g)) {
- strcpy(g->Message, MSG(NOP_ZLIB_INDEX));
- return TRUE;
- } // endif indexing
-#endif // 0
+ // Are we at the end of the memory
+ if (Mempos >= Top) {
+ if ((rc = zutp->nextEntry(g)) != RC_OK)
+ return rc;
-#if defined(NOLIB)
- if (!zlib && LoadZlib()) {
- sprintf(g->Message, MSG(DLL_LOAD_ERROR), GetLastError(), "zlib.dll");
- return TRUE;
- } // endif zlib
-#endif
+ Mempos = Memory = zutp->memory;
+ Top = Memory + zutp->size;
+ } // endif Mempos
- BLKFAM::AllocateBuffer(g);
-//Buflen = Nrec * (Lrecl + 2);
-//Rbuf = Nrec;
-
- // Allocate the compressed buffer
- n = Buflen + 16; // ?????????????????????????????????
- Zlenp = (int*)PlugSubAlloc(g, NULL, n);
- Zbuffer = (Byte*)(Zlenp + 1);
-
- // Allocate and initialize the Z stream
- Zstream = (z_streamp)PlugSubAlloc(g, NULL, sizeof(z_stream));
- Zstream->zalloc = (alloc_func)0;
- Zstream->zfree = (free_func)0;
- Zstream->opaque = (voidpf)0;
- Zstream->next_in = NULL;
- Zstream->avail_in = 0;
-
- if (Tdbp->GetMode() == MODE_READ) {
- msg = "inflateInit";
- zrc = inflateInit(Zstream);
- } else {
- msg = "deflateInit";
- zrc = deflateInit(Zstream, Z_DEFAULT_COMPRESSION);
- } // endif Mode
-
- if (zrc != Z_OK) {
- if (Zstream->msg)
- sprintf(g->Message, "%s error: %s", msg, Zstream->msg);
- else
- sprintf(g->Message, "%s error: %d", msg, zrc);
-
- return TRUE;
- } // endif zrc
-
- if (Tdbp->GetMode() == MODE_INSERT) {
- // Write the file header block
- if (Last == Nrec) {
- CurBlk = Block;
- CurNum = 0;
-
- if (!GetFileLength(g)) {
- // Write the zlib header as an extra block
- strcpy(To_Buf, "PlugDB");
- BlkLen = strlen("PlugDB") + 1;
-
- if (WriteCompressedBuffer(g))
- return TRUE;
-
- } // endif void file
-
- } else {
- // In mode insert, if Last != Nrec, last block must be updated
- CurBlk = Block - 1;
- CurNum = Last;
-
- strcpy(g->Message, MSG(NO_PAR_BLK_INS));
- return TRUE;
- } // endif Last
-
- } else { // MODE_READ
- // First thing to do is to read the header block
- void *rdbuf;
-
- if (Optimized) {
- BlkLen = BlkPos[0];
- rdbuf = Zlenp;
- } else {
- // Get the stored length from the file itself
- if (fread(Zlenp, sizeof(int), 1, Stream) != 1)
- return FALSE; // Empty file
-
- BlkLen = *Zlenp;
- rdbuf = Zbuffer;
- } // endif Optimized
-
- switch (ReadCompressedBuffer(g, rdbuf)) {
- case RC_EF:
- return FALSE;
- case RC_FX:
-#if defined(UNIX)
- sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno));
+#if 0
+ if (!Placed) {
+ /*******************************************************************/
+ /* Record file position in case of UPDATE or DELETE. */
+ /*******************************************************************/
+ int rc;
+
+ next:
+ Fpos = Mempos;
+ CurBlk = (int)Rows++;
+
+ /*******************************************************************/
+ /* Check whether optimization on ROWID */
+ /* can be done, as well as for join as for local filtering. */
+ /*******************************************************************/
+ switch (Tdbp->TestBlock(g)) {
+ case RC_EF:
+ return RC_EF;
+ case RC_NF:
+ // Skip this record
+ if ((rc = SkipRecord(g, false)) != RC_OK)
+ return rc;
+
+ goto next;
+ } // endswitch rc
+
+ } else
+ Placed = false;
#else
- sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL));
+ // Perhaps unuseful
+ Fpos = Mempos;
+ CurBlk = (int)Rows++;
+ Placed = false;
#endif
- case RC_NF:
- return TRUE;
- } // endswitch
- // Some old tables can have PlugDB in their header
- if (strcmp(To_Buf, "PlugDB")) {
- sprintf(g->Message, MSG(BAD_HEADER), Tdbp->GetFile(g));
- return TRUE;
- } // endif strcmp
+ // Immediately calculate next position (Used by DeleteDB)
+ while (*Mempos++ != '\n'); // What about Unix ???
- } // endif Mode
+ // Set caller line buffer
+ len = (Mempos - Fpos) - 1;
- return FALSE;
- } // end of AllocateBuffer
+ // Don't rely on ENDING setting
+ if (len > 0 && *(Mempos - 2) == '\r')
+ len--; // Line ends by CRLF
-/***********************************************************************/
-/* GetPos: return the position of last read record. */
-/***********************************************************************/
-int ZLBFAM::GetPos(void)
- {
- return (Optimized) ? (CurNum + Nrec * CurBlk) : Fpos;
- } // end of GetPos
+ memcpy(Tdbp->GetLine(), Fpos, len);
+ Tdbp->GetLine()[len] = '\0';
+ return RC_OK;
+} // end of ReadBuffer
/***********************************************************************/
-/* GetNextPos: should not be called for this class. */
+/* Table file close routine for MAP access method. */
/***********************************************************************/
-int ZLBFAM::GetNextPos(void)
- {
- if (Optimized) {
- assert(FALSE);
- return 0;
- } else
- return ftell(Stream);
+void ZIPFAM::CloseTableFile(PGLOBAL g, bool)
+{
+ close();
+} // end of CloseTableFile
+#endif // 0
- } // end of GetNextPos
+/* -------------------------- class ZPXFAM --------------------------- */
/***********************************************************************/
-/* SetPos: Replace the table at the specified position. */
+/* Constructors. */
/***********************************************************************/
-bool ZLBFAM::SetPos(PGLOBAL g, int pos __attribute__((unused)))
- {
- sprintf(g->Message, MSG(NO_SETPOS_YET), "ZIP");
- return true;
-#if 0 // All this must be checked
- if (pos < 0) {
- strcpy(g->Message, MSG(INV_REC_POS));
- return true;
- } // endif recpos
-
- CurBlk = pos / Nrec;
- CurNum = pos % Nrec;
-#if defined(_DEBUG)
- num_eq[(CurBlk == OldBlk) ? 1 : 0]++;
-#endif
+ZPXFAM::ZPXFAM(PDOSDEF tdp) : MPXFAM(tdp)
+{
+ zutp = NULL;
+ target = tdp->GetEntry();
+ mul = tdp->GetMul();
+ //Lrecl = tdp->GetLrecl();
+} // end of ZPXFAM standard constructor
- // Indicate the table position was externally set
- Placed = true;
- return false;
-#endif // 0
- } // end of SetPos
+ZPXFAM::ZPXFAM(PZPXFAM txfp) : MPXFAM(txfp)
+{
+ zutp = txfp->zutp;
+ target = txfp->target;
+ mul = txfp->mul;
+//Lrecl = txfp->Lrecl;
+} // end of ZPXFAM copy constructor
/***********************************************************************/
-/* ReadBuffer: Read one line for a text file. */
+/* ZIP GetFileLength: returns file size in number of bytes. */
/***********************************************************************/
-int ZLBFAM::ReadBuffer(PGLOBAL g)
- {
- int n;
- void *rdbuf;
-
- /*********************************************************************/
- /* Sequential reading when Placed is not true. */
- /*********************************************************************/
- if (Placed) {
- Placed = FALSE;
- } else if (++CurNum < Rbuf) {
- CurLine = NxtLine;
-
- // Get the position of the next line in the buffer
- if (Tdbp->GetFtype() == RECFM_VAR)
- while (*NxtLine++ != '\n') ;
- else
- NxtLine += Lrecl;
-
- // Set caller line buffer
- n = NxtLine - CurLine - ((Tdbp->GetFtype() == RECFM_BIN) ? 0 : Ending);
- memcpy(Tdbp->GetLine(), CurLine, n);
- Tdbp->GetLine()[n] = '\0';
- return RC_OK;
- } else if (Rbuf < Nrec && CurBlk != -1) {
- CurNum--; // To have a correct Last value when optimizing
- return RC_EF;
- } else {
- /*******************************************************************/
- /* New block. */
- /*******************************************************************/
- CurNum = 0;
-
- next:
- if (++CurBlk >= Block)
- return RC_EF;
-
- /*******************************************************************/
- /* Before reading a new block, check whether block optimization */
- /* can be done, as well as for join as for local filtering. */
- /*******************************************************************/
- if (Optimized) switch (Tdbp->TestBlock(g)) {
- case RC_EF:
- return RC_EF;
- case RC_NF:
- goto next;
- } // endswitch rc
-
- } // endif's
-
- if (OldBlk == CurBlk)
- goto ok; // Block is already there
-
- if (Optimized) {
- // Store the position of next block
- Fpos = BlkPos[CurBlk];
-
- // fseek is required only in non sequential reading
- if (CurBlk != OldBlk + 1)
- if (fseek(Stream, Fpos, SEEK_SET)) {
- sprintf(g->Message, MSG(FSETPOS_ERROR), Fpos);
- return RC_FX;
- } // endif fseek
-
- // Calculate the length of block to read
- BlkLen = BlkPos[CurBlk + 1] - Fpos;
- rdbuf = Zlenp;
- } else { // !Optimized
- if (CurBlk != OldBlk + 1) {
- strcpy(g->Message, MSG(INV_RAND_ACC));
- return RC_FX;
- } else
- Fpos = ftell(Stream); // Used when optimizing
-
- // Get the stored length from the file itself
- if (fread(Zlenp, sizeof(int), 1, Stream) != 1) {
- if (feof(Stream))
- return RC_EF;
-
- goto err;
- } // endif fread
-
- BlkLen = *Zlenp;
- rdbuf = Zbuffer;
- } // endif Optimized
-
- // Read the next block
- switch (ReadCompressedBuffer(g, rdbuf)) {
- case RC_FX: goto err;
- case RC_NF: return RC_FX;
- case RC_EF: return RC_EF;
- default: Rbuf = (CurBlk == Block - 1) ? Last : Nrec;
- } // endswitch ReadCompressedBuffer
-
- ok:
- if (Tdbp->GetFtype() == RECFM_VAR) {
- int i;
-
- // Get the position of the current line
- for (i = 0, CurLine = To_Buf; i < CurNum; i++)
- while (*CurLine++ != '\n') ; // What about Unix ???
-
- // Now get the position of the next line
- for (NxtLine = CurLine; *NxtLine++ != '\n';) ;
-
- // Set caller line buffer
- n = NxtLine - CurLine - Ending;
- } else {
- CurLine = To_Buf + CurNum * Lrecl;
- NxtLine = CurLine + Lrecl;
- n = Lrecl - ((Tdbp->GetFtype() == RECFM_BIN) ? 0 : Ending);
- } // endif Ftype
-
- memcpy(Tdbp->GetLine(), CurLine, n);
- Tdbp->GetLine()[n] = '\0';
-
- OldBlk = CurBlk; // Last block actually read
- IsRead = TRUE; // Is read indeed
- return RC_OK;
-
- err:
-#if defined(UNIX)
- sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno));
-#else
- sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL));
-#endif
- return RC_FX;
- } // end of ReadBuffer
+int ZPXFAM::GetFileLength(PGLOBAL g)
+{
+ int len;
-/***********************************************************************/
-/* Read and decompress a block from the stream. */
-/***********************************************************************/
-int ZLBFAM::ReadCompressedBuffer(PGLOBAL g, void *rdbuf)
- {
- if (fread(rdbuf, 1, (size_t)BlkLen, Stream) == (unsigned)BlkLen) {
- int zrc;
-
- num_read++;
-
- if (Optimized && BlkLen != signed(*Zlenp + sizeof(int))) {
- sprintf(g->Message, MSG(BAD_BLK_SIZE), CurBlk + 1);
- return RC_NF;
- } // endif BlkLen
-
- // HERE WE MUST INFLATE THE BLOCK
- Zstream->next_in = Zbuffer;
- Zstream->avail_in = (uInt)(*Zlenp);
- Zstream->next_out = (Byte*)To_Buf;
- Zstream->avail_out = Buflen;
- zrc = inflate(Zstream, Z_SYNC_FLUSH);
-
- if (zrc != Z_OK) {
- if (Zstream->msg)
- sprintf(g->Message, MSG(FUNC_ERR_S), "inflate", Zstream->msg);
- else
- sprintf(g->Message, MSG(FUNCTION_ERROR), "inflate", (int)zrc);
-
- return RC_NF;
- } // endif zrc
-
- } else if (feof(Stream)) {
- return RC_EF;
- } else
- return RC_FX;
-
- return RC_OK;
- } // end of ReadCompressedBuffer
+ if (!zutp && OpenTableFile(g))
+ return 0;
-/***********************************************************************/
-/* WriteBuffer: File write routine for DOS access method. */
-/* Update is directly written back into the file, */
-/* with this (fast) method, record size cannot change. */
-/***********************************************************************/
-int ZLBFAM::WriteBuffer(PGLOBAL g)
- {
- assert (Tdbp->GetMode() == MODE_INSERT);
-
- /*********************************************************************/
- /* Prepare the write buffer. */
- /*********************************************************************/
- if (!Closing) {
- if (Tdbp->GetFtype() == RECFM_BIN)
- memcpy(CurLine, Tdbp->GetLine(), Lrecl);
- else
- strcat(strcpy(CurLine, Tdbp->GetLine()), CrLf);
-
-#if defined(_DEBUG)
- if (Tdbp->GetFtype() == RECFM_FIX &&
- (signed)strlen(CurLine) != Lrecl + (signed)strlen(CrLf)) {
- strcpy(g->Message, MSG(BAD_LINE_LEN));
- Closing = TRUE;
- return RC_FX;
- } // endif Lrecl
-#endif // _DEBUG
- } // endif Closing
-
- /*********************************************************************/
- /* In Insert mode, blocs are added sequentialy to the file end. */
- /*********************************************************************/
- if (++CurNum != Rbuf) {
- if (Tdbp->GetFtype() == RECFM_VAR)
- CurLine += strlen(CurLine);
- else
- CurLine += Lrecl;
-
- return RC_OK; // We write only full blocks
- } // endif CurNum
-
- // HERE WE MUST DEFLATE THE BLOCK
- if (Tdbp->GetFtype() == RECFM_VAR)
- NxtLine = CurLine + strlen(CurLine);
- else
- NxtLine = CurLine + Lrecl;
-
- BlkLen = NxtLine - To_Buf;
-
- if (WriteCompressedBuffer(g)) {
- Closing = TRUE; // To tell CloseDB about a Write error
- return RC_FX;
- } // endif WriteCompressedBuffer
-
- CurBlk++;
- CurNum = 0;
- CurLine = To_Buf;
- return RC_OK;
- } // end of WriteBuffer
+ if (zutp->entryopen)
+ len = zutp->size;
+ else
+ len = 0;
+
+ return len;
+} // end of GetFileLength
/***********************************************************************/
-/* Compress the buffer and write the deflated output to stream. */
+/* ZIP Cardinality: return the number of rows if possible. */
/***********************************************************************/
-bool ZLBFAM::WriteCompressedBuffer(PGLOBAL g)
- {
- int zrc;
-
- Zstream->next_in = (Byte*)To_Buf;
- Zstream->avail_in = (uInt)BlkLen;
- Zstream->next_out = Zbuffer;
- Zstream->avail_out = Buflen + 16;
- Zstream->total_out = 0;
- zrc = deflate(Zstream, Z_FULL_FLUSH);
-
- if (zrc != Z_OK) {
- if (Zstream->msg)
- sprintf(g->Message, MSG(FUNC_ERR_S), "deflate", Zstream->msg);
- else
- sprintf(g->Message, MSG(FUNCTION_ERROR), "deflate", (int)zrc);
-
- return TRUE;
- } else
- *Zlenp = Zstream->total_out;
-
- // Now start the writing process.
- BlkLen = *Zlenp + sizeof(int);
-
- if (fwrite(Zlenp, 1, BlkLen, Stream) != (size_t)BlkLen) {
- sprintf(g->Message, MSG(FWRITE_ERROR), strerror(errno));
- return TRUE;
- } // endif size
-
- return FALSE;
- } // end of WriteCompressedBuffer
+int ZPXFAM::Cardinality(PGLOBAL g)
+{
+ if (!g)
+ return 1;
+
+ int card = -1;
+ int len = GetFileLength(g);
+
+ if (!(len % Lrecl))
+ card = len / (int)Lrecl; // Fixed length file
+ else
+ sprintf(g->Message, MSG(NOT_FIXED_LEN), zutp->fn, len, Lrecl);
+
+ // Set number of blocks for later use
+ Block = (card > 0) ? (card + Nrec - 1) / Nrec : 0;
+ return card;
+} // end of Cardinality
/***********************************************************************/
-/* Table file close routine for DOS access method. */
+/* OpenTableFile: Open a DOS/UNIX table file from a ZIP file. */
/***********************************************************************/
-void ZLBFAM::CloseTableFile(PGLOBAL g, bool)
- {
- int rc = RC_OK;
-
- if (Tdbp->GetMode() == MODE_INSERT) {
- LPCSTR name = Tdbp->GetName();
- PDOSDEF defp = (PDOSDEF)Tdbp->GetDef();
-
- // Closing is True if last Write was in error
- if (CurNum && !Closing) {
- // Some more inserted lines remain to be written
- Last = (Nrec - Rbuf) + CurNum;
- Block = CurBlk + 1;
- Rbuf = CurNum--;
- Closing = TRUE;
- rc = WriteBuffer(g);
- } else if (Rbuf == Nrec) {
- Last = Nrec;
- Block = CurBlk;
- } // endif CurNum
-
- if (rc != RC_FX) {
- defp->SetBlock(Block);
- defp->SetLast(Last);
- defp->SetIntCatInfo("Blocks", Block);
- defp->SetIntCatInfo("Last", Last);
- } // endif
-
- fclose(Stream);
- } else
- rc = fclose(Stream);
-
- if (trace)
- htrc("ZLB CloseTableFile: closing %s mode=%d rc=%d\n",
- To_File, Tdbp->GetMode(), rc);
-
- Stream = NULL; // So we can know whether table is open
- To_Fb->Count = 0; // Avoid double closing by PlugCloseAll
-
- if (Tdbp->GetMode() == MODE_READ)
- rc = inflateEnd(Zstream);
- else
- rc = deflateEnd(Zstream);
-
- } // end of CloseTableFile
+bool ZPXFAM::OpenTableFile(PGLOBAL g)
+{
+ // May have been already opened in GetFileLength
+ if (!zutp || !zutp->zipfile) {
+ char filename[_MAX_PATH];
+ MODE mode = Tdbp->GetMode();
+
+ /*********************************************************************/
+ /* Allocate the ZIP utility class. */
+ /*********************************************************************/
+ if (!zutp)
+ zutp = new(g)ZIPUTIL(target, mul);
+
+ // We used the file name relative to recorded datapath
+ PlugSetPath(filename, To_File, Tdbp->GetPath());
+
+ if (!zutp->OpenTable(g, mode, filename)) {
+ // The pseudo "buffer" is here the entire real buffer
+ Memory = zutp->memory;
+ Fpos = Mempos = Memory + Headlen;
+ Top = Memory + zutp->size;
+ To_Fb = zutp->fp; // Useful when closing
+ } else
+ return true;
+
+ } else
+ Reset();
+
+ return false;
+} // end of OpenTableFile
/***********************************************************************/
-/* Rewind routine for ZLIB access method. */
+/* GetNext: go to next entry. */
/***********************************************************************/
-void ZLBFAM::Rewind(void)
- {
- // We must be positioned after the header block
- if (CurBlk >= 0) { // Nothing to do if no block read yet
- if (!Optimized) { // If optimized, fseek will be done in ReadBuffer
- size_t st;
-
- rewind(Stream);
+int ZPXFAM::GetNext(PGLOBAL g)
+{
+ int rc = zutp->nextEntry(g);
- if (!(st = fread(Zlenp, sizeof(int), 1, Stream)) && trace)
- htrc("fread error %d in Rewind", errno);
+ if (rc != RC_OK)
+ return rc;
- fseek(Stream, *Zlenp + sizeof(int), SEEK_SET);
- OldBlk = -1;
- } // endif Optimized
+ int len = zutp->size;
- CurBlk = -1;
- CurNum = Rbuf;
- } // endif CurBlk
+ if (len % Lrecl) {
+ sprintf(g->Message, MSG(NOT_FIXED_LEN), zutp->fn, len, Lrecl);
+ return RC_FX;
+ } // endif size
-//OldBlk = -1;
-//Rbuf = 0; commented out in case we reuse last read block
- } // end of Rewind
+ Memory = zutp->memory;
+ Top = Memory + len;
+ Rewind();
+ return RC_OK;
+} // end of GetNext
-/* ------------------------ End of ZipFam ---------------------------- */
diff --git a/storage/connect/filamzip.h b/storage/connect/filamzip.h
index edb8b5db323..9312fb2f70e 100644
--- a/storage/connect/filamzip.h
+++ b/storage/connect/filamzip.h
@@ -1,170 +1,117 @@
-/************** FilAmZip H Declares Source Code File (.H) **************/
-/* Name: FILAMZIP.H Version 1.2 */
+/************** filamzip H Declares Source Code File (.H) **************/
+/* Name: filamzip.h Version 1.0 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2005-2014 */
+/* (C) Copyright to the author Olivier BERTRAND 2016 */
/* */
-/* This file contains the GZIP access method classes declares. */
+/* This file contains the ZIP file access method classes declares. */
/***********************************************************************/
#ifndef __FILAMZIP_H
#define __FILAMZIP_H
-#include "zlib.h"
+#include "block.h"
+#include "filamap.h"
+#include "unzip.h"
-typedef class ZIPFAM *PZIPFAM;
-typedef class ZBKFAM *PZBKFAM;
-typedef class ZIXFAM *PZIXFAM;
-typedef class ZLBFAM *PZLBFAM;
+#define DLLEXPORT extern "C"
-/***********************************************************************/
-/* This is the access method class declaration for not optimized */
-/* variable record length files compressed using the gzip library */
-/* functions. File is accessed record by record (row). */
-/***********************************************************************/
-class DllExport ZIPFAM : public TXTFAM {
-// friend class DOSCOL;
- public:
- // Constructor
- ZIPFAM(PDOSDEF tdp) : TXTFAM(tdp) {Zfile = NULL; Zpos = 0;}
- ZIPFAM(PZIPFAM txfp);
-
- // Implementation
- virtual AMT GetAmType(void) {return TYPE_AM_ZIP;}
- virtual int GetPos(void);
- virtual int GetNextPos(void);
- virtual PTXF Duplicate(PGLOBAL g)
- {return (PTXF)new(g) ZIPFAM(this);}
-
- // Methods
- virtual void Reset(void);
- virtual int GetFileLength(PGLOBAL g);
- virtual int Cardinality(PGLOBAL g) {return (g) ? -1 : 0;}
- virtual int MaxBlkSize(PGLOBAL g, int s) {return s;}
- virtual bool AllocateBuffer(PGLOBAL g);
- virtual int GetRowID(void);
- virtual bool RecordPos(PGLOBAL g);
- virtual bool SetPos(PGLOBAL g, int recpos);
- virtual int SkipRecord(PGLOBAL g, bool header);
- virtual bool OpenTableFile(PGLOBAL g);
- virtual int ReadBuffer(PGLOBAL g);
- virtual int WriteBuffer(PGLOBAL g);
- virtual int DeleteRecords(PGLOBAL g, int irc);
- virtual void CloseTableFile(PGLOBAL g, bool abort);
- virtual void Rewind(void);
-
- protected:
- int Zerror(PGLOBAL g); // GZ error function
-
- // Members
- gzFile Zfile; // Points to GZ file structure
- z_off_t Zpos; // Uncompressed file position
- }; // end of class ZIPFAM
+typedef class ZIPFAM *PZIPFAM;
+typedef class ZPXFAM *PZPXFAM;
/***********************************************************************/
-/* This is the access method class declaration for optimized variable */
-/* record length files compressed using the gzip library functions. */
-/* The File is accessed by block (requires an opt file). */
+/* This is the ZIP utility fonctions class. */
/***********************************************************************/
-class DllExport ZBKFAM : public ZIPFAM {
- public:
- // Constructor
- ZBKFAM(PDOSDEF tdp);
- ZBKFAM(PZBKFAM txfp);
-
- // Implementation
- virtual int GetPos(void);
- virtual int GetNextPos(void) {return 0;}
- virtual PTXF Duplicate(PGLOBAL g)
- {return (PTXF)new(g) ZBKFAM(this);}
-
- // Methods
- virtual int Cardinality(PGLOBAL g);
- virtual int MaxBlkSize(PGLOBAL g, int s);
- virtual bool AllocateBuffer(PGLOBAL g);
- virtual int GetRowID(void);
- virtual bool RecordPos(PGLOBAL g);
- virtual int SkipRecord(PGLOBAL g, bool header);
- virtual int ReadBuffer(PGLOBAL g);
- virtual int WriteBuffer(PGLOBAL g);
- virtual int DeleteRecords(PGLOBAL g, int irc);
- virtual void CloseTableFile(PGLOBAL g, bool abort);
- virtual void Rewind(void);
-
- protected:
- // Members
- char *CurLine; // Position of current line in buffer
- char *NxtLine; // Position of Next line in buffer
- bool Closing; // True when closing on Insert
- }; // end of class ZBKFAM
+class DllExport ZIPUTIL : public BLOCK {
+public:
+ // Constructor
+ ZIPUTIL(PSZ tgt, bool mul);
+//ZIPUTIL(ZIPUTIL *zutp);
+
+ // Implementation
+//PTXF Duplicate(PGLOBAL g) { return (PTXF) new(g)ZIPFAM(this); }
+
+ // Methods
+ virtual bool OpenTable(PGLOBAL g, MODE mode, char *fn);
+ bool open(PGLOBAL g, char *fn);
+ bool openEntry(PGLOBAL g);
+ void close(void);
+ void closeEntry(void);
+ bool WildMatch(PSZ pat, PSZ str);
+ int findEntry(PGLOBAL g, bool next);
+ int nextEntry(PGLOBAL g);
+
+ // Members
+ unzFile zipfile; // The ZIP container file
+ PSZ target; // The target file name
+ unz_file_info finfo; // The current file info
+ PFBLOCK fp;
+ char *memory;
+ uint size;
+ int multiple; // Multiple targets
+ bool entryopen; // True when open current entry
+ char fn[FILENAME_MAX]; // The current entry file name
+ char mapCaseTable[256];
+}; // end of ZIPFAM
/***********************************************************************/
-/* This is the access method class declaration for fixed record */
-/* length files compressed using the gzip library functions. */
-/* The file is always accessed by block. */
+/* This is the ZIP file access method. */
/***********************************************************************/
-class DllExport ZIXFAM : public ZBKFAM {
- public:
- // Constructor
- ZIXFAM(PDOSDEF tdp);
- ZIXFAM(PZIXFAM txfp) : ZBKFAM(txfp) {}
-
- // Implementation
- virtual int GetNextPos(void) {return 0;}
- virtual PTXF Duplicate(PGLOBAL g)
- {return (PTXF)new(g) ZIXFAM(this);}
-
- // Methods
- virtual int Cardinality(PGLOBAL g);
- virtual bool AllocateBuffer(PGLOBAL g);
- virtual int ReadBuffer(PGLOBAL g);
- virtual int WriteBuffer(PGLOBAL g);
-
- protected:
- // No additional Members
- }; // end of class ZIXFAM
+class DllExport ZIPFAM : public MAPFAM {
+ friend class ZPXFAM;
+public:
+ // Constructors
+ ZIPFAM(PDOSDEF tdp);
+ ZIPFAM(PZIPFAM txfp);
+ ZIPFAM(PDOSDEF tdp, PZPXFAM txfp);
+
+ // Implementation
+ virtual AMT GetAmType(void) { return TYPE_AM_ZIP; }
+ virtual PTXF Duplicate(PGLOBAL g) { return (PTXF) new(g)ZIPFAM(this); }
+
+ // Methods
+ virtual int Cardinality(PGLOBAL g);
+ virtual int GetFileLength(PGLOBAL g);
+//virtual int MaxBlkSize(PGLOBAL g, int s) {return s;}
+ virtual bool OpenTableFile(PGLOBAL g);
+ virtual bool DeferReading(void) { return false; }
+ virtual int GetNext(PGLOBAL g);
+//virtual int ReadBuffer(PGLOBAL g);
+//virtual int WriteBuffer(PGLOBAL g);
+//virtual int DeleteRecords(PGLOBAL g, int irc);
+//virtual void CloseTableFile(PGLOBAL g, bool abort);
+
+protected:
+ // Members
+ ZIPUTIL *zutp;
+ PSZ target;
+ bool mul;
+}; // end of ZIPFAM
/***********************************************************************/
-/* This is the DOS/UNIX Access Method class declaration for PlugDB */
-/* fixed/variable files compressed using the zlib library functions. */
-/* Physically these are written and read using the same technique */
-/* than blocked variable files, only the contain of each block is */
-/* compressed using the deflate zlib function. The purpose of this */
-/* specific format is to have a fast mechanism for direct access of */
-/* records so blocked optimization is fast and direct access (joins) */
-/* is allowed. Note that the block length is written ahead of each */
-/* block to enable reading when optimization file is not available. */
+/* This is the fixed ZIP file access method. */
/***********************************************************************/
-class DllExport ZLBFAM : public BLKFAM {
- public:
- // Constructor
- ZLBFAM(PDOSDEF tdp);
- ZLBFAM(PZLBFAM txfp);
-
- // Implementation
- virtual AMT GetAmType(void) {return TYPE_AM_ZLIB;}
- virtual int GetPos(void);
- virtual int GetNextPos(void);
- virtual PTXF Duplicate(PGLOBAL g)
- {return (PTXF)new(g) ZLBFAM(this);}
- inline void SetOptimized(bool b) {Optimized = b;}
-
- // Methods
- virtual int GetFileLength(PGLOBAL g);
- virtual bool SetPos(PGLOBAL g, int recpos);
- virtual bool AllocateBuffer(PGLOBAL g);
- virtual int ReadBuffer(PGLOBAL g);
- virtual int WriteBuffer(PGLOBAL g);
- virtual void CloseTableFile(PGLOBAL g, bool abort);
- virtual void Rewind(void);
-
- protected:
- bool WriteCompressedBuffer(PGLOBAL g);
- int ReadCompressedBuffer(PGLOBAL g, void *rdbuf);
-
- // Members
- z_streamp Zstream; // Compression/decompression stream
- Byte *Zbuffer; // Compressed block buffer
- int *Zlenp; // Pointer to block length
- bool Optimized; // true when opt file is available
- }; // end of class ZLBFAM
+class DllExport ZPXFAM : public MPXFAM {
+ friend class ZIPFAM;
+public:
+ // Constructors
+ ZPXFAM(PDOSDEF tdp);
+ ZPXFAM(PZPXFAM txfp);
+
+ // Implementation
+ virtual AMT GetAmType(void) { return TYPE_AM_ZIP; }
+ virtual PTXF Duplicate(PGLOBAL g) { return (PTXF) new(g)ZPXFAM(this); }
+
+ // Methods
+ virtual int GetFileLength(PGLOBAL g);
+ virtual int Cardinality(PGLOBAL g);
+ virtual bool OpenTableFile(PGLOBAL g);
+ virtual int GetNext(PGLOBAL g);
+//virtual int ReadBuffer(PGLOBAL g);
+
+protected:
+ // Members
+ ZIPUTIL *zutp;
+ PSZ target;
+ bool mul;
+}; // end of ZPXFAM
#endif // __FILAMZIP_H
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 419a33ed74e..b542ca180c5 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -171,9 +171,9 @@
#define JSONMAX 10 // JSON Default max grp size
extern "C" {
- char version[]= "Version 1.04.0008 August 10, 2016";
+ char version[]= "Version 1.05.0001 December 13, 2016";
#if defined(__WIN__)
- char compver[]= "Version 1.04.0008 " __DATE__ " " __TIME__;
+ char compver[]= "Version 1.05.0001 " __DATE__ " " __TIME__;
char slash= '\\';
#else // !__WIN__
char slash= '/';
@@ -512,13 +512,13 @@ ha_create_table_option connect_table_option_list[]=
HA_TOPTION_NUMBER("QUOTED", quoted, (ulonglong) -1, 0, 3, 1),
HA_TOPTION_NUMBER("ENDING", ending, (ulonglong) -1, 0, INT_MAX32, 1),
HA_TOPTION_NUMBER("COMPRESS", compressed, 0, 0, 2, 1),
-//HA_TOPTION_BOOL("COMPRESS", compressed, 0),
HA_TOPTION_BOOL("MAPPED", mapped, 0),
HA_TOPTION_BOOL("HUGE", huge, 0),
HA_TOPTION_BOOL("SPLIT", split, 0),
HA_TOPTION_BOOL("READONLY", readonly, 0),
HA_TOPTION_BOOL("SEPINDEX", sepindex, 0),
- HA_TOPTION_END
+ HA_TOPTION_BOOL("ZIPPED", zipped, 0),
+ HA_TOPTION_END
};
@@ -532,7 +532,6 @@ ha_create_table_option connect_field_option_list[]=
{
HA_FOPTION_NUMBER("FLAG", offset, (ulonglong) -1, 0, INT_MAX32, 1),
HA_FOPTION_NUMBER("MAX_DIST", freq, 0, 0, INT_MAX32, 1), // BLK_INDX
-//HA_FOPTION_NUMBER("DISTRIB", opt, 0, 0, 2, 1), // used for BLK_INDX
HA_FOPTION_NUMBER("FIELD_LENGTH", fldlen, 0, 0, INT_MAX32, 1),
HA_FOPTION_STRING("DATE_FORMAT", dateformat),
HA_FOPTION_STRING("FIELD_FORMAT", fieldformat),
@@ -678,7 +677,6 @@ static int connect_init_func(void *p)
connect_hton= (handlerton *)p;
connect_hton->state= SHOW_OPTION_YES;
connect_hton->create= connect_create_handler;
-//connect_hton->flags= HTON_TEMPORARY_NOT_SUPPORTED | HTON_NO_PARTITION;
connect_hton->flags= HTON_TEMPORARY_NOT_SUPPORTED;
connect_hton->table_options= connect_table_option_list;
connect_hton->field_options= connect_field_option_list;
@@ -1135,7 +1133,9 @@ bool GetBooleanTableOption(PGLOBAL g, PTOS options, char *opname, bool bdef)
opval= options->sepindex;
else if (!stricmp(opname, "Header"))
opval= (options->header != 0); // Is Boolean for some table types
- else if (options->oplist)
+ else if (!stricmp(opname, "Zipped"))
+ opval = options->zipped;
+ else if (options->oplist)
if ((pv= GetListOption(g, opname, options->oplist)))
opval= (!*pv || *pv == 'y' || *pv == 'Y' || atoi(pv) != 0);
@@ -1242,8 +1242,10 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
if (opval && (!stricmp(opname, "connect")
|| !stricmp(opname, "tabname")
- || !stricmp(opname, "filename")))
- opval = GetRealString(opval);
+ || !stricmp(opname, "filename")
+ || !stricmp(opname, "optname")
+ || !stricmp(opname, "entry")))
+ opval = GetRealString(opval);
if (!opval) {
if (sdef && !strcmp(sdef, "*")) {
@@ -4164,7 +4166,8 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn, bool quick)
case TAB_DIR:
case TAB_MAC:
case TAB_WMI:
- case TAB_OEM:
+ case TAB_ZIP:
+ case TAB_OEM:
#ifdef NO_EMBEDDED_ACCESS_CHECKS
return false;
#endif
@@ -5172,13 +5175,13 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
char v=0, spc= ',', qch= 0;
const char *fncn= "?";
const char *user, *fn, *db, *host, *pwd, *sep, *tbl, *src;
- const char *col, *ocl, *rnk, *pic, *fcl, *skc;
+ const char *col, *ocl, *rnk, *pic, *fcl, *skc, *zfn;
char *tab, *dsn, *shm, *dpath;
#if defined(__WIN__)
char *nsp= NULL, *cls= NULL;
#endif // __WIN__
- int port= 0, hdr= 0, mxr= 0, mxe= 0, rc= 0;
- int cop __attribute__((unused))= 0, lrecl= 0;
+//int hdr, mxe;
+ int port = 0, mxr = 0, rc = 0, mul = 0, lrecl = 0;
#if defined(ODBC_SUPPORT)
POPARM sop= NULL;
char *ucnc= NULL;
@@ -5189,7 +5192,8 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
PJPARM sjp= NULL;
char *driver= NULL;
char *url= NULL;
- char *tabtyp = NULL;
+//char *prop= NULL;
+ char *tabtyp= NULL;
#endif // JDBC_SUPPORT
uint tm, fnc= FNC_NO, supfnc= (FNC_NO | FNC_COL);
bool bif, ok= false, dbf= false;
@@ -5209,7 +5213,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
if (!g)
return HA_ERR_INTERNAL_ERROR;
- user= host= pwd= tbl= src= col= ocl= pic= fcl= skc= rnk= dsn= NULL;
+ user= host= pwd= tbl= src= col= ocl= pic= fcl= skc= rnk= zfn= dsn= NULL;
// Get the useful create options
ttp= GetTypeID(topt->type);
@@ -5222,7 +5226,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
sep= topt->separator;
spc= (!sep) ? ',' : *sep;
qch= topt->qchar ? *topt->qchar : (signed)topt->quoted >= 0 ? '"' : 0;
- hdr= (int)topt->header;
+ mul = (int)topt->multiple;
tbl= topt->tablist;
col= topt->colist;
@@ -5255,13 +5259,16 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#if defined(JDBC_SUPPORT)
driver= GetListOption(g, "Driver", topt->oplist, NULL);
// url= GetListOption(g, "URL", topt->oplist, NULL);
+// prop = GetListOption(g, "Properties", topt->oplist, NULL);
tabtyp = GetListOption(g, "Tabtype", topt->oplist, NULL);
#endif // JDBC_SUPPORT
- mxe= atoi(GetListOption(g,"maxerr", topt->oplist, "0"));
#if defined(PROMPT_OK)
cop= atoi(GetListOption(g, "checkdsn", topt->oplist, "0"));
#endif // PROMPT_OK
- } else {
+#if defined(ZIP_SUPPORT)
+ zfn = GetListOption(g, "Zipfile", topt->oplist, NULL);
+#endif // ZIP_SUPPORT
+ } else {
host= "localhost";
user= (ttp == TAB_ODBC ? NULL : "root");
} // endif option_list
@@ -5365,6 +5372,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
jdef->SetName(create_info->alias);
sjp= (PJPARM)PlugSubAlloc(g, NULL, sizeof(JDBCPARM));
sjp->Driver= driver;
+// sjp->Properties = prop;
sjp->Fsize= 0;
sjp->Scrollable= false;
@@ -5467,7 +5475,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
case TAB_XML:
#endif // LIBXML2_SUPPORT || DOMDOC_SUPPORT
case TAB_JSON:
- if (!fn)
+ if (!fn && !zfn && !mul)
sprintf(g->Message, "Missing %s file name", topt->type);
else
ok= true;
@@ -5581,7 +5589,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
NULL, port, fnc == FNC_COL);
break;
case TAB_CSV:
- qrp= CSVColumns(g, dpath, fn, spc, qch, hdr, mxe, fnc == FNC_COL);
+ qrp = CSVColumns(g, dpath, topt, fnc == FNC_COL);
break;
#if defined(__WIN__)
case TAB_WMI:
@@ -6946,7 +6954,7 @@ maria_declare_plugin(connect)
0x0104, /* version number (1.04) */
NULL, /* status variables */
connect_system_variables, /* system variables */
- "1.04.0008", /* string version */
+ "1.05.0001", /* string version */
MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
}
maria_declare_plugin_end;
diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h
index 60194ac0e3c..3d9ff967618 100644
--- a/storage/connect/ha_connect.h
+++ b/storage/connect/ha_connect.h
@@ -83,42 +83,9 @@ extern handlerton *connect_hton;
These can be specified in the CREATE TABLE:
CREATE TABLE ( ... ) {...here...}
-*/
-#if 0 // moved to mycat.h
-typedef struct ha_table_option_struct TOS, *PTOS;
-
-struct ha_table_option_struct {
- const char *type;
- const char *filename;
- const char *optname;
- const char *tabname;
- const char *tablist;
- const char *dbname;
- const char *separator;
-//const char *connect;
- const char *qchar;
- const char *module;
- const char *subtype;
- const char *catfunc;
- const char *srcdef;
- const char *colist;
- const char *oplist;
- const char *data_charset;
- ulonglong lrecl;
- ulonglong elements;
-//ulonglong estimate;
- ulonglong multiple;
- ulonglong header;
- ulonglong quoted;
- ulonglong ending;
- ulonglong compressed;
- bool mapped;
- bool huge;
- bool split;
- bool readonly;
- bool sepindex;
- };
-#endif // 0
+
+ ------ Was moved to mycat.h ------
+ */
/**
structure for CREATE TABLE options (field options)
diff --git a/storage/connect/ioapi.c b/storage/connect/ioapi.c
new file mode 100644
index 00000000000..7f5c191b2af
--- /dev/null
+++ b/storage/connect/ioapi.c
@@ -0,0 +1,247 @@
+/* ioapi.h -- IO base function header for compress/uncompress .zip
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+*/
+
+#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS)))
+ #define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#if defined(__APPLE__) || defined(IOAPI_NO_64)
+// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
+#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
+#define FTELLO_FUNC(stream) ftello(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
+#else
+#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
+#define FTELLO_FUNC(stream) ftello64(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
+#endif
+
+
+#include "ioapi.h"
+
+voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
+{
+ if (pfilefunc->zfile_func64.zopen64_file != NULL)
+ return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);
+ else
+ {
+ return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode);
+ }
+}
+
+long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
+{
+ if (pfilefunc->zfile_func64.zseek64_file != NULL)
+ return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
+ else
+ {
+ uLong offsetTruncated = (uLong)offset;
+ if (offsetTruncated != offset)
+ return -1;
+ else
+ return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
+ }
+}
+
+ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
+{
+ if (pfilefunc->zfile_func64.zseek64_file != NULL)
+ return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
+ else
+ {
+ uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
+ if ((tell_uLong) == MAXU32)
+ return (ZPOS64_T)-1;
+ else
+ return tell_uLong;
+ }
+}
+
+void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
+{
+ p_filefunc64_32->zfile_func64.zopen64_file = NULL;
+ p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
+ p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
+ p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
+ p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
+ p_filefunc64_32->zfile_func64.ztell64_file = NULL;
+ p_filefunc64_32->zfile_func64.zseek64_file = NULL;
+ p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
+ p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
+ p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
+ p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
+ p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
+}
+
+
+
+static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));
+static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));
+static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));
+static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));
+static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
+
+static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
+{
+ FILE* file = NULL;
+ const char* mode_fopen = NULL;
+ if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+ mode_fopen = "rb";
+ else
+ if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+ mode_fopen = "r+b";
+ else
+ if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+ mode_fopen = "wb";
+
+ if ((filename!=NULL) && (mode_fopen != NULL))
+ file = fopen(filename, mode_fopen);
+ return file;
+}
+
+static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
+{
+ FILE* file = NULL;
+ const char* mode_fopen = NULL;
+ if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+ mode_fopen = "rb";
+ else
+ if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+ mode_fopen = "r+b";
+ else
+ if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+ mode_fopen = "wb";
+
+ if ((filename!=NULL) && (mode_fopen != NULL))
+ file = FOPEN_FUNC((const char*)filename, mode_fopen);
+ return file;
+}
+
+
+static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
+{
+ uLong ret;
+ ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
+ return ret;
+}
+
+static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
+{
+ uLong ret;
+ ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
+ return ret;
+}
+
+static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
+{
+ long ret;
+ ret = ftell((FILE *)stream);
+ return ret;
+}
+
+
+static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
+{
+ ZPOS64_T ret;
+ ret = FTELLO_FUNC((FILE *)stream);
+ return ret;
+}
+
+static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin)
+{
+ int fseek_origin=0;
+ long ret;
+ switch (origin)
+ {
+ case ZLIB_FILEFUNC_SEEK_CUR :
+ fseek_origin = SEEK_CUR;
+ break;
+ case ZLIB_FILEFUNC_SEEK_END :
+ fseek_origin = SEEK_END;
+ break;
+ case ZLIB_FILEFUNC_SEEK_SET :
+ fseek_origin = SEEK_SET;
+ break;
+ default: return -1;
+ }
+ ret = 0;
+ if (fseek((FILE *)stream, offset, fseek_origin) != 0)
+ ret = -1;
+ return ret;
+}
+
+static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
+{
+ int fseek_origin=0;
+ long ret;
+ switch (origin)
+ {
+ case ZLIB_FILEFUNC_SEEK_CUR :
+ fseek_origin = SEEK_CUR;
+ break;
+ case ZLIB_FILEFUNC_SEEK_END :
+ fseek_origin = SEEK_END;
+ break;
+ case ZLIB_FILEFUNC_SEEK_SET :
+ fseek_origin = SEEK_SET;
+ break;
+ default: return -1;
+ }
+ ret = 0;
+
+ if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0)
+ ret = -1;
+
+ return ret;
+}
+
+
+static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
+{
+ int ret;
+ ret = fclose((FILE *)stream);
+ return ret;
+}
+
+static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
+{
+ int ret;
+ ret = ferror((FILE *)stream);
+ return ret;
+}
+
+void fill_fopen_filefunc (pzlib_filefunc_def)
+ zlib_filefunc_def* pzlib_filefunc_def;
+{
+ pzlib_filefunc_def->zopen_file = fopen_file_func;
+ pzlib_filefunc_def->zread_file = fread_file_func;
+ pzlib_filefunc_def->zwrite_file = fwrite_file_func;
+ pzlib_filefunc_def->ztell_file = ftell_file_func;
+ pzlib_filefunc_def->zseek_file = fseek_file_func;
+ pzlib_filefunc_def->zclose_file = fclose_file_func;
+ pzlib_filefunc_def->zerror_file = ferror_file_func;
+ pzlib_filefunc_def->opaque = NULL;
+}
+
+void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def)
+{
+ pzlib_filefunc_def->zopen64_file = fopen64_file_func;
+ pzlib_filefunc_def->zread_file = fread_file_func;
+ pzlib_filefunc_def->zwrite_file = fwrite_file_func;
+ pzlib_filefunc_def->ztell64_file = ftell64_file_func;
+ pzlib_filefunc_def->zseek64_file = fseek64_file_func;
+ pzlib_filefunc_def->zclose_file = fclose_file_func;
+ pzlib_filefunc_def->zerror_file = ferror_file_func;
+ pzlib_filefunc_def->opaque = NULL;
+}
diff --git a/storage/connect/ioapi.h b/storage/connect/ioapi.h
new file mode 100644
index 00000000000..4fa73002053
--- /dev/null
+++ b/storage/connect/ioapi.h
@@ -0,0 +1,209 @@
+/* ioapi.h -- IO base function header for compress/uncompress .zip
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+ Changes
+
+ Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
+ Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
+ More if/def section may be needed to support other platforms
+ Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
+ (but you should use iowin32.c for windows instead)
+
+*/
+
+#ifndef _ZLIBIOAPI64_H
+#define _ZLIBIOAPI64_H
+
+#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
+
+ // Linux needs this to support file operation on files larger then 4+GB
+ // But might need better if/def to select just the platforms that needs them.
+
+ #ifndef __USE_FILE_OFFSET64
+ #define __USE_FILE_OFFSET64
+ #endif
+ #ifndef __USE_LARGEFILE64
+ #define __USE_LARGEFILE64
+ #endif
+ #ifndef _LARGEFILE64_SOURCE
+ #define _LARGEFILE64_SOURCE
+ #endif
+ #ifndef _FILE_OFFSET_BIT
+ #define _FILE_OFFSET_BIT 64
+ #endif
+
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "zlib.h"
+
+#if defined(USE_FILE32API)
+#define fopen64 fopen
+#define ftello64 ftell
+#define fseeko64 fseek
+#else
+#ifdef __FreeBSD__
+#define fopen64 fopen
+#define ftello64 ftello
+#define fseeko64 fseeko
+#endif
+#ifdef _MSC_VER
+ #define fopen64 fopen
+ #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
+ #define ftello64 _ftelli64
+ #define fseeko64 _fseeki64
+ #else // old MSC
+ #define ftello64 ftell
+ #define fseeko64 fseek
+ #endif
+#endif
+#endif
+
+/*
+#ifndef ZPOS64_T
+ #ifdef _WIN32
+ #define ZPOS64_T fpos_t
+ #else
+ #include <stdint.h>
+ #define ZPOS64_T uint64_t
+ #endif
+#endif
+*/
+
+#ifdef HAVE_MINIZIP64_CONF_H
+#include "mz64conf.h"
+#endif
+
+/* a type choosen by DEFINE */
+#ifdef HAVE_64BIT_INT_CUSTOM
+typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T;
+#else
+#ifdef HAS_STDINT_H
+#include "stdint.h"
+typedef uint64_t ZPOS64_T;
+#else
+
+/* Maximum unsigned 32-bit value used as placeholder for zip64 */
+#define MAXU32 0xffffffff
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef unsigned __int64 ZPOS64_T;
+#else
+typedef unsigned long long int ZPOS64_T;
+#endif
+#endif
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define ZLIB_FILEFUNC_SEEK_CUR (1)
+#define ZLIB_FILEFUNC_SEEK_END (2)
+#define ZLIB_FILEFUNC_SEEK_SET (0)
+
+#define ZLIB_FILEFUNC_MODE_READ (1)
+#define ZLIB_FILEFUNC_MODE_WRITE (2)
+#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
+
+#define ZLIB_FILEFUNC_MODE_EXISTING (4)
+#define ZLIB_FILEFUNC_MODE_CREATE (8)
+
+
+#ifndef ZCALLBACK
+ #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
+ #define ZCALLBACK CALLBACK
+ #else
+ #define ZCALLBACK
+ #endif
+#endif
+
+#ifndef OF
+#define OF(args) args
+#endif
+
+typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
+typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
+typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
+typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
+
+typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
+typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
+
+
+/* here is the "old" 32 bits structure structure */
+typedef struct zlib_filefunc_def_s
+{
+ open_file_func zopen_file;
+ read_file_func zread_file;
+ write_file_func zwrite_file;
+ tell_file_func ztell_file;
+ seek_file_func zseek_file;
+ close_file_func zclose_file;
+ testerror_file_func zerror_file;
+ voidpf opaque;
+} zlib_filefunc_def;
+
+typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream));
+typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode));
+
+typedef struct zlib_filefunc64_def_s
+{
+ open64_file_func zopen64_file;
+ read_file_func zread_file;
+ write_file_func zwrite_file;
+ tell64_file_func ztell64_file;
+ seek64_file_func zseek64_file;
+ close_file_func zclose_file;
+ testerror_file_func zerror_file;
+ voidpf opaque;
+} zlib_filefunc64_def;
+
+void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
+void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
+
+/* now internal definition, only for zip.c and unzip.h */
+typedef struct zlib_filefunc64_32_def_s
+{
+ zlib_filefunc64_def zfile_func64;
+ open_file_func zopen32_file;
+ tell_file_func ztell32_file;
+ seek_file_func zseek32_file;
+} zlib_filefunc64_32_def;
+
+
+#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
+#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
+//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))
+//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))
+#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream))
+#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream))
+
+voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
+long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
+ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
+
+void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
+
+#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode)))
+#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream)))
+#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/storage/connect/jdbccat.h b/storage/connect/jdbccat.h
index 37f33d7063d..7108aa376ce 100644
--- a/storage/connect/jdbccat.h
+++ b/storage/connect/jdbccat.h
@@ -8,6 +8,7 @@ typedef struct jdbc_parms {
char *Url; // Driver URL
char *User; // User connect info
char *Pwd; // Password connect info
+//char *Properties; // Connection property list
//int Cto; // Connect timeout
//int Qto; // Query timeout
int Fsize; // Fetch size
diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp
index dca9bd0eac4..a69f84a94a1 100644
--- a/storage/connect/jdbconn.cpp
+++ b/storage/connect/jdbconn.cpp
@@ -55,9 +55,8 @@
#if defined(__WIN__)
extern "C" HINSTANCE s_hModule; // Saved module handle
-#else // !__WIN__
+#endif // __WIN__
#define nullptr 0
-#endif // !__WIN__
TYPCONV GetTypeConv();
int GetConvSize();
@@ -525,10 +524,10 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp)
m_Wrap = strcat(strcpy(wn, "wrappers/"), m_Wrap);
} // endif m_Wrap
- m_Driver = NULL;
- m_Url = NULL;
- m_User = NULL;
- m_Pwd = NULL;
+//m_Driver = NULL;
+//m_Url = NULL;
+//m_User = NULL;
+//m_Pwd = NULL;
m_Ncol = 0;
m_Aff = 0;
m_Rows = 0;
@@ -772,7 +771,7 @@ bool JDBConn::GetJVM(PGLOBAL g)
/***********************************************************************/
int JDBConn::Open(PJPARM sop)
{
-
+ int irc = RC_FX;
bool err = false;
jboolean jt = (trace > 0);
PGLOBAL& g = m_G;
@@ -865,30 +864,37 @@ int JDBConn::Open(PJPARM sop)
switch (rc) {
case JNI_OK:
strcpy(g->Message, "VM successfully created");
+ irc = RC_OK;
break;
case JNI_ERR:
strcpy(g->Message, "Initialising JVM failed: unknown error");
- return RC_FX;
+ break;
case JNI_EDETACHED:
strcpy(g->Message, "Thread detached from the VM");
- return RC_FX;
+ break;
case JNI_EVERSION:
strcpy(g->Message, "JNI version error");
- return RC_FX;
+ break;
case JNI_ENOMEM:
strcpy(g->Message, "Not enough memory");
- return RC_FX;
+ break;
case JNI_EEXIST:
strcpy(g->Message, "VM already created");
- return RC_FX;
+ break;
case JNI_EINVAL:
strcpy(g->Message, "Invalid arguments");
- return RC_FX;
+ break;
default:
- sprintf(g->Message, "Unknown return code %d", rc);
- return RC_FX;
+ sprintf(g->Message, "Unknown return code %d", (int)rc);
+ break;
} // endswitch rc
+ if (trace)
+ htrc("%s\n", g->Message);
+
+ if (irc != RC_OK)
+ return irc;
+
//=============== Display JVM version ===============
jint ver = env->GetVersion();
printf("JVM Version %d.%d\n", ((ver>>16)&0x0f), (ver&0x0f));
@@ -978,10 +984,10 @@ int JDBConn::Open(PJPARM sop)
jobjectArray parms = env->NewObjectArray(4, // constructs java array of 4
env->FindClass("java/lang/String"), NULL); // Strings
- m_Driver = sop->Driver;
- m_Url = sop->Url;
- m_User = sop->User;
- m_Pwd = sop->Pwd;
+//m_Driver = sop->Driver;
+//m_Url = sop->Url;
+//m_User = sop->User;
+//m_Pwd = sop->Pwd;
m_Scrollable = sop->Scrollable;
m_RowsetSize = sop->Fsize;
//m_LoginTimeout = sop->Cto;
@@ -989,17 +995,20 @@ int JDBConn::Open(PJPARM sop)
//m_UseCnc = sop->UseCnc;
// change some elements
- if (m_Driver)
- env->SetObjectArrayElement(parms, 0, env->NewStringUTF(m_Driver));
+ if (sop->Driver)
+ env->SetObjectArrayElement(parms, 0, env->NewStringUTF(sop->Driver));
- if (m_Url)
- env->SetObjectArrayElement(parms, 1, env->NewStringUTF(m_Url));
+ if (sop->Url)
+ env->SetObjectArrayElement(parms, 1, env->NewStringUTF(sop->Url));
- if (m_User)
- env->SetObjectArrayElement(parms, 2, env->NewStringUTF(m_User));
+ if (sop->User)
+ env->SetObjectArrayElement(parms, 2, env->NewStringUTF(sop->User));
- if (m_Pwd)
- env->SetObjectArrayElement(parms, 3, env->NewStringUTF(m_Pwd));
+ if (sop->Pwd)
+ env->SetObjectArrayElement(parms, 3, env->NewStringUTF(sop->Pwd));
+
+//if (sop->Properties)
+// env->SetObjectArrayElement(parms, 4, env->NewStringUTF(sop->Properties));
// call method
rc = env->CallIntMethod(job, cid, parms, m_RowsetSize, m_Scrollable);
@@ -1432,7 +1441,7 @@ bool JDBConn::SetParam(JDBCCOL *colp)
PGLOBAL& g = m_G;
bool rc = false;
PVAL val = colp->GetValue();
- jint n, i = (jint)colp->GetRank();
+ jint n, jrc = 0, i = (jint)colp->GetRank();
jshort s;
jlong lg;
//jfloat f;
@@ -1442,69 +1451,74 @@ bool JDBConn::SetParam(JDBCCOL *colp)
jstring jst = nullptr;
jmethodID dtc, setid = nullptr;
- switch (val->GetType()) {
- case TYPE_STRING:
- if (gmID(g, setid, "SetStringParm", "(ILjava/lang/String;)V"))
- return true;
-
- jst = env->NewStringUTF(val->GetCharValue());
- env->CallVoidMethod(job, setid, i, jst);
- break;
- case TYPE_INT:
- if (gmID(g, setid, "SetIntParm", "(II)V"))
+ if (val->GetNullable() && val->IsNull()) {
+ if (gmID(g, setid, "SetNullParm", "(II)I"))
return true;
- n = (jint)val->GetIntValue();
- env->CallVoidMethod(job, setid, i, n);
- break;
- case TYPE_TINY:
- case TYPE_SHORT:
- if (gmID(g, setid, "SetShortParm", "(IS)V"))
- return true;
+ jrc = env->CallIntMethod(job, setid, i, (jint)GetJDBCType(val->GetType()));
+ } else switch (val->GetType()) {
+ case TYPE_STRING:
+ if (gmID(g, setid, "SetStringParm", "(ILjava/lang/String;)V"))
+ return true;
- s = (jshort)val->GetShortValue();
- env->CallVoidMethod(job, setid, i, s);
- break;
- case TYPE_BIGINT:
- if (gmID(g, setid, "SetBigintParm", "(IJ)V"))
- return true;
+ jst = env->NewStringUTF(val->GetCharValue());
+ env->CallVoidMethod(job, setid, i, jst);
+ break;
+ case TYPE_INT:
+ if (gmID(g, setid, "SetIntParm", "(II)V"))
+ return true;
- lg = (jlong)val->GetBigintValue();
- env->CallVoidMethod(job, setid, i, lg);
- break;
- case TYPE_DOUBLE:
- case TYPE_DECIM:
- if (gmID(g, setid, "SetDoubleParm", "(ID)V"))
- return true;
+ n = (jint)val->GetIntValue();
+ env->CallVoidMethod(job, setid, i, n);
+ break;
+ case TYPE_TINY:
+ case TYPE_SHORT:
+ if (gmID(g, setid, "SetShortParm", "(IS)V"))
+ return true;
- d = (jdouble)val->GetFloatValue();
- env->CallVoidMethod(job, setid, i, d);
- break;
- case TYPE_DATE:
- if ((dat = env->FindClass("java/sql/Timestamp")) == nullptr) {
- strcpy(g->Message, "Cannot find Timestamp class");
- return true;
- } else if (!(dtc = env->GetMethodID(dat, "<init>", "(J)V"))) {
- strcpy(g->Message, "Cannot find Timestamp class constructor");
- return true;
- } // endif's
+ s = (jshort)val->GetShortValue();
+ env->CallVoidMethod(job, setid, i, s);
+ break;
+ case TYPE_BIGINT:
+ if (gmID(g, setid, "SetBigintParm", "(IJ)V"))
+ return true;
- lg = (jlong)val->GetBigintValue() * 1000;
+ lg = (jlong)val->GetBigintValue();
+ env->CallVoidMethod(job, setid, i, lg);
+ break;
+ case TYPE_DOUBLE:
+ case TYPE_DECIM:
+ if (gmID(g, setid, "SetDoubleParm", "(ID)V"))
+ return true;
- if ((datobj = env->NewObject(dat, dtc, lg)) == nullptr) {
- strcpy(g->Message, "Cannot make Timestamp object");
- return true;
- } else if (gmID(g, setid, "SetTimestampParm", "(ILjava/sql/Timestamp;)V"))
+ d = (jdouble)val->GetFloatValue();
+ env->CallVoidMethod(job, setid, i, d);
+ break;
+ case TYPE_DATE:
+ if ((dat = env->FindClass("java/sql/Timestamp")) == nullptr) {
+ strcpy(g->Message, "Cannot find Timestamp class");
+ return true;
+ } else if (!(dtc = env->GetMethodID(dat, "<init>", "(J)V"))) {
+ strcpy(g->Message, "Cannot find Timestamp class constructor");
+ return true;
+ } // endif's
+
+ lg = (jlong)val->GetBigintValue() * 1000;
+
+ if ((datobj = env->NewObject(dat, dtc, lg)) == nullptr) {
+ strcpy(g->Message, "Cannot make Timestamp object");
+ return true;
+ } else if (gmID(g, setid, "SetTimestampParm", "(ILjava/sql/Timestamp;)V"))
+ return true;
+
+ env->CallVoidMethod(job, setid, i, datobj);
+ break;
+ default:
+ sprintf(g->Message, "Parm type %d not supported", val->GetType());
return true;
+ } // endswitch Type
- env->CallVoidMethod(job, setid, i, datobj);
- break;
- default:
- sprintf(g->Message, "Parm type %d not supported", val->GetType());
- return true;
- } // endswitch Type
-
- if (Check()) {
+ if (Check(jrc)) {
sprintf(g->Message, "SetParam: col=%s msg=%s", colp->GetName(), Msg);
rc = true;
} // endif msg
diff --git a/storage/connect/jdbconn.h b/storage/connect/jdbconn.h
index 0a1c52d4576..9d428142839 100644
--- a/storage/connect/jdbconn.h
+++ b/storage/connect/jdbconn.h
@@ -180,9 +180,9 @@ protected:
char *Msg;
char *m_Wrap;
char m_IDQuoteChar[2];
- PSZ m_Driver;
- PSZ m_Url;
- PSZ m_User;
+//PSZ m_Driver;
+//PSZ m_Url;
+//PSZ m_User;
PSZ m_Pwd;
int m_Ncol;
int m_Aff;
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index 88931ea6c13..bc7f231814d 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -5263,3 +5263,50 @@ char *envar(UDF_INIT *initid, UDF_ARGS *args, char *result,
return str;
} // end of envar
+/*********************************************************************************/
+/* Returns the distinct number of B occurences in A. */
+/*********************************************************************************/
+my_bool countin_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+ if (args->arg_count != 2) {
+ strcpy(message, "This function must have 2 arguments");
+ return true;
+ } else if (args->arg_type[0] != STRING_RESULT) {
+ strcpy(message, "First argument must be string");
+ return true;
+ } else if (args->arg_type[1] != STRING_RESULT) {
+ strcpy(message, "Second argument is not a string");
+ return true;
+ } // endif args
+
+ return false;
+} // end of countin_init
+
+long long countin(UDF_INIT *initid, UDF_ARGS *args, char *result,
+ unsigned long *res_length, char *is_null, char *)
+{
+ PSZ str1, str2;
+ char *s;
+ long long n = 0;
+ size_t lg;
+
+ lg = (size_t)args->lengths[0];
+ s = str1 = (PSZ)malloc(lg + 1);
+ memcpy(str1, args->args[0], lg);
+ str1[lg] = 0;
+
+ lg = (size_t)args->lengths[1];
+ str2 = (PSZ)malloc(lg + 1);
+ memcpy(str2, args->args[1], lg);
+ str2[lg] = 0;
+
+ while (s = strstr(s, str2)) {
+ n++;
+ s += lg;
+ } // endwhile
+
+ free(str1);
+ free(str2);
+ return n;
+} // end of countin
+
diff --git a/storage/connect/jsonudf.h b/storage/connect/jsonudf.h
index 1406d9f2f2e..d2890421c62 100644
--- a/storage/connect/jsonudf.h
+++ b/storage/connect/jsonudf.h
@@ -221,6 +221,9 @@ extern "C" {
DllExport my_bool envar_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *envar(UDF_EXEC_ARGS);
+
+ DllExport my_bool countin_init(UDF_INIT*, UDF_ARGS*, char*);
+ DllExport long long countin(UDF_EXEC_ARGS);
} // extern "C"
diff --git a/storage/connect/libdoc.cpp b/storage/connect/libdoc.cpp
index c2882fc0d7c..2470d37c353 100644
--- a/storage/connect/libdoc.cpp
+++ b/storage/connect/libdoc.cpp
@@ -1,6 +1,6 @@
/******************************************************************/
/* Implementation of XML document processing using libxml2 */
-/* Author: Olivier Bertrand 2007-2015 */
+/* Author: Olivier Bertrand 2007-2016 */
/******************************************************************/
#include "my_global.h"
#include <string.h>
@@ -68,8 +68,8 @@ class LIBXMLDOC : public XMLDOCUMENT {
virtual void SetNofree(bool b) {Nofreelist = b;}
// Methods
- virtual bool Initialize(PGLOBAL g);
- virtual bool ParseFile(char *fn);
+ virtual bool Initialize(PGLOBAL g, char *entry, bool zipped);
+ virtual bool ParseFile(PGLOBAL g, char *fn);
virtual bool NewDoc(PGLOBAL g, char *ver);
virtual void AddComment(PGLOBAL g, char *com);
virtual PXNODE GetRoot(PGLOBAL g);
@@ -373,22 +373,33 @@ LIBXMLDOC::LIBXMLDOC(char *nsl, char *nsdf, char *enc, PFBLOCK fp)
/******************************************************************/
/* Initialize XML parser and check library compatibility. */
/******************************************************************/
-bool LIBXMLDOC::Initialize(PGLOBAL g)
- {
+bool LIBXMLDOC::Initialize(PGLOBAL g, char *entry, bool zipped)
+{
+ if (zipped && InitZip(g, entry))
+ return true;
+
int n = xmlKeepBlanksDefault(1);
return MakeNSlist(g);
- } // end of Initialize
+} // end of Initialize
/******************************************************************/
/* Parse the XML file and construct node tree in memory. */
/******************************************************************/
-bool LIBXMLDOC::ParseFile(char *fn)
+bool LIBXMLDOC::ParseFile(PGLOBAL g, char *fn)
{
if (trace)
htrc("ParseFile\n");
- if ((Docp = xmlParseFile(fn))) {
- if (Docp->encoding)
+ if (zip) {
+ // Parse an in memory document
+ char *xdoc = GetMemDoc(g, fn);
+
+ Docp = (xdoc) ? xmlParseDoc((const xmlChar *)xdoc) : NULL;
+ } else
+ Docp = xmlParseFile(fn);
+
+ if (Docp) {
+ if (Docp->encoding)
Encoding = (char*)Docp->encoding;
return false;
@@ -609,6 +620,7 @@ void LIBXMLDOC::CloseDoc(PGLOBAL g, PFBLOCK xp)
} // endif xp
CloseXML2File(g, xp, false);
+ CloseZip();
} // end of Close
/******************************************************************/
diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc
index b4b03e6ba4a..497fe5e1aa8 100644
--- a/storage/connect/mycat.cc
+++ b/storage/connect/mycat.cc
@@ -16,7 +16,7 @@
/*************** Mycat CC Program Source Code File (.CC) ***************/
/* PROGRAM NAME: MYCAT */
/* ------------- */
-/* Version 1.4 */
+/* Version 1.5 */
/* */
/* Author: Olivier Bertrand 2012 - 2016 */
/* */
@@ -64,7 +64,9 @@
#include "filamtxt.h"
#include "tabdos.h"
#include "tabfmt.h"
+#if defined(VCT_SUPPORT)
#include "tabvct.h"
+#endif // VCT_SUPPORT
#include "tabsys.h"
#if defined(__WIN__)
#include "tabmac.h"
@@ -93,6 +95,9 @@
#if defined(XML_SUPPORT)
#include "tabxml.h"
#endif // XML_SUPPORT
+#if defined(ZIP_SUPPORT)
+#include "tabzip.h"
+#endif // ZIP_SUPPORT
#include "mycat.h"
/***********************************************************************/
@@ -152,7 +157,10 @@ TABTYPE GetTypeID(const char *type)
#endif
: (!stricmp(type, "VIR")) ? TAB_VIR
: (!stricmp(type, "JSON")) ? TAB_JSON
- : (!stricmp(type, "OEM")) ? TAB_OEM : TAB_NIY;
+#ifdef ZIP_SUPPORT
+ : (!stricmp(type, "ZIP")) ? TAB_ZIP
+#endif
+ : (!stricmp(type, "OEM")) ? TAB_OEM : TAB_NIY;
} // end of GetTypeID
/***********************************************************************/
@@ -173,6 +181,7 @@ bool IsFileType(TABTYPE type)
case TAB_INI:
case TAB_VEC:
case TAB_JSON:
+// case TAB_ZIP:
isfile= true;
break;
default:
@@ -549,7 +558,9 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
#if defined(XML_SUPPORT)
case TAB_XML: tdp= new(g) XMLDEF; break;
#endif // XML_SUPPORT
- case TAB_VEC: tdp= new(g) VCTDEF; break;
+#if defined(VCT_SUPPORT)
+ case TAB_VEC: tdp = new(g)VCTDEF; break;
+#endif // VCT_SUPPORT
#if defined(ODBC_SUPPORT)
case TAB_ODBC: tdp= new(g) ODBCDEF; break;
#endif // ODBC_SUPPORT
@@ -571,7 +582,10 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
#endif // PIVOT_SUPPORT
case TAB_VIR: tdp= new(g) VIRDEF; break;
case TAB_JSON: tdp= new(g) JSONDEF; break;
- default:
+#if defined(ZIP_SUPPORT)
+ case TAB_ZIP: tdp= new(g) ZIPDEF; break;
+#endif // ZIP_SUPPORT
+ default:
sprintf(g->Message, MSG(BAD_TABLE_TYPE), am, name);
} // endswitch
diff --git a/storage/connect/mycat.h b/storage/connect/mycat.h
index 05163f08f1b..663b68fd4b9 100644
--- a/storage/connect/mycat.h
+++ b/storage/connect/mycat.h
@@ -62,6 +62,7 @@ struct ha_table_option_struct {
bool split;
bool readonly;
bool sepindex;
+ bool zipped;
};
// Possible value for catalog functions
diff --git a/storage/connect/mysql-test/connect/disabled.def b/storage/connect/mysql-test/connect/disabled.def
index 64d7ece3fe1..0e5a5fc64e3 100644
--- a/storage/connect/mysql-test/connect/disabled.def
+++ b/storage/connect/mysql-test/connect/disabled.def
@@ -9,8 +9,8 @@
# Do not use any TAB characters for whitespace.
#
##############################################################################
-jdbc : Variable settings depend on machine configuration
-jdbc_new : Variable settings depend on machine configuration
+#jdbc : Variable settings depend on machine configuration
+#jdbc_new : Variable settings depend on machine configuration
jdbc_oracle : Variable settings depend on machine configuration
jdbc_postgresql : Variable settings depend on machine configuration
json : TABLE_TYPE = JSON conflicts with the SQL syntax
diff --git a/storage/connect/mysql-test/connect/r/jdbc_new.result b/storage/connect/mysql-test/connect/r/jdbc_new.result
index 14381b0b11f..5cc4826213d 100644
--- a/storage/connect/mysql-test/connect/r/jdbc_new.result
+++ b/storage/connect/mysql-test/connect/r/jdbc_new.result
@@ -56,7 +56,7 @@ t1 CREATE TABLE `t1` (
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC'
SELECT * FROM t1;
a b
-0 NULL
+NULL NULL
0 test00
1 test01
2 test02
@@ -72,7 +72,7 @@ t1 CREATE TABLE `t1` (
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC `TABNAME`='t1'
SELECT * FROM t1;
a b
-0 NULL
+NULL NULL
0 test00
1 test01
2 test02
@@ -104,7 +104,7 @@ t1 CREATE TABLE `t1` (
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC
SELECT * FROM t1;
a b
-0 NULL
+NULL NULL
0 0
1 0
2 0
diff --git a/storage/connect/mysql-test/connect/std_data/JdbcMariaDB.jar b/storage/connect/mysql-test/connect/std_data/JdbcMariaDB.jar
index 81f91e4465a..8525da74018 100644
--- a/storage/connect/mysql-test/connect/std_data/JdbcMariaDB.jar
+++ b/storage/connect/mysql-test/connect/std_data/JdbcMariaDB.jar
Binary files differ
diff --git a/storage/connect/mysql-test/connect/t/jdbc.test b/storage/connect/mysql-test/connect/t/jdbc.test
index 41fd298776b..58a527a3e6b 100644
--- a/storage/connect/mysql-test/connect/t/jdbc.test
+++ b/storage/connect/mysql-test/connect/t/jdbc.test
@@ -1,3 +1,4 @@
+-- source windows.inc
-- source jdbconn.inc
SET GLOBAL time_zone='+1:00';
diff --git a/storage/connect/mysql-test/connect/t/jdbc_new.test b/storage/connect/mysql-test/connect/t/jdbc_new.test
index d1ad5117b72..5586cf8c027 100644
--- a/storage/connect/mysql-test/connect/t/jdbc_new.test
+++ b/storage/connect/mysql-test/connect/t/jdbc_new.test
@@ -5,6 +5,7 @@ connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,);
connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT,);
connection master;
+-- source windows.inc
-- source jdbconn.inc
connection slave;
diff --git a/storage/connect/mysql-test/connect/t/windows.inc b/storage/connect/mysql-test/connect/t/windows.inc
new file mode 100644
index 00000000000..88553d8aa59
--- /dev/null
+++ b/storage/connect/mysql-test/connect/t/windows.inc
@@ -0,0 +1,5 @@
+if (`select convert(@@version_compile_os using latin1) IN ("Win32","Win64","Windows") = 0`)
+{
+ skip Need windows;
+}
+
diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h
index 910ce97f48a..cb408494319 100644
--- a/storage/connect/plgdbsem.h
+++ b/storage/connect/plgdbsem.h
@@ -1,9 +1,9 @@
/************** PlgDBSem H Declares Source Code File (.H) **************/
-/* Name: PLGDBSEM.H Version 3.6 */
+/* Name: PLGDBSEM.H Version 3.7 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 1998-2015 */
+/* (C) Copyright to the author Olivier BERTRAND 1998-2016 */
/* */
-/* This file contains the PlugDB++ application type definitions. */
+/* This file contains the CONNECT storage engine definitions. */
/***********************************************************************/
/***********************************************************************/
@@ -49,7 +49,8 @@ enum BLKTYP {TYPE_TABLE = 50, /* Table Name/Srcdef/... Block */
TYPE_FB_MAP = 23, /* Mapped file block (storage) */
TYPE_FB_HANDLE = 24, /* File block (handle) */
TYPE_FB_XML = 21, /* DOM XML file block */
- TYPE_FB_XML2 = 27}; /* libxml2 XML file block */
+ TYPE_FB_XML2 = 27, /* libxml2 XML file block */
+ TYPE_FB_ZIP = 28}; /* ZIP file block */
enum TABTYPE {TAB_UNDEF = 0, /* Table of undefined type */
TAB_DOS = 1, /* Fixed column offset, variable LRECL */
@@ -78,7 +79,8 @@ enum TABTYPE {TAB_UNDEF = 0, /* Table of undefined type */
TAB_JCT = 24, /* Junction tables NIY */
TAB_DMY = 25, /* DMY Dummy tables NIY */
TAB_JDBC = 26, /* Table accessed via JDBC */
- TAB_NIY = 27}; /* Table not implemented yet */
+ TAB_ZIP = 27, /* ZIP file info table */
+ TAB_NIY = 28}; /* Table not implemented yet */
enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_ROWID = 1, /* ROWID type (special column) */
@@ -123,7 +125,7 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_PRX = 129, /* PROXY access method type no */
TYPE_AM_XTB = 130, /* SYS table access method type */
TYPE_AM_BLK = 131, /* BLK access method type no */
- TYPE_AM_ZIP = 132, /* ZIP access method type no */
+ TYPE_AM_GZ = 132, /* GZ access method type no */
TYPE_AM_ZLIB = 133, /* ZLIB access method type no */
TYPE_AM_JSON = 134, /* JSON access method type no */
TYPE_AM_JSN = 135, /* JSN access method type no */
@@ -140,7 +142,8 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_MYSQL = 192, /* MYSQL access method type no */
TYPE_AM_MYX = 193, /* MYSQL EXEC access method type */
TYPE_AM_CAT = 195, /* Catalog access method type no */
- TYPE_AM_OUT = 200}; /* Output relations (storage) */
+ TYPE_AM_ZIP = 198, /* ZIP access method type no */
+ TYPE_AM_OUT = 200}; /* Output relations (storage) */
enum RECFM {RECFM_NAF = -2, /* Not a file */
RECFM_OEM = -1, /* OEM file access method */
diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp
index 13c0dfd1e18..83975c6d8fa 100644
--- a/storage/connect/plgdbutl.cpp
+++ b/storage/connect/plgdbutl.cpp
@@ -68,6 +68,9 @@
#include "tabcol.h" // header of XTAB and COLUMN classes
#include "valblk.h"
#include "rcmsg.h"
+#ifdef ZIP_SUPPORT
+#include "filamzip.h"
+#endif // ZIP_SUPPORT
/***********************************************************************/
/* DB static variables. */
@@ -934,7 +937,16 @@ int PlugCloseFile(PGLOBAL g __attribute__((unused)), PFBLOCK fp, bool all)
CloseXML2File(g, fp, all);
break;
#endif // LIBXML2_SUPPORT
- default:
+#ifdef ZIP_SUPPORT
+ case TYPE_FB_ZIP:
+ ((ZIPUTIL*)fp->File)->close();
+ fp->Memory = NULL;
+ fp->Mode = MODE_ANY;
+ fp->Count = 0;
+ fp->File = NULL;
+ break;
+#endif // ZIP_SUPPORT
+ default:
rc = RC_FX;
} // endswitch Type
diff --git a/storage/connect/plgxml.cpp b/storage/connect/plgxml.cpp
index 3061a6d697e..71b72621b06 100644
--- a/storage/connect/plgxml.cpp
+++ b/storage/connect/plgxml.cpp
@@ -30,19 +30,51 @@ PXDOC GetLibxmlDoc(PGLOBAL g, char *nsl, char *nsdf,
/* XMLDOCUMENT constructor. */
/******************************************************************/
XMLDOCUMENT::XMLDOCUMENT(char *nsl, char *nsdf, char *enc)
- {
- Namespaces = NULL;
+{
+#if defined(ZIP_SUPPORT)
+ zip = NULL;
+#else // !ZIP_SUPPORT
+ zip = false;
+#endif // !ZIP_SUPPORT
+ Namespaces = NULL;
Encoding = enc;
Nslist = nsl;
DefNs = nsdf;
- } // end of XMLDOCUMENT constructor
+} // end of XMLDOCUMENT constructor
+
+/******************************************************************/
+/* Initialize zipped file processing. */
+/******************************************************************/
+bool XMLDOCUMENT::InitZip(PGLOBAL g, char *entry)
+{
+#if defined(ZIP_SUPPORT)
+ bool mul = (entry) ? strchr(entry, '*') || strchr(entry, '?') : false;
+ zip = new(g) ZIPUTIL(entry, mul);
+ return zip == NULL;
+#else // !ZIP_SUPPORT
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
+ return true;
+#endif // !ZIP_SUPPORT
+} // end of InitZip
+
+/******************************************************************/
+/* Make the namespace structure list. */
+/******************************************************************/
+char* XMLDOCUMENT::GetMemDoc(PGLOBAL g, char *fn)
+{
+#if defined(ZIP_SUPPORT)
+ return (zip->OpenTable(g, MODE_ANY, fn)) ? NULL : zip->memory;
+#else // !ZIP_SUPPORT
+ return NULL;
+#endif // !ZIP_SUPPORT
+} // end of GetMemDoc
/******************************************************************/
/* Make the namespace structure list. */
/******************************************************************/
bool XMLDOCUMENT::MakeNSlist(PGLOBAL g)
- {
- char *prefix, *href, *next = Nslist;
+{
+ char *prefix, *href, *next = Nslist;
PNS nsp, *ppns = &Namespaces;
while (next) {
@@ -84,6 +116,19 @@ bool XMLDOCUMENT::MakeNSlist(PGLOBAL g)
} // end of MakeNSlist
/******************************************************************/
+/* Close ZIP file. */
+/******************************************************************/
+void XMLDOCUMENT::CloseZip(void)
+{
+#if defined(ZIP_SUPPORT)
+ if (zip) {
+ zip->close();
+ zip = NULL;
+ } // endif zip
+#endif // ZIP_SUPPORT
+} // end of CloseZip
+
+/******************************************************************/
/* XMLNODE constructor. */
/******************************************************************/
XMLNODE::XMLNODE(PXDOC dp)
diff --git a/storage/connect/plgxml.h b/storage/connect/plgxml.h
index b8e914e0bf1..db7dfa6bda5 100644
--- a/storage/connect/plgxml.h
+++ b/storage/connect/plgxml.h
@@ -1,3 +1,7 @@
+#if defined(ZIP_SUPPORT)
+#include "filamzip.h"
+#endif // ZIP_SUPPORT
+
/******************************************************************/
/* Dual XML implementation base classes defines. */
/******************************************************************/
@@ -72,8 +76,8 @@ class XMLDOCUMENT : public BLOCK {
virtual void SetNofree(bool b) = 0;
// Methods
- virtual bool Initialize(PGLOBAL) = 0;
- virtual bool ParseFile(char *) = 0;
+ virtual bool Initialize(PGLOBAL, char *, bool) = 0;
+ virtual bool ParseFile(PGLOBAL, char *) = 0;
virtual bool NewDoc(PGLOBAL, char *) = 0;
virtual void AddComment(PGLOBAL, char *) = 0;
virtual PXNODE GetRoot(PGLOBAL) = 0;
@@ -91,8 +95,16 @@ class XMLDOCUMENT : public BLOCK {
// Utility
bool MakeNSlist(PGLOBAL g);
+ bool InitZip(PGLOBAL g, char *entry);
+ char *GetMemDoc(PGLOBAL g, char *fn);
+ void CloseZip(void);
// Members
+#if defined(ZIP_SUPPORT)
+ ZIPUTIL *zip; /* Used for zipped file */
+#else // !ZIP_SUPPORT
+ bool zip; /* Always false */
+#endif // !ZIP_SUPPORT
PNS Namespaces; /* To the namespaces */
char *Encoding; /* The document encoding */
char *Nslist; /* Namespace list */
diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp
index 56a7ea8c512..ef91414a9ab 100644
--- a/storage/connect/reldef.cpp
+++ b/storage/connect/reldef.cpp
@@ -1,7 +1,7 @@
/************* RelDef CPP Program Source Code File (.CPP) **************/
/* PROGRAM NAME: RELDEF */
/* ------------- */
-/* Version 1.5 */
+/* Version 1.6 */
/* */
/* COPYRIGHT: */
/* ---------- */
@@ -40,10 +40,12 @@
#include "tabcol.h"
#include "filamap.h"
#include "filamfix.h"
+#if defined(VCT_SUPPORT)
#include "filamvct.h"
-#if defined(ZIP_SUPPORT)
-#include "filamzip.h"
-#endif // ZIP_SUPPORT
+#endif // VCT_SUPPORT
+#if defined(GZ_SUPPORT)
+#include "filamgz.h"
+#endif // GZ_SUPPORT
#include "tabdos.h"
#include "valblk.h"
#include "tabmul.h"
@@ -663,15 +665,15 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
/*********************************************************************/
if (!((PTDBDOS)tdbp)->GetTxfp()) {
if (cmpr) {
-#if defined(ZIP_SUPPORT)
+#if defined(GZ_SUPPORT)
if (cmpr == 1)
- txfp = new(g) ZIPFAM(defp);
+ txfp = new(g) GZFAM(defp);
else
txfp = new(g) ZLBFAM(defp);
-#else // !ZIP_SUPPORT
+#else // !GZ_SUPPORT
strcpy(g->Message, "Compress not supported");
return NULL;
-#endif // !ZIP_SUPPORT
+#endif // !GZ_SUPPORT
} else if (rfm == RECFM_VAR) {
if (map)
txfp = new(g) MAPFAM(defp);
@@ -683,16 +685,19 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
txfp = new(g) MPXFAM(defp);
else
txfp = new(g) FIXFAM(defp);
-
} else if (rfm == RECFM_VCT) {
- assert (Pxdef->GetDefType() == TYPE_AM_VCT);
+#if defined(VCT_SUPPORT)
+ assert(Pxdef->GetDefType() == TYPE_AM_VCT);
if (map)
txfp = new(g) VCMFAM((PVCTDEF)defp);
else
txfp = new(g) VCTFAM((PVCTDEF)defp);
-
- } // endif's
+#else // !VCT_SUPPORT
+ strcpy(g->Message, "VCT no more supported");
+ return NULL;
+#endif // !VCT_SUPPORT
+ } // endif's
((PTDBDOS)tdbp)->SetTxfp(txfp);
} // endif Txfp
diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp
index 98633f49d23..16cc6c33b44 100644
--- a/storage/connect/tabdos.cpp
+++ b/storage/connect/tabdos.cpp
@@ -1,11 +1,11 @@
/************* TabDos C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABDOS */
/* ------------- */
-/* Version 4.9 */
+/* Version 4.9.2 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 1998-2015 */
+/* (C) Copyright to the author Olivier BERTRAND 1998-2016 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -51,6 +51,9 @@
#include "filamap.h"
#include "filamfix.h"
#include "filamdbf.h"
+#if defined(GZ_SUPPORT)
+#include "filamgz.h"
+#endif // GZ_SUPPORT
#if defined(ZIP_SUPPORT)
#include "filamzip.h"
#endif // ZIP_SUPPORT
@@ -93,10 +96,13 @@ DOSDEF::DOSDEF(void)
Pseudo = 3;
Fn = NULL;
Ofn = NULL;
+ Entry = NULL;
To_Indx = NULL;
Recfm = RECFM_VAR;
Mapped = false;
- Padded = false;
+ Zipped = false;
+ Mulentries = false;
+ Padded = false;
Huge = false;
Accept = false;
Eof = false;
@@ -126,6 +132,11 @@ bool DOSDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
: (am && (*am == 'B' || *am == 'b')) ? "B"
: (am && !stricmp(am, "DBF")) ? "D" : "V";
+ if ((Zipped = GetBoolCatInfo("Zipped", false)))
+ Mulentries = ((Entry = GetStringCatInfo(g, "Entry", NULL)))
+ ? strchr(Entry, '*') || strchr(Entry, '?')
+ : GetBoolCatInfo("Mulentries", false);
+
Desc = Fn = GetStringCatInfo(g, "Filename", NULL);
Ofn = GetStringCatInfo(g, "Optname", Fn);
GetCharCatInfo("Recfm", (PSZ)dfm, buf, sizeof(buf));
@@ -333,7 +344,21 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
/* Allocate table and file processing class of the proper type. */
/* Column blocks will be allocated only when needed. */
/*********************************************************************/
- if (Recfm == RECFM_DBF) {
+ if (Zipped) {
+#if defined(ZIP_SUPPORT)
+ if (Recfm == RECFM_VAR) {
+ txfp = new(g)ZIPFAM(this);
+ tdbp = new(g)TDBDOS(this, txfp);
+ } else {
+ txfp = new(g)ZPXFAM(this);
+ tdbp = new(g)TDBFIX(this, txfp);
+ } // endif Recfm
+
+#else // !ZIP_SUPPORT
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
+ return NULL;
+#endif // !ZIP_SUPPORT
+ } else if (Recfm == RECFM_DBF) {
if (Catfunc == FNC_NO) {
if (map)
txfp = new(g) DBMFAM(this);
@@ -350,28 +375,28 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
else if (map)
txfp = new(g) MPXFAM(this);
else if (Compressed) {
-#if defined(ZIP_SUPPORT)
+#if defined(GZ_SUPPORT)
txfp = new(g) ZIXFAM(this);
-#else // !ZIP_SUPPORT
- sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
+#else // !GZ_SUPPORT
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "GZ");
return NULL;
-#endif // !ZIP_SUPPORT
+#endif // !GZ_SUPPORT
} else
txfp = new(g) FIXFAM(this);
tdbp = new(g) TDBFIX(this, txfp);
} else {
if (Compressed) {
-#if defined(ZIP_SUPPORT)
+#if defined(GZ_SUPPORT)
if (Compressed == 1)
- txfp = new(g) ZIPFAM(this);
+ txfp = new(g) GZFAM(this);
else
txfp = new(g) ZLBFAM(this);
-#else // !ZIP_SUPPORT
- sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
+#else // !GZ_SUPPORT
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "GZ");
return NULL;
-#endif // !ZIP_SUPPORT
+#endif // !GZ_SUPPORT
} else if (map)
txfp = new(g) MAPFAM(this);
else
@@ -396,7 +421,7 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
if (map) {
txfp = new(g) MBKFAM(this);
} else if (Compressed) {
-#if defined(ZIP_SUPPORT)
+#if defined(GZ_SUPPORT)
if (Compressed == 1)
txfp = new(g) ZBKFAM(this);
else {
@@ -404,7 +429,7 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
((PZLBFAM)txfp)->SetOptimized(To_Pos != NULL);
} // endelse
#else
- sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "GZ");
return NULL;
#endif
} else
@@ -531,14 +556,14 @@ int TDBDOS::ResetTableOpt(PGLOBAL g, bool dop, bool dox)
// except for ZLIB access method.
if (Txfp->GetAmType() == TYPE_AM_MAP) {
Txfp = new(g) MAPFAM((PDOSDEF)To_Def);
-#if defined(ZIP_SUPPORT)
- } else if (Txfp->GetAmType() == TYPE_AM_ZIP) {
- Txfp = new(g) ZIPFAM((PDOSDEF)To_Def);
+#if defined(GZ_SUPPORT)
+ } else if (Txfp->GetAmType() == TYPE_AM_GZ) {
+ Txfp = new(g) GZFAM((PDOSDEF)To_Def);
} else if (Txfp->GetAmType() == TYPE_AM_ZLIB) {
Txfp->Reset();
((PZLBFAM)Txfp)->SetOptimized(false);
-#endif // ZIP_SUPPORT
- } else if (Txfp->GetAmType() == TYPE_AM_BLK)
+#endif // GZ_SUPPORT
+ } else if (Txfp->GetAmType() == TYPE_AM_BLK)
Txfp = new(g) DOSFAM((PDOSDEF)To_Def);
Txfp->SetTdbp(this);
@@ -609,7 +634,12 @@ int TDBDOS::MakeBlockValues(PGLOBAL g)
defp->SetOptimized(0);
// Estimate the number of needed blocks
- block = (int)((MaxSize + (int)nrec - 1) / (int)nrec);
+ if ((block = (int)((MaxSize + (int)nrec - 1) / (int)nrec)) < 2) {
+ // This may be wrong to do in some cases
+ defp->RemoveOptValues(g);
+ strcpy(g->Message, MSG(TABLE_NOT_OPT));
+ return RC_INFO; // Not to be optimized
+ } // endif block
// We have to use local variables because Txfp->CurBlk is set
// to Rows+1 by unblocked variable length table access methods.
@@ -952,13 +982,14 @@ bool TDBDOS::GetBlockValues(PGLOBAL g)
PCOLDEF cdp;
PDOSDEF defp = (PDOSDEF)To_Def;
PCATLG cat = defp->GetCat();
+ PDBUSER dup = PlgGetUser(g);
#if 0
if (Mode == MODE_INSERT && Txfp->GetAmType() == TYPE_AM_DOS)
return false;
#endif // __WIN__
- if (defp->Optimized)
+ if (defp->Optimized || !(dup->Check & CHK_OPT))
return false; // Already done or to be redone
if (Ftype == RECFM_VAR || defp->Compressed == 2) {
@@ -2079,10 +2110,10 @@ bool TDBDOS::OpenDB(PGLOBAL g)
/*******************************************************************/
if (Txfp->GetAmType() == TYPE_AM_MAP && Mode == MODE_DELETE)
Txfp = new(g) MAPFAM((PDOSDEF)To_Def);
-#if defined(ZIP_SUPPORT)
- else if (Txfp->GetAmType() == TYPE_AM_ZIP)
- Txfp = new(g) ZIPFAM((PDOSDEF)To_Def);
-#endif // ZIP_SUPPORT
+#if defined(GZ_SUPPORT)
+ else if (Txfp->GetAmType() == TYPE_AM_GZ)
+ Txfp = new(g) GZFAM((PDOSDEF)To_Def);
+#endif // GZ_SUPPORT
else // if (Txfp->GetAmType() != TYPE_AM_DOS) ???
Txfp = new(g) DOSFAM((PDOSDEF)To_Def);
diff --git a/storage/connect/tabdos.h b/storage/connect/tabdos.h
index c098886f14b..4c8eb438a26 100644
--- a/storage/connect/tabdos.h
+++ b/storage/connect/tabdos.h
@@ -28,6 +28,7 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
friend class TDBFIX;
friend class TXTFAM;
friend class DBFBASE;
+ friend class ZIPUTIL;
public:
// Constructor
DOSDEF(void);
@@ -40,7 +41,9 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
virtual bool IsHuge(void) {return Huge;}
PSZ GetFn(void) {return Fn;}
PSZ GetOfn(void) {return Ofn;}
- void SetBlock(int block) {Block = block;}
+ PSZ GetEntry(void) {return Entry;}
+ bool GetMul(void) {return Mulentries;}
+ void SetBlock(int block) {Block = block;}
int GetBlock(void) {return Block;}
int GetLast(void) {return Last;}
void SetLast(int last) {Last = last;}
@@ -57,9 +60,9 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
int *GetTo_Pos(void) {return To_Pos;}
// Methods
- virtual int Indexable(void)
- {return (!Multiple && Compressed != 1) ? 1 : 0;}
- virtual bool DeleteIndexFile(PGLOBAL g, PIXDEF pxdf);
+ virtual int Indexable(void)
+ {return (!Multiple && !Mulentries && Compressed != 1) ? 1 : 0;}
+ virtual bool DeleteIndexFile(PGLOBAL g, PIXDEF pxdf);
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE mode);
bool InvalidateIndex(PGLOBAL g);
@@ -72,10 +75,13 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
// Members
PSZ Fn; /* Path/Name of corresponding file */
PSZ Ofn; /* Base Path/Name of matching index files*/
- PIXDEF To_Indx; /* To index definitions blocks */
+ PSZ Entry; /* Zip entry name or pattern */
+ PIXDEF To_Indx; /* To index definitions blocks */
RECFM Recfm; /* 0:VAR, 1:FIX, 2:BIN, 3:VCT, 6:DBF */
bool Mapped; /* 0: disk file, 1: memory mapped file */
- bool Padded; /* true for padded table file */
+ bool Zipped; /* true for zipped table file */
+ bool Mulentries; /* true for multiple entries */
+ bool Padded; /* true for padded table file */
bool Huge; /* true for files larger than 2GB */
bool Accept; /* true if wrong lines are accepted */
bool Eof; /* true if an EOF (0xA) character exists */
@@ -91,7 +97,7 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
int Maxerr; /* Maximum number of bad records (DBF) */
int ReadMode; /* Specific to DBF */
int Ending; /* Length of end of lines */
- int Teds; /* Binary table default endian setting */
+ char Teds; /* Binary table default endian setting */
}; // end of DOSDEF
/***********************************************************************/
diff --git a/storage/connect/tabfix.cpp b/storage/connect/tabfix.cpp
index 55c254f41ea..d99f7800f26 100644
--- a/storage/connect/tabfix.cpp
+++ b/storage/connect/tabfix.cpp
@@ -1,11 +1,11 @@
/************* TabFix C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABFIX */
/* ------------- */
-/* Version 4.9 */
+/* Version 4.9.1 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 1998-2015 */
+/* (C) Copyright to the author Olivier BERTRAND 1998-2016 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -589,9 +589,10 @@ void BINCOL::WriteColumn(PGLOBAL g)
switch (Fmt) {
case 'X':
// Standard not converted values
- if (Eds && IsTypeChar(Buf_Type))
- *(longlong *)p = Value->GetBigintValue();
- else if (Value->GetBinValue(p, Long, Status)) {
+ if (Eds && IsTypeChar(Buf_Type)) {
+ if (Status)
+ Value->GetValueNonAligned<longlong>(p, Value->GetBigintValue());
+ } else if (Value->GetBinValue(p, Long, Status)) {
sprintf(g->Message, MSG(BIN_F_TOO_LONG),
Name, Value->GetSize(), Long);
longjmp(g->jumper[g->jump_level], 31);
@@ -605,7 +606,7 @@ void BINCOL::WriteColumn(PGLOBAL g)
sprintf(g->Message, MSG(VALUE_TOO_BIG), n, Name);
longjmp(g->jumper[g->jump_level], 31);
} else if (Status)
- *(short *)p = (short)n;
+ Value->GetValueNonAligned<short>(p, (short)n);
break;
case 'T': // Tiny integer
@@ -625,7 +626,7 @@ void BINCOL::WriteColumn(PGLOBAL g)
sprintf(g->Message, MSG(VALUE_TOO_BIG), n, Name);
longjmp(g->jumper[g->jump_level], 31);
} else if (Status)
- *(int *)p = Value->GetIntValue();
+ Value->GetValueNonAligned<int>(p, (int)n);
break;
case 'G': // Large (great) integer
@@ -636,12 +637,12 @@ void BINCOL::WriteColumn(PGLOBAL g)
case 'F': // Float
case 'R': // Real
if (Status)
- *(float *)p = (float)Value->GetFloatValue();
+ Value->GetValueNonAligned<float>(p, (float)Value->GetFloatValue());
break;
case 'D': // Double
if (Status)
- *(double *)p = Value->GetFloatValue();
+ Value->GetValueNonAligned<double>(p, Value->GetFloatValue());
break;
case 'C': // Characters
diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp
index b786fb64b56..183bb8f8d65 100644
--- a/storage/connect/tabfmt.cpp
+++ b/storage/connect/tabfmt.cpp
@@ -1,11 +1,11 @@
/************* TabFmt C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABFMT */
/* ------------- */
-/* Version 3.9 */
+/* Version 3.9.2 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 2001 - 2015 */
+/* (C) Copyright to the author Olivier BERTRAND 2001 - 2016 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -51,6 +51,9 @@
#include "plgdbsem.h"
#include "mycat.h"
#include "filamap.h"
+#if defined(GZ_SUPPORT)
+#include "filamgz.h"
+#endif // GZ_SUPPORT
#if defined(ZIP_SUPPORT)
#include "filamzip.h"
#endif // ZIP_SUPPORT
@@ -78,20 +81,24 @@ USETEMP UseTemp(void);
/* of types (TYPE_STRING < TYPE_DOUBLE < TYPE_INT) (1 < 2 < 7). */
/* If these values are changed, this will have to be revisited. */
/***********************************************************************/
-PQRYRES CSVColumns(PGLOBAL g, char *dp, const char *fn, char sep,
- char q, int hdr, int mxr, bool info)
+PQRYRES CSVColumns(PGLOBAL g, char *dp, PTOS topt, bool info)
{
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
TYPE_INT, TYPE_INT, TYPE_SHORT};
static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME,
FLD_PREC, FLD_LENGTH, FLD_SCALE};
static unsigned int length[] = {6, 6, 8, 10, 10, 6};
- char *p, *colname[MAXCOL], dechar, filename[_MAX_PATH], buf[4096];
+ const char *fn;
+ char sep, q;
+ int rc, mxr;
+ bool hdr;
+ char *p, *colname[MAXCOL], dechar, buf[8];
int i, imax, hmax, n, nerr, phase, blank, digit, dec, type;
int ncol = sizeof(buftyp) / sizeof(int);
int num_read = 0, num_max = 10000000; // Statistics
int len[MAXCOL], typ[MAXCOL], prc[MAXCOL];
- FILE *infile;
+ PCSVDEF tdp;
+ PTDBCSV tdbp;
PQRYRES qrp;
PCOLRES crp;
@@ -101,27 +108,13 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, const char *fn, char sep,
goto skipit;
} // endif info
-// num_max = atoi(p+1); // Max num of record to test
-#if defined(__WIN__)
- if (sep == ',' || strnicmp(setlocale(LC_NUMERIC, NULL), "French", 6))
- dechar = '.';
- else
- dechar = ',';
-#else // !__WIN__
- dechar = '.';
-#endif // !__WIN__
-
- if (trace)
- htrc("File %s sep=%c q=%c hdr=%d mxr=%d\n",
- SVP(fn), sep, q, hdr, mxr);
-
- if (!fn) {
- strcpy(g->Message, MSG(MISSING_FNAME));
- return NULL;
- } // endif fn
+ if (GetIntegerTableOption(g, topt, "Multiple", 0)) {
+ strcpy(g->Message, "Cannot find column definition for multiple table");
+ return NULL;
+ } // endif Multiple
+// num_max = atoi(p+1); // Max num of record to test
imax = hmax = nerr = 0;
- mxr = MY_MAX(0, mxr);
for (i = 0; i < MAXCOL; i++) {
colname[i] = NULL;
@@ -131,12 +124,76 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, const char *fn, char sep,
} // endfor i
/*********************************************************************/
- /* Open the input file. */
+ /* Get the CSV table description block. */
/*********************************************************************/
- PlugSetPath(filename, fn, dp);
+ tdp = new(g) CSVDEF;
+#if defined(ZIP_SUPPORT)
+ tdp->Entry = GetStringTableOption(g, topt, "Entry", NULL);
+ tdp->Zipped = GetBooleanTableOption(g, topt, "Zipped", false);
+#endif // ZIP_SUPPORT
+ fn = tdp->Fn = GetStringTableOption(g, topt, "Filename", NULL);
+
+ if (!tdp->Fn) {
+ strcpy(g->Message, MSG(MISSING_FNAME));
+ return NULL;
+ } // endif Fn
+
+ if (!(tdp->Lrecl = GetIntegerTableOption(g, topt, "Lrecl", 0)))
+ tdp->Lrecl = 4096;
+
+ p = GetStringTableOption(g, topt, "Separator", ",");
+ tdp->Sep = (strlen(p) == 2 && p[0] == '\\' && p[1] == 't') ? '\t' : *p;
+
+#if defined(__WIN__)
+ if (tdp->Sep == ',' || strnicmp(setlocale(LC_NUMERIC, NULL), "French", 6))
+ dechar = '.';
+ else
+ dechar = ',';
+#else // !__WIN__
+ dechar = '.';
+#endif // !__WIN__
+
+ sep = tdp->Sep;
+ tdp->Quoted = GetIntegerTableOption(g, topt, "Quoted", -1);
+ p = GetStringTableOption(g, topt, "Qchar", "");
+ tdp->Qot = *p;
+
+ if (tdp->Qot && tdp->Quoted < 0)
+ tdp->Quoted = 0;
+ else if (!tdp->Qot && tdp->Quoted >= 0)
+ tdp->Qot = '"';
- if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "r")))
- return NULL;
+ q = tdp->Qot;
+ hdr = GetBooleanTableOption(g, topt, "Header", false);
+ tdp->Maxerr = GetIntegerTableOption(g, topt, "Maxerr", 0);
+ tdp->Accept = GetBooleanTableOption(g, topt, "Accept", false);
+
+ if (tdp->Accept && tdp->Maxerr == 0)
+ tdp->Maxerr = INT_MAX32; // Accept all bad lines
+
+ mxr = MY_MAX(0, tdp->Maxerr);
+
+ if (trace)
+ htrc("File %s Sep=%c Qot=%c Header=%d maxerr=%d\n",
+ SVP(tdp->Fn), tdp->Sep, tdp->Qot, tdp->Header, tdp->Maxerr);
+
+ if (tdp->Zipped) {
+#if defined(ZIP_SUPPORT)
+ tdbp = new(g)TDBCSV(tdp, new(g)ZIPFAM(tdp));
+#else // !ZIP_SUPPORT
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
+ return NULL;
+#endif // !ZIP_SUPPORT
+ } else
+ tdbp = new(g) TDBCSV(tdp, new(g) DOSFAM(tdp));
+
+ tdbp->SetMode(MODE_READ);
+
+ /*********************************************************************/
+ /* Open the CSV file. */
+ /*********************************************************************/
+ if (tdbp->OpenDB(g))
+ return NULL;
if (hdr) {
/*******************************************************************/
@@ -144,16 +201,8 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, const char *fn, char sep,
/*******************************************************************/
phase = 0;
- if (fgets(buf, sizeof(buf), infile)) {
- n = strlen(buf) + 1;
- buf[n - 2] = '\0';
-#if !defined(__WIN__)
- // The file can be imported from Windows
- if (buf[n - 3] == '\r')
- buf[n - 3] = 0;
-#endif // UNIX
- p = (char*)PlugSubAlloc(g, NULL, n);
- memcpy(p, buf, n);
+ if ((rc = tdbp->ReadDB(g)) == RC_OK) {
+ p = PlgDBDup(g, tdbp->To_Line);
//skip leading blanks
for (; *p == ' '; p++) ;
@@ -165,10 +214,11 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, const char *fn, char sep,
} // endif q
colname[0] = p;
- } else {
+ } else if (rc == RC_EF) {
sprintf(g->Message, MSG(FILE_IS_EMPTY), fn);
goto err;
- } // endif's
+ } else
+ goto err;
for (i = 1; *p; p++)
if (phase == 1 && *p == q) {
@@ -201,15 +251,8 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, const char *fn, char sep,
/*******************************************************************/
/* Now start the reading process. Read one line. */
/*******************************************************************/
- if (fgets(buf, sizeof(buf), infile)) {
- n = strlen(buf);
- buf[n - 1] = '\0';
-#if !defined(__WIN__)
- // The file can be imported from Windows
- if (buf[n - 2] == '\r')
- buf[n - 2] = 0;
-#endif // UNIX
- } else if (feof(infile)) {
+ if ((rc = tdbp->ReadDB(g)) == RC_OK) {
+ } else if (rc == RC_EF) {
sprintf(g->Message, MSG(EOF_AFTER_LINE), num_read -1);
break;
} else {
@@ -222,7 +265,7 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, const char *fn, char sep,
/*******************************************************************/
i = n = phase = blank = digit = dec = 0;
- for (p = buf; *p; p++)
+ for (p = tdbp->To_Line; *p; p++)
if (*p == sep) {
if (phase != 1) {
if (i == MAXCOL - 1) {
@@ -331,7 +374,7 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, const char *fn, char sep,
htrc("\n");
} // endif trace
- fclose(infile);
+ tdbp->CloseDB(g);
skipit:
if (trace)
@@ -381,7 +424,7 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, const char *fn, char sep,
return qrp;
err:
- fclose(infile);
+ tdbp->CloseDB(g);
return NULL;
} // end of CSVCColumns
@@ -458,20 +501,27 @@ PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode)
/*******************************************************************/
/* Allocate a file processing class of the proper type. */
/*******************************************************************/
- if (map) {
+ if (Zipped) {
+#if defined(ZIP_SUPPORT)
+ txfp = new(g) ZIPFAM(this);
+#else // !ZIP_SUPPORT
+ strcpy(g->Message, "ZIP not supported");
+ return NULL;
+#endif // !ZIP_SUPPORT
+ } else if (map) {
// Should be now compatible with UNIX
txfp = new(g) MAPFAM(this);
} else if (Compressed) {
-#if defined(ZIP_SUPPORT)
+#if defined(GZ_SUPPORT)
if (Compressed == 1)
- txfp = new(g) ZIPFAM(this);
+ txfp = new(g) GZFAM(this);
else
txfp = new(g) ZLBFAM(this);
-#else // !ZIP_SUPPORT
+#else // !GZ_SUPPORT
strcpy(g->Message, "Compress not supported");
return NULL;
-#endif // !ZIP_SUPPORT
+#endif // !GZ_SUPPORT
} else
txfp = new(g) DOSFAM(this);
@@ -498,7 +548,7 @@ PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode)
if (map) {
txfp = new(g) MBKFAM(this);
} else if (Compressed) {
-#if defined(ZIP_SUPPORT)
+#if defined(GZ_SUPPORT)
if (Compressed == 1)
txfp = new(g) ZBKFAM(this);
else {
@@ -506,7 +556,7 @@ PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode)
((PZLBFAM)txfp)->SetOptimized(To_Pos != NULL);
} // endelse
#else
- sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "GZ");
return NULL;
#endif
} else
@@ -830,8 +880,9 @@ bool TDBCSV::SkipHeader(PGLOBAL g)
/***********************************************************************/
int TDBCSV::ReadBuffer(PGLOBAL g)
{
- char *p1, *p2, *p = NULL;
- int i, n, len, rc = Txfp->ReadBuffer(g);
+ //char *p1, *p2, *p = NULL;
+ char *p2, *p = NULL;
+ int i, n, len, rc = Txfp->ReadBuffer(g);
bool bad = false;
if (trace > 1)
@@ -846,14 +897,23 @@ int TDBCSV::ReadBuffer(PGLOBAL g)
for (i = 0; i < Fields; i++) {
if (!bad) {
if (Qot && *p2 == Qot) { // Quoted field
- for (n = 0, p1 = ++p2; (p = strchr(p1, Qot)); p1 = p + 2)
- if (*(p + 1) == Qot)
- n++; // Doubled internal quotes
- else
- break; // Final quote
+ //for (n = 0, p1 = ++p2; (p = strchr(p1, Qot)); p1 = p + 2)
+ // if (*(p + 1) == Qot)
+ // n++; // Doubled internal quotes
+ // else
+ // break; // Final quote
+
+ for (n = 0, p = ++p2; p; p++)
+ if (*p == Qot || *p == '\\') {
+ if (*(++p) == Qot)
+ n++; // Escaped internal quotes
+ else if (*(p - 1) == Qot)
+ break; // Final quote
+ } // endif *p
if (p) {
- len = p++ - p2;
+ //len = p++ - p2;
+ len = p - p2 - 1;;
// if (Sep != ' ')
// for (; *p == ' '; p++) ; // Skip blanks
@@ -873,10 +933,12 @@ int TDBCSV::ReadBuffer(PGLOBAL g)
if (n) {
int j, k;
- // Suppress the double of internal quotes
+ // Suppress the escape of internal quotes
for (j = k = 0; j < len; j++, k++) {
- if (p2[j] == Qot)
- j++; // skip first one
+ if (p2[j] == Qot || (p2[j] == '\\' && p2[j + 1] == Qot))
+ j++; // skip escape char
+ else if (p2[j] == '\\')
+ p2[k++] = p2[j++]; // avoid \\Qot
p2[k] = p2[j];
} // endfor i, j
@@ -1464,21 +1526,16 @@ void CSVCOL::WriteColumn(PGLOBAL g)
/* TDBCCL class constructor. */
/***********************************************************************/
TDBCCL::TDBCCL(PCSVDEF tdp) : TDBCAT(tdp)
- {
- Fn = tdp->GetFn();
- Hdr = tdp->Header;
- Mxr = tdp->Maxerr;
- Qtd = tdp->Quoted;
- Sep = tdp->Sep;
- } // end of TDBCCL constructor
+{
+ Topt = tdp->GetTopt();
+} // end of TDBCCL constructor
/***********************************************************************/
/* GetResult: Get the list the CSV file columns. */
/***********************************************************************/
PQRYRES TDBCCL::GetResult(PGLOBAL g)
{
- return CSVColumns(g, ((PTABDEF)To_Def)->GetPath(),
- Fn, Sep, Qtd, Hdr, Mxr, false);
+ return CSVColumns(g, ((PTABDEF)To_Def)->GetPath(), Topt, false);
} // end of GetResult
/* ------------------------ End of TabFmt ---------------------------- */
diff --git a/storage/connect/tabfmt.h b/storage/connect/tabfmt.h
index ce80a276cdc..5ce8d399a64 100644
--- a/storage/connect/tabfmt.h
+++ b/storage/connect/tabfmt.h
@@ -1,7 +1,7 @@
/*************** TabFmt H Declares Source Code File (.H) ***************/
-/* Name: TABFMT.H Version 2.4 */
+/* Name: TABFMT.H Version 2.5 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2001-2014 */
+/* (C) Copyright to the author Olivier BERTRAND 2001-2016 */
/* */
/* This file contains the CSV and FMT classes declares. */
/***********************************************************************/
@@ -13,8 +13,7 @@ typedef class TDBFMT *PTDBFMT;
/***********************************************************************/
/* Functions used externally. */
/***********************************************************************/
-PQRYRES CSVColumns(PGLOBAL g, char *dp, const char *fn, char sep,
- char q, int hdr, int mxr, bool info);
+PQRYRES CSVColumns(PGLOBAL g, char *dp, PTOS topt, bool info);
/***********************************************************************/
/* CSV table. */
@@ -22,7 +21,8 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, const char *fn, char sep,
class DllExport CSVDEF : public DOSDEF { /* Logical table description */
friend class TDBCSV;
friend class TDBCCL;
- public:
+ friend PQRYRES CSVColumns(PGLOBAL, char *, PTOS, bool);
+public:
// Constructor
CSVDEF(void);
@@ -50,9 +50,10 @@ class DllExport CSVDEF : public DOSDEF { /* Logical table description */
/* This is the DOS/UNIX Access Method class declaration for files */
/* that are CSV files with columns separated by the Sep character. */
/***********************************************************************/
-class TDBCSV : public TDBDOS {
+class DllExport TDBCSV : public TDBDOS {
friend class CSVCOL;
- public:
+ friend PQRYRES CSVColumns(PGLOBAL, char *, PTOS, bool);
+public:
// Constructor
TDBCSV(PCSVDEF tdp, PTXF txfp);
TDBCSV(PGLOBAL g, PTDBCSV tdbp);
@@ -101,7 +102,7 @@ class TDBCSV : public TDBDOS {
/* Class CSVCOL: CSV access method column descriptor. */
/* This A.M. is used for Comma Separated V(?) files. */
/***********************************************************************/
-class CSVCOL : public DOSCOL {
+class DllExport CSVCOL : public DOSCOL {
friend class TDBCSV;
friend class TDBFMT;
public:
@@ -129,7 +130,7 @@ class CSVCOL : public DOSCOL {
/* This is the DOS/UNIX Access Method class declaration for files */
/* whose record format is described by a Format keyword. */
/***********************************************************************/
-class TDBFMT : public TDBCSV {
+class DllExport TDBFMT : public TDBCSV {
friend class CSVCOL;
//friend class FMTCOL;
public:
@@ -173,7 +174,7 @@ class TDBFMT : public TDBCSV {
/***********************************************************************/
/* This is the class declaration for the CSV catalog table. */
/***********************************************************************/
-class TDBCCL : public TDBCAT {
+class DllExport TDBCCL : public TDBCAT {
public:
// Constructor
TDBCCL(PCSVDEF tdp);
@@ -183,11 +184,7 @@ class TDBCCL : public TDBCAT {
virtual PQRYRES GetResult(PGLOBAL g);
// Members
- char *Fn; // The CSV file (path) name
- bool Hdr; // true if first line contains headers
- int Mxr; // Maximum number of bad records
- int Qtd; // Quoting level for quoted fields
- char Sep; // Separator for standard CSV files
- }; // end of class TDBCCL
+ PTOS Topt;
+}; // end of class TDBCCL
/* ------------------------- End of TabFmt.H ------------------------- */
diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp
index 93ba3ca264d..c36aa080956 100644
--- a/storage/connect/tabjdbc.cpp
+++ b/storage/connect/tabjdbc.cpp
@@ -110,6 +110,7 @@ bool JDBCDEF::SetParms(PJPARM sjp)
sjp->Url= Url;
sjp->User= Username;
sjp->Pwd= Password;
+//sjp->Properties = Prop;
return true;
} // end of SetParms
@@ -234,6 +235,7 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Read_Only = true;
Wrapname = GetStringCatInfo(g, "Wrapper", NULL);
+//Prop = GetStringCatInfo(g, "Properties", NULL);
Tabcat = GetStringCatInfo(g, "Qualifier", NULL);
Tabcat = GetStringCatInfo(g, "Catalog", Tabcat);
Tabschema = GetStringCatInfo(g, "Dbname", NULL);
@@ -337,6 +339,7 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp)
Schema = tdp->Tabschema;
Ops.User = tdp->Username;
Ops.Pwd = tdp->Password;
+// Ops.Properties = tdp->Prop;
Catalog = tdp->Tabcat;
Srcdef = tdp->Srcdef;
Qrystr = tdp->Qrystr;
@@ -356,6 +359,7 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp)
Ops.Url = NULL;
Ops.User = NULL;
Ops.Pwd = NULL;
+// Ops.Properties = NULL;
Catalog = NULL;
Srcdef = NULL;
Qrystr = NULL;
diff --git a/storage/connect/tabjdbc.h b/storage/connect/tabjdbc.h
index 7244ebd3832..fee8223abaf 100644
--- a/storage/connect/tabjdbc.h
+++ b/storage/connect/tabjdbc.h
@@ -58,6 +58,7 @@ protected:
PSZ Tabschema; /* External table schema */
PSZ Username; /* User connect name */
PSZ Password; /* Password connect info */
+//PSZ Prop; /* Connection Properties */
PSZ Tabcat; /* External table catalog */
PSZ Tabtype; /* External table type */
PSZ Colpat; /* Catalog column pattern */
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index 17260836371..1b9ce8b64c9 100644
--- a/storage/connect/tabjson.cpp
+++ b/storage/connect/tabjson.cpp
@@ -1,6 +1,6 @@
/************* tabjson C++ Program Source Code File (.CPP) *************/
-/* PROGRAM NAME: tabjson Version 1.1 */
-/* (C) Copyright to the author Olivier BERTRAND 2014 - 2015 */
+/* PROGRAM NAME: tabjson Version 1.3 */
+/* (C) Copyright to the author Olivier BERTRAND 2014 - 2016 */
/* This program are the JSON class DB execution routines. */
/***********************************************************************/
@@ -25,6 +25,9 @@
//#include "resource.h" // for IDS_COLUMNS
#include "tabjson.h"
#include "filamap.h"
+#if defined(GZ_SUPPORT)
+#include "filamgz.h"
+#endif // GZ_SUPPORT
#if defined(ZIP_SUPPORT)
#include "filamzip.h"
#endif // ZIP_SUPPORT
@@ -67,7 +70,7 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, 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 *fn, colname[65], fmt[129];
+ char colname[65], fmt[129];
int i, j, lvl, n = 0;
int ncol = sizeof(buftyp) / sizeof(int);
PVAL valp;
@@ -91,19 +94,29 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
goto skipit;
} // endif info
- /*********************************************************************/
+ if (GetIntegerTableOption(g, topt, "Multiple", 0)) {
+ strcpy(g->Message, "Cannot find column definition for multiple table");
+ return NULL;
+ } // endif Multiple
+
+ /*********************************************************************/
/* Open the input file. */
/*********************************************************************/
- if (!(fn = GetStringTableOption(g, topt, "Filename", NULL))) {
- strcpy(g->Message, MSG(MISSING_FNAME));
- return NULL;
- } else {
- lvl = GetIntegerTableOption(g, topt, "Level", 0);
- lvl = (lvl < 0) ? 0 : (lvl > 16) ? 16 : lvl;
- } // endif fn
+ lvl = GetIntegerTableOption(g, topt, "Level", 0);
+ lvl = (lvl < 0) ? 0 : (lvl > 16) ? 16 : lvl;
tdp = new(g) JSONDEF;
- tdp->Fn = fn;
+#if defined(ZIP_SUPPORT)
+ tdp->Entry = GetStringTableOption(g, topt, "Entry", NULL);
+ tdp->Zipped = GetBooleanTableOption(g, topt, "Zipped", false);
+#endif // ZIP_SUPPORT
+ tdp->Fn = GetStringTableOption(g, topt, "Filename", NULL);
+
+ if (!tdp->Fn) {
+ strcpy(g->Message, MSG(MISSING_FNAME));
+ return NULL;
+ } // endif Fn
+
tdp->Database = SetPath(g, db);
tdp->Objname = GetStringTableOption(g, topt, "Object", NULL);
tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0;
@@ -114,7 +127,15 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
tdp->Fn, tdp->Objname, tdp->Pretty, lvl);
if (tdp->Pretty == 2) {
- tjsp = new(g) TDBJSON(tdp, new(g) MAPFAM(tdp));
+ if (tdp->Zipped) {
+#if defined(ZIP_SUPPORT)
+ tjsp = new(g) TDBJSON(tdp, new(g) ZIPFAM(tdp));
+#else // !ZIP_SUPPORT
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
+ return NULL;
+#endif // !ZIP_SUPPORT
+ } else
+ tjsp = new(g) TDBJSON(tdp, new(g) MAPFAM(tdp));
if (tjsp->MakeDocument(g))
return NULL;
@@ -127,10 +148,33 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
} // endif lrecl
tdp->Ending = GetIntegerTableOption(g, topt, "Ending", CRLF);
- tjnp = new(g) TDBJSN(tdp, new(g) DOSFAM(tdp));
+
+ if (tdp->Zipped) {
+#if defined(ZIP_SUPPORT)
+ tjnp = new(g)TDBJSN(tdp, new(g)ZIPFAM(tdp));
+#else // !ZIP_SUPPORT
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
+ return NULL;
+#endif // !ZIP_SUPPORT
+ } else
+ tjnp = new(g) TDBJSN(tdp, new(g) DOSFAM(tdp));
+
tjnp->SetMode(MODE_READ);
- if (tjnp->OpenDB(g))
+#if USE_G
+ // Allocate the parse work memory
+ PGLOBAL G = (PGLOBAL)PlugSubAlloc(g, NULL, sizeof(GLOBAL));
+ memset(G, 0, sizeof(GLOBAL));
+ G->Sarea_Size = tdp->Lrecl * 10;
+ G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size);
+ PlugSubSet(G, G->Sarea, G->Sarea_Size);
+ G->jump_level = -1;
+ tjnp->SetG(G);
+#else
+ tjnp->SetG(g);
+#endif
+
+ if (tjnp->OpenDB(g))
return NULL;
switch (tjnp->ReadDB(g)) {
@@ -395,16 +439,23 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
!(tmp == TMP_FORCE &&
(m == MODE_UPDATE || m == MODE_DELETE));
- if (Compressed) {
+ if (Zipped) {
#if defined(ZIP_SUPPORT)
+ txfp = new(g) ZIPFAM(this);
+#else // !ZIP_SUPPORT
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
+ return NULL;
+#endif // !ZIP_SUPPORT
+ } else if (Compressed) {
+#if defined(GZ_SUPPORT)
if (Compressed == 1)
- txfp = new(g) ZIPFAM(this);
+ txfp = new(g) GZFAM(this);
else
txfp = new(g) ZLBFAM(this);
-#else // !ZIP_SUPPORT
- sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
+#else // !GZ_SUPPORT
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "GZ");
return NULL;
-#endif // !ZIP_SUPPORT
+#endif // !GZ_SUPPORT
} else if (map)
txfp = new(g) MAPFAM(this);
else
@@ -426,7 +477,16 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
((TDBJSN*)tdbp)->G = g;
#endif
} else {
- txfp = new(g) MAPFAM(this);
+ if (Zipped) {
+#if defined(ZIP_SUPPORT)
+ txfp = new(g)ZIPFAM(this);
+#else // !ZIP_SUPPORT
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
+ return NULL;
+#endif // !ZIP_SUPPORT
+ } else
+ txfp = new(g) MAPFAM(this);
+
tdbp = new(g) TDBJSON(this, txfp);
((TDBJSON*)tdbp)->G = g;
} // endif Pretty
diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h
index f7cb74c3c4d..c9d30d48f2a 100644
--- a/storage/connect/tabjson.h
+++ b/storage/connect/tabjson.h
@@ -78,7 +78,8 @@ public:
virtual AMT GetAmType(void) {return TYPE_AM_JSN;}
virtual bool SkipHeader(PGLOBAL g);
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBJSN(this);}
- PJSON GetRow(void) {return Row;}
+ PJSON GetRow(void) {return Row;}
+ void SetG(PGLOBAL g) {G = g;}
// Methods
virtual PTDB CopyOne(PTABS t);
diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp
index 57d204a4286..3b8229fcf51 100644
--- a/storage/connect/tabxml.cpp
+++ b/storage/connect/tabxml.cpp
@@ -1,9 +1,9 @@
/************* Tabxml C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABXML */
/* ------------- */
-/* Version 2.8 */
+/* Version 2.9 */
/* */
-/* Author Olivier BERTRAND 2007 - 2015 */
+/* Author Olivier BERTRAND 2007 - 2016 */
/* */
/* This program are the XML tables classes using MS-DOM or libxml2. */
/***********************************************************************/
@@ -136,7 +136,12 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
goto skipit;
} // endif info
- /*********************************************************************/
+ if (GetIntegerTableOption(g, topt, "Multiple", 0)) {
+ strcpy(g->Message, "Cannot find column definition for multiple table");
+ return NULL;
+ } // endif Multiple
+
+ /*********************************************************************/
/* Open the input file. */
/*********************************************************************/
if (!(fn = GetStringTableOption(g, topt, "Filename", NULL))) {
@@ -154,6 +159,8 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
tdp->Fn = fn;
tdp->Database = SetPath(g, db);
tdp->Tabname = tab;
+ tdp->Zipped = GetBooleanTableOption(g, topt, "Zipped", false);
+ tdp->Entry = GetStringTableOption(g, topt, "Entry", NULL);
if (!(op = GetStringTableOption(g, topt, "Xmlsup", NULL)))
#if defined(__WIN__)
@@ -204,7 +211,8 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
while (true) {
if (!vp->atp &&
- !(node = (vp->nl) ? vp->nl->GetItem(g, vp->k++, node) : NULL))
+ !(node = (vp->nl) ? vp->nl->GetItem(g, vp->k++, tdp->Usedom ? node : NULL)
+ : NULL))
if (j) {
vp = lvlp[--j];
@@ -254,7 +262,8 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
if (j < lvl && ok) {
vp = lvlp[j+1];
vp->k = 0;
- vp->atp = node->GetAttribute(g, NULL);
+ vp->pn = node;
+ vp->atp = node->GetAttribute(g, NULL);
vp->nl = node->GetChildElements(g);
if (tdp->Usedom && vp->nl->GetLength() == 1) {
@@ -265,7 +274,7 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
if (vp->atp || vp->b) {
if (!vp->atp)
- node = vp->nl->GetItem(g, vp->k++, node);
+ node = vp->nl->GetItem(g, vp->k++, tdp->Usedom ? node : NULL);
strncat(fmt, colname, XLEN(fmt));
strncat(fmt, "/", XLEN(fmt));
@@ -424,11 +433,14 @@ XMLDEF::XMLDEF(void)
DefNs = NULL;
Attrib = NULL;
Hdattr = NULL;
+ Entry = NULL;
Coltype = 1;
Limit = 0;
Header = 0;
Xpand = false;
Usedom = false;
+ Zipped = false;
+ Mulentries = false;
} // end of XMLDEF constructor
/***********************************************************************/
@@ -507,7 +519,14 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
// Get eventual table node attribute
Attrib = GetStringCatInfo(g, "Attribute", NULL);
Hdattr = GetStringCatInfo(g, "HeadAttr", NULL);
- return false;
+
+ // Specific for zipped files
+ if ((Zipped = GetBoolCatInfo("Zipped", false)))
+ Mulentries = ((Entry = GetStringCatInfo(g, "Entry", NULL)))
+ ? strchr(Entry, '*') || strchr(Entry, '?')
+ : GetBoolCatInfo("Mulentries", false);
+
+ return false;
} // end of DefineAM
/***********************************************************************/
@@ -547,6 +566,7 @@ TDBXML::TDBXML(PXMLDEF tdp) : TDBASE(tdp)
Xfile = tdp->Fn;
Enc = tdp->Encoding;
Tabname = tdp->Tabname;
+#if 0 // why all these?
Rowname = (tdp->Rowname) ? tdp->Rowname : NULL;
Colname = (tdp->Colname) ? tdp->Colname : NULL;
Mulnode = (tdp->Mulnode) ? tdp->Mulnode : NULL;
@@ -555,10 +575,22 @@ TDBXML::TDBXML(PXMLDEF tdp) : TDBASE(tdp)
DefNs = (tdp->DefNs) ? tdp->DefNs : NULL;
Attrib = (tdp->Attrib) ? tdp->Attrib : NULL;
Hdattr = (tdp->Hdattr) ? tdp->Hdattr : NULL;
- Coltype = tdp->Coltype;
+#endif // 0
+ Rowname = tdp->Rowname;
+ Colname = tdp->Colname;
+ Mulnode = tdp->Mulnode;
+ XmlDB = tdp->XmlDB;
+ Nslist = tdp->Nslist;
+ DefNs = tdp->DefNs;
+ Attrib = tdp->Attrib;
+ Hdattr = tdp->Hdattr;
+ Entry = tdp->Entry;
+ Coltype = tdp->Coltype;
Limit = tdp->Limit;
Xpand = tdp->Xpand;
- Changed = false;
+ Zipped = tdp->Zipped;
+ Mulentries = tdp->Mulentries;
+ Changed = false;
Checked = false;
NextSame = false;
NewRow = false;
@@ -600,10 +632,13 @@ TDBXML::TDBXML(PTDBXML tdbp) : TDBASE(tdbp)
DefNs = tdbp->DefNs;
Attrib = tdbp->Attrib;
Hdattr = tdbp->Hdattr;
- Coltype = tdbp->Coltype;
+ Entry = tdbp->Entry;
+ Coltype = tdbp->Coltype;
Limit = tdbp->Limit;
Xpand = tdbp->Xpand;
- Changed = tdbp->Changed;
+ Zipped = tdbp->Zipped;
+ Mulentries = tdbp->Mulentries;
+ Changed = tdbp->Changed;
Checked = tdbp->Checked;
NextSame = tdbp->NextSame;
NewRow = tdbp->NewRow;
@@ -681,7 +716,7 @@ int TDBXML::LoadTableFile(PGLOBAL g, char *filename)
/*********************************************************************/
/* Firstly we check whether this file have been already loaded. */
/*********************************************************************/
- if (Mode == MODE_READ || Mode == MODE_ANY)
+ if ((Mode == MODE_READ || Mode == MODE_ANY) && !Zipped)
for (fp = dup->Openlist; fp; fp = fp->Next)
if (fp->Type == type && fp->Length && fp->Count)
if (!stricmp(fp->Fname, filename))
@@ -703,7 +738,7 @@ int TDBXML::LoadTableFile(PGLOBAL g, char *filename)
return RC_FX;
// Initialize the implementation
- if (Docp->Initialize(g)) {
+ if (Docp->Initialize(g, Entry, Zipped)) {
sprintf(g->Message, MSG(INIT_FAILED), (Usedom) ? "DOM" : "libxml2");
return RC_FX;
} // endif init
@@ -712,7 +747,7 @@ int TDBXML::LoadTableFile(PGLOBAL g, char *filename)
htrc("TDBXML: parsing %s rc=%d\n", filename, rc);
// Parse the XML file
- if (Docp->ParseFile(filename)) {
+ if (Docp->ParseFile(g, filename)) {
// Does the file exist?
int h= global_open(g, MSGID_NONE, filename, _O_RDONLY);
diff --git a/storage/connect/tabxml.h b/storage/connect/tabxml.h
index 7ba3166881d..6c586d79dec 100644
--- a/storage/connect/tabxml.h
+++ b/storage/connect/tabxml.h
@@ -1,7 +1,7 @@
/*************** Tabxml H Declares Source Code File (.H) ***************/
-/* Name: TABXML.H Version 1.6 */
+/* Name: TABXML.H Version 1.7 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2007-2015 */
+/* (C) Copyright to the author Olivier BERTRAND 2007-2016 */
/* */
/* This file contains the XML table classes declares. */
/***********************************************************************/
@@ -42,12 +42,15 @@ class DllExport XMLDEF : public TABDEF { /* Logical table description */
char *DefNs; /* Dummy name of default namespace */
char *Attrib; /* Table node attributes */
char *Hdattr; /* Header node attributes */
- int Coltype; /* Default column type */
+ char *Entry; /* Zip entry name or pattern */
+ int Coltype; /* Default column type */
int Limit; /* Limit of multiple values */
int Header; /* n first rows are header rows */
bool Xpand; /* Put multiple tags in several rows */
bool Usedom; /* True: DOM, False: libxml2 */
- }; // end of XMLDEF
+ bool Zipped; /* True: Zipped XML file(s) */
+ bool Mulentries; /* True: multiple entries in zip file*/
+}; // end of XMLDEF
#if defined(INCLUDE_TDBXML)
/***********************************************************************/
@@ -122,7 +125,9 @@ class DllExport TDBXML : public TDBASE {
bool Bufdone; // True when column buffers allocated
bool Nodedone; // True when column nodes allocated
bool Void; // True if the file does not exist
- char *Xfile; // The XML file
+ bool Zipped; // True if Zipped XML file(s)
+ bool Mulentries; // True if multiple entries in zip file
+ char *Xfile; // The XML file
char *Enc; // New XML table file encoding
char *Tabname; // Name of Table node
char *Rowname; // Name of first level nodes
@@ -133,7 +138,8 @@ class DllExport TDBXML : public TDBASE {
char *DefNs; // Dummy name of default namespace
char *Attrib; // Table node attribut(s)
char *Hdattr; // Header node attribut(s)
- int Coltype; // Default column type
+ char *Entry; // Zip entry name or pattern
+ int Coltype; // Default column type
int Limit; // Limit of multiple values
int Header; // n first rows are header rows
int Multiple; // If multiple files
diff --git a/storage/connect/tabzip.cpp b/storage/connect/tabzip.cpp
new file mode 100644
index 00000000000..11f414ee154
--- /dev/null
+++ b/storage/connect/tabzip.cpp
@@ -0,0 +1,230 @@
+/************* TabZip C++ Program Source Code File (.CPP) **************/
+/* PROGRAM NAME: TABZIP Version 1.0 */
+/* (C) Copyright to the author Olivier BERTRAND 2016 */
+/* This program are the TABZIP class DB execution routines. */
+/***********************************************************************/
+
+/***********************************************************************/
+/* Include relevant sections of the MariaDB header file. */
+/***********************************************************************/
+#include <my_global.h>
+
+/***********************************************************************/
+/* Include application header files: */
+/* global.h is header containing all global declarations. */
+/* plgdbsem.h is header containing the DB application declarations. */
+/* (x)table.h is header containing the TDBASE declarations. */
+/* tabzip.h is header containing the TABZIP classes declarations. */
+/***********************************************************************/
+#include "global.h"
+#include "plgdbsem.h"
+#include "xtable.h"
+#include "filamtxt.h"
+#include "filamzip.h"
+#include "resource.h" // for IDS_COLUMNS
+#include "tabdos.h"
+#include "tabzip.h"
+
+/* -------------------------- Class ZIPDEF --------------------------- */
+
+/************************************************************************/
+/* DefineAM: define specific AM block values. */
+/************************************************************************/
+bool ZIPDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
+{
+//target = GetStringCatInfo(g, "Target", NULL);
+ return DOSDEF::DefineAM(g, "ZIP", poff);
+} // end of DefineAM
+
+/***********************************************************************/
+/* GetTable: makes a new Table Description Block. */
+/***********************************************************************/
+PTDB ZIPDEF::GetTable(PGLOBAL g, MODE m)
+{
+ return new(g) TDBZIP(this);
+} // end of GetTable
+
+/* ------------------------------------------------------------------- */
+
+/***********************************************************************/
+/* Implementation of the TDBZIP class. */
+/***********************************************************************/
+TDBZIP::TDBZIP(PZIPDEF tdp) : TDBASE(tdp)
+{
+ zipfile = NULL;
+ zfn = tdp->Fn;
+//target = tdp->target;
+ nexterr = UNZ_OK;
+} // end of TDBZIP standard constructor
+
+/***********************************************************************/
+/* Allocate ZIP column description block. */
+/***********************************************************************/
+PCOL TDBZIP::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
+{
+ return new(g) ZIPCOL(cdp, this, cprec, n);
+} // end of MakeCol
+
+/***********************************************************************/
+/* open a zip file. */
+/* param: filename path and the filename of the zip file to open. */
+/* return: true if open, false otherwise. */
+/***********************************************************************/
+bool TDBZIP::open(PGLOBAL g, const char *filename)
+{
+ if (!zipfile && !(zipfile = unzOpen64(filename)))
+ sprintf(g->Message, "Zipfile open error");
+
+ return (zipfile == NULL);
+} // end of open
+
+/***********************************************************************/
+/* Close the zip file. */
+/***********************************************************************/
+void TDBZIP::close()
+{
+ if (zipfile) {
+ unzClose(zipfile);
+ zipfile = NULL;
+ } // endif zipfile
+
+} // end of close
+
+/***********************************************************************/
+/* ZIP Cardinality: returns table size in number of rows. */
+/***********************************************************************/
+int TDBZIP::Cardinality(PGLOBAL g)
+{
+ if (!g)
+ return 1;
+ else if (Cardinal < 0) {
+ if (!open(g, zfn)) {
+ unz_global_info64 ginfo;
+ int err = unzGetGlobalInfo64(zipfile, &ginfo);
+
+ Cardinal = (err == UNZ_OK) ? ginfo.number_entry : 0;
+ } else
+ Cardinal = 0;
+
+ } // endif Cardinal
+
+ return Cardinal;
+} // end of Cardinality
+
+/***********************************************************************/
+/* ZIP GetMaxSize: returns file size estimate in number of lines. */
+/***********************************************************************/
+int TDBZIP::GetMaxSize(PGLOBAL g)
+{
+ if (MaxSize < 0)
+ MaxSize = Cardinality(g);
+
+ return MaxSize;
+} // end of GetMaxSize
+
+/***********************************************************************/
+/* ZIP Access Method opening routine. */
+/***********************************************************************/
+bool TDBZIP::OpenDB(PGLOBAL g)
+{
+ if (Use == USE_OPEN)
+ // Table already open
+ return false;
+
+ Use = USE_OPEN; // To be clean
+ return open(g, zfn);
+} // end of OpenDB
+
+/***********************************************************************/
+/* ReadDB: Data Base read routine for ZIP access method. */
+/***********************************************************************/
+int TDBZIP::ReadDB(PGLOBAL g)
+{
+ if (nexterr == UNZ_END_OF_LIST_OF_FILE)
+ return RC_EF;
+ else if (nexterr != UNZ_OK) {
+ sprintf(g->Message, "unzGoToNextFile error %d", nexterr);
+ return RC_FX;
+ } // endif nexterr
+
+ int err = unzGetCurrentFileInfo64(zipfile, &finfo, fn,
+ sizeof(fn), NULL, 0, NULL, 0);
+
+ if (err != UNZ_OK) {
+ sprintf(g->Message, "unzGetCurrentFileInfo64 error %d", err);
+ return RC_FX;
+ } // endif err
+
+ nexterr = unzGoToNextFile(zipfile);
+ return RC_OK;
+} // end of ReadDB
+
+/***********************************************************************/
+/* WriteDB: Data Base write routine for ZIP access method. */
+/***********************************************************************/
+int TDBZIP::WriteDB(PGLOBAL g)
+{
+ strcpy(g->Message, "ZIP tables are read only");
+ return RC_FX;
+} // end of WriteDB
+
+/***********************************************************************/
+/* Data Base delete line routine for ZIP access method. */
+/***********************************************************************/
+int TDBZIP::DeleteDB(PGLOBAL g, int irc)
+{
+ strcpy(g->Message, "Delete not enabled for ZIP tables");
+ return RC_FX;
+} // end of DeleteDB
+
+/***********************************************************************/
+/* Data Base close routine for ZIP access method. */
+/***********************************************************************/
+void TDBZIP::CloseDB(PGLOBAL g)
+{
+ close();
+ Use = USE_READY; // Just to be clean
+} // end of CloseDB
+
+/* ---------------------------- ZIPCOL ------------------------------- */
+
+/***********************************************************************/
+/* ZIPCOL public constructor. */
+/***********************************************************************/
+ZIPCOL::ZIPCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
+ : COLBLK(cdp, tdbp, i)
+{
+ if (cprec) {
+ Next = cprec->GetNext();
+ cprec->SetNext(this);
+ } else {
+ Next = tdbp->GetColumns();
+ tdbp->SetColumns(this);
+ } // endif cprec
+
+ Tdbz = (TDBZIP*)tdbp;
+ flag = cdp->GetOffset();
+} // end of ZIPCOL constructor
+
+/***********************************************************************/
+/* ReadColumn: */
+/***********************************************************************/
+void ZIPCOL::ReadColumn(PGLOBAL g)
+{
+ switch (flag) {
+ case 1:
+ Value->SetValue(Tdbz->finfo.compressed_size);
+ break;
+ case 2:
+ Value->SetValue(Tdbz->finfo.uncompressed_size);
+ break;
+ case 3:
+ Value->SetValue((int)Tdbz->finfo.compression_method);
+ break;
+ default:
+ Value->SetValue_psz((PSZ)Tdbz->fn);
+ } // endswitch flag
+
+} // end of ReadColumn
+
+/* -------------------------- End of tabzip -------------------------- */
diff --git a/storage/connect/tabzip.h b/storage/connect/tabzip.h
new file mode 100644
index 00000000000..6f1735258e7
--- /dev/null
+++ b/storage/connect/tabzip.h
@@ -0,0 +1,100 @@
+/*************** tabzip H Declares Source Code File (.H) ***************/
+/* Name: tabzip.h Version 1.0 */
+/* */
+/* (C) Copyright to the author Olivier BERTRAND 2016 */
+/* */
+/* This file contains the ZIP classe declares. */
+/***********************************************************************/
+#include "osutil.h"
+#include "block.h"
+#include "colblk.h"
+#include "xtable.h"
+#include "unzip.h"
+
+typedef class ZIPDEF *PZIPDEF;
+typedef class TDBZIP *PTDBZIP;
+typedef class ZIPCOL *PZIPCOL;
+
+/***********************************************************************/
+/* ZIP table: display info about a ZIP file. */
+/***********************************************************************/
+class DllExport ZIPDEF : public DOSDEF { /* Table description */
+ friend class TDBZIP;
+ friend class ZIPFAM;
+public:
+ // Constructor
+ ZIPDEF(void) {}
+
+ // Implementation
+ virtual const char *GetType(void) {return "ZIP";}
+
+ // Methods
+ virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
+ virtual PTDB GetTable(PGLOBAL g, MODE m);
+
+protected:
+ // Members
+ PSZ target; // The inside file to query
+}; // end of ZIPDEF
+
+/***********************************************************************/
+/* This is the ZIP Access Method class declaration. */
+/***********************************************************************/
+class DllExport TDBZIP : public TDBASE {
+ friend class ZIPCOL;
+public:
+ // Constructor
+ TDBZIP(PZIPDEF tdp);
+
+ // Implementation
+ virtual AMT GetAmType(void) {return TYPE_AM_ZIP;}
+
+ // Methods
+ virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
+ virtual int Cardinality(PGLOBAL g);
+ virtual int GetMaxSize(PGLOBAL g);
+ virtual int GetRecpos(void) {return 0;}
+
+ // Database routines
+ virtual bool OpenDB(PGLOBAL g);
+ virtual int ReadDB(PGLOBAL g);
+ virtual int WriteDB(PGLOBAL g);
+ virtual int DeleteDB(PGLOBAL g, int irc);
+ virtual void CloseDB(PGLOBAL g);
+
+protected:
+ bool open(PGLOBAL g, const char *filename);
+ void close(void);
+
+ // Members
+ unzFile zipfile; // The ZIP container file
+ PSZ zfn; // The ZIP file name
+//PSZ target;
+ unz_file_info64 finfo; // The current file info
+ char fn[FILENAME_MAX]; // The current file name
+ int nexterr; // Next file error
+}; // end of class TDBZIP
+
+/***********************************************************************/
+/* Class ZIPCOL: ZIP access method column descriptor. */
+/***********************************************************************/
+class DllExport ZIPCOL : public COLBLK {
+ friend class TDBZIP;
+public:
+ // Constructors
+ ZIPCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "ZIP");
+
+ // Implementation
+ virtual int GetAmType(void) { return TYPE_AM_ZIP; }
+
+ // Methods
+ virtual void ReadColumn(PGLOBAL g);
+
+protected:
+ // Default constructor not to be used
+ ZIPCOL(void) {}
+
+ // Members
+ TDBZIP *Tdbz;
+ int flag;
+}; // end of class ZIPCOL
diff --git a/storage/connect/unzip.c b/storage/connect/unzip.c
new file mode 100644
index 00000000000..909350435a5
--- /dev/null
+++ b/storage/connect/unzip.c
@@ -0,0 +1,2125 @@
+/* unzip.c -- IO for uncompress .zip files using zlib
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications of Unzip for Zip64
+ Copyright (C) 2007-2008 Even Rouault
+
+ Modifications for Zip64 support on both zip and unzip
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+
+ ------------------------------------------------------------------------------------
+ Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
+ compatibility with older software. The following is from the original crypt.c.
+ Code woven in by Terry Thorsen 1/2003.
+
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+
+ crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
+
+ The encryption/decryption parts of this source code (as opposed to the
+ non-echoing password parts) were originally written in Europe. The
+ whole source package can be freely distributed, including from the USA.
+ (Prior to January 2000, re-export from the US was a violation of US law.)
+
+ This encryption code is a direct transcription of the algorithm from
+ Roger Schlafly, described by Phil Katz in the file appnote.txt. This
+ file (appnote.txt) is distributed with the PKZIP program (even in the
+ version without encryption capabilities).
+
+ ------------------------------------------------------------------------------------
+
+ Changes in unzip.c
+
+ 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
+ 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
+ 2007-2008 - Even Rouault - Remove old C style function prototypes
+ 2007-2008 - Even Rouault - Add unzip support for ZIP64
+
+ Copyright (C) 2007-2008 Even Rouault
+
+
+ Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
+ Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
+ should only read the compressed/uncompressed size from the Zip64 format if
+ the size from normal header was 0xFFFFFFFF
+ Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
+ Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
+ Patch created by Daniel Borca
+
+ Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
+
+ Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
+
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef NOUNCRYPT
+ #define NOUNCRYPT
+#endif
+
+#include "zlib.h"
+#include "unzip.h"
+
+#ifdef STDC
+# include <stddef.h>
+# include <string.h>
+# include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+ extern int errno;
+#else
+# include <errno.h>
+#endif
+
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+
+#ifndef CASESENSITIVITYDEFAULT_NO
+# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
+# define CASESENSITIVITYDEFAULT_NO
+# endif
+#endif
+
+
+#ifndef UNZ_BUFSIZE
+#define UNZ_BUFSIZE (16384)
+#endif
+
+#ifndef UNZ_MAXFILENAMEINZIP
+#define UNZ_MAXFILENAMEINZIP (256)
+#endif
+
+#ifndef ALLOC
+# define ALLOC(size) (malloc(size))
+#endif
+#ifndef TRYFREE
+# define TRYFREE(p) {if (p) free(p);}
+#endif
+
+#define SIZECENTRALDIRITEM (0x2e)
+#define SIZEZIPLOCALHEADER (0x1e)
+
+
+const char unz_copyright[] =
+ " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
+
+/* unz_file_info_interntal contain internal info about a file in zipfile*/
+typedef struct unz_file_info64_internal_s
+{
+ ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
+} unz_file_info64_internal;
+
+
+/* file_in_zip_read_info_s contain internal information about a file in zipfile,
+ when reading and decompress it */
+typedef struct
+{
+ char *read_buffer; /* internal buffer for compressed data */
+ z_stream stream; /* zLib stream structure for inflate */
+
+#ifdef HAVE_BZIP2
+ bz_stream bstream; /* bzLib stream structure for bziped */
+#endif
+
+ ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
+ uLong stream_initialised; /* flag set if stream structure is initialised*/
+
+ ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
+ uInt size_local_extrafield;/* size of the local extra field */
+ ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/
+ ZPOS64_T total_out_64;
+
+ uLong crc32; /* crc32 of all data uncompressed */
+ uLong crc32_wait; /* crc32 we must obtain after decompress all */
+ ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
+ ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
+ zlib_filefunc64_32_def z_filefunc;
+ voidpf filestream; /* io structore of the zipfile */
+ uLong compression_method; /* compression method (0==store) */
+ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+ int raw;
+} file_in_zip64_read_info_s;
+
+
+/* unz64_s contain internal information about the zipfile
+*/
+typedef struct
+{
+ zlib_filefunc64_32_def z_filefunc;
+ int is64bitOpenFunction;
+ voidpf filestream; /* io structore of the zipfile */
+ unz_global_info64 gi; /* public global information */
+ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+ ZPOS64_T num_file; /* number of the current file in the zipfile*/
+ ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/
+ ZPOS64_T current_file_ok; /* flag about the usability of the current file*/
+ ZPOS64_T central_pos; /* position of the beginning of the central dir*/
+
+ ZPOS64_T size_central_dir; /* size of the central directory */
+ ZPOS64_T offset_central_dir; /* offset of start of central directory with
+ respect to the starting disk number */
+
+ unz_file_info64 cur_file_info; /* public info about the current file in zip*/
+ unz_file_info64_internal cur_file_info_internal; /* private info about it*/
+ file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
+ file if we are decompressing it */
+ int encrypted;
+
+ int isZip64;
+
+# ifndef NOUNCRYPT
+ unsigned long keys[3]; /* keys defining the pseudo-random sequence */
+ const z_crc_t* pcrc_32_tab;
+# endif
+} unz64_s;
+
+
+#ifndef NOUNCRYPT
+#include "crypt.h"
+#endif
+
+/* ===========================================================================
+ Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+ for end of file.
+ IN assertion: the stream s has been sucessfully opened for reading.
+*/
+
+
+local int unz64local_getByte OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ int *pi));
+
+local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
+{
+ unsigned char c;
+ int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
+ if (err==1)
+ {
+ *pi = (int)c;
+ return UNZ_OK;
+ }
+ else
+ {
+ if (ZERROR64(*pzlib_filefunc_def,filestream))
+ return UNZ_ERRNO;
+ else
+ return UNZ_EOF;
+ }
+}
+
+
+/* ===========================================================================
+ Reads a long in LSB order from the given gz_stream. Sets
+*/
+local int unz64local_getShort OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX));
+
+local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX)
+{
+ uLong x ;
+ int i = 0;
+ int err;
+
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (uLong)i;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((uLong)i)<<8;
+
+ if (err==UNZ_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+local int unz64local_getLong OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX));
+
+local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX)
+{
+ uLong x ;
+ int i = 0;
+ int err;
+
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (uLong)i;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((uLong)i)<<8;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((uLong)i)<<16;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((uLong)i)<<24;
+
+ if (err==UNZ_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+local int unz64local_getLong64 OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ ZPOS64_T *pX));
+
+
+local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ ZPOS64_T *pX)
+{
+ ZPOS64_T x ;
+ int i = 0;
+ int err;
+
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (ZPOS64_T)i;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<8;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<16;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<24;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<32;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<40;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<48;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<56;
+
+ if (err==UNZ_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+/* My own strcmpi / strcasecmp */
+local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
+{
+ for (;;)
+ {
+ char c1=*(fileName1++);
+ char c2=*(fileName2++);
+ if ((c1>='a') && (c1<='z'))
+ c1 -= 0x20;
+ if ((c2>='a') && (c2<='z'))
+ c2 -= 0x20;
+ if (c1=='\0')
+ return ((c2=='\0') ? 0 : -1);
+ if (c2=='\0')
+ return 1;
+ if (c1<c2)
+ return -1;
+ if (c1>c2)
+ return 1;
+ }
+}
+
+
+#ifdef CASESENSITIVITYDEFAULT_NO
+#define CASESENSITIVITYDEFAULTVALUE 2
+#else
+#define CASESENSITIVITYDEFAULTVALUE 1
+#endif
+
+#ifndef STRCMPCASENOSENTIVEFUNCTION
+#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
+#endif
+
+/*
+ Compare two filename (fileName1,fileName2).
+ If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+ If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+ or strcasecmp)
+ If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+ (like 1 on Unix, 2 on Windows)
+
+*/
+extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
+ const char* fileName2,
+ int iCaseSensitivity)
+
+{
+ if (iCaseSensitivity==0)
+ iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
+
+ if (iCaseSensitivity==1)
+ return strcmp(fileName1,fileName2);
+
+ return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
+}
+
+#ifndef BUFREADCOMMENT
+#define BUFREADCOMMENT (0x400)
+#endif
+
+/*
+ Locate the Central directory of a zipfile (at the end, just before
+ the global comment)
+*/
+local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
+local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
+{
+ unsigned char* buf;
+ ZPOS64_T uSizeFile;
+ ZPOS64_T uBackRead;
+ ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+ ZPOS64_T uPosFound=0;
+
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+ return 0;
+
+
+ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+ if (uMaxBack>uSizeFile)
+ uMaxBack = uSizeFile;
+
+ buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+ if (buf==NULL)
+ return 0;
+
+ uBackRead = 4;
+ while (uBackRead<uMaxBack)
+ {
+ uLong uReadSize;
+ ZPOS64_T uReadPos ;
+ int i;
+ if (uBackRead+BUFREADCOMMENT>uMaxBack)
+ uBackRead = uMaxBack;
+ else
+ uBackRead+=BUFREADCOMMENT;
+ uReadPos = uSizeFile-uBackRead ;
+
+ uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+ (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ break;
+
+ if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+ break;
+
+ for (i=(int)uReadSize-3; (i--)>0;)
+ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+ ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
+ {
+ uPosFound = uReadPos+i;
+ break;
+ }
+
+ if (uPosFound!=0)
+ break;
+ }
+ TRYFREE(buf);
+ return uPosFound;
+}
+
+
+/*
+ Locate the Central directory 64 of a zipfile (at the end, just before
+ the global comment)
+*/
+local ZPOS64_T unz64local_SearchCentralDir64 OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream));
+
+local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream)
+{
+ unsigned char* buf;
+ ZPOS64_T uSizeFile;
+ ZPOS64_T uBackRead;
+ ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+ ZPOS64_T uPosFound=0;
+ uLong uL;
+ ZPOS64_T relativeOffset;
+
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+ return 0;
+
+
+ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+ if (uMaxBack>uSizeFile)
+ uMaxBack = uSizeFile;
+
+ buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+ if (buf==NULL)
+ return 0;
+
+ uBackRead = 4;
+ while (uBackRead<uMaxBack)
+ {
+ uLong uReadSize;
+ ZPOS64_T uReadPos;
+ int i;
+ if (uBackRead+BUFREADCOMMENT>uMaxBack)
+ uBackRead = uMaxBack;
+ else
+ uBackRead+=BUFREADCOMMENT;
+ uReadPos = uSizeFile-uBackRead ;
+
+ uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+ (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ break;
+
+ if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+ break;
+
+ for (i=(int)uReadSize-3; (i--)>0;)
+ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+ ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
+ {
+ uPosFound = uReadPos+i;
+ break;
+ }
+
+ if (uPosFound!=0)
+ break;
+ }
+ TRYFREE(buf);
+ if (uPosFound == 0)
+ return 0;
+
+ /* Zip64 end of central directory locator */
+ if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return 0;
+
+ /* the signature, already checked */
+ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+ return 0;
+
+ /* number of the disk with the start of the zip64 end of central directory */
+ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+ return 0;
+ if (uL != 0)
+ return 0;
+
+ /* relative offset of the zip64 end of central directory record */
+ if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
+ return 0;
+
+ /* total number of disks */
+ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+ return 0;
+ if (uL != 1)
+ return 0;
+
+ /* Goto end of central directory record */
+ if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return 0;
+
+ /* the signature */
+ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+ return 0;
+
+ if (uL != 0x06064b50)
+ return 0;
+
+ return relativeOffset;
+}
+
+/*
+ Open a Zip file. path contain the full pathname (by example,
+ on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
+ "zlib/zlib114.zip".
+ If the zipfile cannot be opened (file doesn't exist or in not valid), the
+ return value is NULL.
+ Else, the return value is a unzFile Handle, usable with other function
+ of this unzip package.
+*/
+local unzFile unzOpenInternal (const void *path,
+ zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
+ int is64bitOpenFunction)
+{
+ unz64_s us;
+ unz64_s *s;
+ ZPOS64_T central_pos;
+ uLong uL;
+
+ uLong number_disk; /* number of the current dist, used for
+ spaning ZIP, unsupported, always 0*/
+ uLong number_disk_with_CD; /* number the the disk with central dir, used
+ for spaning ZIP, unsupported, always 0*/
+ ZPOS64_T number_entry_CD; /* total number of entries in
+ the central dir
+ (same than number_entry on nospan) */
+
+ int err=UNZ_OK;
+
+ if (unz_copyright[0]!=' ')
+ return NULL;
+
+ us.z_filefunc.zseek32_file = NULL;
+ us.z_filefunc.ztell32_file = NULL;
+ if (pzlib_filefunc64_32_def==NULL)
+ fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
+ else
+ us.z_filefunc = *pzlib_filefunc64_32_def;
+ us.is64bitOpenFunction = is64bitOpenFunction;
+
+
+
+ us.filestream = ZOPEN64(us.z_filefunc,
+ path,
+ ZLIB_FILEFUNC_MODE_READ |
+ ZLIB_FILEFUNC_MODE_EXISTING);
+ if (us.filestream==NULL)
+ return NULL;
+
+ central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
+ if (central_pos)
+ {
+ uLong uS;
+ ZPOS64_T uL64;
+
+ us.isZip64 = 1;
+
+ if (ZSEEK64(us.z_filefunc, us.filestream,
+ central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err=UNZ_ERRNO;
+
+ /* the signature, already checked */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* size of zip64 end of central directory record */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* version made by */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* version needed to extract */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* number of this disk */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* number of the disk with the start of the central directory */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* total number of entries in the central directory on this disk */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* total number of entries in the central directory */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if ((number_entry_CD!=us.gi.number_entry) ||
+ (number_disk_with_CD!=0) ||
+ (number_disk!=0))
+ err=UNZ_BADZIPFILE;
+
+ /* size of the central directory */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* offset of start of central directory with respect to the
+ starting disk number */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ us.gi.size_comment = 0;
+ }
+ else
+ {
+ central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
+ if (central_pos==0)
+ err=UNZ_ERRNO;
+
+ us.isZip64 = 0;
+
+ if (ZSEEK64(us.z_filefunc, us.filestream,
+ central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err=UNZ_ERRNO;
+
+ /* the signature, already checked */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* number of this disk */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* number of the disk with the start of the central directory */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* total number of entries in the central dir on this disk */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ us.gi.number_entry = uL;
+
+ /* total number of entries in the central dir */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ number_entry_CD = uL;
+
+ if ((number_entry_CD!=us.gi.number_entry) ||
+ (number_disk_with_CD!=0) ||
+ (number_disk!=0))
+ err=UNZ_BADZIPFILE;
+
+ /* size of the central directory */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ us.size_central_dir = uL;
+
+ /* offset of start of central directory with respect to the
+ starting disk number */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ us.offset_central_dir = uL;
+
+ /* zipfile comment length */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
+ (err==UNZ_OK))
+ err=UNZ_BADZIPFILE;
+
+ if (err!=UNZ_OK)
+ {
+ ZCLOSE64(us.z_filefunc, us.filestream);
+ return NULL;
+ }
+
+ us.byte_before_the_zipfile = central_pos -
+ (us.offset_central_dir+us.size_central_dir);
+ us.central_pos = central_pos;
+ us.pfile_in_zip_read = NULL;
+ us.encrypted = 0;
+
+
+ s=(unz64_s*)ALLOC(sizeof(unz64_s));
+ if( s != NULL)
+ {
+ *s=us;
+ unzGoToFirstFile((unzFile)s);
+ }
+ return (unzFile)s;
+}
+
+
+extern unzFile ZEXPORT unzOpen2 (const char *path,
+ zlib_filefunc_def* pzlib_filefunc32_def)
+{
+ if (pzlib_filefunc32_def != NULL)
+ {
+ zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+ fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
+ return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
+ }
+ else
+ return unzOpenInternal(path, NULL, 0);
+}
+
+extern unzFile ZEXPORT unzOpen2_64 (const void *path,
+ zlib_filefunc64_def* pzlib_filefunc_def)
+{
+ if (pzlib_filefunc_def != NULL)
+ {
+ zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+ zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
+ zlib_filefunc64_32_def_fill.ztell32_file = NULL;
+ zlib_filefunc64_32_def_fill.zseek32_file = NULL;
+ return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
+ }
+ else
+ return unzOpenInternal(path, NULL, 1);
+}
+
+extern unzFile ZEXPORT unzOpen (const char *path)
+{
+ return unzOpenInternal(path, NULL, 0);
+}
+
+extern unzFile ZEXPORT unzOpen64 (const void *path)
+{
+ return unzOpenInternal(path, NULL, 1);
+}
+
+/*
+ Close a ZipFile opened with unzOpen.
+ If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+ these files MUST be closed with unzCloseCurrentFile before call unzClose.
+ return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzClose (unzFile file)
+{
+ unz64_s* s;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+
+ if (s->pfile_in_zip_read!=NULL)
+ unzCloseCurrentFile(file);
+
+ ZCLOSE64(s->z_filefunc, s->filestream);
+ TRYFREE(s);
+ return UNZ_OK;
+}
+
+
+/*
+ Write info about the ZipFile in the *pglobal_info structure.
+ No preparation of the structure is needed
+ return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
+{
+ unz64_s* s;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ *pglobal_info=s->gi;
+ return UNZ_OK;
+}
+
+extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
+{
+ unz64_s* s;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ /* to do : check if number_entry is not truncated */
+ pglobal_info32->number_entry = (uLong)s->gi.number_entry;
+ pglobal_info32->size_comment = s->gi.size_comment;
+ return UNZ_OK;
+}
+/*
+ Translate date/time from Dos format to tm_unz (readable more easilty)
+*/
+local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
+{
+ ZPOS64_T uDate;
+ uDate = (ZPOS64_T)(ulDosDate>>16);
+ ptm->tm_mday = (uInt)(uDate&0x1f) ;
+ ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
+ ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
+
+ ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
+ ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
+ ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
+}
+
+/*
+ Get Info about the current file in the zipfile, with internal only info
+*/
+local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
+ unz_file_info64 *pfile_info,
+ unz_file_info64_internal
+ *pfile_info_internal,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize));
+
+local int unz64local_GetCurrentFileInfoInternal (unzFile file,
+ unz_file_info64 *pfile_info,
+ unz_file_info64_internal
+ *pfile_info_internal,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize)
+{
+ unz64_s* s;
+ unz_file_info64 file_info;
+ unz_file_info64_internal file_info_internal;
+ int err=UNZ_OK;
+ uLong uMagic;
+ long lSeek=0;
+ uLong uL;
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (ZSEEK64(s->z_filefunc, s->filestream,
+ s->pos_in_central_dir+s->byte_before_the_zipfile,
+ ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err=UNZ_ERRNO;
+
+
+ /* we check the magic */
+ if (err==UNZ_OK)
+ {
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
+ err=UNZ_ERRNO;
+ else if (uMagic!=0x02014b50)
+ err=UNZ_BADZIPFILE;
+ }
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+ err=UNZ_ERRNO;
+ file_info.compressed_size = uL;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+ err=UNZ_ERRNO;
+ file_info.uncompressed_size = uL;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ // relative offset of local header
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+ err=UNZ_ERRNO;
+ file_info_internal.offset_curfile = uL;
+
+ lSeek+=file_info.size_filename;
+ if ((err==UNZ_OK) && (szFileName!=NULL))
+ {
+ uLong uSizeRead ;
+ if (file_info.size_filename<fileNameBufferSize)
+ {
+ *(szFileName+file_info.size_filename)='\0';
+ uSizeRead = file_info.size_filename;
+ }
+ else
+ uSizeRead = fileNameBufferSize;
+
+ if ((file_info.size_filename>0) && (fileNameBufferSize>0))
+ if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
+ err=UNZ_ERRNO;
+ lSeek -= uSizeRead;
+ }
+
+ // Read extrafield
+ if ((err==UNZ_OK) && (extraField!=NULL))
+ {
+ ZPOS64_T uSizeRead ;
+ if (file_info.size_file_extra<extraFieldBufferSize)
+ uSizeRead = file_info.size_file_extra;
+ else
+ uSizeRead = extraFieldBufferSize;
+
+ if (lSeek!=0)
+ {
+ if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+ lSeek=0;
+ else
+ err=UNZ_ERRNO;
+ }
+
+ if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
+ if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
+ err=UNZ_ERRNO;
+
+ lSeek += file_info.size_file_extra - (uLong)uSizeRead;
+ }
+ else
+ lSeek += file_info.size_file_extra;
+
+
+ if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
+ {
+ uLong acc = 0;
+
+ // since lSeek now points to after the extra field we need to move back
+ lSeek -= file_info.size_file_extra;
+
+ if (lSeek!=0)
+ {
+ if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+ lSeek=0;
+ else
+ err=UNZ_ERRNO;
+ }
+
+ while(acc < file_info.size_file_extra)
+ {
+ uLong headerId;
+ uLong dataSize;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* ZIP64 extra fields */
+ if (headerId == 0x0001)
+ {
+ uLong uL;
+
+ if(file_info.uncompressed_size == MAXU32)
+ {
+ if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ if(file_info.compressed_size == MAXU32)
+ {
+ if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ if(file_info_internal.offset_curfile == MAXU32)
+ {
+ /* Relative Header offset */
+ if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ if(file_info.disk_num_start == MAXU32)
+ {
+ /* Disk Start Number */
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ }
+ else
+ {
+ if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
+ err=UNZ_ERRNO;
+ }
+
+ acc += 2 + 2 + dataSize;
+ }
+ }
+
+ if ((err==UNZ_OK) && (szComment!=NULL))
+ {
+ uLong uSizeRead ;
+ if (file_info.size_file_comment<commentBufferSize)
+ {
+ *(szComment+file_info.size_file_comment)='\0';
+ uSizeRead = file_info.size_file_comment;
+ }
+ else
+ uSizeRead = commentBufferSize;
+
+ if (lSeek!=0)
+ {
+ if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+ lSeek=0;
+ else
+ err=UNZ_ERRNO;
+ }
+
+ if ((file_info.size_file_comment>0) && (commentBufferSize>0))
+ if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
+ err=UNZ_ERRNO;
+ lSeek+=file_info.size_file_comment - uSizeRead;
+ }
+ else
+ lSeek+=file_info.size_file_comment;
+
+
+ if ((err==UNZ_OK) && (pfile_info!=NULL))
+ *pfile_info=file_info;
+
+ if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
+ *pfile_info_internal=file_info_internal;
+
+ return err;
+}
+
+
+
+/*
+ Write info about the ZipFile in the *pglobal_info structure.
+ No preparation of the structure is needed
+ return UNZ_OK if there is no problem.
+*/
+extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
+ unz_file_info64 * pfile_info,
+ char * szFileName, uLong fileNameBufferSize,
+ void *extraField, uLong extraFieldBufferSize,
+ char* szComment, uLong commentBufferSize)
+{
+ return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
+ szFileName,fileNameBufferSize,
+ extraField,extraFieldBufferSize,
+ szComment,commentBufferSize);
+}
+
+extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
+ unz_file_info * pfile_info,
+ char * szFileName, uLong fileNameBufferSize,
+ void *extraField, uLong extraFieldBufferSize,
+ char* szComment, uLong commentBufferSize)
+{
+ int err;
+ unz_file_info64 file_info64;
+ err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
+ szFileName,fileNameBufferSize,
+ extraField,extraFieldBufferSize,
+ szComment,commentBufferSize);
+ if ((err==UNZ_OK) && (pfile_info != NULL))
+ {
+ pfile_info->version = file_info64.version;
+ pfile_info->version_needed = file_info64.version_needed;
+ pfile_info->flag = file_info64.flag;
+ pfile_info->compression_method = file_info64.compression_method;
+ pfile_info->dosDate = file_info64.dosDate;
+ pfile_info->crc = file_info64.crc;
+
+ pfile_info->size_filename = file_info64.size_filename;
+ pfile_info->size_file_extra = file_info64.size_file_extra;
+ pfile_info->size_file_comment = file_info64.size_file_comment;
+
+ pfile_info->disk_num_start = file_info64.disk_num_start;
+ pfile_info->internal_fa = file_info64.internal_fa;
+ pfile_info->external_fa = file_info64.external_fa;
+
+ pfile_info->tmu_date = file_info64.tmu_date,
+
+
+ pfile_info->compressed_size = (uLong)file_info64.compressed_size;
+ pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
+
+ }
+ return err;
+}
+/*
+ Set the current file of the zipfile to the first file.
+ return UNZ_OK if there is no problem
+*/
+extern int ZEXPORT unzGoToFirstFile (unzFile file)
+{
+ int err=UNZ_OK;
+ unz64_s* s;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ s->pos_in_central_dir=s->offset_central_dir;
+ s->num_file=0;
+ err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL,0,NULL,0,NULL,0);
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+/*
+ Set the current file of the zipfile to the next file.
+ return UNZ_OK if there is no problem
+ return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+extern int ZEXPORT unzGoToNextFile (unzFile file)
+{
+ unz64_s* s;
+ int err;
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return UNZ_END_OF_LIST_OF_FILE;
+ if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
+ if (s->num_file+1==s->gi.number_entry)
+ return UNZ_END_OF_LIST_OF_FILE;
+
+ s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
+ s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
+ s->num_file++;
+ err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL,0,NULL,0,NULL,0);
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+
+/*
+ Try locate the file szFileName in the zipfile.
+ For the iCaseSensitivity signification, see unzStringFileNameCompare
+
+ return value :
+ UNZ_OK if the file is found. It becomes the current file.
+ UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
+{
+ unz64_s* s;
+ int err;
+
+ /* We remember the 'current' position in the file so that we can jump
+ * back there if we fail.
+ */
+ unz_file_info64 cur_file_infoSaved;
+ unz_file_info64_internal cur_file_info_internalSaved;
+ ZPOS64_T num_fileSaved;
+ ZPOS64_T pos_in_central_dirSaved;
+
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+
+ if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
+ return UNZ_PARAMERROR;
+
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return UNZ_END_OF_LIST_OF_FILE;
+
+ /* Save the current state */
+ num_fileSaved = s->num_file;
+ pos_in_central_dirSaved = s->pos_in_central_dir;
+ cur_file_infoSaved = s->cur_file_info;
+ cur_file_info_internalSaved = s->cur_file_info_internal;
+
+ err = unzGoToFirstFile(file);
+
+ while (err == UNZ_OK)
+ {
+ char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
+ err = unzGetCurrentFileInfo64(file,NULL,
+ szCurrentFileName,sizeof(szCurrentFileName)-1,
+ NULL,0,NULL,0);
+ if (err == UNZ_OK)
+ {
+ if (unzStringFileNameCompare(szCurrentFileName,
+ szFileName,iCaseSensitivity)==0)
+ return UNZ_OK;
+ err = unzGoToNextFile(file);
+ }
+ }
+
+ /* We failed, so restore the state of the 'current file' to where we
+ * were.
+ */
+ s->num_file = num_fileSaved ;
+ s->pos_in_central_dir = pos_in_central_dirSaved ;
+ s->cur_file_info = cur_file_infoSaved;
+ s->cur_file_info_internal = cur_file_info_internalSaved;
+ return err;
+}
+
+
+/*
+///////////////////////////////////////////
+// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
+// I need random access
+//
+// Further optimization could be realized by adding an ability
+// to cache the directory in memory. The goal being a single
+// comprehensive file read to put the file I need in a memory.
+*/
+
+/*
+typedef struct unz_file_pos_s
+{
+ ZPOS64_T pos_in_zip_directory; // offset in file
+ ZPOS64_T num_of_file; // # of file
+} unz_file_pos;
+*/
+
+extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos)
+{
+ unz64_s* s;
+
+ if (file==NULL || file_pos==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return UNZ_END_OF_LIST_OF_FILE;
+
+ file_pos->pos_in_zip_directory = s->pos_in_central_dir;
+ file_pos->num_of_file = s->num_file;
+
+ return UNZ_OK;
+}
+
+extern int ZEXPORT unzGetFilePos(
+ unzFile file,
+ unz_file_pos* file_pos)
+{
+ unz64_file_pos file_pos64;
+ int err = unzGetFilePos64(file,&file_pos64);
+ if (err==UNZ_OK)
+ {
+ file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
+ file_pos->num_of_file = (uLong)file_pos64.num_of_file;
+ }
+ return err;
+}
+
+extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
+{
+ unz64_s* s;
+ int err;
+
+ if (file==NULL || file_pos==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+
+ /* jump to the right spot */
+ s->pos_in_central_dir = file_pos->pos_in_zip_directory;
+ s->num_file = file_pos->num_of_file;
+
+ /* set the current file */
+ err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL,0,NULL,0,NULL,0);
+ /* return results */
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+extern int ZEXPORT unzGoToFilePos(
+ unzFile file,
+ unz_file_pos* file_pos)
+{
+ unz64_file_pos file_pos64;
+ if (file_pos == NULL)
+ return UNZ_PARAMERROR;
+
+ file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
+ file_pos64.num_of_file = file_pos->num_of_file;
+ return unzGoToFilePos64(file,&file_pos64);
+}
+
+/*
+// Unzip Helper Functions - should be here?
+///////////////////////////////////////////
+*/
+
+/*
+ Read the local header of the current zipfile
+ Check the coherency of the local header and info in the end of central
+ directory about this file
+ store in *piSizeVar the size of extra info in local header
+ (filename and size of extra field data)
+*/
+local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
+ ZPOS64_T * poffset_local_extrafield,
+ uInt * psize_local_extrafield)
+{
+ uLong uMagic,uData,uFlags;
+ uLong size_filename;
+ uLong size_extra_field;
+ int err=UNZ_OK;
+
+ *piSizeVar = 0;
+ *poffset_local_extrafield = 0;
+ *psize_local_extrafield = 0;
+
+ if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
+ s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return UNZ_ERRNO;
+
+
+ if (err==UNZ_OK)
+ {
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
+ err=UNZ_ERRNO;
+ else if (uMagic!=0x04034b50)
+ err=UNZ_BADZIPFILE;
+ }
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
+ err=UNZ_ERRNO;
+/*
+ else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
+ err=UNZ_BADZIPFILE;
+*/
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
+ err=UNZ_ERRNO;
+ else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
+ err=UNZ_BADZIPFILE;
+
+ if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
+/* #ifdef HAVE_BZIP2 */
+ (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
+/* #endif */
+ (s->cur_file_info.compression_method!=Z_DEFLATED))
+ err=UNZ_BADZIPFILE;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
+ err=UNZ_ERRNO;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
+ err=UNZ_ERRNO;
+ else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
+ err=UNZ_BADZIPFILE;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
+ err=UNZ_ERRNO;
+ else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
+ err=UNZ_BADZIPFILE;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
+ err=UNZ_ERRNO;
+ else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
+ err=UNZ_BADZIPFILE;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
+ err=UNZ_ERRNO;
+ else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
+ err=UNZ_BADZIPFILE;
+
+ *piSizeVar += (uInt)size_filename;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
+ err=UNZ_ERRNO;
+ *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
+ SIZEZIPLOCALHEADER + size_filename;
+ *psize_local_extrafield = (uInt)size_extra_field;
+
+ *piSizeVar += (uInt)size_extra_field;
+
+ return err;
+}
+
+/*
+ Open for reading data the current file in the zipfile.
+ If there is no error and the file is opened, the return value is UNZ_OK.
+*/
+extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
+ int* level, int raw, const char* password)
+{
+ int err=UNZ_OK;
+ uInt iSizeVar;
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ ZPOS64_T offset_local_extrafield; /* offset of the local extra field */
+ uInt size_local_extrafield; /* size of the local extra field */
+# ifndef NOUNCRYPT
+ char source[12];
+# else
+ if (password != NULL)
+ return UNZ_PARAMERROR;
+# endif
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return UNZ_PARAMERROR;
+
+ if (s->pfile_in_zip_read != NULL)
+ unzCloseCurrentFile(file);
+
+ if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
+ return UNZ_BADZIPFILE;
+
+ pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_INTERNALERROR;
+
+ pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
+ pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
+ pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
+ pfile_in_zip_read_info->pos_local_extrafield=0;
+ pfile_in_zip_read_info->raw=raw;
+
+ if (pfile_in_zip_read_info->read_buffer==NULL)
+ {
+ TRYFREE(pfile_in_zip_read_info);
+ return UNZ_INTERNALERROR;
+ }
+
+ pfile_in_zip_read_info->stream_initialised=0;
+
+ if (method!=NULL)
+ *method = (int)s->cur_file_info.compression_method;
+
+ if (level!=NULL)
+ {
+ *level = 6;
+ switch (s->cur_file_info.flag & 0x06)
+ {
+ case 6 : *level = 1; break;
+ case 4 : *level = 2; break;
+ case 2 : *level = 9; break;
+ }
+ }
+
+ if ((s->cur_file_info.compression_method!=0) &&
+/* #ifdef HAVE_BZIP2 */
+ (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
+/* #endif */
+ (s->cur_file_info.compression_method!=Z_DEFLATED))
+
+ err=UNZ_BADZIPFILE;
+
+ pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
+ pfile_in_zip_read_info->crc32=0;
+ pfile_in_zip_read_info->total_out_64=0;
+ pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
+ pfile_in_zip_read_info->filestream=s->filestream;
+ pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
+ pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
+
+ pfile_in_zip_read_info->stream.total_out = 0;
+
+ if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
+ {
+#ifdef HAVE_BZIP2
+ pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
+ pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
+ pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
+ pfile_in_zip_read_info->bstream.state = (voidpf)0;
+
+ pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
+ pfile_in_zip_read_info->stream.zfree = (free_func)0;
+ pfile_in_zip_read_info->stream.opaque = (voidpf)0;
+ pfile_in_zip_read_info->stream.next_in = (voidpf)0;
+ pfile_in_zip_read_info->stream.avail_in = 0;
+
+ err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
+ if (err == Z_OK)
+ pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
+ else
+ {
+ TRYFREE(pfile_in_zip_read_info);
+ return err;
+ }
+#else
+ pfile_in_zip_read_info->raw=1;
+#endif
+ }
+ else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
+ {
+ pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
+ pfile_in_zip_read_info->stream.zfree = (free_func)0;
+ pfile_in_zip_read_info->stream.opaque = (voidpf)0;
+ pfile_in_zip_read_info->stream.next_in = 0;
+ pfile_in_zip_read_info->stream.avail_in = 0;
+
+ err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
+ if (err == Z_OK)
+ pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
+ else
+ {
+ TRYFREE(pfile_in_zip_read_info);
+ return err;
+ }
+ /* windowBits is passed < 0 to tell that there is no zlib header.
+ * Note that in this case inflate *requires* an extra "dummy" byte
+ * after the compressed stream in order to complete decompression and
+ * return Z_STREAM_END.
+ * In unzip, i don't wait absolutely Z_STREAM_END because I known the
+ * size of both compressed and uncompressed data
+ */
+ }
+ pfile_in_zip_read_info->rest_read_compressed =
+ s->cur_file_info.compressed_size ;
+ pfile_in_zip_read_info->rest_read_uncompressed =
+ s->cur_file_info.uncompressed_size ;
+
+
+ pfile_in_zip_read_info->pos_in_zipfile =
+ s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
+ iSizeVar;
+
+ pfile_in_zip_read_info->stream.avail_in = (uInt)0;
+
+ s->pfile_in_zip_read = pfile_in_zip_read_info;
+ s->encrypted = 0;
+
+# ifndef NOUNCRYPT
+ if (password != NULL)
+ {
+ int i;
+ s->pcrc_32_tab = get_crc_table();
+ init_keys(password,s->keys,s->pcrc_32_tab);
+ if (ZSEEK64(s->z_filefunc, s->filestream,
+ s->pfile_in_zip_read->pos_in_zipfile +
+ s->pfile_in_zip_read->byte_before_the_zipfile,
+ SEEK_SET)!=0)
+ return UNZ_INTERNALERROR;
+ if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
+ return UNZ_INTERNALERROR;
+
+ for (i = 0; i<12; i++)
+ zdecode(s->keys,s->pcrc_32_tab,source[i]);
+
+ s->pfile_in_zip_read->pos_in_zipfile+=12;
+ s->encrypted=1;
+ }
+# endif
+
+
+ return UNZ_OK;
+}
+
+extern int ZEXPORT unzOpenCurrentFile (unzFile file)
+{
+ return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
+}
+
+extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password)
+{
+ return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
+}
+
+extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
+{
+ return unzOpenCurrentFile3(file, method, level, raw, NULL);
+}
+
+/** Addition for GDAL : START */
+
+extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
+{
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ s=(unz64_s*)file;
+ if (file==NULL)
+ return 0; //UNZ_PARAMERROR;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+ if (pfile_in_zip_read_info==NULL)
+ return 0; //UNZ_PARAMERROR;
+ return pfile_in_zip_read_info->pos_in_zipfile +
+ pfile_in_zip_read_info->byte_before_the_zipfile;
+}
+
+/** Addition for GDAL : END */
+
+/*
+ Read bytes from the current file.
+ buf contain buffer where data must be copied
+ len the size of buf.
+
+ return the number of byte copied if somes bytes are copied
+ return 0 if the end of file was reached
+ return <0 with error code if there is an error
+ (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
+{
+ int err=UNZ_OK;
+ uInt iRead = 0;
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+
+ if (pfile_in_zip_read_info->read_buffer == NULL)
+ return UNZ_END_OF_LIST_OF_FILE;
+ if (len==0)
+ return 0;
+
+ pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
+
+ pfile_in_zip_read_info->stream.avail_out = (uInt)len;
+
+ if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
+ (!(pfile_in_zip_read_info->raw)))
+ pfile_in_zip_read_info->stream.avail_out =
+ (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
+
+ if ((len>pfile_in_zip_read_info->rest_read_compressed+
+ pfile_in_zip_read_info->stream.avail_in) &&
+ (pfile_in_zip_read_info->raw))
+ pfile_in_zip_read_info->stream.avail_out =
+ (uInt)pfile_in_zip_read_info->rest_read_compressed+
+ pfile_in_zip_read_info->stream.avail_in;
+
+ while (pfile_in_zip_read_info->stream.avail_out>0)
+ {
+ if ((pfile_in_zip_read_info->stream.avail_in==0) &&
+ (pfile_in_zip_read_info->rest_read_compressed>0))
+ {
+ uInt uReadThis = UNZ_BUFSIZE;
+ if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
+ uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
+ if (uReadThis == 0)
+ return UNZ_EOF;
+ if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
+ pfile_in_zip_read_info->filestream,
+ pfile_in_zip_read_info->pos_in_zipfile +
+ pfile_in_zip_read_info->byte_before_the_zipfile,
+ ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return UNZ_ERRNO;
+ if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
+ pfile_in_zip_read_info->filestream,
+ pfile_in_zip_read_info->read_buffer,
+ uReadThis)!=uReadThis)
+ return UNZ_ERRNO;
+
+
+# ifndef NOUNCRYPT
+ if(s->encrypted)
+ {
+ uInt i;
+ for(i=0;i<uReadThis;i++)
+ pfile_in_zip_read_info->read_buffer[i] =
+ zdecode(s->keys,s->pcrc_32_tab,
+ pfile_in_zip_read_info->read_buffer[i]);
+ }
+# endif
+
+
+ pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
+
+ pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
+
+ pfile_in_zip_read_info->stream.next_in =
+ (Bytef*)pfile_in_zip_read_info->read_buffer;
+ pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
+ }
+
+ if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
+ {
+ uInt uDoCopy,i ;
+
+ if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
+ (pfile_in_zip_read_info->rest_read_compressed == 0))
+ return (iRead==0) ? UNZ_EOF : iRead;
+
+ if (pfile_in_zip_read_info->stream.avail_out <
+ pfile_in_zip_read_info->stream.avail_in)
+ uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
+ else
+ uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
+
+ for (i=0;i<uDoCopy;i++)
+ *(pfile_in_zip_read_info->stream.next_out+i) =
+ *(pfile_in_zip_read_info->stream.next_in+i);
+
+ pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
+
+ pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
+ pfile_in_zip_read_info->stream.next_out,
+ uDoCopy);
+ pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
+ pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
+ pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
+ pfile_in_zip_read_info->stream.next_out += uDoCopy;
+ pfile_in_zip_read_info->stream.next_in += uDoCopy;
+ pfile_in_zip_read_info->stream.total_out += uDoCopy;
+ iRead += uDoCopy;
+ }
+ else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
+ {
+#ifdef HAVE_BZIP2
+ uLong uTotalOutBefore,uTotalOutAfter;
+ const Bytef *bufBefore;
+ uLong uOutThis;
+
+ pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in;
+ pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;
+ pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;
+ pfile_in_zip_read_info->bstream.total_in_hi32 = 0;
+ pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out;
+ pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;
+ pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
+ pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
+
+ uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
+ bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
+
+ err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
+
+ uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
+ uOutThis = uTotalOutAfter-uTotalOutBefore;
+
+ pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
+
+ pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
+ pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
+ iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
+
+ pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
+ pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;
+ pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;
+ pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
+ pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
+ pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
+
+ if (err==BZ_STREAM_END)
+ return (iRead==0) ? UNZ_EOF : iRead;
+ if (err!=BZ_OK)
+ break;
+#endif
+ } // end Z_BZIP2ED
+ else
+ {
+ ZPOS64_T uTotalOutBefore,uTotalOutAfter;
+ const Bytef *bufBefore;
+ ZPOS64_T uOutThis;
+ int flush=Z_SYNC_FLUSH;
+
+ uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
+ bufBefore = pfile_in_zip_read_info->stream.next_out;
+
+ /*
+ if ((pfile_in_zip_read_info->rest_read_uncompressed ==
+ pfile_in_zip_read_info->stream.avail_out) &&
+ (pfile_in_zip_read_info->rest_read_compressed == 0))
+ flush = Z_FINISH;
+ */
+ err=inflate(&pfile_in_zip_read_info->stream,flush);
+
+ if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
+ err = Z_DATA_ERROR;
+
+ uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
+ uOutThis = uTotalOutAfter-uTotalOutBefore;
+
+ pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
+
+ pfile_in_zip_read_info->crc32 =
+ crc32(pfile_in_zip_read_info->crc32,bufBefore,
+ (uInt)(uOutThis));
+
+ pfile_in_zip_read_info->rest_read_uncompressed -=
+ uOutThis;
+
+ iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
+
+ if (err==Z_STREAM_END)
+ return (iRead==0) ? UNZ_EOF : iRead;
+ if (err!=Z_OK)
+ break;
+ }
+ }
+
+ if (err==Z_OK)
+ return iRead;
+ return err;
+}
+
+
+/*
+ Give the current position in uncompressed data
+*/
+extern z_off_t ZEXPORT unztell (unzFile file)
+{
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+ return (z_off_t)pfile_in_zip_read_info->stream.total_out;
+}
+
+extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
+{
+
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return (ZPOS64_T)-1;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return (ZPOS64_T)-1;
+
+ return pfile_in_zip_read_info->total_out_64;
+}
+
+
+/*
+ return 1 if the end of file was reached, 0 elsewhere
+*/
+extern int ZEXPORT unzeof (unzFile file)
+{
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+ if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
+ return 1;
+ else
+ return 0;
+}
+
+
+
+/*
+Read extra field from the current file (opened by unzOpenCurrentFile)
+This is the local-header version of the extra field (sometimes, there is
+more info in the local-header version than in the central-header)
+
+ if buf==NULL, it return the size of the local extra field that can be read
+
+ if buf!=NULL, len is the size of the buffer, the extra header is copied in
+ buf.
+ the return value is the number of bytes copied in buf, or (if <0)
+ the error code
+*/
+extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
+{
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ uInt read_now;
+ ZPOS64_T size_to_read;
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+ size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
+ pfile_in_zip_read_info->pos_local_extrafield);
+
+ if (buf==NULL)
+ return (int)size_to_read;
+
+ if (len>size_to_read)
+ read_now = (uInt)size_to_read;
+ else
+ read_now = (uInt)len ;
+
+ if (read_now==0)
+ return 0;
+
+ if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
+ pfile_in_zip_read_info->filestream,
+ pfile_in_zip_read_info->offset_local_extrafield +
+ pfile_in_zip_read_info->pos_local_extrafield,
+ ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return UNZ_ERRNO;
+
+ if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
+ pfile_in_zip_read_info->filestream,
+ buf,read_now)!=read_now)
+ return UNZ_ERRNO;
+
+ return (int)read_now;
+}
+
+/*
+ Close the file in zip opened with unzOpenCurrentFile
+ Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+extern int ZEXPORT unzCloseCurrentFile (unzFile file)
+{
+ int err=UNZ_OK;
+
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+
+ if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
+ (!pfile_in_zip_read_info->raw))
+ {
+ if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
+ err=UNZ_CRCERROR;
+ }
+
+
+ TRYFREE(pfile_in_zip_read_info->read_buffer);
+ pfile_in_zip_read_info->read_buffer = NULL;
+ if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
+ inflateEnd(&pfile_in_zip_read_info->stream);
+#ifdef HAVE_BZIP2
+ else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
+ BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
+#endif
+
+
+ pfile_in_zip_read_info->stream_initialised = 0;
+ TRYFREE(pfile_in_zip_read_info);
+
+ s->pfile_in_zip_read=NULL;
+
+ return err;
+}
+
+
+/*
+ Get the global comment string of the ZipFile, in the szComment buffer.
+ uSizeBuf is the size of the szComment buffer.
+ return the number of byte copied or an error code <0
+*/
+extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
+{
+ unz64_s* s;
+ uLong uReadThis ;
+ if (file==NULL)
+ return (int)UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+
+ uReadThis = uSizeBuf;
+ if (uReadThis>s->gi.size_comment)
+ uReadThis = s->gi.size_comment;
+
+ if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return UNZ_ERRNO;
+
+ if (uReadThis>0)
+ {
+ *szComment='\0';
+ if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
+ return UNZ_ERRNO;
+ }
+
+ if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
+ *(szComment+s->gi.size_comment)='\0';
+ return (int)uReadThis;
+}
+
+/* Additions by RX '2004 */
+extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
+{
+ unz64_s* s;
+
+ if (file==NULL)
+ return 0; //UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return 0;
+ if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
+ if (s->num_file==s->gi.number_entry)
+ return 0;
+ return s->pos_in_central_dir;
+}
+
+extern uLong ZEXPORT unzGetOffset (unzFile file)
+{
+ ZPOS64_T offset64;
+
+ if (file==NULL)
+ return 0; //UNZ_PARAMERROR;
+ offset64 = unzGetOffset64(file);
+ return (uLong)offset64;
+}
+
+extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
+{
+ unz64_s* s;
+ int err;
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+
+ s->pos_in_central_dir = pos;
+ s->num_file = s->gi.number_entry; /* hack */
+ err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL,0,NULL,0,NULL,0);
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
+{
+ return unzSetOffset64(file,pos);
+}
diff --git a/storage/connect/unzip.h b/storage/connect/unzip.h
new file mode 100644
index 00000000000..2104e391507
--- /dev/null
+++ b/storage/connect/unzip.h
@@ -0,0 +1,437 @@
+/* unzip.h -- IO for uncompress .zip files using zlib
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications of Unzip for Zip64
+ Copyright (C) 2007-2008 Even Rouault
+
+ Modifications for Zip64 support on both zip and unzip
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+ ---------------------------------------------------------------------------------
+
+ Condition of use and distribution are the same than zlib :
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ ---------------------------------------------------------------------------------
+
+ Changes
+
+ See header of unzip64.c
+
+*/
+
+#ifndef _unz64_H
+#define _unz64_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#ifndef _ZLIBIOAPI_H
+#include "ioapi.h"
+#endif
+
+#ifdef HAVE_BZIP2
+#include "bzlib.h"
+#endif
+
+#define Z_BZIP2ED 12
+
+#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+ from (void*) without cast */
+typedef struct TagunzFile__ { int unused; } unzFile__;
+typedef unzFile__ *unzFile;
+#else
+typedef voidp unzFile;
+#endif
+
+
+#define UNZ_OK (0)
+#define UNZ_END_OF_LIST_OF_FILE (-100)
+#define UNZ_ERRNO (Z_ERRNO)
+#define UNZ_EOF (0)
+#define UNZ_PARAMERROR (-102)
+#define UNZ_BADZIPFILE (-103)
+#define UNZ_INTERNALERROR (-104)
+#define UNZ_CRCERROR (-105)
+
+/* tm_unz contain date/time info */
+typedef struct tm_unz_s
+{
+ uInt tm_sec; /* seconds after the minute - [0,59] */
+ uInt tm_min; /* minutes after the hour - [0,59] */
+ uInt tm_hour; /* hours since midnight - [0,23] */
+ uInt tm_mday; /* day of the month - [1,31] */
+ uInt tm_mon; /* months since January - [0,11] */
+ uInt tm_year; /* years - [1980..2044] */
+} tm_unz;
+
+/* unz_global_info structure contain global data about the ZIPfile
+ These data comes from the end of central dir */
+typedef struct unz_global_info64_s
+{
+ ZPOS64_T number_entry; /* total number of entries in
+ the central dir on this disk */
+ uLong size_comment; /* size of the global comment of the zipfile */
+} unz_global_info64;
+
+typedef struct unz_global_info_s
+{
+ uLong number_entry; /* total number of entries in
+ the central dir on this disk */
+ uLong size_comment; /* size of the global comment of the zipfile */
+} unz_global_info;
+
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_info64_s
+{
+ uLong version; /* version made by 2 bytes */
+ uLong version_needed; /* version needed to extract 2 bytes */
+ uLong flag; /* general purpose bit flag 2 bytes */
+ uLong compression_method; /* compression method 2 bytes */
+ uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
+ uLong crc; /* crc-32 4 bytes */
+ ZPOS64_T compressed_size; /* compressed size 8 bytes */
+ ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */
+ uLong size_filename; /* filename length 2 bytes */
+ uLong size_file_extra; /* extra field length 2 bytes */
+ uLong size_file_comment; /* file comment length 2 bytes */
+
+ uLong disk_num_start; /* disk number start 2 bytes */
+ uLong internal_fa; /* internal file attributes 2 bytes */
+ uLong external_fa; /* external file attributes 4 bytes */
+
+ tm_unz tmu_date;
+} unz_file_info64;
+
+typedef struct unz_file_info_s
+{
+ uLong version; /* version made by 2 bytes */
+ uLong version_needed; /* version needed to extract 2 bytes */
+ uLong flag; /* general purpose bit flag 2 bytes */
+ uLong compression_method; /* compression method 2 bytes */
+ uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
+ uLong crc; /* crc-32 4 bytes */
+ uLong compressed_size; /* compressed size 4 bytes */
+ uLong uncompressed_size; /* uncompressed size 4 bytes */
+ uLong size_filename; /* filename length 2 bytes */
+ uLong size_file_extra; /* extra field length 2 bytes */
+ uLong size_file_comment; /* file comment length 2 bytes */
+
+ uLong disk_num_start; /* disk number start 2 bytes */
+ uLong internal_fa; /* internal file attributes 2 bytes */
+ uLong external_fa; /* external file attributes 4 bytes */
+
+ tm_unz tmu_date;
+} unz_file_info;
+
+extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
+ const char* fileName2,
+ int iCaseSensitivity));
+/*
+ Compare two filename (fileName1,fileName2).
+ If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+ If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+ or strcasecmp)
+ If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+ (like 1 on Unix, 2 on Windows)
+*/
+
+
+extern unzFile ZEXPORT unzOpen OF((const char *path));
+extern unzFile ZEXPORT unzOpen64 OF((const void *path));
+/*
+ Open a Zip file. path contain the full pathname (by example,
+ on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
+ "zlib/zlib113.zip".
+ If the zipfile cannot be opened (file don't exist or in not valid), the
+ return value is NULL.
+ Else, the return value is a unzFile Handle, usable with other function
+ of this unzip package.
+ the "64" function take a const void* pointer, because the path is just the
+ value passed to the open64_file_func callback.
+ Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path
+ is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char*
+ does not describe the reality
+*/
+
+
+extern unzFile ZEXPORT unzOpen2 OF((const char *path,
+ zlib_filefunc_def* pzlib_filefunc_def));
+/*
+ Open a Zip file, like unzOpen, but provide a set of file low level API
+ for read/write the zip file (see ioapi.h)
+*/
+
+extern unzFile ZEXPORT unzOpen2_64 OF((const void *path,
+ zlib_filefunc64_def* pzlib_filefunc_def));
+/*
+ Open a Zip file, like unz64Open, but provide a set of file low level API
+ for read/write the zip file (see ioapi.h)
+*/
+
+extern int ZEXPORT unzClose OF((unzFile file));
+/*
+ Close a ZipFile opened with unzOpen.
+ If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+ these files MUST be closed with unzCloseCurrentFile before call unzClose.
+ return UNZ_OK if there is no problem. */
+
+extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
+ unz_global_info *pglobal_info));
+
+extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file,
+ unz_global_info64 *pglobal_info));
+/*
+ Write info about the ZipFile in the *pglobal_info structure.
+ No preparation of the structure is needed
+ return UNZ_OK if there is no problem. */
+
+
+extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
+ char *szComment,
+ uLong uSizeBuf));
+/*
+ Get the global comment string of the ZipFile, in the szComment buffer.
+ uSizeBuf is the size of the szComment buffer.
+ return the number of byte copied or an error code <0
+*/
+
+
+/***************************************************************************/
+/* Unzip package allow you browse the directory of the zipfile */
+
+extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
+/*
+ Set the current file of the zipfile to the first file.
+ return UNZ_OK if there is no problem
+*/
+
+extern int ZEXPORT unzGoToNextFile OF((unzFile file));
+/*
+ Set the current file of the zipfile to the next file.
+ return UNZ_OK if there is no problem
+ return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+
+extern int ZEXPORT unzLocateFile OF((unzFile file,
+ const char *szFileName,
+ int iCaseSensitivity));
+/*
+ Try locate the file szFileName in the zipfile.
+ For the iCaseSensitivity signification, see unzStringFileNameCompare
+
+ return value :
+ UNZ_OK if the file is found. It becomes the current file.
+ UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+
+
+/* ****************************************** */
+/* Ryan supplied functions */
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_pos_s
+{
+ uLong pos_in_zip_directory; /* offset in zip file directory */
+ uLong num_of_file; /* # of file */
+} unz_file_pos;
+
+extern int ZEXPORT unzGetFilePos(
+ unzFile file,
+ unz_file_pos* file_pos);
+
+extern int ZEXPORT unzGoToFilePos(
+ unzFile file,
+ unz_file_pos* file_pos);
+
+typedef struct unz64_file_pos_s
+{
+ ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */
+ ZPOS64_T num_of_file; /* # of file */
+} unz64_file_pos;
+
+extern int ZEXPORT unzGetFilePos64(
+ unzFile file,
+ unz64_file_pos* file_pos);
+
+extern int ZEXPORT unzGoToFilePos64(
+ unzFile file,
+ const unz64_file_pos* file_pos);
+
+/* ****************************************** */
+
+extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file,
+ unz_file_info64 *pfile_info,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize));
+
+extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
+ unz_file_info *pfile_info,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize));
+/*
+ Get Info about the current file
+ if pfile_info!=NULL, the *pfile_info structure will contain somes info about
+ the current file
+ if szFileName!=NULL, the filemane string will be copied in szFileName
+ (fileNameBufferSize is the size of the buffer)
+ if extraField!=NULL, the extra field information will be copied in extraField
+ (extraFieldBufferSize is the size of the buffer).
+ This is the Central-header version of the extra field
+ if szComment!=NULL, the comment string of the file will be copied in szComment
+ (commentBufferSize is the size of the buffer)
+*/
+
+
+/** Addition for GDAL : START */
+
+extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));
+
+/** Addition for GDAL : END */
+
+
+/***************************************************************************/
+/* for reading the content of the current zipfile, you can open it, read data
+ from it, and close it (you can close it before reading all the file)
+ */
+
+extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
+/*
+ Open for reading data the current file in the zipfile.
+ If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
+ const char* password));
+/*
+ Open for reading data the current file in the zipfile.
+ password is a crypting password
+ If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
+ int* method,
+ int* level,
+ int raw));
+/*
+ Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+ if raw==1
+ *method will receive method of compression, *level will receive level of
+ compression
+ note : you can set level parameter as NULL (if you did not want known level,
+ but you CANNOT set method parameter as NULL
+*/
+
+extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
+ int* method,
+ int* level,
+ int raw,
+ const char* password));
+/*
+ Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+ if raw==1
+ *method will receive method of compression, *level will receive level of
+ compression
+ note : you can set level parameter as NULL (if you did not want known level,
+ but you CANNOT set method parameter as NULL
+*/
+
+
+extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
+/*
+ Close the file in zip opened with unzOpenCurrentFile
+ Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+
+extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
+ voidp buf,
+ unsigned len));
+/*
+ Read bytes from the current file (opened by unzOpenCurrentFile)
+ buf contain buffer where data must be copied
+ len the size of buf.
+
+ return the number of byte copied if somes bytes are copied
+ return 0 if the end of file was reached
+ return <0 with error code if there is an error
+ (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+
+extern z_off_t ZEXPORT unztell OF((unzFile file));
+
+extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));
+/*
+ Give the current position in uncompressed data
+*/
+
+extern int ZEXPORT unzeof OF((unzFile file));
+/*
+ return 1 if the end of file was reached, 0 elsewhere
+*/
+
+extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
+ voidp buf,
+ unsigned len));
+/*
+ Read extra field from the current file (opened by unzOpenCurrentFile)
+ This is the local-header version of the extra field (sometimes, there is
+ more info in the local-header version than in the central-header)
+
+ if buf==NULL, it return the size of the local extra field
+
+ if buf!=NULL, len is the size of the buffer, the extra header is copied in
+ buf.
+ the return value is the number of bytes copied in buf, or (if <0)
+ the error code
+*/
+
+/***************************************************************************/
+
+/* Get the current file offset */
+extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file);
+extern uLong ZEXPORT unzGetOffset (unzFile file);
+
+/* Set the current file offset */
+extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos);
+extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _unz64_H */
diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp
index 64d0e13e8c4..ced690e77c0 100644
--- a/storage/connect/value.cpp
+++ b/storage/connect/value.cpp
@@ -1,7 +1,7 @@
/************* Value C++ Functions Source Code File (.CPP) *************/
-/* Name: VALUE.CPP Version 2.5 */
+/* Name: VALUE.CPP Version 2.6 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2001-2015 */
+/* (C) Copyright to the author Olivier BERTRAND 2001-2016 */
/* */
/* This file contains the VALUE and derived classes family functions. */
/* These classes contain values of different types. They are used so */
@@ -792,19 +792,29 @@ uchar TYPVAL<uchar>::GetTypedValue(PVBLK blk, int n)
/***********************************************************************/
/* TYPVAL SetBinValue: with bytes extracted from a line. */
+/* Currently only used reading column of binary files. */
/***********************************************************************/
template <class TYPE>
void TYPVAL<TYPE>::SetBinValue(void *p)
- {
- Tval = *(TYPE *)p;
- Null = false;
- } // end of SetBinValue
+{
+#if defined(UNALIGNED_OK)
+ // x86 can cast non-aligned memory directly
+ Tval = *(TYPE *)p;
+#else
+ // Prevent unaligned memory access on MIPS and ArmHF platforms.
+ // Make use of memcpy instead of straight pointer dereferencing.
+ // Currently only used by WriteColumn of binary files.
+ // From original author: Vicentiu Ciorbaru <vicentiu@mariadb.org>
+ memcpy(&Tval, p, sizeof(TYPE));
+#endif
+ Null = false;
+} // end of SetBinValue
/***********************************************************************/
/* GetBinValue: fill a buffer with the internal binary value. */
/* This function checks whether the buffer length is enough and */
/* returns true if not. Actual filling occurs only if go is true. */
-/* Currently used by WriteColumn of binary files. */
+/* Currently only used writing column of binary files. */
/***********************************************************************/
template <class TYPE>
bool TYPVAL<TYPE>::GetBinValue(void *buf, int buflen, bool go)
@@ -819,7 +829,16 @@ bool TYPVAL<TYPE>::GetBinValue(void *buf, int buflen, bool go)
//#endif
if (go)
- *(TYPE *)buf = Tval;
+#if defined(UNALIGNED_OK)
+ // x86 can cast non-aligned memory directly
+ *(TYPE *)buf = Tval;
+#else
+ // Prevent unaligned memory access on MIPS and ArmHF platforms.
+ // Make use of memcpy instead of straight pointer dereferencing.
+ // Currently only used by WriteColumn of binary files.
+ // From original author: Vicentiu Ciorbaru <vicentiu@mariadb.org>
+ memcpy(buf, &Tval, sizeof(TYPE));
+#endif
Null = false;
return false;
diff --git a/storage/connect/value.h b/storage/connect/value.h
index c5a381e89da..a670ade4c28 100644
--- a/storage/connect/value.h
+++ b/storage/connect/value.h
@@ -1,7 +1,7 @@
/**************** Value H Declares Source Code File (.H) ***************/
-/* Name: VALUE.H Version 2.1 */
+/* Name: VALUE.H Version 2.2 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2001-2014 */
+/* (C) Copyright to the author Olivier BERTRAND 2001-2016 */
/* */
/* This file contains the VALUE and derived classes declares. */
/***********************************************************************/
@@ -17,6 +17,13 @@
#include "block.h"
/***********************************************************************/
+/* This should list the processors accepting unaligned numeral values.*/
+/***********************************************************************/
+#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(_M_IA64)
+#define UNALIGNED_OK
+#endif
+
+/***********************************************************************/
/* Types used in some class definitions. */
/***********************************************************************/
enum CONV {CNV_ANY = 0, /* Convert to any type */
@@ -116,27 +123,46 @@ class DllExport VALUE : public BLOCK {
virtual bool Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op);
virtual bool FormatValue(PVAL vp, char *fmt) = 0;
- /**
- Set value from a non-aligned in-memory value in the machine byte order.
- TYPE can be either of:
- - int, short, longlong
- - uint, ushort, ulonglong
- - float, double
- @param - a pointer to a non-aligned value of type TYPE.
- */
- template<typename TYPE>
- void SetValueNonAligned(const char *p)
- {
-#if defined(__i386__) || defined(__x86_64__)
- SetValue(*((TYPE*) p)); // x86 can cast non-aligned memory directly
+ /**
+ Set value from a non-aligned in-memory value in the machine byte order.
+ TYPE can be either of:
+ - int, short, longlong
+ - uint, ushort, ulonglong
+ - float, double
+ @param - a pointer to a non-aligned value of type TYPE.
+ */
+ template<typename TYPE>
+ void SetValueNonAligned(const char *p)
+ {
+#if defined(UNALIGNED_OK)
+ SetValue(*((TYPE*)p)); // x86 can cast non-aligned memory directly
#else
- TYPE tmp; // a slower version for non-x86 platforms
- memcpy(&tmp, p, sizeof(tmp));
- SetValue(tmp);
+ TYPE tmp; // a slower version for non-x86 platforms
+ memcpy(&tmp, p, sizeof(tmp));
+ SetValue(tmp);
#endif
- }
+ } // end of SetValueNonAligned
+
+ /**
+ Get value from a non-aligned in-memory value in the machine byte order.
+ TYPE can be either of:
+ - int, short, longlong
+ - uint, ushort, ulonglong
+ - float, double
+ @params - a pointer to a non-aligned value of type TYPE, the TYPE value.
+ */
+ template<typename TYPE>
+ void GetValueNonAligned(char *p, TYPE n)
+ {
+#if defined(UNALIGNED_OK)
+ *(TYPE *)p = n; // x86 can cast non-aligned memory directly
+#else
+ TYPE tmp = n; // a slower version for non-x86 platforms
+ memcpy(p, &tmp, sizeof(tmp));
+#endif
+ } // end of SetValueNonAligned
- protected:
+protected:
virtual bool SetConstFormat(PGLOBAL, FORMAT&) = 0;
const char *GetXfmt(void);
diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp
index 56312630278..a2cf4e77b80 100755
--- a/storage/connect/xindex.cpp
+++ b/storage/connect/xindex.cpp
@@ -45,7 +45,9 @@
//nclude "array.h"
#include "filamtxt.h"
#include "tabdos.h"
+#if defined(VCT_SUPPORT)
#include "tabvct.h"
+#endif // VCT_SUPPORT
/***********************************************************************/
/* Macro or external routine definition */
@@ -293,9 +295,11 @@ bool XINDEX::AddColumns(void)
return false; // Not applying to static index
else if (IsMul())
return false; // Not done yet for multiple index
- else if (Tbxp->GetAmType() == TYPE_AM_VCT && ((PTDBVCT)Tbxp)->IsSplit())
+#if defined(VCT_SUPPORT)
+ else if (Tbxp->GetAmType() == TYPE_AM_VCT && ((PTDBVCT)Tbxp)->IsSplit())
return false; // This would require to read additional files
- else
+#endif // VCT_SUPPORT
+ else
return true;
} // end of AddColumns
diff --git a/storage/connect/zip.c b/storage/connect/zip.c
new file mode 100644
index 00000000000..ea54853e858
--- /dev/null
+++ b/storage/connect/zip.c
@@ -0,0 +1,2007 @@
+/* zip.c -- IO on .zip files using zlib
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+ Changes
+ Oct-2009 - Mathias Svensson - Remove old C style function prototypes
+ Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
+ Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
+ Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
+ It is used when recreting zip archive with RAW when deleting items from a zip.
+ ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.
+ Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
+ Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
+
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "zlib.h"
+#include "zip.h"
+
+#ifdef STDC
+# include <stddef.h>
+# include <string.h>
+# include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+ extern int errno;
+#else
+# include <errno.h>
+#endif
+
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+#ifndef VERSIONMADEBY
+# define VERSIONMADEBY (0x0) /* platform depedent */
+#endif
+
+#ifndef Z_BUFSIZE
+#define Z_BUFSIZE (64*1024) //(16384)
+#endif
+
+#ifndef Z_MAXFILENAMEINZIP
+#define Z_MAXFILENAMEINZIP (256)
+#endif
+
+#ifndef ALLOC
+# define ALLOC(size) (malloc(size))
+#endif
+#ifndef TRYFREE
+# define TRYFREE(p) {if (p) free(p);}
+#endif
+
+/*
+#define SIZECENTRALDIRITEM (0x2e)
+#define SIZEZIPLOCALHEADER (0x1e)
+*/
+
+/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
+
+
+// NOT sure that this work on ALL platform
+#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
+
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+#ifndef DEF_MEM_LEVEL
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+#endif
+const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
+
+
+#define SIZEDATA_INDATABLOCK (4096-(4*4))
+
+#define LOCALHEADERMAGIC (0x04034b50)
+#define CENTRALHEADERMAGIC (0x02014b50)
+#define ENDHEADERMAGIC (0x06054b50)
+#define ZIP64ENDHEADERMAGIC (0x6064b50)
+#define ZIP64ENDLOCHEADERMAGIC (0x7064b50)
+
+#define FLAG_LOCALHEADER_OFFSET (0x06)
+#define CRC_LOCALHEADER_OFFSET (0x0e)
+
+#define SIZECENTRALHEADER (0x2e) /* 46 */
+
+typedef struct linkedlist_datablock_internal_s
+{
+ struct linkedlist_datablock_internal_s* next_datablock;
+ uLong avail_in_this_block;
+ uLong filled_in_this_block;
+ uLong unused; /* for future use and alignement */
+ unsigned char data[SIZEDATA_INDATABLOCK];
+} linkedlist_datablock_internal;
+
+typedef struct linkedlist_data_s
+{
+ linkedlist_datablock_internal* first_block;
+ linkedlist_datablock_internal* last_block;
+} linkedlist_data;
+
+
+typedef struct
+{
+ z_stream stream; /* zLib stream structure for inflate */
+#ifdef HAVE_BZIP2
+ bz_stream bstream; /* bzLib stream structure for bziped */
+#endif
+
+ int stream_initialised; /* 1 is stream is initialised */
+ uInt pos_in_buffered_data; /* last written byte in buffered_data */
+
+ ZPOS64_T pos_local_header; /* offset of the local header of the file
+ currenty writing */
+ char* central_header; /* central header data for the current file */
+ uLong size_centralExtra;
+ uLong size_centralheader; /* size of the central header for cur file */
+ uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
+ uLong flag; /* flag of the file currently writing */
+
+ int method; /* compression method of file currenty wr.*/
+ int raw; /* 1 for directly writing raw data */
+ Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
+ uLong dosDate;
+ uLong crc32;
+ int encrypt;
+ int zip64; /* Add ZIP64 extened information in the extra field */
+ ZPOS64_T pos_zip64extrainfo;
+ ZPOS64_T totalCompressedData;
+ ZPOS64_T totalUncompressedData;
+#ifndef NOCRYPT
+ unsigned long keys[3]; /* keys defining the pseudo-random sequence */
+ const z_crc_t* pcrc_32_tab;
+ int crypt_header_size;
+#endif
+} curfile64_info;
+
+typedef struct
+{
+ zlib_filefunc64_32_def z_filefunc;
+ voidpf filestream; /* io structore of the zipfile */
+ linkedlist_data central_dir;/* datablock with central dir in construction*/
+ int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
+ curfile64_info ci; /* info on the file curretly writing */
+
+ ZPOS64_T begin_pos; /* position of the beginning of the zipfile */
+ ZPOS64_T add_position_when_writting_offset;
+ ZPOS64_T number_entry;
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+ char *globalcomment;
+#endif
+
+} zip64_internal;
+
+
+#ifndef NOCRYPT
+#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
+#include "crypt.h"
+#endif
+
+local linkedlist_datablock_internal* allocate_new_datablock()
+{
+ linkedlist_datablock_internal* ldi;
+ ldi = (linkedlist_datablock_internal*)
+ ALLOC(sizeof(linkedlist_datablock_internal));
+ if (ldi!=NULL)
+ {
+ ldi->next_datablock = NULL ;
+ ldi->filled_in_this_block = 0 ;
+ ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
+ }
+ return ldi;
+}
+
+local void free_datablock(linkedlist_datablock_internal* ldi)
+{
+ while (ldi!=NULL)
+ {
+ linkedlist_datablock_internal* ldinext = ldi->next_datablock;
+ TRYFREE(ldi);
+ ldi = ldinext;
+ }
+}
+
+local void init_linkedlist(linkedlist_data* ll)
+{
+ ll->first_block = ll->last_block = NULL;
+}
+
+local void free_linkedlist(linkedlist_data* ll)
+{
+ free_datablock(ll->first_block);
+ ll->first_block = ll->last_block = NULL;
+}
+
+
+local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
+{
+ linkedlist_datablock_internal* ldi;
+ const unsigned char* from_copy;
+
+ if (ll==NULL)
+ return ZIP_INTERNALERROR;
+
+ if (ll->last_block == NULL)
+ {
+ ll->first_block = ll->last_block = allocate_new_datablock();
+ if (ll->first_block == NULL)
+ return ZIP_INTERNALERROR;
+ }
+
+ ldi = ll->last_block;
+ from_copy = (unsigned char*)buf;
+
+ while (len>0)
+ {
+ uInt copy_this;
+ uInt i;
+ unsigned char* to_copy;
+
+ if (ldi->avail_in_this_block==0)
+ {
+ ldi->next_datablock = allocate_new_datablock();
+ if (ldi->next_datablock == NULL)
+ return ZIP_INTERNALERROR;
+ ldi = ldi->next_datablock ;
+ ll->last_block = ldi;
+ }
+
+ if (ldi->avail_in_this_block < len)
+ copy_this = (uInt)ldi->avail_in_this_block;
+ else
+ copy_this = (uInt)len;
+
+ to_copy = &(ldi->data[ldi->filled_in_this_block]);
+
+ for (i=0;i<copy_this;i++)
+ *(to_copy+i)=*(from_copy+i);
+
+ ldi->filled_in_this_block += copy_this;
+ ldi->avail_in_this_block -= copy_this;
+ from_copy += copy_this ;
+ len -= copy_this;
+ }
+ return ZIP_OK;
+}
+
+
+
+/****************************************************************************/
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+/* ===========================================================================
+ Inputs a long in LSB order to the given file
+ nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
+*/
+
+local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
+local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
+{
+ unsigned char buf[8];
+ int n;
+ for (n = 0; n < nbByte; n++)
+ {
+ buf[n] = (unsigned char)(x & 0xff);
+ x >>= 8;
+ }
+ if (x != 0)
+ { /* data overflow - hack for ZIP64 (X Roche) */
+ for (n = 0; n < nbByte; n++)
+ {
+ buf[n] = 0xff;
+ }
+ }
+
+ if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
+ return ZIP_ERRNO;
+ else
+ return ZIP_OK;
+}
+
+local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
+local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
+{
+ unsigned char* buf=(unsigned char*)dest;
+ int n;
+ for (n = 0; n < nbByte; n++) {
+ buf[n] = (unsigned char)(x & 0xff);
+ x >>= 8;
+ }
+
+ if (x != 0)
+ { /* data overflow - hack for ZIP64 */
+ for (n = 0; n < nbByte; n++)
+ {
+ buf[n] = 0xff;
+ }
+ }
+}
+
+/****************************************************************************/
+
+
+local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
+{
+ uLong year = (uLong)ptm->tm_year;
+ if (year>=1980)
+ year-=1980;
+ else if (year>=80)
+ year-=80;
+ return
+ (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
+ ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
+}
+
+
+/****************************************************************************/
+
+local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
+
+local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
+{
+ unsigned char c;
+ int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
+ if (err==1)
+ {
+ *pi = (int)c;
+ return ZIP_OK;
+ }
+ else
+ {
+ if (ZERROR64(*pzlib_filefunc_def,filestream))
+ return ZIP_ERRNO;
+ else
+ return ZIP_EOF;
+ }
+}
+
+
+/* ===========================================================================
+ Reads a long in LSB order from the given gz_stream. Sets
+*/
+local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
+
+local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
+{
+ uLong x ;
+ int i = 0;
+ int err;
+
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (uLong)i;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((uLong)i)<<8;
+
+ if (err==ZIP_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
+
+local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
+{
+ uLong x ;
+ int i = 0;
+ int err;
+
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (uLong)i;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((uLong)i)<<8;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((uLong)i)<<16;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((uLong)i)<<24;
+
+ if (err==ZIP_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
+
+
+local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
+{
+ ZPOS64_T x;
+ int i = 0;
+ int err;
+
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (ZPOS64_T)i;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<8;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<16;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<24;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<32;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<40;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<48;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<56;
+
+ if (err==ZIP_OK)
+ *pX = x;
+ else
+ *pX = 0;
+
+ return err;
+}
+
+#ifndef BUFREADCOMMENT
+#define BUFREADCOMMENT (0x400)
+#endif
+/*
+ Locate the Central directory of a zipfile (at the end, just before
+ the global comment)
+*/
+local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
+
+local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
+{
+ unsigned char* buf;
+ ZPOS64_T uSizeFile;
+ ZPOS64_T uBackRead;
+ ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+ ZPOS64_T uPosFound=0;
+
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+ return 0;
+
+
+ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+ if (uMaxBack>uSizeFile)
+ uMaxBack = uSizeFile;
+
+ buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+ if (buf==NULL)
+ return 0;
+
+ uBackRead = 4;
+ while (uBackRead<uMaxBack)
+ {
+ uLong uReadSize;
+ ZPOS64_T uReadPos ;
+ int i;
+ if (uBackRead+BUFREADCOMMENT>uMaxBack)
+ uBackRead = uMaxBack;
+ else
+ uBackRead+=BUFREADCOMMENT;
+ uReadPos = uSizeFile-uBackRead ;
+
+ uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+ (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ break;
+
+ if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+ break;
+
+ for (i=(int)uReadSize-3; (i--)>0;)
+ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+ ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
+ {
+ uPosFound = uReadPos+i;
+ break;
+ }
+
+ if (uPosFound!=0)
+ break;
+ }
+ TRYFREE(buf);
+ return uPosFound;
+}
+
+/*
+Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
+the global comment)
+*/
+local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
+
+local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
+{
+ unsigned char* buf;
+ ZPOS64_T uSizeFile;
+ ZPOS64_T uBackRead;
+ ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+ ZPOS64_T uPosFound=0;
+ uLong uL;
+ ZPOS64_T relativeOffset;
+
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+ return 0;
+
+ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+ if (uMaxBack>uSizeFile)
+ uMaxBack = uSizeFile;
+
+ buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+ if (buf==NULL)
+ return 0;
+
+ uBackRead = 4;
+ while (uBackRead<uMaxBack)
+ {
+ uLong uReadSize;
+ ZPOS64_T uReadPos;
+ int i;
+ if (uBackRead+BUFREADCOMMENT>uMaxBack)
+ uBackRead = uMaxBack;
+ else
+ uBackRead+=BUFREADCOMMENT;
+ uReadPos = uSizeFile-uBackRead ;
+
+ uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+ (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ break;
+
+ if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+ break;
+
+ for (i=(int)uReadSize-3; (i--)>0;)
+ {
+ // Signature "0x07064b50" Zip64 end of central directory locater
+ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
+ {
+ uPosFound = uReadPos+i;
+ break;
+ }
+ }
+
+ if (uPosFound!=0)
+ break;
+ }
+
+ TRYFREE(buf);
+ if (uPosFound == 0)
+ return 0;
+
+ /* Zip64 end of central directory locator */
+ if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return 0;
+
+ /* the signature, already checked */
+ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+ return 0;
+
+ /* number of the disk with the start of the zip64 end of central directory */
+ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+ return 0;
+ if (uL != 0)
+ return 0;
+
+ /* relative offset of the zip64 end of central directory record */
+ if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
+ return 0;
+
+ /* total number of disks */
+ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+ return 0;
+ if (uL != 1)
+ return 0;
+
+ /* Goto Zip64 end of central directory record */
+ if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return 0;
+
+ /* the signature */
+ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+ return 0;
+
+ if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'
+ return 0;
+
+ return relativeOffset;
+}
+
+int LoadCentralDirectoryRecord(zip64_internal* pziinit)
+{
+ int err=ZIP_OK;
+ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+
+ ZPOS64_T size_central_dir; /* size of the central directory */
+ ZPOS64_T offset_central_dir; /* offset of start of central directory */
+ ZPOS64_T central_pos;
+ uLong uL;
+
+ uLong number_disk; /* number of the current dist, used for
+ spaning ZIP, unsupported, always 0*/
+ uLong number_disk_with_CD; /* number the the disk with central dir, used
+ for spaning ZIP, unsupported, always 0*/
+ ZPOS64_T number_entry;
+ ZPOS64_T number_entry_CD; /* total number of entries in
+ the central dir
+ (same than number_entry on nospan) */
+ uLong VersionMadeBy;
+ uLong VersionNeeded;
+ uLong size_comment;
+
+ int hasZIP64Record = 0;
+
+ // check first if we find a ZIP64 record
+ central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
+ if(central_pos > 0)
+ {
+ hasZIP64Record = 1;
+ }
+ else if(central_pos == 0)
+ {
+ central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
+ }
+
+/* disable to allow appending to empty ZIP archive
+ if (central_pos==0)
+ err=ZIP_ERRNO;
+*/
+
+ if(hasZIP64Record)
+ {
+ ZPOS64_T sizeEndOfCentralDirectory;
+ if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
+ err=ZIP_ERRNO;
+
+ /* the signature, already checked */
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* size of zip64 end of central directory record */
+ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* version made by */
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* version needed to extract */
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* number of this disk */
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* number of the disk with the start of the central directory */
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* total number of entries in the central directory on this disk */
+ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* total number of entries in the central directory */
+ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
+ err=ZIP_BADZIPFILE;
+
+ /* size of the central directory */
+ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* offset of start of central directory with respect to the
+ starting disk number */
+ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ // TODO..
+ // read the comment from the standard central header.
+ size_comment = 0;
+ }
+ else
+ {
+ // Read End of central Directory info
+ if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err=ZIP_ERRNO;
+
+ /* the signature, already checked */
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* number of this disk */
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* number of the disk with the start of the central directory */
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* total number of entries in the central dir on this disk */
+ number_entry = 0;
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+ else
+ number_entry = uL;
+
+ /* total number of entries in the central dir */
+ number_entry_CD = 0;
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+ else
+ number_entry_CD = uL;
+
+ if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
+ err=ZIP_BADZIPFILE;
+
+ /* size of the central directory */
+ size_central_dir = 0;
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+ else
+ size_central_dir = uL;
+
+ /* offset of start of central directory with respect to the starting disk number */
+ offset_central_dir = 0;
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+ else
+ offset_central_dir = uL;
+
+
+ /* zipfile global comment length */
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
+ err=ZIP_ERRNO;
+ }
+
+ if ((central_pos<offset_central_dir+size_central_dir) &&
+ (err==ZIP_OK))
+ err=ZIP_BADZIPFILE;
+
+ if (err!=ZIP_OK)
+ {
+ ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
+ return ZIP_ERRNO;
+ }
+
+ if (size_comment>0)
+ {
+ pziinit->globalcomment = (char*)ALLOC(size_comment+1);
+ if (pziinit->globalcomment)
+ {
+ size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
+ pziinit->globalcomment[size_comment]=0;
+ }
+ }
+
+ byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
+ pziinit->add_position_when_writting_offset = byte_before_the_zipfile;
+
+ {
+ ZPOS64_T size_central_dir_to_read = size_central_dir;
+ size_t buf_size = SIZEDATA_INDATABLOCK;
+ void* buf_read = (void*)ALLOC(buf_size);
+ if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
+ err=ZIP_ERRNO;
+
+ while ((size_central_dir_to_read>0) && (err==ZIP_OK))
+ {
+ ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
+ if (read_this > size_central_dir_to_read)
+ read_this = size_central_dir_to_read;
+
+ if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
+ err=ZIP_ERRNO;
+
+ if (err==ZIP_OK)
+ err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
+
+ size_central_dir_to_read-=read_this;
+ }
+ TRYFREE(buf_read);
+ }
+ pziinit->begin_pos = byte_before_the_zipfile;
+ pziinit->number_entry = number_entry_CD;
+
+ if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
+ err=ZIP_ERRNO;
+
+ return err;
+}
+
+
+#endif /* !NO_ADDFILEINEXISTINGZIP*/
+
+
+/************************************************************/
+extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
+{
+ zip64_internal ziinit;
+ zip64_internal* zi;
+ int err=ZIP_OK;
+
+ ziinit.z_filefunc.zseek32_file = NULL;
+ ziinit.z_filefunc.ztell32_file = NULL;
+ if (pzlib_filefunc64_32_def==NULL)
+ fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
+ else
+ ziinit.z_filefunc = *pzlib_filefunc64_32_def;
+
+ ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
+ pathname,
+ (append == APPEND_STATUS_CREATE) ?
+ (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
+ (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
+
+ if (ziinit.filestream == NULL)
+ return NULL;
+
+ if (append == APPEND_STATUS_CREATEAFTER)
+ ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
+
+ ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
+ ziinit.in_opened_file_inzip = 0;
+ ziinit.ci.stream_initialised = 0;
+ ziinit.number_entry = 0;
+ ziinit.add_position_when_writting_offset = 0;
+ init_linkedlist(&(ziinit.central_dir));
+
+
+
+ zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
+ if (zi==NULL)
+ {
+ ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
+ return NULL;
+ }
+
+ /* now we add file in a zipfile */
+# ifndef NO_ADDFILEINEXISTINGZIP
+ ziinit.globalcomment = NULL;
+ if (append == APPEND_STATUS_ADDINZIP)
+ {
+ // Read and Cache Central Directory Records
+ err = LoadCentralDirectoryRecord(&ziinit);
+ }
+
+ if (globalcomment)
+ {
+ *globalcomment = ziinit.globalcomment;
+ }
+# endif /* !NO_ADDFILEINEXISTINGZIP*/
+
+ if (err != ZIP_OK)
+ {
+# ifndef NO_ADDFILEINEXISTINGZIP
+ TRYFREE(ziinit.globalcomment);
+# endif /* !NO_ADDFILEINEXISTINGZIP*/
+ TRYFREE(zi);
+ return NULL;
+ }
+ else
+ {
+ *zi = ziinit;
+ return (zipFile)zi;
+ }
+}
+
+extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
+{
+ if (pzlib_filefunc32_def != NULL)
+ {
+ zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+ fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
+ return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
+ }
+ else
+ return zipOpen3(pathname, append, globalcomment, NULL);
+}
+
+extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
+{
+ if (pzlib_filefunc_def != NULL)
+ {
+ zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+ zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
+ zlib_filefunc64_32_def_fill.ztell32_file = NULL;
+ zlib_filefunc64_32_def_fill.zseek32_file = NULL;
+ return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
+ }
+ else
+ return zipOpen3(pathname, append, globalcomment, NULL);
+}
+
+
+
+extern zipFile ZEXPORT zipOpen (const char* pathname, int append)
+{
+ return zipOpen3((const void*)pathname,append,NULL,NULL);
+}
+
+extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
+{
+ return zipOpen3(pathname,append,NULL,NULL);
+}
+
+int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
+{
+ /* write the local header */
+ int err;
+ uInt size_filename = (uInt)strlen(filename);
+ uInt size_extrafield = size_extrafield_local;
+
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
+
+ if (err==ZIP_OK)
+ {
+ if(zi->ci.zip64)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
+ }
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
+
+ // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
+ if (err==ZIP_OK)
+ {
+ if(zi->ci.zip64)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
+ }
+ if (err==ZIP_OK)
+ {
+ if(zi->ci.zip64)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
+ }
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
+
+ if(zi->ci.zip64)
+ {
+ size_extrafield += 20;
+ }
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
+
+ if ((err==ZIP_OK) && (size_filename > 0))
+ {
+ if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
+ err = ZIP_ERRNO;
+ }
+
+ if ((err==ZIP_OK) && (size_extrafield_local > 0))
+ {
+ if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
+ err = ZIP_ERRNO;
+ }
+
+
+ if ((err==ZIP_OK) && (zi->ci.zip64))
+ {
+ // write the Zip64 extended info
+ short HeaderID = 1;
+ short DataSize = 16;
+ ZPOS64_T CompressedSize = 0;
+ ZPOS64_T UncompressedSize = 0;
+
+ // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
+ zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
+
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);
+
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
+ }
+
+ return err;
+}
+
+/*
+ NOTE.
+ When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
+ before calling this function it can be done with zipRemoveExtraInfoBlock
+
+ It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
+ unnecessary allocations.
+ */
+extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw,
+ int windowBits,int memLevel, int strategy,
+ const char* password, uLong crcForCrypting,
+ uLong versionMadeBy, uLong flagBase, int zip64)
+{
+ zip64_internal* zi;
+ uInt size_filename;
+ uInt size_comment;
+ uInt i;
+ int err = ZIP_OK;
+
+# ifdef NOCRYPT
+ (crcForCrypting);
+ if (password != NULL)
+ return ZIP_PARAMERROR;
+# endif
+
+ if (file == NULL)
+ return ZIP_PARAMERROR;
+
+#ifdef HAVE_BZIP2
+ if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
+ return ZIP_PARAMERROR;
+#else
+ if ((method!=0) && (method!=Z_DEFLATED))
+ return ZIP_PARAMERROR;
+#endif
+
+ zi = (zip64_internal*)file;
+
+ if (zi->in_opened_file_inzip == 1)
+ {
+ err = zipCloseFileInZip (file);
+ if (err != ZIP_OK)
+ return err;
+ }
+
+ if (filename==NULL)
+ filename="-";
+
+ if (comment==NULL)
+ size_comment = 0;
+ else
+ size_comment = (uInt)strlen(comment);
+
+ size_filename = (uInt)strlen(filename);
+
+ if (zipfi == NULL)
+ zi->ci.dosDate = 0;
+ else
+ {
+ if (zipfi->dosDate != 0)
+ zi->ci.dosDate = zipfi->dosDate;
+ else
+ zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
+ }
+
+ zi->ci.flag = flagBase;
+ if ((level==8) || (level==9))
+ zi->ci.flag |= 2;
+ if (level==2)
+ zi->ci.flag |= 4;
+ if (level==1)
+ zi->ci.flag |= 6;
+ if (password != NULL)
+ zi->ci.flag |= 1;
+
+ zi->ci.crc32 = 0;
+ zi->ci.method = method;
+ zi->ci.encrypt = 0;
+ zi->ci.stream_initialised = 0;
+ zi->ci.pos_in_buffered_data = 0;
+ zi->ci.raw = raw;
+ zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
+
+ zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
+ zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
+
+ zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
+
+ zi->ci.size_centralExtra = size_extrafield_global;
+ zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
+ /* version info */
+ zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
+ zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
+ zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
+ zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
+ zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
+
+ if (zipfi==NULL)
+ zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
+ else
+ zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
+
+ if (zipfi==NULL)
+ zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
+ else
+ zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
+
+ if(zi->ci.pos_local_header >= 0xffffffff)
+ zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
+ else
+ zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);
+
+ for (i=0;i<size_filename;i++)
+ *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
+
+ for (i=0;i<size_extrafield_global;i++)
+ *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
+ *(((const char*)extrafield_global)+i);
+
+ for (i=0;i<size_comment;i++)
+ *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
+ size_extrafield_global+i) = *(comment+i);
+ if (zi->ci.central_header == NULL)
+ return ZIP_INTERNALERROR;
+
+ zi->ci.zip64 = zip64;
+ zi->ci.totalCompressedData = 0;
+ zi->ci.totalUncompressedData = 0;
+ zi->ci.pos_zip64extrainfo = 0;
+
+ err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
+
+#ifdef HAVE_BZIP2
+ zi->ci.bstream.avail_in = (uInt)0;
+ zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
+ zi->ci.bstream.total_in_hi32 = 0;
+ zi->ci.bstream.total_in_lo32 = 0;
+ zi->ci.bstream.total_out_hi32 = 0;
+ zi->ci.bstream.total_out_lo32 = 0;
+#endif
+
+ zi->ci.stream.avail_in = (uInt)0;
+ zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.stream.next_out = zi->ci.buffered_data;
+ zi->ci.stream.total_in = 0;
+ zi->ci.stream.total_out = 0;
+ zi->ci.stream.data_type = Z_BINARY;
+
+#ifdef HAVE_BZIP2
+ if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+#else
+ if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+#endif
+ {
+ if(zi->ci.method == Z_DEFLATED)
+ {
+ zi->ci.stream.zalloc = (alloc_func)0;
+ zi->ci.stream.zfree = (free_func)0;
+ zi->ci.stream.opaque = (voidpf)0;
+
+ if (windowBits>0)
+ windowBits = -windowBits;
+
+ err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
+
+ if (err==Z_OK)
+ zi->ci.stream_initialised = Z_DEFLATED;
+ }
+ else if(zi->ci.method == Z_BZIP2ED)
+ {
+#ifdef HAVE_BZIP2
+ // Init BZip stuff here
+ zi->ci.bstream.bzalloc = 0;
+ zi->ci.bstream.bzfree = 0;
+ zi->ci.bstream.opaque = (voidpf)0;
+
+ err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
+ if(err == BZ_OK)
+ zi->ci.stream_initialised = Z_BZIP2ED;
+#endif
+ }
+
+ }
+
+# ifndef NOCRYPT
+ zi->ci.crypt_header_size = 0;
+ if ((err==Z_OK) && (password != NULL))
+ {
+ unsigned char bufHead[RAND_HEAD_LEN];
+ unsigned int sizeHead;
+ zi->ci.encrypt = 1;
+ zi->ci.pcrc_32_tab = get_crc_table();
+ /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
+
+ sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
+ zi->ci.crypt_header_size = sizeHead;
+
+ if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
+ err = ZIP_ERRNO;
+ }
+# endif
+
+ if (err==Z_OK)
+ zi->in_opened_file_inzip = 1;
+ return err;
+}
+
+extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw,
+ int windowBits,int memLevel, int strategy,
+ const char* password, uLong crcForCrypting,
+ uLong versionMadeBy, uLong flagBase)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ windowBits, memLevel, strategy,
+ password, crcForCrypting, versionMadeBy, flagBase, 0);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw,
+ int windowBits,int memLevel, int strategy,
+ const char* password, uLong crcForCrypting)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ windowBits, memLevel, strategy,
+ password, crcForCrypting, VERSIONMADEBY, 0, 0);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw,
+ int windowBits,int memLevel, int strategy,
+ const char* password, uLong crcForCrypting, int zip64)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ windowBits, memLevel, strategy,
+ password, crcForCrypting, VERSIONMADEBY, 0, zip64);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ NULL, 0, VERSIONMADEBY, 0, 0);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw, int zip64)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ NULL, 0, VERSIONMADEBY, 0, zip64);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void*extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int zip64)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, 0,
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ NULL, 0, VERSIONMADEBY, 0, zip64);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void*extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, 0,
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ NULL, 0, VERSIONMADEBY, 0, 0);
+}
+
+local int zip64FlushWriteBuffer(zip64_internal* zi)
+{
+ int err=ZIP_OK;
+
+ if (zi->ci.encrypt != 0)
+ {
+#ifndef NOCRYPT
+ uInt i;
+ int t;
+ for (i=0;i<zi->ci.pos_in_buffered_data;i++)
+ zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
+#endif
+ }
+
+ if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
+ err = ZIP_ERRNO;
+
+ zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
+
+#ifdef HAVE_BZIP2
+ if(zi->ci.method == Z_BZIP2ED)
+ {
+ zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
+ zi->ci.bstream.total_in_lo32 = 0;
+ zi->ci.bstream.total_in_hi32 = 0;
+ }
+ else
+#endif
+ {
+ zi->ci.totalUncompressedData += zi->ci.stream.total_in;
+ zi->ci.stream.total_in = 0;
+ }
+
+
+ zi->ci.pos_in_buffered_data = 0;
+
+ return err;
+}
+
+extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
+{
+ zip64_internal* zi;
+ int err=ZIP_OK;
+
+ if (file == NULL)
+ return ZIP_PARAMERROR;
+ zi = (zip64_internal*)file;
+
+ if (zi->in_opened_file_inzip == 0)
+ return ZIP_PARAMERROR;
+
+ zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
+
+#ifdef HAVE_BZIP2
+ if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
+ {
+ zi->ci.bstream.next_in = (void*)buf;
+ zi->ci.bstream.avail_in = len;
+ err = BZ_RUN_OK;
+
+ while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
+ {
+ if (zi->ci.bstream.avail_out == 0)
+ {
+ if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+ err = ZIP_ERRNO;
+ zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
+ }
+
+
+ if(err != BZ_RUN_OK)
+ break;
+
+ if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+ {
+ uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
+// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
+ err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN);
+
+ zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
+ }
+ }
+
+ if(err == BZ_RUN_OK)
+ err = ZIP_OK;
+ }
+ else
+#endif
+ {
+ zi->ci.stream.next_in = (Bytef*)buf;
+ zi->ci.stream.avail_in = len;
+
+ while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
+ {
+ if (zi->ci.stream.avail_out == 0)
+ {
+ if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+ err = ZIP_ERRNO;
+ zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.stream.next_out = zi->ci.buffered_data;
+ }
+
+
+ if(err != ZIP_OK)
+ break;
+
+ if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+ {
+ uLong uTotalOutBefore = zi->ci.stream.total_out;
+ err=deflate(&zi->ci.stream, Z_NO_FLUSH);
+ if(uTotalOutBefore > zi->ci.stream.total_out)
+ {
+ int bBreak = 0;
+ bBreak++;
+ }
+
+ zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
+ }
+ else
+ {
+ uInt copy_this,i;
+ if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
+ copy_this = zi->ci.stream.avail_in;
+ else
+ copy_this = zi->ci.stream.avail_out;
+
+ for (i = 0; i < copy_this; i++)
+ *(((char*)zi->ci.stream.next_out)+i) =
+ *(((const char*)zi->ci.stream.next_in)+i);
+ {
+ zi->ci.stream.avail_in -= copy_this;
+ zi->ci.stream.avail_out-= copy_this;
+ zi->ci.stream.next_in+= copy_this;
+ zi->ci.stream.next_out+= copy_this;
+ zi->ci.stream.total_in+= copy_this;
+ zi->ci.stream.total_out+= copy_this;
+ zi->ci.pos_in_buffered_data += copy_this;
+ }
+ }
+ }// while(...)
+ }
+
+ return err;
+}
+
+extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
+{
+ return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
+}
+
+extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
+{
+ zip64_internal* zi;
+ ZPOS64_T compressed_size;
+ uLong invalidValue = 0xffffffff;
+ short datasize = 0;
+ int err=ZIP_OK;
+
+ if (file == NULL)
+ return ZIP_PARAMERROR;
+ zi = (zip64_internal*)file;
+
+ if (zi->in_opened_file_inzip == 0)
+ return ZIP_PARAMERROR;
+ zi->ci.stream.avail_in = 0;
+
+ if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+ {
+ while (err==ZIP_OK)
+ {
+ uLong uTotalOutBefore;
+ if (zi->ci.stream.avail_out == 0)
+ {
+ if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+ err = ZIP_ERRNO;
+ zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.stream.next_out = zi->ci.buffered_data;
+ }
+ uTotalOutBefore = zi->ci.stream.total_out;
+ err=deflate(&zi->ci.stream, Z_FINISH);
+ zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
+ }
+ }
+ else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+ {
+#ifdef HAVE_BZIP2
+ err = BZ_FINISH_OK;
+ while (err==BZ_FINISH_OK)
+ {
+ uLong uTotalOutBefore;
+ if (zi->ci.bstream.avail_out == 0)
+ {
+ if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+ err = ZIP_ERRNO;
+ zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
+ }
+ uTotalOutBefore = zi->ci.bstream.total_out_lo32;
+ err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH);
+ if(err == BZ_STREAM_END)
+ err = Z_STREAM_END;
+
+ zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
+ }
+
+ if(err == BZ_FINISH_OK)
+ err = ZIP_OK;
+#endif
+ }
+
+ if (err==Z_STREAM_END)
+ err=ZIP_OK; /* this is normal */
+
+ if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
+ {
+ if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
+ err = ZIP_ERRNO;
+ }
+
+ if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+ {
+ int tmp_err = deflateEnd(&zi->ci.stream);
+ if (err == ZIP_OK)
+ err = tmp_err;
+ zi->ci.stream_initialised = 0;
+ }
+#ifdef HAVE_BZIP2
+ else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+ {
+ int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
+ if (err==ZIP_OK)
+ err = tmperr;
+ zi->ci.stream_initialised = 0;
+ }
+#endif
+
+ if (!zi->ci.raw)
+ {
+ crc32 = (uLong)zi->ci.crc32;
+ uncompressed_size = zi->ci.totalUncompressedData;
+ }
+ compressed_size = zi->ci.totalCompressedData;
+
+# ifndef NOCRYPT
+ compressed_size += zi->ci.crypt_header_size;
+# endif
+
+ // update Current Item crc and sizes,
+ if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
+ {
+ /*version Made by*/
+ zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
+ /*version needed*/
+ zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
+
+ }
+
+ zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
+
+
+ if(compressed_size >= 0xffffffff)
+ zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
+ else
+ zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
+
+ /// set internal file attributes field
+ if (zi->ci.stream.data_type == Z_ASCII)
+ zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
+
+ if(uncompressed_size >= 0xffffffff)
+ zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
+ else
+ zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
+
+ // Add ZIP64 extra info field for uncompressed size
+ if(uncompressed_size >= 0xffffffff)
+ datasize += 8;
+
+ // Add ZIP64 extra info field for compressed size
+ if(compressed_size >= 0xffffffff)
+ datasize += 8;
+
+ // Add ZIP64 extra info field for relative offset to local file header of current file
+ if(zi->ci.pos_local_header >= 0xffffffff)
+ datasize += 8;
+
+ if(datasize > 0)
+ {
+ char* p = NULL;
+
+ if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
+ {
+ // we can not write more data to the buffer that we have room for.
+ return ZIP_BADZIPFILE;
+ }
+
+ p = zi->ci.central_header + zi->ci.size_centralheader;
+
+ // Add Extra Information Header for 'ZIP64 information'
+ zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
+ p += 2;
+ zip64local_putValue_inmemory(p, datasize, 2); // DataSize
+ p += 2;
+
+ if(uncompressed_size >= 0xffffffff)
+ {
+ zip64local_putValue_inmemory(p, uncompressed_size, 8);
+ p += 8;
+ }
+
+ if(compressed_size >= 0xffffffff)
+ {
+ zip64local_putValue_inmemory(p, compressed_size, 8);
+ p += 8;
+ }
+
+ if(zi->ci.pos_local_header >= 0xffffffff)
+ {
+ zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
+ p += 8;
+ }
+
+ // Update how much extra free space we got in the memory buffer
+ // and increase the centralheader size so the new ZIP64 fields are included
+ // ( 4 below is the size of HeaderID and DataSize field )
+ zi->ci.size_centralExtraFree -= datasize + 4;
+ zi->ci.size_centralheader += datasize + 4;
+
+ // Update the extra info size field
+ zi->ci.size_centralExtra += datasize + 4;
+ zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
+ }
+
+ if (err==ZIP_OK)
+ err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
+
+ free(zi->ci.central_header);
+
+ if (err==ZIP_OK)
+ {
+ // Update the LocalFileHeader with the new values.
+
+ ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
+
+ if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err = ZIP_ERRNO;
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
+
+ if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff )
+ {
+ if(zi->ci.pos_zip64extrainfo > 0)
+ {
+ // Update the size in the ZIP64 extended field.
+ if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err = ZIP_ERRNO;
+
+ if (err==ZIP_OK) /* compressed size, unknown */
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
+
+ if (err==ZIP_OK) /* uncompressed size, unknown */
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
+ }
+ else
+ err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal
+ }
+ else
+ {
+ if (err==ZIP_OK) /* compressed size, unknown */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
+
+ if (err==ZIP_OK) /* uncompressed size, unknown */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
+ }
+
+ if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err = ZIP_ERRNO;
+ }
+
+ zi->number_entry ++;
+ zi->in_opened_file_inzip = 0;
+
+ return err;
+}
+
+extern int ZEXPORT zipCloseFileInZip (zipFile file)
+{
+ return zipCloseFileInZipRaw (file,0,0);
+}
+
+int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
+{
+ int err = ZIP_OK;
+ ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
+
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
+
+ /*num disks*/
+ if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
+
+ /*relative offset*/
+ if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
+
+ /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
+ if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
+
+ return err;
+}
+
+int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
+{
+ int err = ZIP_OK;
+
+ uLong Zip64DataSize = 44;
+
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
+
+ if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
+
+ if (err==ZIP_OK) /* version made by */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
+
+ if (err==ZIP_OK) /* version needed */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
+
+ if (err==ZIP_OK) /* number of this disk */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
+
+ if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
+
+ if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
+
+ if (err==ZIP_OK) /* total number of entries in the central dir */
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
+
+ if (err==ZIP_OK) /* size of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
+
+ if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
+ {
+ ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
+ }
+ return err;
+}
+int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
+{
+ int err = ZIP_OK;
+
+ /*signature*/
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
+
+ if (err==ZIP_OK) /* number of this disk */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
+
+ if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
+
+ if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
+ {
+ {
+ if(zi->number_entry >= 0xFFFF)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
+ }
+ }
+
+ if (err==ZIP_OK) /* total number of entries in the central dir */
+ {
+ if(zi->number_entry >= 0xFFFF)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
+ }
+
+ if (err==ZIP_OK) /* size of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
+
+ if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
+ {
+ ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
+ if(pos >= 0xffffffff)
+ {
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
+ }
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
+ }
+
+ return err;
+}
+
+int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
+{
+ int err = ZIP_OK;
+ uInt size_global_comment = 0;
+
+ if(global_comment != NULL)
+ size_global_comment = (uInt)strlen(global_comment);
+
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
+
+ if (err == ZIP_OK && size_global_comment > 0)
+ {
+ if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
+ err = ZIP_ERRNO;
+ }
+ return err;
+}
+
+extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
+{
+ zip64_internal* zi;
+ int err = 0;
+ uLong size_centraldir = 0;
+ ZPOS64_T centraldir_pos_inzip;
+ ZPOS64_T pos;
+
+ if (file == NULL)
+ return ZIP_PARAMERROR;
+
+ zi = (zip64_internal*)file;
+
+ if (zi->in_opened_file_inzip == 1)
+ {
+ err = zipCloseFileInZip (file);
+ }
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+ if (global_comment==NULL)
+ global_comment = zi->globalcomment;
+#endif
+
+ centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
+
+ if (err==ZIP_OK)
+ {
+ linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
+ while (ldi!=NULL)
+ {
+ if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
+ {
+ if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
+ err = ZIP_ERRNO;
+ }
+
+ size_centraldir += ldi->filled_in_this_block;
+ ldi = ldi->next_datablock;
+ }
+ }
+ free_linkedlist(&(zi->central_dir));
+
+ pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
+ if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
+ {
+ ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
+ Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
+
+ Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
+ }
+
+ if (err==ZIP_OK)
+ err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
+
+ if(err == ZIP_OK)
+ err = Write_GlobalComment(zi, global_comment);
+
+ if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)
+ if (err == ZIP_OK)
+ err = ZIP_ERRNO;
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+ TRYFREE(zi->globalcomment);
+#endif
+ TRYFREE(zi);
+
+ return err;
+}
+
+extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
+{
+ char* p = pData;
+ int size = 0;
+ char* pNewHeader;
+ char* pTmp;
+ short header;
+ short dataSize;
+
+ int retVal = ZIP_OK;
+
+ if(pData == NULL || *dataLen < 4)
+ return ZIP_PARAMERROR;
+
+ pNewHeader = (char*)ALLOC(*dataLen);
+ pTmp = pNewHeader;
+
+ while(p < (pData + *dataLen))
+ {
+ header = *(short*)p;
+ dataSize = *(((short*)p)+1);
+
+ if( header == sHeader ) // Header found.
+ {
+ p += dataSize + 4; // skip it. do not copy to temp buffer
+ }
+ else
+ {
+ // Extra Info block should not be removed, So copy it to the temp buffer.
+ memcpy(pTmp, p, dataSize + 4);
+ p += dataSize + 4;
+ size += dataSize + 4;
+ }
+
+ }
+
+ if(size < *dataLen)
+ {
+ // clean old extra info block.
+ memset(pData,0, *dataLen);
+
+ // copy the new extra info block over the old
+ if(size > 0)
+ memcpy(pData, pNewHeader, size);
+
+ // set the new extra info size
+ *dataLen = size;
+
+ retVal = ZIP_OK;
+ }
+ else
+ retVal = ZIP_ERRNO;
+
+ TRYFREE(pNewHeader);
+
+ return retVal;
+}
diff --git a/storage/connect/zip.h b/storage/connect/zip.h
new file mode 100644
index 00000000000..8aaebb62343
--- /dev/null
+++ b/storage/connect/zip.h
@@ -0,0 +1,362 @@
+/* zip.h -- IO on .zip files using zlib
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+ ---------------------------------------------------------------------------
+
+ Condition of use and distribution are the same than zlib :
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ ---------------------------------------------------------------------------
+
+ Changes
+
+ See header of zip.h
+
+*/
+
+#ifndef _zip12_H
+#define _zip12_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//#define HAVE_BZIP2
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#ifndef _ZLIBIOAPI_H
+#include "ioapi.h"
+#endif
+
+#ifdef HAVE_BZIP2
+#include "bzlib.h"
+#endif
+
+#define Z_BZIP2ED 12
+
+#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+ from (void*) without cast */
+typedef struct TagzipFile__ { int unused; } zipFile__;
+typedef zipFile__ *zipFile;
+#else
+typedef voidp zipFile;
+#endif
+
+#define ZIP_OK (0)
+#define ZIP_EOF (0)
+#define ZIP_ERRNO (Z_ERRNO)
+#define ZIP_PARAMERROR (-102)
+#define ZIP_BADZIPFILE (-103)
+#define ZIP_INTERNALERROR (-104)
+
+#ifndef DEF_MEM_LEVEL
+# if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+# else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+# endif
+#endif
+/* default memLevel */
+
+/* tm_zip contain date/time info */
+typedef struct tm_zip_s
+{
+ uInt tm_sec; /* seconds after the minute - [0,59] */
+ uInt tm_min; /* minutes after the hour - [0,59] */
+ uInt tm_hour; /* hours since midnight - [0,23] */
+ uInt tm_mday; /* day of the month - [1,31] */
+ uInt tm_mon; /* months since January - [0,11] */
+ uInt tm_year; /* years - [1980..2044] */
+} tm_zip;
+
+typedef struct
+{
+ tm_zip tmz_date; /* date in understandable format */
+ uLong dosDate; /* if dos_date == 0, tmu_date is used */
+/* uLong flag; */ /* general purpose bit flag 2 bytes */
+
+ uLong internal_fa; /* internal file attributes 2 bytes */
+ uLong external_fa; /* external file attributes 4 bytes */
+} zip_fileinfo;
+
+typedef const char* zipcharpc;
+
+
+#define APPEND_STATUS_CREATE (0)
+#define APPEND_STATUS_CREATEAFTER (1)
+#define APPEND_STATUS_ADDINZIP (2)
+
+extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
+extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append));
+/*
+ Create a zipfile.
+ pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
+ an Unix computer "zlib/zlib113.zip".
+ if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
+ will be created at the end of the file.
+ (useful if the file contain a self extractor code)
+ if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
+ add files in existing zip (be sure you don't add file that doesn't exist)
+ If the zipfile cannot be opened, the return value is NULL.
+ Else, the return value is a zipFile Handle, usable with other function
+ of this zip package.
+*/
+
+/* Note : there is no delete function into a zipfile.
+ If you want delete file into a zipfile, you must open a zipfile, and create another
+ Of couse, you can use RAW reading and writing to copy the file you did not want delte
+*/
+
+extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
+ int append,
+ zipcharpc* globalcomment,
+ zlib_filefunc_def* pzlib_filefunc_def));
+
+extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname,
+ int append,
+ zipcharpc* globalcomment,
+ zlib_filefunc64_def* pzlib_filefunc_def));
+
+extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level));
+
+extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int zip64));
+
+/*
+ Open a file in the ZIP for writing.
+ filename : the filename in zip (if NULL, '-' without quote will be used
+ *zipfi contain supplemental information
+ if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
+ contains the extrafield data the the local header
+ if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
+ contains the extrafield data the the local header
+ if comment != NULL, comment contain the comment string
+ method contain the compression method (0 for store, Z_DEFLATED for deflate)
+ level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
+ zip64 is set to 1 if a zip64 extended information block should be added to the local file header.
+ this MUST be '1' if the uncompressed size is >= 0xffffffff.
+
+*/
+
+
+extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw));
+
+
+extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int zip64));
+/*
+ Same than zipOpenNewFileInZip, except if raw=1, we write raw file
+ */
+
+extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int windowBits,
+ int memLevel,
+ int strategy,
+ const char* password,
+ uLong crcForCrypting));
+
+extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int windowBits,
+ int memLevel,
+ int strategy,
+ const char* password,
+ uLong crcForCrypting,
+ int zip64
+ ));
+
+/*
+ Same than zipOpenNewFileInZip2, except
+ windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
+ password : crypting password (NULL for no crypting)
+ crcForCrypting : crc of file to compress (needed for crypting)
+ */
+
+extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int windowBits,
+ int memLevel,
+ int strategy,
+ const char* password,
+ uLong crcForCrypting,
+ uLong versionMadeBy,
+ uLong flagBase
+ ));
+
+
+extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int windowBits,
+ int memLevel,
+ int strategy,
+ const char* password,
+ uLong crcForCrypting,
+ uLong versionMadeBy,
+ uLong flagBase,
+ int zip64
+ ));
+/*
+ Same than zipOpenNewFileInZip4, except
+ versionMadeBy : value for Version made by field
+ flag : value for flag field (compression level info will be added)
+ */
+
+
+extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
+ const void* buf,
+ unsigned len));
+/*
+ Write data in the zipfile
+*/
+
+extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
+/*
+ Close the current file in the zipfile
+*/
+
+extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
+ uLong uncompressed_size,
+ uLong crc32));
+
+extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file,
+ ZPOS64_T uncompressed_size,
+ uLong crc32));
+
+/*
+ Close the current file in the zipfile, for file opened with
+ parameter raw=1 in zipOpenNewFileInZip2
+ uncompressed_size and crc32 are value for the uncompressed size
+*/
+
+extern int ZEXPORT zipClose OF((zipFile file,
+ const char* global_comment));
+/*
+ Close the zipfile
+*/
+
+
+extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader));
+/*
+ zipRemoveExtraInfoBlock - Added by Mathias Svensson
+
+ Remove extra information block from a extra information data for the local file header or central directory header
+
+ It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode.
+
+ 0x0001 is the signature header for the ZIP64 extra information blocks
+
+ usage.
+ Remove ZIP64 Extra information from a central director extra field data
+ zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001);
+
+ Remove ZIP64 Extra information from a Local File Header extra field data
+ zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001);
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _zip64_H */
diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc
index 7f06aed9ff0..37e7bde61db 100644
--- a/storage/innobase/btr/btr0defragment.cc
+++ b/storage/innobase/btr/btr0defragment.cc
@@ -843,6 +843,6 @@ DECLARE_THREAD(btr_defragment_thread)(
}
}
btr_defragment_shutdown();
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 315c951a9fe..44ea9eae505 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -3181,7 +3181,7 @@ DECLARE_THREAD(buf_resize_thread)(void*)
srv_buf_resize_thread_active = false;
my_thread_end();
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc
index f555875559d..4deee54d97f 100644
--- a/storage/innobase/buf/buf0dblwr.cc
+++ b/storage/innobase/buf/buf0dblwr.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2013, 2017, MariaDB Corporation. 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
@@ -509,8 +509,9 @@ buf_dblwr_init_or_load_pages(
return(err);
}
- } else {
-
+ } else if (memcmp(field_ref_zero, page + FIL_PAGE_LSN, 8)) {
+ /* Each valid page header must contain
+ a nonzero FIL_PAGE_LSN field. */
recv_dblwr.add(page);
}
@@ -544,11 +545,9 @@ buf_dblwr_process(void)
for (recv_dblwr_t::list::iterator i = recv_dblwr.pages.begin();
i != recv_dblwr.pages.end();
++i, ++page_no_dblwr) {
- bool is_compressed = false;
-
- const byte* page = *i;
- ulint page_no = page_get_page_no(page);
- ulint space_id = page_get_space_id(page);
+ byte* page = *i;
+ ulint page_no = page_get_page_no(page);
+ ulint space_id = page_get_space_id(page);
fil_space_t* space = fil_space_get(space_id);
@@ -560,158 +559,130 @@ buf_dblwr_process(void)
fil_space_open_if_needed(space);
+ const page_id_t page_id(space_id, page_no);
+
if (page_no >= space->size) {
- /* Do not report the warning if the tablespace is
- schedule for truncate or was truncated and we have live
- MLOG_TRUNCATE record in redo. */
- bool skip_warning =
- srv_is_tablespace_truncated(space_id)
- || srv_was_tablespace_truncated(space);
-
- if (!skip_warning) {
- ib::warn() << "Page " << page_no_dblwr
- << " in the doublewrite buffer is"
- " not within space bounds: page "
- << page_id_t(space_id, page_no);
+ /* Do not report the warning if the tablespace
+ is scheduled for truncation or was truncated
+ and we have parsed an MLOG_TRUNCATE record. */
+ if (!srv_is_tablespace_truncated(space_id)
+ && !srv_was_tablespace_truncated(space)) {
+ ib::warn() << "A copy of page " << page_id
+ << " in the doublewrite buffer slot "
+ << page_no_dblwr
+ << " is not within space bounds";
}
- } else {
- const page_size_t page_size(space->flags);
- const page_id_t page_id(space_id, page_no);
+ continue;
+ }
- /* We want to ensure that for partial reads the
- unread portion of the page is NUL. */
- memset(read_buf, 0x0, page_size.physical());
+ const page_size_t page_size(space->flags);
+ ut_ad(!buf_page_is_zeroes(page, page_size));
- IORequest request;
+ /* We want to ensure that for partial reads the
+ unread portion of the page is NUL. */
+ memset(read_buf, 0x0, page_size.physical());
- request.dblwr_recover();
+ IORequest request;
- /* Read in the actual page from the file */
- dberr_t err = fil_io(
- request, true,
- page_id, page_size,
- 0, page_size.physical(), read_buf, NULL, NULL);
+ request.dblwr_recover();
- if (err != DB_SUCCESS) {
+ /* Read in the actual page from the file */
+ dberr_t err = fil_io(
+ request, true,
+ page_id, page_size,
+ 0, page_size.physical(), read_buf, NULL, NULL);
- ib::warn()
- << "Double write buffer recovery: "
- << page_id << " read failed with "
- << "error: " << ut_strerr(err);
- }
+ if (err != DB_SUCCESS) {
+ ib::warn()
+ << "Double write buffer recovery: "
+ << page_id << " read failed with "
+ << "error: " << ut_strerr(err);
+ }
- /* Is page compressed ? */
- is_compressed = fil_page_is_compressed_encrypted(read_buf) |
- fil_page_is_compressed(read_buf);
+ const bool is_all_zero = buf_page_is_zeroes(
+ read_buf, page_size);
- /* If page was compressed, decompress it before we
- check checksum. */
- if (is_compressed) {
- fil_decompress_page(NULL, read_buf, UNIV_PAGE_SIZE, NULL, true);
+ if (is_all_zero) {
+ /* We will check if the copy in the
+ doublewrite buffer is valid. If not, we will
+ ignore this page (there should be redo log
+ records to initialize it). */
+ } else {
+ if (fil_page_is_compressed_encrypted(read_buf) ||
+ fil_page_is_compressed(read_buf)) {
+ /* Decompress the page before
+ validating the checksum. */
+ fil_decompress_page(
+ NULL, read_buf, UNIV_PAGE_SIZE,
+ NULL, true);
}
- if (err != DB_SUCCESS) {
- ib::warn()
- << "Double write buffer recovery: "
- << page_id << " read failed with "
- << "error: " << ut_strerr(err);
+ if (fil_space_verify_crypt_checksum(
+ read_buf, page_size)
+ || !buf_page_is_corrupted(
+ true, read_buf, page_size, false)) {
+ /* The page is good; there is no need
+ to consult the doublewrite buffer. */
+ continue;
}
- if (fil_space_verify_crypt_checksum(read_buf, page_size)) {
-
- /* page is encrypted and checksum is OK */
- } else if (buf_page_is_corrupted(
- true, read_buf, page_size,
- fsp_is_checksum_disabled(space_id))) {
-
- ib::warn() << "Database page corruption or"
- << " a failed file read of page "
- << page_id
- << ". Trying to recover it from the"
- << " doublewrite buffer.";
-
- /* Is page compressed ? */
- is_compressed = fil_page_is_compressed_encrypted(page) |
- fil_page_is_compressed(page);
-
- /* If page was compressed, decompress it before we
- check checksum. */
- if (is_compressed) {
- fil_decompress_page(NULL, (byte*)page, UNIV_PAGE_SIZE, NULL, true);
- }
-
- if (fil_space_verify_crypt_checksum(page, page_size)) {
- /* the doublewrite buffer page is encrypted and OK */
- } else if (buf_page_is_corrupted(
- true, page, page_size,
- fsp_is_checksum_disabled(space_id))) {
-
- ib::error() << "Dump of the page:";
-
- buf_page_print(
- read_buf, page_size,
- BUF_PAGE_PRINT_NO_CRASH);
- ib::error() << "Dump of corresponding"
- " page in doublewrite buffer:";
-
- buf_page_print(
- page, page_size,
- BUF_PAGE_PRINT_NO_CRASH);
-
- ib::fatal() << "The page in the"
- " doublewrite buffer is"
- " corrupt. Cannot continue"
- " operation. You can try to"
- " recover the database with"
- " innodb_force_recovery=6";
- }
- } else if (buf_page_is_zeroes(read_buf, page_size)
- && !buf_page_is_zeroes(page, page_size)
- && !buf_page_is_corrupted(
- true, page, page_size,
- fsp_is_checksum_disabled(space_id))) {
-
- /* Database page contained only zeroes, while
- a valid copy is available in dblwr buffer. */
-
- } else {
-
- bool t1 = buf_page_is_zeroes(
- read_buf, page_size);
-
- bool t2 = buf_page_is_zeroes(page, page_size);
-
- bool t3 = buf_page_is_corrupted(
- true, page, page_size,
- fsp_is_checksum_disabled(space_id));
+ /* We intentionally skip this message for
+ is_all_zero pages. */
+ ib::info()
+ << "Trying to recover page " << page_id
+ << " from the doublewrite buffer.";
+ }
- if (t1 && !(t2 || t3)) {
+ /* Next, validate the doublewrite page. */
+ if (fil_page_is_compressed_encrypted(page) ||
+ fil_page_is_compressed(page)) {
+ /* Decompress the page before
+ validating the checksum. */
+ fil_decompress_page(
+ NULL, page, UNIV_PAGE_SIZE, NULL, true);
+ }
- /* Database page contained only
- zeroes, while a valid copy is
- available in dblwr buffer. */
+ if (!fil_space_verify_crypt_checksum(page, page_size)
+ && buf_page_is_corrupted(true, page, page_size, false)) {
+ if (!is_all_zero) {
+ ib::warn() << "A doublewrite copy of page "
+ << page_id << " is corrupted.";
+ }
+ /* Theoretically we could have another good
+ copy for this page in the doublewrite
+ buffer. If not, we will report a fatal error
+ for a corrupted page somewhere else if that
+ page was truly needed. */
+ continue;
+ }
- } else {
- continue;
- }
+ if (page_no == 0) {
+ /* Check the FSP_SPACE_FLAGS. */
+ ulint flags = fsp_header_get_flags(page);
+ if (!fsp_flags_is_valid(flags)
+ && fsp_flags_convert_from_101(flags)
+ == ULINT_UNDEFINED) {
+ ib::warn() << "Ignoring a doublewrite copy"
+ " of page " << page_id
+ << " due to invalid flags "
+ << ib::hex(flags);
+ continue;
}
+ /* The flags on the page should be converted later. */
+ }
- IORequest write_request(IORequest::WRITE);
+ /* Write the good page from the doublewrite buffer to
+ the intended position. */
- /* Write the good page from the doublewrite
- buffer to the intended position. */
+ IORequest write_request(IORequest::WRITE);
- fil_io(write_request, true,
- page_id, page_size,
- 0, page_size.physical(),
- const_cast<byte*>(page), NULL, NULL);
+ fil_io(write_request, true, page_id, page_size,
+ 0, page_size.physical(),
+ const_cast<byte*>(page), NULL, NULL);
- ib::info()
- << "Recovered page "
- << page_id
- << " from the doublewrite buffer.";
- }
+ ib::info() << "Recovered page " << page_id
+ << " from the doublewrite buffer.";
}
recv_dblwr.pages.clear();
diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc
index af68fd2af32..19290e73ca4 100644
--- a/storage/innobase/buf/buf0dump.cc
+++ b/storage/innobase/buf/buf0dump.cc
@@ -820,7 +820,7 @@ DECLARE_THREAD(buf_dump_thread)(void*)
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index 2738fbd0ec7..da25afc0663 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -3487,7 +3487,7 @@ thread_exit:
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
@@ -3538,7 +3538,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_worker)(
my_thread_end();
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
diff --git a/storage/innobase/buf/buf0mtflu.cc b/storage/innobase/buf/buf0mtflu.cc
index 7c15b12950e..4bf6d2116f1 100644
--- a/storage/innobase/buf/buf0mtflu.cc
+++ b/storage/innobase/buf/buf0mtflu.cc
@@ -383,7 +383,7 @@ DECLARE_THREAD(mtflush_io_thread)(void* arg)
}
}
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 3cf236e643b..73c7bf027ca 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -7236,56 +7236,6 @@ dict_index_zip_pad_optimal_page_size(
return(ut_max(sz, min_sz));
}
-/** Convert a 32 bit integer table flags to the 32 bit FSP Flags.
-Fsp Flags are written into the tablespace header at the offset
-FSP_SPACE_FLAGS and are also stored in the fil_space_t::flags field.
-The following chart shows the translation of the low order bit.
-Other bits are the same.
- Low order bit
- | REDUNDANT | COMPACT | COMPRESSED | DYNAMIC
-dict_table_t::flags | 0 | 1 | 1 | 1
-fil_space_t::flags | 0 | 0 | 1 | 1
-@param[in] table_flags dict_table_t::flags
-@return tablespace flags (fil_space_t::flags) */
-ulint
-dict_tf_to_fsp_flags(ulint table_flags)
-{
- DBUG_EXECUTE_IF("dict_tf_to_fsp_flags_failure",
- return(ULINT_UNDEFINED););
-
- bool has_atomic_blobs =
- DICT_TF_HAS_ATOMIC_BLOBS(table_flags);
- page_size_t page_size = dict_tf_get_page_size(table_flags);
- bool has_data_dir = DICT_TF_HAS_DATA_DIR(table_flags);
- bool page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags);
- ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags);
-
- ut_ad(!page_size.is_compressed() || has_atomic_blobs);
-
- ulint fsp_flags = fsp_flags_init(page_size,
- has_atomic_blobs,
- has_data_dir,
- 0,
- 0,
- 0);
-
- /* In addition, tablespace flags also contain if the page
- compression is used for this table. */
- if (page_compression) {
- fsp_flags |= FSP_FLAGS_SET_PAGE_COMPRESSION(fsp_flags, page_compression);
- }
-
- /* In addition, tablespace flags also contain page compression level
- if page compression is used for this table. */
- if (page_compression && page_compression_level) {
- fsp_flags |= FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(fsp_flags, page_compression_level);
- }
-
- ut_ad(fsp_flags_is_valid(fsp_flags));
-
- return(fsp_flags);
-}
-
/*************************************************************//**
Convert table flag to row format string.
@return row format name. */
diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc
index 756e1010d66..db14983cd8f 100644
--- a/storage/innobase/dict/dict0load.cc
+++ b/storage/innobase/dict/dict0load.cc
@@ -1215,7 +1215,7 @@ dict_check_sys_tables(
look to see if it is already in the tablespace cache. */
if (fil_space_for_table_exists_in_mem(
space_id, table_name.m_name,
- false, true, NULL, 0, NULL)) {
+ false, true, NULL, 0, NULL, flags)) {
/* Recovery can open a datafile that does not
match SYS_DATAFILES. If they don't match, update
SYS_DATAFILES. */
@@ -1239,15 +1239,13 @@ dict_check_sys_tables(
char* filepath = dict_get_first_path(space_id);
/* Check that the .ibd file exists. */
- ulint fsp_flags = dict_tf_to_fsp_flags(flags);
validate = true; /* Encryption */
dberr_t err = fil_ibd_open(
validate,
!srv_read_only_mode && srv_log_file_size != 0,
FIL_TYPE_TABLESPACE,
- space_id,
- fsp_flags,
+ space_id, dict_tf_to_fsp_flags(flags),
table_name.m_name,
filepath,
NULL);
@@ -2628,7 +2626,7 @@ dict_load_tablespace(
/* The tablespace may already be open. */
if (fil_space_for_table_exists_in_mem(
table->space, space_name, false,
- true, heap, table->id, table)) {
+ true, heap, table->id, table, table->flags)) {
return;
}
@@ -2657,10 +2655,10 @@ dict_load_tablespace(
/* Try to open the tablespace. We set the 2nd param (fix_dict) to
false because we do not have an x-lock on dict_operation_lock */
- ulint fsp_flags = dict_tf_to_fsp_flags(table->flags);
dberr_t err = fil_ibd_open(
true, false, FIL_TYPE_TABLESPACE, table->space,
- fsp_flags, space_name, filepath, table);
+ dict_tf_to_fsp_flags(table->flags),
+ space_name, filepath, table);
if (err != DB_SUCCESS) {
/* We failed to find a sensible tablespace file */
diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc
index 87502ef130c..44edb9442dd 100644
--- a/storage/innobase/dict/dict0stats.cc
+++ b/storage/innobase/dict/dict0stats.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2009, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2009, 2016, 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
@@ -1150,7 +1150,8 @@ dict_stats_analyze_index_level(
them away) which brings non-determinism. We skip only
leaf-level delete marks because delete marks on
non-leaf level do not make sense. */
- if (level == 0 &&
+
+ if (level == 0 && srv_stats_include_delete_marked? 0:
rec_get_deleted_flag(
rec,
page_is_comp(btr_pcur_get_page(&pcur)))) {
@@ -1332,8 +1333,12 @@ enum page_scan_method_t {
the given page and count the number of
distinct ones, also ignore delete marked
records */
- QUIT_ON_FIRST_NON_BORING/* quit when the first record that differs
+ QUIT_ON_FIRST_NON_BORING,/* quit when the first record that differs
from its right neighbor is found */
+ COUNT_ALL_NON_BORING_INCLUDE_DEL_MARKED/* scan all records on
+ the given page and count the number of
+ distinct ones, include delete marked
+ records */
};
/* @} */
@@ -1606,6 +1611,8 @@ dict_stats_analyze_index_below_cur(
offsets_rec = dict_stats_scan_page(
&rec, offsets1, offsets2, index, page, n_prefix,
+ srv_stats_include_delete_marked ?
+ COUNT_ALL_NON_BORING_INCLUDE_DEL_MARKED:
COUNT_ALL_NON_BORING_AND_SKIP_DEL_MARKED, n_diff,
n_external_pages);
diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc
index 827e206b738..8a05a8e3fea 100644
--- a/storage/innobase/dict/dict0stats_bg.cc
+++ b/storage/innobase/dict/dict0stats_bg.cc
@@ -448,7 +448,7 @@ DECLARE_THREAD(dict_stats_thread)(void*)
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit instead of return(). */
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index c5bae8a2b85..bb592accdf9 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -2294,7 +2294,7 @@ DECLARE_THREAD(fil_crypt_thread)(
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 3070badd6db..0e28c1d68aa 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -585,11 +585,6 @@ fil_node_open_file(
{
os_offset_t size_bytes;
bool success;
- byte* buf2;
- byte* page;
- ulint flags;
- ulint min_size;
- ulint space_id;
bool read_only_mode;
fil_space_t* space = node->space;
@@ -635,95 +630,80 @@ retry:
ut_a(size_bytes != (os_offset_t) -1);
ut_a(space->purpose != FIL_TYPE_LOG);
+ const page_size_t page_size(space->flags);
+ const ulint psize = page_size.physical();
+ const ulint min_size = FIL_IBD_FILE_INITIAL_SIZE
+ * psize;
+
+ if (size_bytes < min_size) {
+ ib::error() << "The size of the file " << node->name
+ << " is only " << size_bytes
+ << " bytes, should be at least " << min_size;
+ os_file_close(node->handle);
+ return(false);
+ }
/* Read the first page of the tablespace */
- buf2 = static_cast<byte*>(ut_malloc_nokey(2 * UNIV_PAGE_SIZE));
+ byte* buf2 = static_cast<byte*>(ut_malloc_nokey(2 * psize));
/* Align the memory for file i/o if we might have O_DIRECT
set */
- page = static_cast<byte*>(ut_align(buf2, UNIV_PAGE_SIZE));
- ut_ad(page == page_align(page));
+ byte* page = static_cast<byte*>(ut_align(buf2, psize));
IORequest request(IORequest::READ);
success = os_file_read(
request,
- node->handle, page, 0, UNIV_PAGE_SIZE);
+ node->handle, page, 0, psize);
srv_stats.page0_read.add(1);
- space_id = fsp_header_get_space_id(page);
- flags = fsp_header_get_flags(page);
-
- /* Close the file now that we have read the space id from it */
-
+ const ulint space_id
+ = fsp_header_get_space_id(page);
+ ulint flags = fsp_header_get_flags(page);
+ const ulint size = fsp_header_get_field(
+ page, FSP_SIZE);
+ const ulint free_limit = fsp_header_get_field(
+ page, FSP_FREE_LIMIT);
+ const ulint free_len = flst_get_len(
+ FSP_HEADER_OFFSET + FSP_FREE + page);
+ ut_free(buf2);
os_file_close(node->handle);
- const page_size_t page_size(space->flags);
-
- min_size = FIL_IBD_FILE_INITIAL_SIZE * page_size.physical();
-
- if (size_bytes < min_size) {
-
- ib::error() << "The size of tablespace " << space_id << " file "
- << node->name << " is only " << size_bytes
- << ", should be at least " << min_size << "!";
-
- ut_error;
- }
-
- if (space->flags != flags) {
- ulint sflags = (space->flags & ~FSP_FLAGS_MASK_DATA_DIR);
- ulint fflags = (flags & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE);
-
- /* DATA_DIR option is on different place on MariaDB
- compared to MySQL. If this is the difference. Fix
- it. */
-
- if (sflags == fflags) {
- ib::warn()
- << "Tablespace " << space_id
- << " flags " << space->flags
- << " in the data dictionary but in file " << node->name
- << " are " << flags
- << ". Temporally corrected because DATA_DIR option to "
- << space->flags;
-
- flags = space->flags;
- } else {
- ib::fatal()
- << "Table flags are "
- << ib::hex(space->flags) << " in the data"
- " dictionary but the flags in file "
- << node->name << " are " << ib::hex(flags)
- << "!";
+ if (!fsp_flags_is_valid(flags)) {
+ ulint cflags = fsp_flags_convert_from_101(flags);
+ if (cflags == ULINT_UNDEFINED) {
+ ib::error()
+ << "Expected tablespace flags "
+ << ib::hex(flags)
+ << " but found " << ib::hex(flags)
+ << " in the file " << node->name;
+ return(false);
}
- }
+ flags = cflags;
+ }
- {
- ulint size = fsp_header_get_field(
- page, FSP_SIZE);
- ulint free_limit = fsp_header_get_field(
- page, FSP_FREE_LIMIT);
- ulint free_len = flst_get_len(
- FSP_HEADER_OFFSET + FSP_FREE + page);
-
- ut_ad(space->free_limit == 0
- || space->free_limit == free_limit);
- ut_ad(space->free_len == 0
- || space->free_len == free_len);
- space->size_in_header = size;
- space->free_limit = free_limit;
- space->free_len = free_len;
+ if (UNIV_UNLIKELY(space_id != space->id)) {
+ ib::error()
+ << "Expected tablespace id " << space->id
+ << " but found " << space_id
+ << "in the file" << node->name;
+ return(false);
}
- ut_free(buf2);
+ ut_ad(space->free_limit == 0
+ || space->free_limit == free_limit);
+ ut_ad(space->free_len == 0
+ || space->free_len == free_len);
+ space->size_in_header = size;
+ space->free_limit = free_limit;
+ space->free_len = free_len;
if (node->size == 0) {
ulint extent_size;
- extent_size = page_size.physical() * FSP_EXTENT_SIZE;
+ extent_size = psize * FSP_EXTENT_SIZE;
/* After apply-incremental, tablespaces are not extended
to a whole megabyte. Do not cut off valid data. */
@@ -734,9 +714,7 @@ retry:
extent_size);
}
- node->size = (ulint)
- (size_bytes / page_size.physical());
-
+ node->size = size_bytes / psize;
space->size += node->size;
}
}
@@ -1575,7 +1553,7 @@ fil_space_create(
fil_space_t* space;
ut_ad(fil_system);
- ut_ad(fsp_flags_is_valid(flags));
+ ut_ad(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK));
ut_ad(srv_page_size == UNIV_PAGE_SIZE_ORIG || flags != 0);
DBUG_EXECUTE_IF("fil_space_create_failure", return(NULL););
@@ -2344,6 +2322,7 @@ fil_op_write_log(
ulint len;
ut_ad(first_page_no == 0);
+ ut_ad(fsp_flags_is_valid(flags));
/* fil_name_parse() requires that there be at least one path
separator and that the file path end with ".ibd". */
@@ -2564,7 +2543,7 @@ fil_recreate_tablespace(
/* Align the memory for file i/o */
page = static_cast<byte*>(ut_align(buf, UNIV_PAGE_SIZE));
- flags = fsp_flags_set_page_size(flags, univ_page_size);
+ flags |= FSP_FLAGS_PAGE_SSIZE();
fsp_header_init_fields(page, space_id, flags);
@@ -2640,13 +2619,11 @@ fil_recreate_tablespace(
byte* page = buf_block_get_frame(block);
- if (!fsp_flags_is_compressed(flags)) {
-
+ if (!FSP_FLAGS_GET_ZIP_SSIZE(flags)) {
ut_ad(!page_size.is_compressed());
buf_flush_init_for_writing(
- block, page, NULL, recv_lsn,
- fsp_is_checksum_disabled(space_id));
+ block, page, NULL, recv_lsn, false);
err = fil_write(cur_page_id, page_size, 0,
page_size.physical(), page);
@@ -3699,7 +3676,7 @@ fil_ibd_create(
byte* buf2;
byte* page;
bool success;
- bool has_data_dir = FSP_FLAGS_HAS_DATA_DIR(flags);
+ bool has_data_dir = FSP_FLAGS_HAS_DATA_DIR(flags) != 0;
fil_space_t* space = NULL;
fil_space_crypt_t *crypt_data = NULL;
@@ -3707,7 +3684,7 @@ fil_ibd_create(
ut_ad(!srv_read_only_mode);
ut_a(space_id < SRV_LOG_SPACE_FIRST_ID);
ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE);
- ut_a(fsp_flags_is_valid(flags));
+ ut_a(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK));
/* Create the subdirectories in the path, if they are
not there already. */
@@ -3809,10 +3786,7 @@ fil_ibd_create(
memset(page, '\0', UNIV_PAGE_SIZE);
- /* Add the UNIV_PAGE_SIZE to the table flags and write them to the
- tablespace header. */
- flags = fsp_flags_set_page_size(flags, univ_page_size);
-
+ flags |= FSP_FLAGS_PAGE_SSIZE();
fsp_header_init_fields(page, space_id, flags);
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, space_id);
@@ -3889,7 +3863,7 @@ fil_ibd_create(
}
space = fil_space_create(name, space_id, flags, FIL_TYPE_TABLESPACE,
- crypt_data, true);
+ crypt_data, true);
if (!fil_node_create_low(path, size, space, false, true)) {
if (crypt_data) {
@@ -3901,20 +3875,23 @@ fil_ibd_create(
mtr_t mtr;
const fil_node_t* file = UT_LIST_GET_FIRST(space->chain);
- mtr_start(&mtr);
+ mtr.start();
fil_op_write_log(
MLOG_FILE_CREATE2, space_id, 0, file->name,
- NULL, space->flags, &mtr);
+ NULL, space->flags & ~FSP_FLAGS_MEM_MASK, &mtr);
fil_name_write(space, 0, file, &mtr);
- mtr_commit(&mtr);
+ mtr.commit();
+
err = DB_SUCCESS;
}
os_file_close(file);
+
if (err != DB_SUCCESS) {
if (has_data_dir) {
RemoteDatafile::delete_link_file(name);
}
+
os_file_delete(innodb_data_file_key, path);
}
@@ -3945,7 +3922,7 @@ statement to update the dictionary tables if they are incorrect.
@param[in] fix_dict true if the dictionary is available to be fixed
@param[in] purpose FIL_TYPE_TABLESPACE or FIL_TYPE_TEMPORARY
@param[in] id tablespace ID
-@param[in] flags tablespace flags
+@param[in] flags expected FSP_SPACE_FLAGS
@param[in] space_name tablespace name of the datafile
If file-per-table, it is the table name in the databasename/tablename format
@param[in] path_in expected filepath, usually read from dictionary
@@ -3970,7 +3947,6 @@ fil_ibd_open(
RemoteDatafile df_remote; /* remote location */
ulint tablespaces_found = 0;
ulint valid_tablespaces_found = 0;
- bool for_import = (purpose == FIL_TYPE_IMPORT);
ut_ad(!fix_dict || rw_lock_own(dict_operation_lock, RW_LOCK_X));
@@ -3979,10 +3955,13 @@ fil_ibd_open(
ut_ad(!fix_dict || srv_log_file_size != 0);
ut_ad(fil_type_is_data(purpose));
- if (!fsp_flags_is_valid(flags)) {
+ /* Table flags can be ULINT_UNDEFINED if
+ dict_tf_to_fsp_flags_failure is set. */
+ if (flags == ULINT_UNDEFINED) {
return(DB_CORRUPTION);
}
+ ut_ad(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK));
df_default.init(space_name, flags);
df_dict.init(space_name, flags);
df_remote.init(space_name, flags);
@@ -4075,16 +4054,13 @@ fil_ibd_open(
/* Read and validate the first page of these three tablespace
locations, if found. */
valid_tablespaces_found +=
- (df_remote.validate_to_dd(id, flags, for_import)
- == DB_SUCCESS) ? 1 : 0;
+ (df_remote.validate_to_dd(id, flags) == DB_SUCCESS);
valid_tablespaces_found +=
- (df_default.validate_to_dd(id, flags, for_import)
- == DB_SUCCESS) ? 1 : 0;
+ (df_default.validate_to_dd(id, flags) == DB_SUCCESS);
valid_tablespaces_found +=
- (df_dict.validate_to_dd(id, flags, for_import)
- == DB_SUCCESS) ? 1 : 0;
+ (df_dict.validate_to_dd(id, flags) == DB_SUCCESS);
/* Make sense of these three possible locations.
First, bail out if no tablespace files were found. */
@@ -4095,7 +4071,7 @@ fil_ibd_open(
return(DB_CORRUPTION);
}
if (!validate) {
- return(DB_SUCCESS);
+ goto skip_validate;
}
/* Do not open any tablespaces if more than one tablespace with
@@ -4256,6 +4232,10 @@ skip_validate:
true) == NULL) {
err = DB_ERROR;
}
+
+ if (purpose != FIL_TYPE_IMPORT && !srv_read_only_mode) {
+ fsp_flags_try_adjust(id, flags & ~FSP_FLAGS_MEM_MASK);
+ }
}
return(err);
@@ -4547,8 +4527,16 @@ fil_ibd_load(
ut_ad(space == NULL);
+ /* Adjust the memory-based flags that would normally be set by
+ dict_tf_to_fsp_flags(). In recovery, we have no data dictionary. */
+ ulint flags = file.flags();
+ if (FSP_FLAGS_HAS_PAGE_COMPRESSION(flags)) {
+ flags |= page_zip_level
+ << FSP_FLAGS_MEM_COMPRESSION_LEVEL;
+ }
+
space = fil_space_create(
- file.name(), space_id, file.flags(), FIL_TYPE_TABLESPACE,
+ file.name(), space_id, flags, FIL_TYPE_TABLESPACE,
file.get_crypt_info(), false);
if (space == NULL) {
@@ -4620,7 +4608,41 @@ fil_report_missing_tablespace(
" you deleted or moved .ibd files?";
}
-/** Returns true if a matching tablespace exists in the InnoDB tablespace
+/** Try to adjust FSP_SPACE_FLAGS if they differ from the expectations.
+(Typically when upgrading from MariaDB 10.1.0..10.1.20.)
+@param[in] space_id tablespace ID
+@param[in] flags desired tablespace flags */
+UNIV_INTERN
+void
+fsp_flags_try_adjust(ulint space_id, ulint flags)
+{
+ ut_ad(!srv_read_only_mode);
+ ut_ad(fsp_flags_is_valid(flags));
+
+ mtr_t mtr;
+ mtr_start(&mtr);
+ if (buf_block_t* b = buf_page_get(
+ page_id_t(space_id, 0), page_size_t(flags),
+ RW_X_LATCH, &mtr)) {
+ ulint f = fsp_header_get_flags(b->frame);
+ /* Suppress the message if only the DATA_DIR flag to differs. */
+ if ((f ^ flags) & ~(1U << FSP_FLAGS_POS_RESERVED)) {
+ ib::warn()
+ << "adjusting FSP_SPACE_FLAGS of tablespace "
+ << space_id
+ << " from " << ib::hex(f)
+ << " to " << ib::hex(flags);
+ }
+ if (f != flags) {
+ mlog_write_ulint(FSP_HEADER_OFFSET
+ + FSP_SPACE_FLAGS + b->frame,
+ flags, MLOG_4BYTES, &mtr);
+ }
+ }
+ mtr_commit(&mtr);
+}
+
+/** Determine if a matching tablespace exists in the InnoDB tablespace
memory cache. Note that if we have not done a crash recovery at the database
startup, there may be many tablespaces which are not yet in the memory cache.
@param[in] id Tablespace ID
@@ -4632,6 +4654,7 @@ error log if a matching tablespace is not found from memory.
@param[in] heap Heap memory
@param[in] table_id table id
@param[in] table table
+@param[in] table_flags table flags
@return true if a matching tablespace exists in the memory cache */
bool
fil_space_for_table_exists_in_mem(
@@ -4641,12 +4664,13 @@ fil_space_for_table_exists_in_mem(
bool adjust_space,
mem_heap_t* heap,
table_id_t table_id,
- dict_table_t* table)
+ dict_table_t* table,
+ ulint table_flags)
{
- fil_space_t* fnamespace = NULL;
+ fil_space_t* fnamespace;
fil_space_t* space;
- ut_ad(fil_system);
+ const ulint expected_flags = dict_tf_to_fsp_flags(table_flags);
mutex_enter(&fil_system->mutex);
@@ -4654,50 +4678,41 @@ fil_space_for_table_exists_in_mem(
space = fil_space_get_by_id(id);
- /* If tablespace contains encryption information
- copy it also to table. */
- if (space && space->crypt_data &&
- table && !table->crypt_data) {
- table->crypt_data = space->crypt_data;
- }
+ /* Look if there is a space with the same name; the name is the
+ directory path from the datadir to the file */
- if (space != NULL) {
- /* If this space has the expected name, use it. */
- fnamespace = fil_space_get_by_name(name);
- if (space == fnamespace) {
- /* Found */
+ fnamespace = fil_space_get_by_name(name);
+ bool valid = space && !((space->flags ^ expected_flags)
+ & ~FSP_FLAGS_MEM_MASK);
- mutex_exit(&fil_system->mutex);
- return(true);
- }
+ if (valid && table && !table->crypt_data) {
+ table->crypt_data = space->crypt_data;
}
- /* Info from "fnamespace" comes from the ibd file itself, it can
- be different from data obtained from System tables since file
- operations are not transactional. If adjust_space is set, and the
- mismatching space are between a user table and its temp table, we
- shall adjust the ibd file name according to system table info */
- if (adjust_space
- && space != NULL
- && row_is_mysql_tmp_table_name(space->name)
- && !row_is_mysql_tmp_table_name(name)) {
-
+ if (!space) {
+ } else if (!valid || space == fnamespace) {
+ /* Found with the same file name, or got a flag mismatch. */
+ goto func_exit;
+ } else if (adjust_space
+ && row_is_mysql_tmp_table_name(space->name)
+ && !row_is_mysql_tmp_table_name(name)) {
+ /* Info from fnamespace comes from the ibd file
+ itself, it can be different from data obtained from
+ System tables since renaming files is not
+ transactional. We shall adjust the ibd file name
+ according to system table info. */
mutex_exit(&fil_system->mutex);
DBUG_EXECUTE_IF("ib_crash_before_adjust_fil_space",
DBUG_SUICIDE(););
- if (fnamespace) {
- const char* tmp_name;
-
- tmp_name = dict_mem_create_temporary_tablename(
- heap, name, table_id);
+ const char* tmp_name = dict_mem_create_temporary_tablename(
+ heap, name, table_id);
- fil_rename_tablespace(
- fnamespace->id,
- UT_LIST_GET_FIRST(fnamespace->chain)->name,
- tmp_name, NULL);
- }
+ fil_rename_tablespace(
+ fnamespace->id,
+ UT_LIST_GET_FIRST(fnamespace->chain)->name,
+ tmp_name, NULL);
DBUG_EXECUTE_IF("ib_crash_after_adjust_one_fil_space",
DBUG_SUICIDE(););
@@ -4712,16 +4727,12 @@ fil_space_for_table_exists_in_mem(
mutex_enter(&fil_system->mutex);
fnamespace = fil_space_get_by_name(name);
ut_ad(space == fnamespace);
- mutex_exit(&fil_system->mutex);
-
- return(true);
+ goto func_exit;
}
if (!print_error_if_does_not_exist) {
-
- mutex_exit(&fil_system->mutex);
-
- return(false);
+ valid = false;
+ goto func_exit;
}
if (space == NULL) {
@@ -4740,10 +4751,8 @@ fil_space_for_table_exists_in_mem(
}
error_exit:
ib::warn() << TROUBLESHOOT_DATADICT_MSG;
-
- mutex_exit(&fil_system->mutex);
-
- return(false);
+ valid = false;
+ goto func_exit;
}
if (0 != strcmp(space->name, name)) {
@@ -4762,9 +4771,19 @@ error_exit:
goto error_exit;
}
+func_exit:
+ if (valid) {
+ /* Adjust the flags that are in FSP_FLAGS_MEM_MASK.
+ FSP_SPACE_FLAGS will not be written back here. */
+ space->flags = expected_flags;
+ }
mutex_exit(&fil_system->mutex);
- return(false);
+ if (valid && !srv_read_only_mode) {
+ fsp_flags_try_adjust(id, expected_flags & ~FSP_FLAGS_MEM_MASK);
+ }
+
+ return(valid);
}
/** Return the space ID based on the tablespace name.
@@ -6425,15 +6444,12 @@ truncate_t::truncate(
{
dberr_t err = DB_SUCCESS;
char* path;
- bool has_data_dir = FSP_FLAGS_HAS_DATA_DIR(flags);
ut_a(!is_system_tablespace(space_id));
- if (has_data_dir) {
+ if (FSP_FLAGS_HAS_DATA_DIR(flags)) {
ut_ad(dir_path != NULL);
-
path = fil_make_filepath(dir_path, tablename, IBD, true);
-
} else {
path = fil_make_filepath(NULL, tablename, IBD, false);
}
diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc
index cdcd9924d41..9e6aa60ec01 100644
--- a/storage/innobase/fsp/fsp0file.cc
+++ b/storage/innobase/fsp/fsp0file.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, MariaDB Corporation.
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
@@ -343,17 +344,37 @@ Datafile::read_first_page(bool read_only_mode)
}
}
- if (err == DB_SUCCESS && m_order == 0) {
+ if (err != DB_SUCCESS) {
+ return(err);
+ }
+ if (m_order == 0) {
+ m_space_id = fsp_header_get_space_id(m_first_page);
m_flags = fsp_header_get_flags(m_first_page);
+ if (!fsp_flags_is_valid(m_flags)) {
+ ulint cflags = fsp_flags_convert_from_101(m_flags);
+ if (cflags == ULINT_UNDEFINED) {
+ ib::error()
+ << "Invalid flags " << ib::hex(m_flags)
+ << " in " << m_filepath;
+ return(DB_CORRUPTION);
+ } else {
+ m_flags = cflags;
+ }
+ }
+ }
- m_space_id = fsp_header_get_space_id(m_first_page);
+ const page_size_t ps(m_flags);
+ if (ps.physical() > page_size) {
+ ib::error() << "File " << m_filepath
+ << " should be longer than "
+ << page_size << " bytes";
+ return(DB_CORRUPTION);
}
m_crypt_info = fil_space_read_crypt_data(
m_space_id, m_first_page,
- FSP_HEADER_OFFSET + fsp_header_get_encryption_offset(
- page_size_t(m_flags)));
+ FSP_HEADER_OFFSET + fsp_header_get_encryption_offset(ps));
return(err);
}
@@ -374,14 +395,10 @@ space ID and flags. The file should exist and be successfully opened
in order for this function to validate it.
@param[in] space_id The expected tablespace ID.
@param[in] flags The expected tablespace flags.
-@param[in] for_import if it is for importing
@retval DB_SUCCESS if tablespace is valid, DB_ERROR if not.
m_is_valid is also set true on success, else false. */
dberr_t
-Datafile::validate_to_dd(
- ulint space_id,
- ulint flags,
- bool for_import)
+Datafile::validate_to_dd(ulint space_id, ulint flags)
{
dberr_t err;
@@ -392,7 +409,7 @@ Datafile::validate_to_dd(
/* Validate this single-table-tablespace with the data dictionary,
but do not compare the DATA_DIR flag, in case the tablespace was
remotely located. */
- err = validate_first_page(0, for_import);
+ err = validate_first_page(0);
if (err != DB_SUCCESS) {
return(err);
}
@@ -400,9 +417,7 @@ Datafile::validate_to_dd(
/* Make sure the datafile we found matched the space ID.
If the datafile is a file-per-table tablespace then also match
the row format and zip page size. */
- if (m_space_id == space_id
- && ((m_flags & ~FSP_FLAGS_MASK_DATA_DIR)
- == (flags & ~FSP_FLAGS_MASK_DATA_DIR))) {
+ if (m_space_id == space_id && m_flags == flags) {
/* Datafile matches the tablespace expected. */
return(DB_SUCCESS);
}
@@ -411,9 +426,10 @@ Datafile::validate_to_dd(
m_is_valid = false;
ib::error() << "In file '" << m_filepath << "', tablespace id and"
- " flags are " << m_space_id << " and " << m_flags << ", but in"
- " the InnoDB data dictionary they are " << space_id << " and "
- << flags << ". Have you moved InnoDB .ibd files around without"
+ " flags are " << m_space_id << " and " << ib::hex(m_flags)
+ << ", but in the InnoDB data dictionary they are "
+ << space_id << " and " << ib::hex(flags)
+ << ". Have you moved InnoDB .ibd files around without"
" using the commands DISCARD TABLESPACE and IMPORT TABLESPACE?"
" " << TROUBLESHOOT_DATADICT_MSG;
@@ -435,7 +451,7 @@ Datafile::validate_for_recovery()
ut_ad(is_open());
ut_ad(!srv_read_only_mode);
- err = validate_first_page(0, false);
+ err = validate_first_page(0);
switch (err) {
case DB_SUCCESS:
@@ -463,14 +479,13 @@ Datafile::validate_for_recovery()
return(err);
}
- err = restore_from_doublewrite(0);
- if (err != DB_SUCCESS) {
- return(err);
+ if (restore_from_doublewrite()) {
+ return(DB_CORRUPTION);
}
/* Free the previously read first page and then re-validate. */
free_first_page();
- err = validate_first_page(0, false);
+ err = validate_first_page(0);
}
if (err == DB_SUCCESS) {
@@ -485,14 +500,11 @@ tablespace is opened. This occurs before the fil_space_t is created
so the Space ID found here must not already be open.
m_is_valid is set true on success, else false.
@param[out] flush_lsn contents of FIL_PAGE_FILE_FLUSH_LSN
-@param[in] for_import if it is for importing
-(only valid for the first file of the system tablespace)
@retval DB_SUCCESS on if the datafile is valid
@retval DB_CORRUPTION if the datafile is not readable
@retval DB_TABLESPACE_EXISTS if there is a duplicate space_id */
dberr_t
-Datafile::validate_first_page(lsn_t* flush_lsn,
- bool for_import)
+Datafile::validate_first_page(lsn_t* flush_lsn)
{
char* prev_name;
char* prev_filepath;
@@ -550,8 +562,7 @@ Datafile::validate_first_page(lsn_t* flush_lsn,
free_first_page();
return(DB_ERROR);
- } else if (!fsp_flags_is_valid(m_flags)
- || FSP_FLAGS_GET_TEMPORARY(m_flags)) {
+ } else if (!fsp_flags_is_valid(m_flags)) {
/* Tablespace flags must be valid. */
error_txt = "Tablespace flags are invalid";
} else if (page_get_page_no(m_first_page) != 0) {
@@ -768,17 +779,15 @@ Datafile::find_space_id()
}
-/** Finds a given page of the given space id from the double write buffer
-and copies it to the corresponding .ibd file.
-@param[in] page_no Page number to restore
-@return DB_SUCCESS if page was restored from doublewrite, else DB_ERROR */
-dberr_t
-Datafile::restore_from_doublewrite(
- ulint restore_page_no)
+/** Restore the first page of the tablespace from
+the double write buffer.
+@return whether the operation failed */
+bool
+Datafile::restore_from_doublewrite()
{
/* Find if double write buffer contains page_no of given space id. */
- const byte* page = recv_sys->dblwr.find_page(
- m_space_id, restore_page_no);
+ const byte* page = recv_sys->dblwr.find_page(m_space_id, 0);
+ const page_id_t page_id(m_space_id, 0);
if (page == NULL) {
/* If the first page of the given user tablespace is not there
@@ -786,23 +795,34 @@ Datafile::restore_from_doublewrite(
now. Hence this is treated as an error. */
ib::error()
- << "Corrupted page "
- << page_id_t(m_space_id, restore_page_no)
+ << "Corrupted page " << page_id
<< " of datafile '" << m_filepath
<< "' could not be found in the doublewrite buffer.";
- return(DB_CORRUPTION);
+ return(true);
}
- const ulint flags = mach_read_from_4(
+ ulint flags = mach_read_from_4(
FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page);
+ if (!fsp_flags_is_valid(flags)) {
+ ulint cflags = fsp_flags_convert_from_101(flags);
+ if (cflags == ULINT_UNDEFINED) {
+ ib::warn()
+ << "Ignoring a doublewrite copy of page "
+ << page_id
+ << " due to invalid flags " << ib::hex(flags);
+ return(true);
+ }
+ flags = cflags;
+ /* The flags on the page should be converted later. */
+ }
+
const page_size_t page_size(flags);
- ut_a(page_get_page_no(page) == restore_page_no);
+ ut_a(page_get_page_no(page) == page_id.page_no());
- ib::info() << "Restoring page "
- << page_id_t(m_space_id, restore_page_no)
+ ib::info() << "Restoring page " << page_id
<< " of datafile '" << m_filepath
<< "' from the doublewrite buffer. Writing "
<< page_size.physical() << " bytes into file '"
@@ -812,7 +832,8 @@ Datafile::restore_from_doublewrite(
return(os_file_write(
request,
- m_filepath, m_handle, page, 0, page_size.physical()));
+ m_filepath, m_handle, page, 0, page_size.physical())
+ == DB_SUCCESS);
}
/** Create a link filename based on the contents of m_name,
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index 70d73ead0b7..27990e8243e 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -181,146 +181,6 @@ fsp_get_space_header(
return(header);
}
-/** Convert a 32 bit integer tablespace flags to the 32 bit table flags.
-This can only be done for a tablespace that was built as a file-per-table
-tablespace. Note that the fsp_flags cannot show the difference between a
-Compact and Redundant table, so an extra Compact boolean must be supplied.
- Low order bit
- | REDUNDANT | COMPACT | COMPRESSED | DYNAMIC
-fil_space_t::flags | 0 | 0 | 1 | 1
-dict_table_t::flags | 0 | 1 | 1 | 1
-@param[in] fsp_flags fil_space_t::flags
-@param[in] compact true if not Redundant row format
-@return tablespace flags (fil_space_t::flags) */
-ulint
-fsp_flags_to_dict_tf(
- ulint fsp_flags,
- bool compact)
-{
- /* If the table in this file-per-table tablespace is Compact
- row format, the low order bit will not indicate Compact. */
- bool post_antelope = FSP_FLAGS_GET_POST_ANTELOPE(fsp_flags);
- ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(fsp_flags);
- bool atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(fsp_flags);
- bool data_dir = FSP_FLAGS_HAS_DATA_DIR(fsp_flags);
- bool page_compressed = FSP_FLAGS_GET_PAGE_COMPRESSION(fsp_flags);
- ulint comp_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(fsp_flags);
-
- /* FSP_FLAGS_GET_TEMPORARY(fsp_flags) does not have an equivalent
- flag position in the table flags. But it would go into flags2 if
- any code is created where that is needed. */
-
- ulint flags = dict_tf_init(post_antelope | compact, zip_ssize,
- atomic_blobs, data_dir,
- page_compressed, comp_level, 0);
-
- return(flags);
-}
-
-/** Validate the tablespace flags.
-These flags are stored in the tablespace header at offset FSP_SPACE_FLAGS.
-They should be 0 for ROW_FORMAT=COMPACT and ROW_FORMAT=REDUNDANT.
-The newer row formats, COMPRESSED and DYNAMIC, use a file format > Antelope
-so they should have a file format number plus the DICT_TF_COMPACT bit set.
-@param[in] flags Tablespace flags
-@return true if valid, false if not */
-bool
-fsp_flags_is_valid(
- ulint flags)
-{
- bool post_antelope = FSP_FLAGS_GET_POST_ANTELOPE(flags);
- ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(flags);
- bool atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(flags);
- ulint page_ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags);
- bool has_data_dir = FSP_FLAGS_HAS_DATA_DIR(flags);
- bool is_temp = FSP_FLAGS_GET_TEMPORARY(flags);
- ulint unused = FSP_FLAGS_GET_UNUSED(flags);
- bool page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(flags);
- ulint page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags);
-
- const char *file;
- ulint line;
-
-#define GOTO_ERROR file = __FILE__; line = __LINE__; goto err_exit;
-
- DBUG_EXECUTE_IF("fsp_flags_is_valid_failure", return(false););
-
- /* The Antelope row formats REDUNDANT and COMPACT did
- not use tablespace flags, so the entire 4-byte field
- is zero for Antelope row formats. */
- if (flags == 0) {
- return(true);
- }
-
- /* Barracuda row formats COMPRESSED and DYNAMIC use a feature called
- ATOMIC_BLOBS which builds on the page structure introduced for the
- COMPACT row format by allowing long fields to be broken into prefix
- and externally stored parts. So if it is Post_antelope, it uses
- Atomic BLOBs. */
- if (post_antelope != atomic_blobs) {
- GOTO_ERROR;
- return(false);
- }
-
- /* Make sure there are no bits that we do not know about. */
- if (unused != 0) {
- GOTO_ERROR;
- }
-
- /* The zip ssize can be zero if it is other than compressed row format,
- or it could be from 1 to the max. */
- if (zip_ssize > PAGE_ZIP_SSIZE_MAX) {
- GOTO_ERROR;
- }
-
- /* The actual page size must be within 4k and 16K (3 =< ssize =< 5). */
- if (page_ssize != 0
- && (page_ssize < UNIV_PAGE_SSIZE_MIN
- || page_ssize > UNIV_PAGE_SSIZE_MAX)) {
- GOTO_ERROR;
- }
-
- /* Only single-table tablespaces use the DATA DIRECTORY clause.
- It is not compatible with the TABLESPACE clause. Nor is it
- compatible with the TEMPORARY clause. */
- if (has_data_dir && is_temp) {
- GOTO_ERROR;
- return(false);
- }
-
- /* Page compression level requires page compression and atomic blobs
- to be set */
- if (page_compression_level || page_compression) {
- if (!page_compression || !atomic_blobs) {
- GOTO_ERROR;
- }
- }
-
-#if UNIV_FORMAT_MAX != UNIV_FORMAT_B
-# error UNIV_FORMAT_MAX != UNIV_FORMAT_B, Add more validations.
-#endif
-#if FSP_FLAGS_POS_UNUSED != 13
- //# error You have added a new FSP_FLAG without adding a validation check.
-#endif
-
- return(true);
-
-err_exit:
- ib::error() << "Tablespace flags: " << flags << " corrupted "
- << " in file: " << file << " line: " << line
- << " post_antelope: " << post_antelope
- << " atomic_blobs: " << atomic_blobs
- << " unused: " << unused
- << " zip_ssize: " << zip_ssize << " max: " << PAGE_ZIP_SSIZE_MAX
- << " page_ssize: " << page_ssize
- << " " << UNIV_PAGE_SSIZE_MIN << ":" << UNIV_PAGE_SSIZE_MAX
- << " has_data_dir: " << has_data_dir
- << " is_temp: " << is_temp
- << " page_compressed: " << page_compression
- << " page_compression_level: " << page_compression_level;
- return (false);
-}
-
/** Check if checksum is disabled for the given space.
@param[in] space_id tablespace ID
@return true if checksum is disabled for given space. */
@@ -835,6 +695,7 @@ fsp_header_init_fields(
ulint space_id, /*!< in: space id */
ulint flags) /*!< in: tablespace flags (FSP_SPACE_FLAGS) */
{
+ flags &= ~FSP_FLAGS_MEM_MASK;
ut_a(fsp_flags_is_valid(flags));
mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_ID + page,
@@ -889,7 +750,8 @@ fsp_header_init(
mlog_write_ulint(header + FSP_SIZE, size, MLOG_4BYTES, mtr);
mlog_write_ulint(header + FSP_FREE_LIMIT, 0, MLOG_4BYTES, mtr);
- mlog_write_ulint(header + FSP_SPACE_FLAGS, space->flags,
+ mlog_write_ulint(header + FSP_SPACE_FLAGS,
+ space->flags & ~FSP_FLAGS_MEM_MASK,
MLOG_4BYTES, mtr);
mlog_write_ulint(header + FSP_FRAG_N_USED, 0, MLOG_4BYTES, mtr);
diff --git a/storage/innobase/fsp/fsp0space.cc b/storage/innobase/fsp/fsp0space.cc
index ed557fb8334..76269a749f9 100644
--- a/storage/innobase/fsp/fsp0space.cc
+++ b/storage/innobase/fsp/fsp0space.cc
@@ -126,15 +126,13 @@ Tablespace::open_or_create(bool is_temp)
if (it == begin) {
/* First data file. */
- ulint flags;
-
- flags = fsp_flags_set_page_size(0, univ_page_size);
-
/* Create the tablespace entry for the multi-file
tablespace in the tablespace manager. */
space = fil_space_create(
- m_name, m_space_id, flags, is_temp
- ? FIL_TYPE_TEMPORARY : FIL_TYPE_TABLESPACE, it->m_crypt_info,
+ m_name, m_space_id, FSP_FLAGS_PAGE_SSIZE(),
+ is_temp
+ ? FIL_TYPE_TEMPORARY : FIL_TYPE_TABLESPACE,
+ it->m_crypt_info,
false);
}
diff --git a/storage/innobase/fsp/fsp0sysspace.cc b/storage/innobase/fsp/fsp0sysspace.cc
index 9a9e7051403..6f7d09b6faa 100644
--- a/storage/innobase/fsp/fsp0sysspace.cc
+++ b/storage/innobase/fsp/fsp0sysspace.cc
@@ -577,11 +577,11 @@ SysTablespace::read_lsn_and_check_flags(lsn_t* flushed_lsn)
first datafile. */
for (int retry = 0; retry < 2; ++retry) {
- err = it->validate_first_page(flushed_lsn, false);
+ err = it->validate_first_page(flushed_lsn);
if (err != DB_SUCCESS
&& (retry == 1
- || it->restore_from_doublewrite(0) != DB_SUCCESS)) {
+ || it->restore_from_doublewrite())) {
it->close();
diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc
index 45c71f6f1cd..1cb3fcb80e8 100644
--- a/storage/innobase/fts/fts0opt.cc
+++ b/storage/innobase/fts/fts0opt.cc
@@ -582,9 +582,6 @@ fts_zip_read_word(
fts_zip_t* zip, /*!< in: Zip state + data */
fts_string_t* word) /*!< out: uncompressed word */
{
-#ifdef UNIV_DEBUG
- ulint i;
-#endif
short len = 0;
void* null = NULL;
byte* ptr = word->f_str;
@@ -660,10 +657,9 @@ fts_zip_read_word(
}
}
-#ifdef UNIV_DEBUG
/* All blocks must be freed at end of inflate. */
if (zip->status != Z_OK) {
- for (i = 0; i < ib_vector_size(zip->blocks); ++i) {
+ for (ulint i = 0; i < ib_vector_size(zip->blocks); ++i) {
if (ib_vector_getp(zip->blocks, i)) {
ut_free(ib_vector_getp(zip->blocks, i));
ib_vector_set(zip->blocks, i, &null);
@@ -674,7 +670,6 @@ fts_zip_read_word(
if (ptr != NULL) {
ut_ad(word->f_len == strlen((char*) ptr));
}
-#endif /* UNIV_DEBUG */
return(zip->status == Z_OK || zip->status == Z_STREAM_END ? ptr : NULL);
}
@@ -3142,7 +3137,7 @@ fts_optimize_thread(
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 93f5c936915..c66773d9bdf 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -3865,7 +3865,6 @@ innobase_init(
uint format_id;
ulong num_pll_degree;
ulint srv_buf_pool_size_org = 0;
- ulint fsp_flags =0;
DBUG_ENTER("innobase_init");
handlerton* innobase_hton= (handlerton*) p;
@@ -4095,12 +4094,7 @@ innobase_init(
page_size_t(srv_page_size, srv_page_size, false));
srv_sys_space.set_space_id(TRX_SYS_SPACE);
-
- /* Create the filespace flags. */
- fsp_flags = fsp_flags_init(
- univ_page_size, false, false, false, 0, 0);
- srv_sys_space.set_flags(fsp_flags);
-
+ srv_sys_space.set_flags(FSP_FLAGS_PAGE_SSIZE());
srv_sys_space.set_name("innodb_system");
srv_sys_space.set_path(srv_data_home);
@@ -4121,11 +4115,7 @@ innobase_init(
Set the name and path. */
srv_tmp_space.set_name("innodb_temporary");
srv_tmp_space.set_path(srv_data_home);
-
- /* Create the filespace flags with the temp flag set. */
- fsp_flags = fsp_flags_init(
- univ_page_size, false, false, false, 0, 0);
- srv_tmp_space.set_flags(fsp_flags);
+ srv_sys_space.set_flags(FSP_FLAGS_PAGE_SSIZE());
if (!srv_tmp_space.parse_params(innobase_temp_data_file_path, false)) {
DBUG_RETURN(innobase_init_abort());
@@ -17692,6 +17682,37 @@ ha_innobase::get_auto_increment(
whether we update the table autoinc counter or not. */
ulonglong col_max_value = innobase_get_int_col_max_value(table->next_number_field);
+ /** The following logic is needed to avoid duplicate key error
+ for autoincrement column.
+
+ (1) InnoDB gives the current autoincrement value with respect
+ to increment and offset value.
+
+ (2) Basically it does compute_next_insert_id() logic inside InnoDB
+ to avoid the current auto increment value changed by handler layer.
+
+ (3) It is restricted only for insert operations. */
+
+ if (increment > 1 && thd_sql_command(m_user_thd) != SQLCOM_ALTER_TABLE
+ && autoinc < col_max_value) {
+
+ ulonglong prev_auto_inc = autoinc;
+
+ autoinc = ((autoinc - 1) + increment - offset)/ increment;
+
+ autoinc = autoinc * increment + offset;
+
+ /* If autoinc exceeds the col_max_value then reset
+ to old autoinc value. Because in case of non-strict
+ sql mode, boundary value is not considered as error. */
+
+ if (autoinc >= col_max_value) {
+ autoinc = prev_auto_inc;
+ }
+
+ ut_ad(autoinc > 0);
+ }
+
/* Called for the first time ? */
if (trx->n_autoinc_rows == 0) {
@@ -20735,6 +20756,12 @@ static MYSQL_SYSVAR_BOOL(use_fallocate, innobase_use_fallocate,
"Use posix_fallocate() to allocate files. DEPRECATED, has no effect.",
NULL, NULL, FALSE);
+static MYSQL_SYSVAR_BOOL(stats_include_delete_marked,
+ srv_stats_include_delete_marked,
+ PLUGIN_VAR_OPCMDARG,
+ "Scan delete marked records for persistent stat",
+ NULL, NULL, FALSE);
+
static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity,
PLUGIN_VAR_RQCMDARG,
"Number of IOPs the server can do. Tunes the background IO rate",
@@ -21962,6 +21989,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(doublewrite),
MYSQL_SYSVAR(use_atomic_writes),
MYSQL_SYSVAR(use_fallocate),
+ MYSQL_SYSVAR(stats_include_delete_marked),
MYSQL_SYSVAR(api_enable_binlog),
MYSQL_SYSVAR(api_enable_mdl),
MYSQL_SYSVAR(api_disable_rowlock),
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 341c341f112..744c9b1486d 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -2467,6 +2467,7 @@ innobase_fts_check_doc_id_index_in_def(
return(FTS_NOT_EXIST_DOC_ID_INDEX);
}
+
/*******************************************************************//**
Create an index table where indexes are ordered as follows:
@@ -2534,30 +2535,11 @@ innobase_create_key_defs(
columns and if the index does not contain column prefix(es)
(only prefix/part of the column is indexed), MySQL will treat the
index as a PRIMARY KEY unless the table already has one. */
+ ut_ad(altered_table->s->primary_key == 0
+ || altered_table->s->primary_key == MAX_KEY);
- if (n_add > 0 && !new_primary && got_default_clust
- && (key_info[*add].flags & HA_NOSAME)
- && !(key_info[*add].flags & HA_KEY_HAS_PART_KEY_SEG)) {
- uint key_part = key_info[*add].user_defined_key_parts;
-
- new_primary = true;
-
- while (key_part--) {
- const uint maybe_null
- = key_info[*add].key_part[key_part].key_type
- & FIELDFLAG_MAYBE_NULL;
- bool is_v
- = innobase_is_v_fld(
- key_info[*add].key_part[key_part].field);
- DBUG_ASSERT(!maybe_null
- == !key_info[*add].key_part[key_part].
- field->real_maybe_null());
-
- if (maybe_null || is_v) {
- new_primary = false;
- break;
- }
- }
+ if (got_default_clust && !new_primary) {
+ new_primary = (altered_table->s->primary_key != MAX_KEY);
}
const bool rebuild = new_primary || add_fts_doc_id
@@ -2577,8 +2559,14 @@ innobase_create_key_defs(
ulint primary_key_number;
if (new_primary) {
- DBUG_ASSERT(n_add > 0);
- primary_key_number = *add;
+ if (n_add == 0) {
+ DBUG_ASSERT(got_default_clust);
+ DBUG_ASSERT(altered_table->s->primary_key
+ == 0);
+ primary_key_number = 0;
+ } else {
+ primary_key_number = *add;
+ }
} else if (got_default_clust) {
/* Create the GEN_CLUST_INDEX */
index_def_t* index = indexdef++;
@@ -4781,6 +4769,8 @@ new_clustered_failed:
ctx->add_cols = add_cols;
} else {
DBUG_ASSERT(!innobase_need_rebuild(ha_alter_info, old_table));
+ DBUG_ASSERT(old_table->s->primary_key
+ == altered_table->s->primary_key);
for (dict_index_t* index
= dict_table_get_first_index(user_table);
@@ -6309,6 +6299,27 @@ alter_templ_needs_rebuild(
}
+/** Get the name of an erroneous key.
+@param[in] error_key_num InnoDB number of the erroneus key
+@param[in] ha_alter_info changes that were being performed
+@param[in] table InnoDB table
+@return the name of the erroneous key */
+static
+const char*
+get_error_key_name(
+ ulint error_key_num,
+ const Alter_inplace_info* ha_alter_info,
+ const dict_table_t* table)
+{
+ if (error_key_num == ULINT_UNDEFINED) {
+ return(FTS_DOC_ID_INDEX_NAME);
+ } else if (ha_alter_info->key_count == 0) {
+ return(dict_table_get_first_index(table)->name);
+ } else {
+ return(ha_alter_info->key_info_buffer[error_key_num].name);
+ }
+}
+
/** Alter the table structure in-place with operations
specified using Alter_inplace_info.
The level of concurrency allowed during this operation depends
@@ -6508,17 +6519,13 @@ oom:
case DB_ONLINE_LOG_TOO_BIG:
DBUG_ASSERT(ctx->online);
my_error(ER_INNODB_ONLINE_LOG_TOO_BIG, MYF(0),
- (m_prebuilt->trx->error_key_num == ULINT_UNDEFINED)
- ? FTS_DOC_ID_INDEX_NAME
- : ha_alter_info->key_info_buffer[
- m_prebuilt->trx->error_key_num].name);
+ get_error_key_name(m_prebuilt->trx->error_key_num,
+ ha_alter_info, m_prebuilt->table));
break;
case DB_INDEX_CORRUPT:
my_error(ER_INDEX_CORRUPT, MYF(0),
- (m_prebuilt->trx->error_key_num == ULINT_UNDEFINED)
- ? FTS_DOC_ID_INDEX_NAME
- : ha_alter_info->key_info_buffer[
- m_prebuilt->trx->error_key_num].name);
+ get_error_key_name(m_prebuilt->trx->error_key_num,
+ ha_alter_info, m_prebuilt->table));
break;
case DB_DECRYPTION_FAILED: {
String str;
@@ -7737,14 +7744,13 @@ commit_try_rebuild(
DBUG_RETURN(true);
case DB_ONLINE_LOG_TOO_BIG:
my_error(ER_INNODB_ONLINE_LOG_TOO_BIG, MYF(0),
- ha_alter_info->key_info_buffer[0].name);
+ get_error_key_name(err_key, ha_alter_info,
+ rebuilt_table));
DBUG_RETURN(true);
case DB_INDEX_CORRUPT:
my_error(ER_INDEX_CORRUPT, MYF(0),
- (err_key == ULINT_UNDEFINED)
- ? FTS_DOC_ID_INDEX_NAME
- : ha_alter_info->key_info_buffer[err_key]
- .name);
+ get_error_key_name(err_key, ha_alter_info,
+ rebuilt_table));
DBUG_RETURN(true);
default:
my_error_innodb(error, table_name, user_table->flags);
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 349b105be6a..6e86cd3eb4a 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -1037,6 +1037,7 @@ fil_space_t::flags | 0 | 0 | 1 | 1
==================================================================
@param[in] table_flags dict_table_t::flags
@return tablespace flags (fil_space_t::flags) */
+UNIV_INLINE
ulint
dict_tf_to_fsp_flags(ulint table_flags)
MY_ATTRIBUTE((const));
diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
index 3bb00294bfa..a75f0b245af 100644
--- a/storage/innobase/include/dict0dict.ic
+++ b/storage/innobase/include/dict0dict.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2016, MariaDB Corporation
+Copyright (c) 2013, 2017, MariaDB Corporation.
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
@@ -968,54 +968,56 @@ dict_tf_set(
}
}
-/** Initialize a dict_table_t::flags pointer.
-@param[in] compact, Table uses Compact or greater
-@param[in] zip_ssize Zip Shift Size (log 2 minus 9)
-@param[in] atomic_blobs Table uses Compressed or Dynamic
-@param[in] data_dir Table uses DATA DIRECTORY
-@param[in] page_compression Table uses page compression
-@param[in] page_compression_level used compression level
-@param[in] not_used For future */
+/** Convert a 32 bit integer table flags to the 32 bit FSP Flags.
+Fsp Flags are written into the tablespace header at the offset
+FSP_SPACE_FLAGS and are also stored in the fil_space_t::flags field.
+The following chart shows the translation of the low order bit.
+Other bits are the same.
+========================= Low order bit ==========================
+ | REDUNDANT | COMPACT | COMPRESSED | DYNAMIC
+dict_table_t::flags | 0 | 1 | 1 | 1
+fil_space_t::flags | 0 | 0 | 1 | 1
+==================================================================
+@param[in] table_flags dict_table_t::flags
+@return tablespace flags (fil_space_t::flags) */
UNIV_INLINE
ulint
-dict_tf_init(
- bool compact,
- ulint zip_ssize,
- bool atomic_blobs,
- bool data_dir,
- bool page_compressed,
- ulint page_compression_level,
- ulint not_used)
+dict_tf_to_fsp_flags(ulint table_flags)
{
- ulint flags = 0;
+ ulint fsp_flags;
+ ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(
+ table_flags);
+ ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags);
- if (compact) {
- flags |= DICT_TF_COMPACT;
- }
+ ut_ad((DICT_TF_GET_PAGE_COMPRESSION(table_flags) == 0)
+ == (page_compression_level == 0));
- if (zip_ssize) {
- flags |= (zip_ssize << DICT_TF_POS_ZIP_SSIZE);
- }
+ DBUG_EXECUTE_IF("dict_tf_to_fsp_flags_failure",
+ return(ULINT_UNDEFINED););
- if (atomic_blobs) {
- flags |= (1 << DICT_TF_POS_ATOMIC_BLOBS);
- }
+ /* Adjust bit zero. */
+ fsp_flags = DICT_TF_HAS_ATOMIC_BLOBS(table_flags) ? 1 : 0;
+
+ /* ZIP_SSIZE and ATOMIC_BLOBS are at the same position. */
+ fsp_flags |= table_flags
+ & (DICT_TF_MASK_ZIP_SSIZE | DICT_TF_MASK_ATOMIC_BLOBS);
+
+ fsp_flags |= FSP_FLAGS_PAGE_SSIZE();
- if (data_dir) {
- flags |= (1 << DICT_TF_POS_DATA_DIR);
+ if (page_compression_level) {
+ fsp_flags |= FSP_FLAGS_MASK_PAGE_COMPRESSION;
}
- if (page_compressed) {
- flags |= (1 << DICT_TF_POS_ATOMIC_BLOBS)
- | (1 << DICT_TF_POS_PAGE_COMPRESSION)
- | (page_compression_level << DICT_TF_POS_PAGE_COMPRESSION_LEVEL);
+ ut_a(fsp_flags_is_valid(fsp_flags));
- ut_ad(zip_ssize == 0);
- ut_ad(dict_tf_get_page_compression(flags) == TRUE);
- ut_ad(dict_tf_get_page_compression_level(flags) == page_compression_level);
+ if (DICT_TF_HAS_DATA_DIR(table_flags)) {
+ fsp_flags |= 1U << FSP_FLAGS_MEM_DATA_DIR;
}
- return(flags);
+ fsp_flags |= atomic_writes << FSP_FLAGS_MEM_ATOMIC_WRITES;
+ fsp_flags |= page_compression_level << FSP_FLAGS_MEM_COMPRESSION_LEVEL;
+
+ return(fsp_flags);
}
/********************************************************************//**
@@ -1863,4 +1865,3 @@ dict_table_have_virtual_index(
return(false);
}
-
diff --git a/storage/innobase/include/dict0pagecompress.h b/storage/innobase/include/dict0pagecompress.h
index f8873aec965..6641f6ba85f 100644
--- a/storage/innobase/include/dict0pagecompress.h
+++ b/storage/innobase/include/dict0pagecompress.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013 SkySQL Ab. All Rights Reserved.
+Copyright (C) 2013, 2017, MariaDB Corporation. 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
@@ -56,17 +56,6 @@ dict_table_page_compression_level(
const dict_table_t* table) /*!< in: table */
__attribute__((const));
-/********************************************************************//**
-Verify that dictionary flags match tablespace flags
-@return true if flags match, false if not */
-UNIV_INLINE
-ibool
-dict_tf_verify_flags(
-/*=================*/
- ulint table_flags, /*!< in: dict_table_t::flags */
- ulint fsp_flags) /*!< in: fil_space_t::flags */
- __attribute__((const));
-
#ifndef UNIV_NONINL
#include "dict0pagecompress.ic"
#endif
diff --git a/storage/innobase/include/dict0pagecompress.ic b/storage/innobase/include/dict0pagecompress.ic
index 05a26f00711..67f4a26723f 100644
--- a/storage/innobase/include/dict0pagecompress.ic
+++ b/storage/innobase/include/dict0pagecompress.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013 SkySQL Ab. All Rights Reserved.
+Copyright (C) 2013, 2017, MariaDB Corporation. 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
@@ -25,80 +25,6 @@ Created 11/12/2013 Jan Lindström jan.lindstrom@skysql.com
***********************************************************************/
/********************************************************************//**
-Verify that dictionary flags match tablespace flags
-@return true if flags match, false if not */
-UNIV_INLINE
-ibool
-dict_tf_verify_flags(
-/*=================*/
- ulint table_flags, /*!< in: dict_table_t::flags */
- ulint fsp_flags) /*!< in: fil_space_t::flags */
-{
- ulint table_unused = DICT_TF_GET_UNUSED(table_flags);
- ulint compact = DICT_TF_GET_COMPACT(table_flags);
- ulint ssize = DICT_TF_GET_ZIP_SSIZE(table_flags);
- ulint atomic_blobs = DICT_TF_HAS_ATOMIC_BLOBS(table_flags);
- ulint data_dir = DICT_TF_HAS_DATA_DIR(table_flags);
- ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags);
- ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags);
- ulint post_antelope = FSP_FLAGS_GET_POST_ANTELOPE(fsp_flags);
- ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(fsp_flags);
- ulint fsp_atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(fsp_flags);
- ulint page_ssize = FSP_FLAGS_GET_PAGE_SSIZE(fsp_flags);
- ulint fsp_unused = FSP_FLAGS_GET_UNUSED(fsp_flags);
- ulint fsp_page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(fsp_flags);
- ulint fsp_page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(fsp_flags);
-
- DBUG_EXECUTE_IF("dict_tf_verify_flags_failure",
- return(ULINT_UNDEFINED););
-
- ut_a(!table_unused);
- ut_a(!fsp_unused);
- ut_a(page_ssize == 0 || page_ssize != 0); /* silence compiler */
- ut_a(compact == 0 || compact == 1); /* silence compiler */
- ut_a(data_dir == 0 || data_dir == 1); /* silence compiler */
- ut_a(post_antelope == 0 || post_antelope == 1); /* silence compiler */
-
- if (ssize != zip_ssize) {
- fprintf(stderr,
- "InnoDB: Error: table flags has zip_ssize %ld"
- " in the data dictionary\n"
- "InnoDB: but the flags in file has zip_ssize %ld\n",
- ssize, zip_ssize);
- return (FALSE);
- }
- if (atomic_blobs != fsp_atomic_blobs) {
- fprintf(stderr,
- "InnoDB: Error: table flags has atomic_blobs %ld"
- " in the data dictionary\n"
- "InnoDB: but the flags in file has atomic_blobs %ld\n",
- atomic_blobs, fsp_atomic_blobs);
-
- return (FALSE);
- }
- if (page_compression != fsp_page_compression) {
- fprintf(stderr,
- "InnoDB: Error: table flags has page_compression %ld"
- " in the data dictionary\n"
- "InnoDB: but the flags in file ahas page_compression %ld\n",
- page_compression, fsp_page_compression);
-
- return (FALSE);
- }
- if (page_compression_level != fsp_page_compression_level) {
- fprintf(stderr,
- "InnoDB: Error: table flags has page_compression_level %ld"
- " in the data dictionary\n"
- "InnoDB: but the flags in file has page_compression_level %ld\n",
- page_compression_level, fsp_page_compression_level);
-
- return (FALSE);
- }
-
- return(TRUE);
-}
-
-/********************************************************************//**
Extract the page compression level from dict_table_t::flags.
These flags are in memory, so assert that they are valid.
@return page compression level, or 0 if not compressed */
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 5cf75395d8c..7428ff2c936 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -42,7 +42,6 @@ Created 10/25/1995 Heikki Tuuri
struct trx_t;
class page_id_t;
class truncate_t;
-struct btr_create_t;
/* structure containing encryption specification */
typedef struct fil_space_crypt_struct fil_space_crypt_t;
@@ -131,7 +130,8 @@ struct fil_space_t {
/*!< recovered tablespace size in pages;
0 if no size change was read from the redo log,
or if the size change was implemented */
- ulint flags; /*!< tablespace flags; see
+ ulint flags; /*!< FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags;
+ see fsp0types.h,
fsp_flags_is_valid(),
page_size_t(ulint) (constructor) */
ulint n_reserved_extents;
@@ -970,6 +970,14 @@ fil_ibd_create(
ulint key_id)
MY_ATTRIBUTE((warn_unused_result));
+/** Try to adjust FSP_SPACE_FLAGS if they differ from the expectations.
+(Typically when upgrading from MariaDB 10.1.0..10.1.20.)
+@param[in] space_id tablespace ID
+@param[in] flags desired tablespace flags */
+UNIV_INTERN
+void
+fsp_flags_try_adjust(ulint space_id, ulint flags);
+
/********************************************************************//**
Tries to open a single-table tablespace and optionally checks the space id is
right in it. If does not succeed, prints an error message to the .err log. This
@@ -994,7 +1002,7 @@ statement to update the dictionary tables if they are incorrect.
@param[in] fix_dict true if the dictionary is available to be fixed
@param[in] purpose FIL_TYPE_TABLESPACE or FIL_TYPE_TEMPORARY
@param[in] id tablespace ID
-@param[in] flags tablespace flags
+@param[in] flags expected FSP_SPACE_FLAGS
@param[in] space_name tablespace name of the datafile
If file-per-table, it is the table name in the databasename/tablename format
@param[in] path_in expected filepath, usually read from dictionary
@@ -1070,7 +1078,8 @@ fil_space_for_table_exists_in_mem(
when find table space mismatch */
mem_heap_t* heap, /*!< in: heap memory */
table_id_t table_id, /*!< in: table id */
- dict_table_t* table); /*!< in: table or NULL */
+ dict_table_t* table, /*!< in: table or NULL */
+ ulint table_flags); /*!< in: table flags */
/** Try to extend a tablespace if it is smaller than the specified size.
@param[in,out] space tablespace
diff --git a/storage/innobase/include/fil0pagecompress.h b/storage/innobase/include/fil0pagecompress.h
index e65d3491155..0bf6aa75f19 100644
--- a/storage/innobase/include/fil0pagecompress.h
+++ b/storage/innobase/include/fil0pagecompress.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2016 MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2013, 2017 MariaDB Corporation. 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
@@ -49,15 +49,6 @@ fil_space_is_page_compressed(
/*=========================*/
ulint id); /*!< in: space id */
/*******************************************************************//**
-Returns the page compression flag of the space, or false if the space
-is not compressed. The tablespace must be cached in the memory cache.
-@return true if page compressed, false if not or space not found */
-UNIV_INTERN
-bool
-fil_space_get_page_compressed(
-/*=========================*/
- fil_space_t* space); /*!< in: space id */
-/*******************************************************************//**
Returns the atomic writes flag of the space, or false if the space
is not using atomic writes. The tablespace must be cached in the memory cache.
@return atomic write table option value */
diff --git a/storage/innobase/include/fsp0file.h b/storage/innobase/include/fsp0file.h
index 5129c63108a..1c4ac8152c9 100644
--- a/storage/innobase/include/fsp0file.h
+++ b/storage/innobase/include/fsp0file.h
@@ -231,13 +231,9 @@ public:
successfully opened in order for this function to validate it.
@param[in] space_id The expected tablespace ID.
@param[in] flags The expected tablespace flags.
- @param[in] for_import is it for importing
@retval DB_SUCCESS if tablespace is valid, DB_ERROR if not.
m_is_valid is also set true on success, else false. */
- dberr_t validate_to_dd(
- ulint space_id,
- ulint flags,
- bool for_import)
+ dberr_t validate_to_dd(ulint space_id, ulint flags)
MY_ATTRIBUTE((warn_unused_result));
/** Validates this datafile for the purpose of recovery.
@@ -256,13 +252,10 @@ public:
so the Space ID found here must not already be open.
m_is_valid is set true on success, else false.
@param[out] flush_lsn contents of FIL_PAGE_FILE_FLUSH_LSN
- @param[in] for_import if it is for importing
- (only valid for the first file of the system tablespace)
@retval DB_SUCCESS on if the datafile is valid
@retval DB_CORRUPTION if the datafile is not readable
@retval DB_TABLESPACE_EXISTS if there is a duplicate space_id */
- dberr_t validate_first_page(lsn_t* flush_lsn,
- bool for_import)
+ dberr_t validate_first_page(lsn_t* flush_lsn)
MY_ATTRIBUTE((warn_unused_result));
/** Get Datafile::m_name.
@@ -414,12 +407,10 @@ private:
else DB_ERROR. */
dberr_t find_space_id();
- /** Finds a given page of the given space id from the double write
- buffer and copies it to the corresponding .ibd file.
- @param[in] page_no Page number to restore
- @return DB_SUCCESS if page was restored, else DB_ERROR */
- dberr_t restore_from_doublewrite(
- ulint restore_page_no);
+ /** Restore the first page of the tablespace from
+ the double write buffer.
+ @return whether the operation failed */
+ bool restore_from_doublewrite();
/** Points into m_filepath to the file name with extension */
char* m_filename;
diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h
index 2551677ecbe..fa8d5b76960 100644
--- a/storage/innobase/include/fsp0fsp.h
+++ b/storage/innobase/include/fsp0fsp.h
@@ -43,17 +43,55 @@ Created 12/18/1995 Heikki Tuuri
#endif /* !UNIV_INNOCHECKSUM */
#include "fsp0types.h"
-#define FSP_FLAGS_POS_DATA_DIR_ORACLE (FSP_FLAGS_POS_ATOMIC_BLOBS \
- + FSP_FLAGS_WIDTH_ATOMIC_BLOBS \
- + FSP_FLAGS_WIDTH_PAGE_SSIZE)
-/** Bit mask of the DATA_DIR field */
-#define FSP_FLAGS_MASK_DATA_DIR_ORACLE \
- ((~(~0U << FSP_FLAGS_WIDTH_DATA_DIR)) \
- << FSP_FLAGS_POS_DATA_DIR_ORACLE)
-
-#define FSP_FLAGS_HAS_DATA_DIR_ORACLE(flags) \
- ((flags & FSP_FLAGS_MASK_DATA_DIR_ORACLE) \
- >> FSP_FLAGS_POS_DATA_DIR_ORACLE)
+/** @return the PAGE_SSIZE flags for the current innodb_page_size */
+#define FSP_FLAGS_PAGE_SSIZE() \
+ ((UNIV_PAGE_SIZE == UNIV_PAGE_SIZE_ORIG) ? \
+ 0 : (UNIV_PAGE_SIZE_SHIFT - UNIV_ZIP_SIZE_SHIFT_MIN + 1) \
+ << FSP_FLAGS_POS_PAGE_SSIZE)
+
+/* @defgroup Compatibility macros for MariaDB 10.1.0 through 10.1.20;
+see the table in fsp0types.h @{ */
+/** Zero relative shift position of the PAGE_COMPRESSION field */
+#define FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101 \
+ (FSP_FLAGS_POS_ATOMIC_BLOBS \
+ + FSP_FLAGS_WIDTH_ATOMIC_BLOBS)
+/** Zero relative shift position of the PAGE_COMPRESSION_LEVEL field */
+#define FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101 \
+ (FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101 + 1)
+/** Zero relative shift position of the ATOMIC_WRITES field */
+#define FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101 \
+ (FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101 + 4)
+/** Zero relative shift position of the PAGE_SSIZE field */
+#define FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101 \
+ (FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101 + 2)
+
+/** Bit mask of the PAGE_COMPRESSION field */
+#define FSP_FLAGS_MASK_PAGE_COMPRESSION_MARIADB101 \
+ (1U << FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101)
+/** Bit mask of the PAGE_COMPRESSION_LEVEL field */
+#define FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL_MARIADB101 \
+ (15U << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101)
+/** Bit mask of the ATOMIC_WRITES field */
+#define FSP_FLAGS_MASK_ATOMIC_WRITES_MARIADB101 \
+ (3U << FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101)
+/** Bit mask of the PAGE_SSIZE field */
+#define FSP_FLAGS_MASK_PAGE_SSIZE_MARIADB101 \
+ (15U << FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101)
+
+/** Return the value of the PAGE_COMPRESSION field */
+#define FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags) \
+ ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_MARIADB101) \
+ >> FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101)
+/** Return the value of the PAGE_COMPRESSION_LEVEL field */
+#define FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL_MARIADB101(flags) \
+ ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL_MARIADB101) \
+ >> FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101)
+/** Return the value of the PAGE_SSIZE field */
+#define FSP_FLAGS_GET_PAGE_SSIZE_MARIADB101(flags) \
+ ((flags & FSP_FLAGS_MASK_PAGE_SSIZE_MARIADB101) \
+ >> FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101)
+
+/* @} */
/* @defgroup Tablespace Header Constants (moved from fsp0fsp.c) @{ */
@@ -629,47 +667,135 @@ fseg_print(
mtr_t* mtr); /*!< in/out: mini-transaction */
#endif /* UNIV_BTR_PRINT */
-/** Determine if the tablespace is compressed from tablespace flags.
-@param[in] flags Tablespace flags
-@return true if compressed, false if not compressed */
-UNIV_INLINE
-bool
-fsp_flags_is_compressed(
- ulint flags);
-
-/** Initialize an FSP flags integer.
-@param[in] page_size page sizes in bytes and compression flag.
-@param[in] atomic_blobs Used by Dynammic and Compressed.
-@param[in] has_data_dir This tablespace is in a remote location.
-@param[in] page_compressed Table uses page compression
-@param[in] page_compression_level Page compression level
-@param[in] not_used For future
-@return tablespace flags after initialization */
+/** Convert FSP_SPACE_FLAGS from the buggy MariaDB 10.1.0..10.1.20 format.
+@param[in] flags the contents of FSP_SPACE_FLAGS
+@return the flags corrected from the buggy MariaDB 10.1 format
+@retval ULINT_UNDEFINED if the flags are not in the buggy 10.1 format */
+MY_ATTRIBUTE((warn_unused_result, const))
UNIV_INLINE
ulint
-fsp_flags_init(
- const page_size_t& page_size,
- bool atomic_blobs,
- bool has_data_dir,
- bool page_compression,
- ulint page_compression_level,
- ulint not_used);
-
-/** Convert a 32 bit integer tablespace flags to the 32 bit table flags.
-This can only be done for a tablespace that was built as a file-per-table
-tablespace. Note that the fsp_flags cannot show the difference between a
-Compact and Redundant table, so an extra Compact boolean must be supplied.
- Low order bit
- | REDUNDANT | COMPACT | COMPRESSED | DYNAMIC
-fil_space_t::flags | 0 | 0 | 1 | 1
-dict_table_t::flags | 0 | 1 | 1 | 1
-@param[in] fsp_flags fil_space_t::flags
-@param[in] compact true if not Redundant row format
-@return tablespace flags (fil_space_t::flags) */
-ulint
-fsp_flags_to_dict_tf(
- ulint fsp_flags,
- bool compact);
+fsp_flags_convert_from_101(ulint flags)
+{
+ DBUG_EXECUTE_IF("fsp_flags_is_valid_failure",
+ return(ULINT_UNDEFINED););
+ if (flags == 0) {
+ return(flags);
+ }
+
+ if (flags >> 18) {
+ /* The most significant FSP_SPACE_FLAGS bit that was ever set
+ by MariaDB 10.1.0 to 10.1.20 was bit 17 (misplaced DATA_DIR flag).
+ The flags must be less than 1<<18 in order to be valid. */
+ return(ULINT_UNDEFINED);
+ }
+
+ if ((flags & (FSP_FLAGS_MASK_POST_ANTELOPE | FSP_FLAGS_MASK_ATOMIC_BLOBS))
+ == FSP_FLAGS_MASK_ATOMIC_BLOBS) {
+ /* If the "atomic blobs" flag (indicating
+ ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED) flag
+ is set, then the "post Antelope" (ROW_FORMAT!=REDUNDANT) flag
+ must also be set. */
+ return(ULINT_UNDEFINED);
+ }
+
+ /* Bits 6..10 denote compression in MariaDB 10.1.0 to 10.1.20.
+ They must be either 0b00000 or 0b00011 through 0b10011.
+ In correct versions, these bits would be
+ 0bd0sss where d is the DATA_DIR flag (garbage bit) and
+ sss is the PAGE_SSIZE (3, 4, 6, or 7).
+
+ NOTE: MariaDB 10.1.0 to 10.1.20 can misinterpret
+ uncompressed data files with innodb_page_size=4k or 64k as
+ compressed innodb_page_size=16k files. Below is an exhaustive
+ state space analysis.
+
+ -0by1zzz: impossible (the bit 4 must be clean; see above)
+ -0b101xx: DATA_DIR, innodb_page_size>4k: invalid (COMPRESSION_LEVEL>9)
+ +0bx0011: innodb_page_size=4k:
+ !!! Misinterpreted as COMPRESSION_LEVEL=9 or 1, COMPRESSION=1.
+ -0bx0010: impossible, because sss must be 0b011 or 0b1xx
+ -0bx0001: impossible, because sss must be 0b011 or 0b1xx
+ -0b10000: DATA_DIR, innodb_page_size=16:
+ invalid (COMPRESSION_LEVEL=8 but COMPRESSION=0)
+ +0b00111: no DATA_DIR, innodb_page_size=64k:
+ !!! Misinterpreted as COMPRESSION_LEVEL=3, COMPRESSION=1.
+ -0b00101: impossible, because sss must be 0 for 16k, not 0b101
+ -0b001x0: no DATA_DIR, innodb_page_size=32k or 8k:
+ invalid (COMPRESSION_LEVEL=3 but COMPRESSION=0)
+ +0b00000: innodb_page_size=16k (looks like COMPRESSION=0)
+ ??? Could actually be compressed; see PAGE_SSIZE below */
+ const ulint level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL_MARIADB101(
+ flags);
+ if (FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags) != (level != 0)
+ || level > 9) {
+ /* The compression flags are not in the buggy MariaDB
+ 10.1 format. */
+ return(ULINT_UNDEFINED);
+ }
+ if (!(~flags & FSP_FLAGS_MASK_ATOMIC_WRITES_MARIADB101)) {
+ /* The ATOMIC_WRITES flags cannot be 0b11.
+ (The bits 11..12 should actually never be 0b11,
+ because in MySQL they would be SHARED|TEMPORARY.) */
+ return(ULINT_UNDEFINED);
+ }
+
+ /* Bits 13..16 are the wrong position for PAGE_SSIZE, and they
+ should contain one of the values 3,4,6,7, that is, be of the form
+ 0b0011 or 0b01xx (except 0b0110).
+ In correct versions, these bits should be 0bc0se
+ where c is the MariaDB COMPRESSED flag
+ and e is the MySQL 5.7 ENCRYPTION flag
+ and s is the MySQL 8.0 SDI flag. MariaDB can only support s=0, e=0.
+
+ Compressed innodb_page_size=16k tables with correct FSP_SPACE_FLAGS
+ will be properly rejected by older MariaDB 10.1.x because they
+ would read as PAGE_SSIZE>=8 which is not valid. */
+
+ const ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE_MARIADB101(flags);
+ if (ssize == 1 || ssize == 2 || ssize == 5 || ssize & 8) {
+ /* the page_size is not between 4k and 64k;
+ 16k should be encoded as 0, not 5 */
+ return(ULINT_UNDEFINED);
+ }
+ const ulint zssize = FSP_FLAGS_GET_ZIP_SSIZE(flags);
+ if (zssize == 0) {
+ /* not ROW_FORMAT=COMPRESSED */
+ } else if (zssize > (ssize ? ssize : 5)) {
+ /* invalid KEY_BLOCK_SIZE */
+ return(ULINT_UNDEFINED);
+ } else if (~flags & (FSP_FLAGS_MASK_POST_ANTELOPE
+ | FSP_FLAGS_MASK_ATOMIC_BLOBS)) {
+ /* both these flags should be set for
+ ROW_FORMAT=COMPRESSED */
+ return(ULINT_UNDEFINED);
+ }
+
+ flags = ((flags & 0x3f) | ssize << FSP_FLAGS_POS_PAGE_SSIZE
+ | FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags)
+ << FSP_FLAGS_POS_PAGE_COMPRESSION);
+ ut_ad(fsp_flags_is_valid(flags));
+ return(flags);
+}
+
+/** Compare tablespace flags.
+@param[in] expected expected flags from dict_tf_to_fsp_flags()
+@param[in] actual flags read from FSP_SPACE_FLAGS
+@return whether the flags match */
+MY_ATTRIBUTE((warn_unused_result))
+UNIV_INLINE
+bool
+fsp_flags_match(ulint expected, ulint actual)
+{
+ expected &= ~FSP_FLAGS_MEM_MASK;
+ ut_ad(fsp_flags_is_valid(expected));
+
+ if (actual == expected) {
+ return(true);
+ }
+
+ actual = fsp_flags_convert_from_101(actual);
+ return(actual == expected);
+}
/** Calculates the descriptor index within a descriptor page.
@param[in] page_size page size
diff --git a/storage/innobase/include/fsp0fsp.ic b/storage/innobase/include/fsp0fsp.ic
index 6d0d6f05a9f..6317a67a089 100644
--- a/storage/innobase/include/fsp0fsp.ic
+++ b/storage/innobase/include/fsp0fsp.ic
@@ -40,162 +40,6 @@ fsp_descr_page(
== FSP_XDES_OFFSET);
}
-/** Determine if the tablespace is compressed from tablespace flags.
-@param[in] flags Tablespace flags
-@return true if compressed, false if not compressed */
-UNIV_INLINE
-bool
-fsp_flags_is_compressed(
- ulint flags)
-{
- return(FSP_FLAGS_GET_ZIP_SSIZE(flags) != 0);
-}
-
-#define ACTUAL_SSIZE(ssize) (0 == ssize ? UNIV_PAGE_SSIZE_ORIG : ssize)
-
-/** Convert a page size, which is a power of 2, to an ssize, which is
-the number of bit shifts from 512 to make that page size.
-@param[in] page_size compressed page size in bytes
-@return an ssize created from the page size provided. */
-UNIV_INLINE
-ulint
-page_size_to_ssize(
- ulint page_size)
-{
- ulint ssize;
-
- for (ssize = UNIV_ZIP_SIZE_SHIFT_MIN;
- ((ulint) 1 << ssize) < page_size;
- ssize++) {};
-
- return(ssize - UNIV_ZIP_SIZE_SHIFT_MIN + 1);
-}
-
-/** Add the compressed page size to the tablespace flags.
-@param[in] flags Tablespace flags
-@param[in] page_size page sizes in bytes and compression flag.
-@return tablespace flags after zip size is added */
-UNIV_INLINE
-ulint
-fsp_flags_set_zip_size(
- ulint flags,
- const page_size_t& page_size)
-{
- if (!page_size.is_compressed()) {
- return(flags);
- }
-
- /* Zip size should be a power of 2 between UNIV_ZIP_SIZE_MIN
- and UNIV_ZIP_SIZE_MAX */
- ut_ad(page_size.physical() >= UNIV_ZIP_SIZE_MIN);
- ut_ad(page_size.physical() <= UNIV_ZIP_SIZE_MAX);
- ut_ad(ut_is_2pow(page_size.physical()));
-
- ulint ssize = page_size_to_ssize(page_size.physical());
-
- ut_ad(ssize > 0);
- ut_ad(ssize <= UNIV_PAGE_SSIZE_MAX);
-
- flags |= (ssize << FSP_FLAGS_POS_ZIP_SSIZE);
-
- ut_ad(fsp_flags_is_valid(flags));
-
- return(flags);
-}
-
-/** Add the page size to the tablespace flags.
-@param[in] flags Tablespace flags
-@param[in] page_size page sizes in bytes and compression flag.
-@return tablespace flags after page size is added */
-UNIV_INLINE
-ulint
-fsp_flags_set_page_size(
- ulint flags,
- const page_size_t& page_size)
-{
- /* Page size should be a power of two between UNIV_PAGE_SIZE_MIN
- and UNIV_PAGE_SIZE */
- ut_ad(page_size.logical() >= UNIV_PAGE_SIZE_MIN);
- ut_ad(page_size.logical() <= UNIV_PAGE_SIZE_MAX);
- ut_ad(ut_is_2pow(page_size.logical()));
-
- /* Remove this assert once we add support for different
- page size per tablespace. Currently all tablespaces must
- have a page size that is equal to innodb-page-size */
- ut_ad(page_size.logical() == UNIV_PAGE_SIZE);
-
- if (page_size.logical() == UNIV_PAGE_SIZE_ORIG) {
- ut_ad(0 == FSP_FLAGS_GET_PAGE_SSIZE(flags));
-
- } else {
- ulint ssize = page_size_to_ssize(page_size.logical());
-
- ut_ad(ssize);
- ut_ad(ssize <= UNIV_PAGE_SSIZE_MAX);
-
- flags |= (ssize << FSP_FLAGS_POS_PAGE_SSIZE);
- }
-
- ut_ad(fsp_flags_is_valid(flags));
-
- return(flags);
-}
-
-/** Initialize an FSP flags integer.
-@param[in] page_size page sizes in bytes and compression flag.
-@param[in] atomic_blobs Used by Dynammic and Compressed.
-@param[in] has_data_dir This tablespace is in a remote location.
-@param[in] page_compressed Table uses page compression
-@param[in] page_compression_level Page compression level
-@param[in] not_used For future
-@@return tablespace flags after initialization */
-UNIV_INLINE
-ulint
-fsp_flags_init(
- const page_size_t& page_size,
- bool atomic_blobs,
- bool has_data_dir,
- bool page_compression,
- ulint page_compression_level,
- ulint not_used)
-{
- ut_ad(page_size.physical() <= page_size.logical());
- ut_ad(!page_size.is_compressed() || atomic_blobs);
-
- /* Page size should be a power of two between UNIV_PAGE_SIZE_MIN
- and UNIV_PAGE_SIZE, but zip_size may be 0 if not compressed. */
- ulint flags = fsp_flags_set_page_size(0, page_size);
-
- if (atomic_blobs) {
- flags |= FSP_FLAGS_MASK_POST_ANTELOPE
- | FSP_FLAGS_MASK_ATOMIC_BLOBS;
- }
-
- /* If the zip_size is explicit and different from the default,
- compressed row format is implied. */
- flags = fsp_flags_set_zip_size(flags, page_size);
-
- if (has_data_dir) {
- flags |= FSP_FLAGS_MASK_DATA_DIR;
- }
-
- /* In addition, tablespace flags also contain if the page
- compression is used for this table. */
- if (page_compression) {
- flags |= FSP_FLAGS_SET_PAGE_COMPRESSION(flags, page_compression);
- }
-
- /* In addition, tablespace flags also contain page compression level
- if page compression is used for this table. */
- if (page_compression && page_compression_level) {
- flags |= FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(flags, page_compression_level);
- }
-
- ut_ad(fsp_flags_is_valid(flags));
-
- return(flags);
-}
-
/** Calculates the descriptor index within a descriptor page.
@param[in] page_size page size
@param[in] offset page offset
diff --git a/storage/innobase/include/fsp0pagecompress.h b/storage/innobase/include/fsp0pagecompress.h
index 9038aa0fdef..b45a4b87890 100644
--- a/storage/innobase/include/fsp0pagecompress.h
+++ b/storage/innobase/include/fsp0pagecompress.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2013, 2017, MariaDB Corporation. 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
@@ -48,15 +48,6 @@ fsp_header_get_compression_level(
const page_t* page); /*!< in: first page of a tablespace */
/********************************************************************//**
-Determine if the tablespace is page compressed from dict_table_t::flags.
-@return TRUE if page compressed, FALSE if not compressed */
-UNIV_INLINE
-bool
-fsp_flags_is_page_compressed(
-/*=========================*/
- ulint flags); /*!< in: tablespace flags */
-
-/********************************************************************//**
Extract the page compression level from tablespace flags.
A tablespace has only one physical page compression level
whether that page is compressed or not.
diff --git a/storage/innobase/include/fsp0pagecompress.ic b/storage/innobase/include/fsp0pagecompress.ic
index 0915fae4b92..bb11371d712 100644
--- a/storage/innobase/include/fsp0pagecompress.ic
+++ b/storage/innobase/include/fsp0pagecompress.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2013, 2017, MariaDB Corporation. 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
@@ -26,18 +26,6 @@ Created 11/12/2013 Jan Lindström jan.lindstrom@mariadb.com
***********************************************************************/
/********************************************************************//**
-Determine if the tablespace is page compressed from dict_table_t::flags.
-@return TRUE if page compressed, FALSE if not page compressed */
-UNIV_INLINE
-bool
-fsp_flags_is_page_compressed(
-/*=========================*/
- ulint flags) /*!< in: tablespace flags */
-{
- return(FSP_FLAGS_GET_PAGE_COMPRESSION(flags));
-}
-
-/********************************************************************//**
Determine the tablespace is page compression level from dict_table_t::flags.
@return page compression level or 0 if not compressed*/
UNIV_INLINE
@@ -119,16 +107,10 @@ fil_space_is_page_compressed(
/*=========================*/
ulint id) /*!< in: space id */
{
- ulint flags;
-
- flags = fil_space_get_flags(id);
-
- if (flags && flags != ULINT_UNDEFINED) {
-
- return(fsp_flags_is_page_compressed(flags));
- }
+ ulint flags = fil_space_get_flags(id);
- return(0);
+ return(flags != ULINT_UNDEFINED
+ && FSP_FLAGS_HAS_PAGE_COMPRESSION(flags));
}
#endif /* UNIV_INNOCHECKSUM */
diff --git a/storage/innobase/include/fsp0types.h b/storage/innobase/include/fsp0types.h
index 1c535677e83..429af4210b7 100644
--- a/storage/innobase/include/fsp0types.h
+++ b/storage/innobase/include/fsp0types.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2016, MariaDB Corporation.
+Copyright (c) 2014, 2017, MariaDB Corporation.
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
@@ -187,18 +187,6 @@ every XDES_DESCRIBED_PER_PAGE pages in every tablespace. */
/*--------------------------------------*/
/* @} */
-/** Validate the tablespace flags.
-These flags are stored in the tablespace header at offset FSP_SPACE_FLAGS.
-They should be 0 for ROW_FORMAT=COMPACT and ROW_FORMAT=REDUNDANT.
-The newer row formats, COMPRESSED and DYNAMIC, use a file format > Antelope
-so they should have a file format number plus the DICT_TF_COMPACT bit set.
-@param[in] flags Tablespace flags
-@return true if valid, false if not */
-bool
-fsp_flags_is_valid(
- ulint flags)
- MY_ATTRIBUTE((warn_unused_result, const));
-
/** Check if tablespace is system temporary.
@param[in] space_id verify is checksum is enabled for given space.
@return true if tablespace is system temporary. */
@@ -240,43 +228,68 @@ to the two Barracuda row formats COMPRESSED and DYNAMIC. */
#define FSP_FLAGS_WIDTH_ATOMIC_BLOBS 1
/** Number of flag bits used to indicate the tablespace page size */
#define FSP_FLAGS_WIDTH_PAGE_SSIZE 4
-/** Width of the DATA_DIR flag. This flag indicates that the tablespace
-is found in a remote location, not the default data directory. */
-#define FSP_FLAGS_WIDTH_DATA_DIR 1
-/** Width of the SHARED flag. This flag indicates that the tablespace
-was created with CREATE TABLESPACE and can be shared by multiple tables. */
-#define FSP_FLAGS_WIDTH_SHARED 1
-/** Width of the TEMPORARY flag. This flag indicates that the tablespace
-is a temporary tablespace and everything in it is temporary, meaning that
-it is for a single client and should be deleted upon startup if it exists. */
-#define FSP_FLAGS_WIDTH_TEMPORARY 1
-/** Width of the encryption flag. This flag indicates that the tablespace
-is a tablespace with encryption. */
-#define FSP_FLAGS_WIDTH_ENCRYPTION 1
-
-/** Number of flag bits used to indicate the page compression and compression level */
-#define FSP_FLAGS_WIDTH_PAGE_COMPRESSION 1
-#define FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL 4
-
-/** Number of flag bits used to indicate atomic writes for this tablespace */
-#define FSP_FLAGS_WIDTH_ATOMIC_WRITES 2
-
-/** Width of all the currently known tablespace flags */
+/** Number of reserved bits */
+#define FSP_FLAGS_WIDTH_RESERVED 6
+/** Number of flag bits used to indicate the page compression */
+#define FSP_FLAGS_WIDTH_PAGE_COMPRESSION 1
+
+/** Width of all the currently known persistent tablespace flags */
#define FSP_FLAGS_WIDTH (FSP_FLAGS_WIDTH_POST_ANTELOPE \
+ FSP_FLAGS_WIDTH_ZIP_SSIZE \
+ FSP_FLAGS_WIDTH_ATOMIC_BLOBS \
+ FSP_FLAGS_WIDTH_PAGE_SSIZE \
- + FSP_FLAGS_WIDTH_DATA_DIR \
- + FSP_FLAGS_WIDTH_SHARED \
- + FSP_FLAGS_WIDTH_TEMPORARY \
- + FSP_FLAGS_WIDTH_ENCRYPTION \
- + FSP_FLAGS_WIDTH_PAGE_COMPRESSION \
- + FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL \
- + FSP_FLAGS_WIDTH_ATOMIC_WRITES )
-
-/** A mask of all the known/used bits in tablespace flags */
+ + FSP_FLAGS_WIDTH_RESERVED \
+ + FSP_FLAGS_WIDTH_PAGE_COMPRESSION)
+
+/** A mask of all the known/used bits in FSP_SPACE_FLAGS */
#define FSP_FLAGS_MASK (~(~0U << FSP_FLAGS_WIDTH))
+/* FSP_SPACE_FLAGS position and name in MySQL 5.6/MariaDB 10.0 or older
+and MariaDB 10.1.20 or older MariaDB 10.1 and in MariaDB 10.1.21
+or newer.
+MySQL 5.6 MariaDB 10.1.x MariaDB 10.1.21
+====================================================================
+Below flags in same offset
+====================================================================
+0: POST_ANTELOPE 0:POST_ANTELOPE 0: POST_ANTELOPE
+1..4: ZIP_SSIZE(0..5) 1..4:ZIP_SSIZE(0..5) 1..4: ZIP_SSIZE(0..5)
+(NOTE: bit 4 is always 0)
+5: ATOMIC_BLOBS 5:ATOMIC_BLOBS 5: ATOMIC_BLOBS
+=====================================================================
+Below note the order difference:
+=====================================================================
+6..9: PAGE_SSIZE(3..7) 6: COMPRESSION 6..9: PAGE_SSIZE(3..7)
+10: DATA_DIR 7..10: COMP_LEVEL(0..9) 10: RESERVED (5.6 DATA_DIR)
+=====================================================================
+The flags below were in incorrect position in MariaDB 10.1,
+or have been introduced in MySQL 5.7 or 8.0:
+=====================================================================
+11: UNUSED 11..12:ATOMIC_WRITES 11: RESERVED (5.7 SHARED)
+ 12: RESERVED (5.7 TEMPORARY)
+ 13..15:PAGE_SSIZE(3..7) 13: RESERVED (5.7 ENCRYPTION)
+ 14: RESERVED (8.0 SDI)
+ 15: RESERVED
+ 16: PAGE_SSIZE_msb(0) 16: COMPRESSION
+ 17: DATA_DIR 17: UNUSED
+ 18: UNUSED
+=====================================================================
+The flags below only exist in fil_space_t::flags, not in FSP_SPACE_FLAGS:
+=====================================================================
+ 25: DATA_DIR
+ 26..27: ATOMIC_WRITES
+ 28..31: COMPRESSION_LEVEL
+*/
+
+/** A mask of the memory-only flags in fil_space_t::flags */
+#define FSP_FLAGS_MEM_MASK (~0U << FSP_FLAGS_MEM_DATA_DIR)
+
+/** Zero relative shift position of the DATA_DIR flag */
+#define FSP_FLAGS_MEM_DATA_DIR 25
+/** Zero relative shift position of the ATOMIC_WRITES field */
+#define FSP_FLAGS_MEM_ATOMIC_WRITES 26
+/** Zero relative shift position of the COMPRESSION_LEVEL field */
+#define FSP_FLAGS_MEM_COMPRESSION_LEVEL 28
+
/** Zero relative shift position of the POST_ANTELOPE field */
#define FSP_FLAGS_POS_POST_ANTELOPE 0
/** Zero relative shift position of the ZIP_SSIZE field */
@@ -285,34 +298,16 @@ is a tablespace with encryption. */
/** Zero relative shift position of the ATOMIC_BLOBS field */
#define FSP_FLAGS_POS_ATOMIC_BLOBS (FSP_FLAGS_POS_ZIP_SSIZE \
+ FSP_FLAGS_WIDTH_ZIP_SSIZE)
-/** Zero relative shift position of the PAGE_SSIZE field */
+/** Zero relative shift position of the start of the PAGE_SSIZE bits */
#define FSP_FLAGS_POS_PAGE_SSIZE (FSP_FLAGS_POS_ATOMIC_BLOBS \
- + FSP_FLAGS_WIDTH_ATOMIC_BLOBS)
-/** Zero relative shift position of the start of the DATA_DIR bit */
-#define FSP_FLAGS_POS_DATA_DIR (FSP_FLAGS_POS_PAGE_SSIZE \
+ + FSP_FLAGS_WIDTH_ATOMIC_BLOBS)
+/** Zero relative shift position of the start of the RESERVED bits
+these are only used in MySQL 5.7 and used for compatibility. */
+#define FSP_FLAGS_POS_RESERVED (FSP_FLAGS_POS_PAGE_SSIZE \
+ FSP_FLAGS_WIDTH_PAGE_SSIZE)
-/** Zero relative shift position of the start of the SHARED bit */
-#define FSP_FLAGS_POS_SHARED (FSP_FLAGS_POS_DATA_DIR \
- + FSP_FLAGS_WIDTH_DATA_DIR)
-/** Zero relative shift position of the start of the TEMPORARY bit */
-#define FSP_FLAGS_POS_TEMPORARY (FSP_FLAGS_POS_SHARED \
- + FSP_FLAGS_WIDTH_SHARED)
-/** Zero relative shift position of the start of the ENCRYPTION bit */
-#define FSP_FLAGS_POS_ENCRYPTION (FSP_FLAGS_POS_TEMPORARY \
- + FSP_FLAGS_WIDTH_TEMPORARY)
/** Zero relative shift position of the PAGE_COMPRESSION field */
-#define FSP_FLAGS_POS_PAGE_COMPRESSION (FSP_FLAGS_POS_ENCRYPTION \
- + FSP_FLAGS_WIDTH_ENCRYPTION)
-/** Zero relative shift position of the PAGE_COMPRESSION_LEVEL field */
-#define FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL (FSP_FLAGS_POS_PAGE_COMPRESSION \
- + FSP_FLAGS_WIDTH_PAGE_COMPRESSION)
-/** Zero relative shift position of the ATOMIC_WRITES field */
-#define FSP_FLAGS_POS_ATOMIC_WRITES (FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL \
- + FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL)
-/** Zero relative shift position of the start of the UNUSED bits */
-#define FSP_FLAGS_POS_UNUSED (FSP_FLAGS_POS_ATOMIC_WRITES \
- + FSP_FLAGS_WIDTH_ATOMIC_WRITES)
-
+#define FSP_FLAGS_POS_PAGE_COMPRESSION (FSP_FLAGS_POS_RESERVED \
+ + FSP_FLAGS_WIDTH_RESERVED)
/** Bit mask of the POST_ANTELOPE field */
#define FSP_FLAGS_MASK_POST_ANTELOPE \
@@ -330,26 +325,22 @@ is a tablespace with encryption. */
#define FSP_FLAGS_MASK_PAGE_SSIZE \
((~(~0U << FSP_FLAGS_WIDTH_PAGE_SSIZE)) \
<< FSP_FLAGS_POS_PAGE_SSIZE)
-/** Bit mask of the DATA_DIR field */
-#define FSP_FLAGS_MASK_DATA_DIR \
- ((~(~0U << FSP_FLAGS_WIDTH_DATA_DIR)) \
- << FSP_FLAGS_POS_DATA_DIR)
-/** Bit mask of the TEMPORARY field */
-#define FSP_FLAGS_MASK_TEMPORARY \
- ((~(~0U << FSP_FLAGS_WIDTH_TEMPORARY)) \
- << FSP_FLAGS_POS_TEMPORARY)
+/** Bit mask of the RESERVED1 field */
+#define FSP_FLAGS_MASK_RESERVED \
+ ((~(~0U << FSP_FLAGS_WIDTH_RESERVED)) \
+ << FSP_FLAGS_POS_RESERVED)
/** Bit mask of the PAGE_COMPRESSION field */
-#define FSP_FLAGS_MASK_PAGE_COMPRESSION \
+#define FSP_FLAGS_MASK_PAGE_COMPRESSION \
((~(~0U << FSP_FLAGS_WIDTH_PAGE_COMPRESSION)) \
<< FSP_FLAGS_POS_PAGE_COMPRESSION)
-/** Bit mask of the PAGE_COMPRESSION_LEVEL field */
-#define FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL \
- ((~(~0U << FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL)) \
- << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL)
-/** Bit mask of the ATOMIC_WRITES field */
-#define FSP_FLAGS_MASK_ATOMIC_WRITES \
- ((~(~0U << FSP_FLAGS_WIDTH_ATOMIC_WRITES)) \
- << FSP_FLAGS_POS_ATOMIC_WRITES)
+
+/** Bit mask of the in-memory ATOMIC_WRITES field */
+#define FSP_FLAGS_MASK_MEM_ATOMIC_WRITES \
+ (3U << FSP_FLAGS_MEM_ATOMIC_WRITES)
+
+/** Bit mask of the in-memory COMPRESSION_LEVEL field */
+#define FSP_FLAGS_MASK_MEM_COMPRESSION_LEVEL \
+ (15U << FSP_FLAGS_MEM_COMPRESSION_LEVEL)
/** Return the value of the POST_ANTELOPE field */
#define FSP_FLAGS_GET_POST_ANTELOPE(flags) \
@@ -367,43 +358,88 @@ is a tablespace with encryption. */
#define FSP_FLAGS_GET_PAGE_SSIZE(flags) \
((flags & FSP_FLAGS_MASK_PAGE_SSIZE) \
>> FSP_FLAGS_POS_PAGE_SSIZE)
-/** Return the value of the DATA_DIR field */
-#define FSP_FLAGS_HAS_DATA_DIR(flags) \
- ((flags & FSP_FLAGS_MASK_DATA_DIR) \
- >> FSP_FLAGS_POS_DATA_DIR)
-/** Return the contents of the TEMPORARY field */
-#define FSP_FLAGS_GET_TEMPORARY(flags) \
- ((flags & FSP_FLAGS_MASK_TEMPORARY) \
- >> FSP_FLAGS_POS_TEMPORARY)
+/** @return the RESERVED flags */
+#define FSP_FLAGS_GET_RESERVED(flags) \
+ ((flags & FSP_FLAGS_MASK_RESERVED) \
+ >> FSP_FLAGS_POS_RESERVED)
+/** @return the PAGE_COMPRESSION flag */
+#define FSP_FLAGS_HAS_PAGE_COMPRESSION(flags) \
+ ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION) \
+ >> FSP_FLAGS_POS_PAGE_COMPRESSION)
+
/** Return the contents of the UNUSED bits */
#define FSP_FLAGS_GET_UNUSED(flags) \
(flags >> FSP_FLAGS_POS_UNUSED)
-/** Return the value of the PAGE_COMPRESSION field */
-#define FSP_FLAGS_GET_PAGE_COMPRESSION(flags) \
- ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION) \
- >> FSP_FLAGS_POS_PAGE_COMPRESSION)
-/** Return the value of the PAGE_COMPRESSION_LEVEL field */
+
+/** @return the value of the DATA_DIR field */
+#define FSP_FLAGS_HAS_DATA_DIR(flags) \
+ (flags & 1U << FSP_FLAGS_MEM_DATA_DIR)
+/** @return the COMPRESSION_LEVEL field */
#define FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags) \
- ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL) \
- >> FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL)
-/** Return the value of the ATOMIC_WRITES field */
+ ((flags & FSP_FLAGS_MASK_MEM_COMPRESSION_LEVEL) \
+ >> FSP_FLAGS_MEM_COMPRESSION_LEVEL)
+/** @return the ATOMIC_WRITES field */
#define FSP_FLAGS_GET_ATOMIC_WRITES(flags) \
- ((flags & FSP_FLAGS_MASK_ATOMIC_WRITES) \
- >> FSP_FLAGS_POS_ATOMIC_WRITES)
-/* @} */
+ ((flags & FSP_FLAGS_MASK_MEM_ATOMIC_WRITES) \
+ >> FSP_FLAGS_MEM_ATOMIC_WRITES)
-/** Set a PAGE_COMPRESSION into the correct bits in a given
-tablespace flags. */
-#define FSP_FLAGS_SET_PAGE_COMPRESSION(flags, compression) \
- (flags | (compression << FSP_FLAGS_POS_PAGE_COMPRESSION))
+/* @} */
-/** Set a PAGE_COMPRESSION_LEVEL into the correct bits in a given
-tablespace flags. */
-#define FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(flags, level) \
- (flags | (level << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL))
+/** Validate the tablespace flags, which are stored in the
+tablespace header at offset FSP_SPACE_FLAGS.
+@param[in] flags the contents of FSP_SPACE_FLAGS
+@return whether the flags are correct (not in the buggy 10.1) format */
+MY_ATTRIBUTE((warn_unused_result, const))
+UNIV_INLINE
+bool
+fsp_flags_is_valid(ulint flags)
+{
+ DBUG_EXECUTE_IF("fsp_flags_is_valid_failure",
+ return(false););
+ if (flags == 0) {
+ return(true);
+ }
+ if (flags & ~FSP_FLAGS_MASK) {
+ return(false);
+ }
+ if ((flags & (FSP_FLAGS_MASK_POST_ANTELOPE | FSP_FLAGS_MASK_ATOMIC_BLOBS))
+ == FSP_FLAGS_MASK_ATOMIC_BLOBS) {
+ /* If the "atomic blobs" flag (indicating
+ ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED) flag
+ is set, then the "post Antelope" (ROW_FORMAT!=REDUNDANT) flag
+ must also be set. */
+ return(false);
+ }
+ /* Bits 10..14 should be 0b0000d where d is the DATA_DIR flag
+ of MySQL 5.6 and MariaDB 10.0, which we ignore.
+ In the buggy FSP_SPACE_FLAGS written by MariaDB 10.1.0 to 10.1.20,
+ bits 10..14 would be nonzero 0bsssaa where sss is
+ nonzero PAGE_SSIZE (3, 4, 6, or 7)
+ and aa is ATOMIC_WRITES (not 0b11). */
+ if (FSP_FLAGS_GET_RESERVED(flags) & ~1) {
+ return(false);
+ }
+
+ const ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags);
+ if (ssize == 1 || ssize == 2 || ssize == 5 || ssize & 8) {
+ /* the page_size is not between 4k and 64k;
+ 16k should be encoded as 0, not 5 */
+ return(false);
+ }
+ const ulint zssize = FSP_FLAGS_GET_ZIP_SSIZE(flags);
+ if (zssize == 0) {
+ /* not ROW_FORMAT=COMPRESSED */
+ } else if (zssize > (ssize ? ssize : 5)) {
+ /* invalid KEY_BLOCK_SIZE */
+ return(false);
+ } else if (~flags & (FSP_FLAGS_MASK_POST_ANTELOPE
+ | FSP_FLAGS_MASK_ATOMIC_BLOBS)) {
+ /* both these flags should be set for
+ ROW_FORMAT=COMPRESSED */
+ return(false);
+ }
+
+ return(true);
+}
-/** Set a ATOMIC_WRITES into the correct bits in a given
-tablespace flags. */
-#define FSP_FLAGS_SET_ATOMIC_WRITES(flags, atomics) \
- (flags | (atomics << FSP_FLAGS_POS_ATOMIC_WRITES))
#endif /* fsp0types_h */
diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h
index f54c935027b..acffa1b562b 100644
--- a/storage/innobase/include/log0recv.h
+++ b/storage/innobase/include/log0recv.h
@@ -173,7 +173,7 @@ struct recv_addr_t{
struct recv_dblwr_t {
/** Add a page frame to the doublewrite recovery buffer. */
- void add(const byte* page) {
+ void add(byte* page) {
pages.push_back(page);
}
@@ -184,7 +184,7 @@ struct recv_dblwr_t {
@retval NULL if no page was found */
const byte* find_page(ulint space_id, ulint page_no);
- typedef std::list<const byte*, ut_allocator<const byte*> > list;
+ typedef std::list<byte*, ut_allocator<byte*> > list;
/** Recovered doublewrite buffer page frames */
list pages;
diff --git a/storage/innobase/include/os0thread.h b/storage/innobase/include/os0thread.h
index 9ba35b6f359..74b5a65766c 100644
--- a/storage/innobase/include/os0thread.h
+++ b/storage/innobase/include/os0thread.h
@@ -117,9 +117,24 @@ os_thread_create_func(
os_thread_id_t* thread_id); /*!< out: id of the created
thread, or NULL */
-/** Exits the current thread. */
+/** Waits until the specified thread completes and joins it.
+Its return value is ignored.
+@param[in,out] thread thread to join */
+UNIV_INTERN
void
-os_thread_exit()
+os_thread_join(os_thread_t thread);
+
+/*****************************************************************//**
+Exits the current thread. */
+UNIV_INTERN
+void
+os_thread_exit(
+/*===========*/
+ void* exit_value, /*!< in: exit value; in Windows this void*
+ is cast as a DWORD */
+ bool detach = true) /*!< in: if true, the thread will be detached
+ right before exiting. If false, another thread
+ is responsible for joining this thread. */
UNIV_COLD MY_ATTRIBUTE((noreturn));
/*****************************************************************//**
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index 227bcfb7781..6e85032dfba 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -485,6 +485,7 @@ extern unsigned long long srv_stats_persistent_sample_pages;
extern my_bool srv_stats_auto_recalc;
extern unsigned long long srv_stats_modified_counter;
extern my_bool srv_stats_sample_traditional;
+extern my_bool srv_stats_include_delete_marked;
extern ibool srv_use_doublewrite_buf;
extern ulong srv_doublewrite_batch_size;
diff --git a/storage/innobase/lock/lock0wait.cc b/storage/innobase/lock/lock0wait.cc
index 867e596bca2..adc775c7f74 100644
--- a/storage/innobase/lock/lock0wait.cc
+++ b/storage/innobase/lock/lock0wait.cc
@@ -563,7 +563,7 @@ DECLARE_THREAD(lock_wait_timeout_thread)(void*)
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index cf7825bd542..11a9772800f 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -2607,7 +2607,7 @@ DECLARE_THREAD(log_scrub_thread)(void*)
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index e5aab543f5d..48a8b26ec4f 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -587,7 +587,7 @@ DECLARE_THREAD(recv_writer_thread)(
/* We count the number of threads in os_thread_exit().
A created thread should always use that to exit and not
use return() to exit. */
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
diff --git a/storage/innobase/mach/mach0data.cc b/storage/innobase/mach/mach0data.cc
index 2d3e6730f75..0d0da9f2ff3 100644
--- a/storage/innobase/mach/mach0data.cc
+++ b/storage/innobase/mach/mach0data.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2016, 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
@@ -40,55 +40,88 @@ mach_parse_compressed(
const byte** ptr,
const byte* end_ptr)
{
- ulint val;
-
if (*ptr >= end_ptr) {
+eof:
*ptr = NULL;
return(0);
}
- val = mach_read_from_1(*ptr);
+ ib_uint32_t val = mach_read_from_1(*ptr);
- if (val < 0x80) {
+ if (val < 0x80U) {
/* 0nnnnnnn (7 bits) */
++*ptr;
- return(static_cast<ib_uint32_t>(val));
- } else if (val < 0xC0) {
+ return(val);
+ }
+
+ /* Workaround GCC bug
+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77673:
+ the compiler moves mach_read_from_4 right to the beginning of the
+ function, causing and out-of-bounds read if we are reading a short
+ integer close to the end of buffer. */
+#if defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__clang__)
+#define DEPLOY_FENCE
+#endif
+
+#ifdef DEPLOY_FENCE
+ __atomic_thread_fence(__ATOMIC_ACQUIRE);
+#endif
+
+ if (val < 0xC0U) {
/* 10nnnnnn nnnnnnnn (14 bits) */
- if (end_ptr >= *ptr + 2) {
- val = mach_read_from_2(*ptr) & 0x3FFF;
- ut_ad(val > 0x7F);
- *ptr += 2;
- return(static_cast<ib_uint32_t>(val));
+ if (end_ptr < *ptr + 2) {
+ goto eof;
}
- } else if (val < 0xE0) {
+
+ val = mach_read_from_2(*ptr) & 0x7FFFUL;
+ *ptr += 2;
+ return(val);
+ }
+
+#ifdef DEPLOY_FENCE
+ __atomic_thread_fence(__ATOMIC_ACQUIRE);
+#endif
+
+ if (val < 0xE0U) {
/* 110nnnnn nnnnnnnn nnnnnnnn (21 bits) */
- if (end_ptr >= *ptr + 3) {
- val = mach_read_from_3(*ptr) & 0x1FFFFF;
- ut_ad(val > 0x3FFF);
- *ptr += 3;
- return(static_cast<ib_uint32_t>(val));
+ if (end_ptr < *ptr + 3) {
+ goto eof;
}
- } else if (val < 0xF0) {
+
+ val = mach_read_from_3(*ptr) & 0x3FFFFFUL;
+ *ptr += 3;
+ return(val);
+ }
+
+#ifdef DEPLOY_FENCE
+ __atomic_thread_fence(__ATOMIC_ACQUIRE);
+#endif
+
+ if (val < 0xF0U) {
/* 1110nnnn nnnnnnnn nnnnnnnn nnnnnnnn (28 bits) */
- if (end_ptr >= *ptr + 4) {
- val = mach_read_from_4(*ptr) & 0xFFFFFFF;
- ut_ad(val > 0x1FFFFF);
- *ptr += 4;
- return(static_cast<ib_uint32_t>(val));
- }
- } else {
- ut_ad(val == 0xF0);
-
- /* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */
- if (end_ptr >= *ptr + 5) {
- val = mach_read_from_4(*ptr + 1);
- ut_ad(val > 0xFFFFFFF);
- *ptr += 5;
- return(static_cast<ib_uint32_t>(val));
+ if (end_ptr < *ptr + 4) {
+ goto eof;
}
+
+ val = mach_read_from_4(*ptr) & 0x1FFFFFFFUL;
+ *ptr += 4;
+ return(val);
+ }
+
+#ifdef DEPLOY_FENCE
+ __atomic_thread_fence(__ATOMIC_ACQUIRE);
+#endif
+
+#undef DEPLOY_FENCE
+
+ /* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */
+ ut_ad(val == 0xF0U);
+
+ if (end_ptr < *ptr + 5) {
+ goto eof;
}
- *ptr = NULL;
- return(0);
+ val = mach_read_from_4(*ptr + 1);
+ *ptr += 5;
+ return(val);
}
diff --git a/storage/innobase/os/os0thread.cc b/storage/innobase/os/os0thread.cc
index fd88fafa69d..d39fb0decc2 100644
--- a/storage/innobase/os/os0thread.cc
+++ b/storage/innobase/os/os0thread.cc
@@ -166,9 +166,33 @@ os_thread_create_func(
return((os_thread_t)new_thread_id);
}
+/** Waits until the specified thread completes and joins it.
+Its return value is ignored.
+@param[in,out] thread thread to join */
+void
+os_thread_join(os_thread_t thread)
+{
+#ifdef __WIN__
+ /* Do nothing. */
+#else
+#ifdef UNIV_DEBUG
+ const int ret =
+#endif /* UNIV_DEBUG */
+ pthread_join(thread, NULL);
+
+ /* Waiting on already-quit threads is allowed. */
+ ut_ad(ret == 0 || ret == ESRCH);
+#endif /* __WIN__ */
+}
+
/** Exits the current thread. */
void
-os_thread_exit()
+os_thread_exit(
+ void* exit_value, /*!< in: exit value; in Windows this void*
+ is cast as a DWORD */
+ bool detach) /*!< in: if true, the thread will be detached
+ right before exiting. If false, another thread
+ is responsible for joining this thread. */
{
#ifdef UNIV_DEBUG_THREAD_CREATION
ib::info() << "Thread exits, id "
@@ -180,17 +204,16 @@ os_thread_exit()
#endif
mutex_enter(&thread_mutex);
-
os_thread_count--;
-
-#ifdef _WIN32
mutex_exit(&thread_mutex);
+#ifdef _WIN32
ExitThread(0);
#else
- mutex_exit(&thread_mutex);
- pthread_detach(pthread_self());
- pthread_exit(NULL);
+ if (detach) {
+ pthread_detach(pthread_self());
+ }
+ pthread_exit(exit_value);
#endif
}
diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc
index 3179c63f162..05fecd006fa 100644
--- a/storage/innobase/row/row0ftsort.cc
+++ b/storage/innobase/row/row0ftsort.cc
@@ -1088,7 +1088,7 @@ func_exit:
os_event_set(psort_info->psort_common->sort_event);
psort_info->child_status = FTS_CHILD_EXITING;
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
@@ -1135,7 +1135,7 @@ fts_parallel_merge(
os_event_set(psort_info->psort_common->merge_event);
psort_info->child_status = FTS_CHILD_EXITING;
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 7fe925ae3ee..a6f4b221302 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -361,8 +361,7 @@ public:
m_space(ULINT_UNDEFINED),
m_xdes(),
m_xdes_page_no(ULINT_UNDEFINED),
- m_space_flags(ULINT_UNDEFINED),
- m_table_flags(ULINT_UNDEFINED) UNIV_NOTHROW { }
+ m_space_flags(ULINT_UNDEFINED) UNIV_NOTHROW { }
/** Free any extent descriptor instance */
virtual ~AbstractCallback()
@@ -529,10 +528,6 @@ protected:
/** Flags value read from the header page */
ulint m_space_flags;
-
- /** Derived from m_space_flags and row format type, the row format
- type is determined from the page header. */
- ulint m_table_flags;
};
/** Determine the page size to use for traversing the tablespace
@@ -547,6 +542,18 @@ AbstractCallback::init(
const page_t* page = block->frame;
m_space_flags = fsp_header_get_flags(page);
+ if (!fsp_flags_is_valid(m_space_flags)) {
+ ulint cflags = fsp_flags_convert_from_101(m_space_flags);
+ if (cflags == ULINT_UNDEFINED) {
+ ib::error() << "Invalid FSP_SPACE_FLAGS="
+ << ib::hex(m_space_flags);
+ return(DB_CORRUPTION);
+ }
+ m_space_flags = cflags;
+ }
+
+ /* Clear the DATA_DIR flag, which is basically garbage. */
+ m_space_flags &= ~(1U << FSP_FLAGS_POS_RESERVED);
m_page_size.copy_from(page_size_t(m_space_flags));
if (!is_compressed_table() && !m_page_size.equals_to(univ_page_size)) {
@@ -614,45 +621,6 @@ struct FetchIndexRootPages : public AbstractCallback {
return(m_space);
}
- /** Check if the .ibd file row format is the same as the table's.
- @param ibd_table_flags determined from space and page.
- @return DB_SUCCESS or error code. */
- dberr_t check_row_format(ulint ibd_table_flags) UNIV_NOTHROW
- {
- dberr_t err;
- rec_format_t ibd_rec_format;
- rec_format_t table_rec_format;
-
- if (!dict_tf_is_valid(ibd_table_flags)) {
-
- ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR,
- ER_TABLE_SCHEMA_MISMATCH,
- ".ibd file has invalid table flags: %lx",
- ibd_table_flags);
-
- return(DB_CORRUPTION);
- }
-
- ibd_rec_format = dict_tf_get_rec_format(ibd_table_flags);
- table_rec_format = dict_tf_get_rec_format(m_table->flags);
-
- if (table_rec_format != ibd_rec_format) {
-
- ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR,
- ER_TABLE_SCHEMA_MISMATCH,
- "Table has %s row format, .ibd"
- " file has %s row format.",
- dict_tf_to_row_format_string(m_table->flags),
- dict_tf_to_row_format_string(ibd_table_flags));
-
- err = DB_CORRUPTION;
- } else {
- err = DB_SUCCESS;
- }
-
- return(err);
- }
-
/** Called for each block as it is read from the file.
@param offset physical offset in the file
@param block block to convert, it is not from the buffer pool.
@@ -713,12 +681,17 @@ FetchIndexRootPages::operator() (
m_indexes.push_back(Index(id, block->page.id.page_no()));
if (m_indexes.size() == 1) {
-
- m_table_flags = fsp_flags_to_dict_tf(
- m_space_flags,
- page_is_comp(page) ? true : false);
-
- err = check_row_format(m_table_flags);
+ /* Check that the tablespace flags match the table flags. */
+ ulint expected = dict_tf_to_fsp_flags(m_table->flags);
+ if (!fsp_flags_match(expected, m_space_flags)) {
+ ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR,
+ ER_TABLE_SCHEMA_MISMATCH,
+ "Expected FSP_SPACE_FLAGS=0x%x, .ibd "
+ "file contains 0x%x.",
+ unsigned(expected),
+ unsigned(m_space_flags));
+ return(DB_CORRUPTION);
+ }
}
}
@@ -1896,19 +1869,14 @@ PageConverter::update_header(
ib::warn() << "Space id check in the header failed: ignored";
}
- ulint space_flags = fsp_header_get_flags(get_frame(block));
-
- if (!fsp_flags_is_valid(space_flags)) {
-
- ib::error() << "Unsupported tablespace format "
- << space_flags;
-
- return(DB_UNSUPPORTED);
- }
-
mach_write_to_8(
get_frame(block) + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
m_current_lsn);
+
+ /* Write back the adjusted flags. */
+ mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS
+ + get_frame(block), m_space_flags);
+
/* Write space_id to the tablespace header, page 0. */
mach_write_to_4(
get_frame(block) + FSP_HEADER_OFFSET + FSP_SPACE_ID,
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index fbcb6149add..b25fde9b2b7 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -4897,6 +4897,13 @@ wait_again:
" threads exited when creating"
" FTS index '"
<< indexes[i]->name << "'";
+ } else {
+ for (j = 0; j < FTS_NUM_AUX_INDEX;
+ j++) {
+
+ os_thread_join(merge_info[j]
+ .thread_hdl);
+ }
}
} else {
/* This cannot report duplicates; an
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 187dd06acf1..5a2075c77a0 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -1508,6 +1508,8 @@ run_again:
row_ins_step(thr);
+ DEBUG_SYNC_C("ib_after_row_insert_step");
+
err = trx->error_state;
if (err != DB_SUCCESS) {
@@ -3546,19 +3548,22 @@ This deletes the fil_space_t if found and the file on disk.
@param[in] space_id Tablespace ID
@param[in] tablename Table name, same as the tablespace name
@param[in] filepath File path of tablespace to delete
+@param[in] table_flags table flags
@return error code or DB_SUCCESS */
UNIV_INLINE
dberr_t
row_drop_single_table_tablespace(
ulint space_id,
const char* tablename,
- const char* filepath)
+ const char* filepath,
+ ulint table_flags)
{
dberr_t err = DB_SUCCESS;
/* If the tablespace is not in the cache, just delete the file. */
if (!fil_space_for_table_exists_in_mem(
- space_id, tablename, true, false, NULL, 0, NULL)) {
+ space_id, tablename, true, false, NULL, 0, NULL,
+ table_flags)) {
/* Force a delete of any discarded or temporary files. */
fil_delete_file(filepath);
@@ -4039,11 +4044,13 @@ row_drop_table_for_mysql(
ulint space_id;
bool ibd_file_missing;
bool is_discarded;
+ ulint table_flags;
case DB_SUCCESS:
space_id = table->space;
ibd_file_missing = table->ibd_file_missing;
is_discarded = dict_table_is_discarded(table);
+ table_flags = table->flags;
ut_ad(!dict_table_is_temporary(table));
err = row_drop_ancillary_fts_tables(table, trx);
@@ -4079,7 +4086,7 @@ row_drop_table_for_mysql(
/* We can now drop the single-table tablespace. */
err = row_drop_single_table_tablespace(
- space_id, tablename, filepath);
+ space_id, tablename, filepath, table_flags);
break;
case DB_OUT_OF_FILE_SPACE:
diff --git a/storage/innobase/row/row0trunc.cc b/storage/innobase/row/row0trunc.cc
index 094c0b45e6d..1dea23bc657 100644
--- a/storage/innobase/row/row0trunc.cc
+++ b/storage/innobase/row/row0trunc.cc
@@ -904,7 +904,7 @@ TruncateLogger::operator()(mtr_t* mtr, btr_pcur_t* pcur)
/* For compressed tables we need to store extra meta-data
required during btr_create(). */
- if (fsp_flags_is_compressed(m_flags)) {
+ if (FSP_FLAGS_GET_ZIP_SSIZE(m_flags)) {
const dict_index_t* dict_index = find(index.m_id);
@@ -2581,7 +2581,7 @@ truncate_t::parse(
ut_ad(!m_indexes.empty());
- if (fsp_flags_is_compressed(m_tablespace_flags)) {
+ if (FSP_FLAGS_GET_ZIP_SSIZE(m_tablespace_flags)) {
/* Parse the number of index fields from TRUNCATE log record */
for (ulint i = 0; i < m_indexes.size(); ++i) {
@@ -2880,12 +2880,12 @@ truncate_t::create_indexes(
++it) {
btr_create_t btr_redo_create_info(
- fsp_flags_is_compressed(flags)
+ FSP_FLAGS_GET_ZIP_SSIZE(flags)
? &it->m_fields[0] : NULL);
btr_redo_create_info.format_flags = format_flags;
- if (fsp_flags_is_compressed(flags)) {
+ if (FSP_FLAGS_GET_ZIP_SSIZE(flags)) {
btr_redo_create_info.n_fields = it->m_n_fields;
/* Skip the NUL appended field */
@@ -3020,7 +3020,7 @@ truncate_t::write(
}
/* If tablespace compressed then field info of each index. */
- if (fsp_flags_is_compressed(flags)) {
+ if (FSP_FLAGS_GET_ZIP_SSIZE(flags)) {
for (ulint i = 0; i < m_indexes.size(); ++i) {
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 5d478e4529f..9ddb11006e3 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -391,10 +391,11 @@ this many index pages, there are 2 ways to calculate statistics:
in the innodb database.
* quick transient stats, that are used if persistent stats for the given
table/index are not found in the innodb database */
-unsigned long long srv_stats_transient_sample_pages = 8;
-my_bool srv_stats_persistent = TRUE;
-unsigned long long srv_stats_persistent_sample_pages = 20;
-my_bool srv_stats_auto_recalc = TRUE;
+UNIV_INTERN unsigned long long srv_stats_transient_sample_pages = 8;
+UNIV_INTERN my_bool srv_stats_persistent = TRUE;
+UNIV_INTERN my_bool srv_stats_include_delete_marked = FALSE;
+UNIV_INTERN unsigned long long srv_stats_persistent_sample_pages = 20;
+UNIV_INTERN my_bool srv_stats_auto_recalc = TRUE;
/* The number of rows modified before we calculate new statistics (default 0
= current limits) */
@@ -1867,7 +1868,7 @@ exit_func:
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
@@ -1981,7 +1982,7 @@ loop:
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
@@ -2592,7 +2593,7 @@ suspend_thread:
}
my_thread_end();
- os_thread_exit();
+ os_thread_exit(NULL, false);
DBUG_RETURN(0);
}
@@ -2736,7 +2737,7 @@ DECLARE_THREAD(srv_worker_thread)(
my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
}
@@ -3063,7 +3064,7 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
}
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index d0b7ddc0449..41500204d8d 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -332,7 +332,7 @@ DECLARE_THREAD(io_handler_thread)(
The thread actually never comes here because it is exited in an
os_event_wait(). */
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
@@ -443,12 +443,8 @@ create_log_files(
has been completed and renamed. */
sprintf(logfilename + dirnamelen, "ib_logfile%u", INIT_LOG_FILE0);
- /* Disable the doublewrite buffer for log files, not required */
-
fil_space_t* log_space = fil_space_create(
- "innodb_redo_log", SRV_LOG_SPACE_FIRST_ID,
- fsp_flags_set_page_size(0, univ_page_size),
- FIL_TYPE_LOG,
+ "innodb_redo_log", SRV_LOG_SPACE_FIRST_ID, 0, FIL_TYPE_LOG,
NULL, /* No encryption yet */
true /* this is create */);
ut_a(fil_validate());
@@ -645,7 +641,6 @@ srv_undo_tablespace_open(
{
os_file_t fh;
bool ret;
- ulint flags;
dberr_t err = DB_ERROR;
char undo_name[sizeof "innodb_undo000"];
@@ -690,11 +685,9 @@ srv_undo_tablespace_open(
fil_set_max_space_id_if_bigger(space_id);
- /* Set the compressed page size to 0 (non-compressed) */
- flags = fsp_flags_init(
- univ_page_size, false, false, false, 0, 0);
space = fil_space_create(
- undo_name, space_id, flags, FIL_TYPE_TABLESPACE, NULL, true);
+ undo_name, space_id, FSP_FLAGS_PAGE_SSIZE(),
+ FIL_TYPE_TABLESPACE, NULL, true);
ut_a(fil_validate());
ut_a(space);
@@ -2035,8 +2028,7 @@ innobase_start_or_create_for_mysql(void)
/* Disable the doublewrite buffer for log files. */
fil_space_t* log_space = fil_space_create(
"innodb_redo_log",
- SRV_LOG_SPACE_FIRST_ID,
- fsp_flags_set_page_size(0, univ_page_size),
+ SRV_LOG_SPACE_FIRST_ID, 0,
FIL_TYPE_LOG,
NULL /* no encryption yet */,
true /* create */);
@@ -2425,6 +2417,13 @@ files_checked:
srv_startup_is_before_trx_rollback_phase = false;
if (!srv_read_only_mode) {
+ const ulint flags = FSP_FLAGS_PAGE_SSIZE();
+ for (ulint id = 0; id <= srv_undo_tablespaces; id++) {
+ if (fil_space_get(id)) {
+ fsp_flags_try_adjust(id, flags);
+ }
+ }
+
/* Create the thread which watches the timeouts
for lock waits */
thread_handles[2 + SRV_MAX_N_IO_THREADS] = os_thread_create(
diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc
index dc779fefc58..9e4a0a8cb0a 100644
--- a/storage/innobase/trx/trx0roll.cc
+++ b/storage/innobase/trx/trx0roll.cc
@@ -880,7 +880,7 @@ DECLARE_THREAD(trx_rollback_or_clean_all_recovered)(
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
- os_thread_exit();
+ os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
diff --git a/storage/perfschema/pfs.cc b/storage/perfschema/pfs.cc
index 4cd1a35fd77..b58862d4824 100644
--- a/storage/perfschema/pfs.cc
+++ b/storage/perfschema/pfs.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2008, 2016, 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
@@ -2562,10 +2562,7 @@ start_table_io_wait_v1(PSI_table_locker_state *state,
if (! pfs_table->m_io_enabled)
return NULL;
- PFS_thread *pfs_thread= pfs_table->m_thread_owner;
-
- DBUG_ASSERT(pfs_thread ==
- my_pthread_getspecific_ptr(PFS_thread*, THR_PFS));
+ PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
register uint flags;
ulonglong timer_start= 0;
@@ -2668,7 +2665,7 @@ start_table_lock_wait_v1(PSI_table_locker_state *state,
if (! pfs_table->m_lock_enabled)
return NULL;
- PFS_thread *pfs_thread= pfs_table->m_thread_owner;
+ PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
PFS_TL_LOCK_TYPE lock_type;
@@ -3070,7 +3067,12 @@ start_socket_wait_v1(PSI_socket_locker_state *state,
if (flag_thread_instrumentation)
{
- PFS_thread *pfs_thread= pfs_socket->m_thread_owner;
+ /*
+ Do not use pfs_socket->m_thread_owner here,
+ as different threads may use concurrently the same socket,
+ for example during a KILL.
+ */
+ PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
if (unlikely(pfs_thread == NULL))
return NULL;
@@ -3438,6 +3440,8 @@ static void end_idle_wait_v1(PSI_idle_locker* locker)
if (flag_events_waits_history_long)
insert_events_waits_history_long(wait);
thread->m_events_waits_current--;
+
+ DBUG_ASSERT(wait == thread->m_events_waits_current);
}
}
@@ -3519,6 +3523,8 @@ static void end_mutex_wait_v1(PSI_mutex_locker* locker, int rc)
if (flag_events_waits_history_long)
insert_events_waits_history_long(wait);
thread->m_events_waits_current--;
+
+ DBUG_ASSERT(wait == thread->m_events_waits_current);
}
}
}
@@ -3598,6 +3604,8 @@ static void end_rwlock_rdwait_v1(PSI_rwlock_locker* locker, int rc)
if (flag_events_waits_history_long)
insert_events_waits_history_long(wait);
thread->m_events_waits_current--;
+
+ DBUG_ASSERT(wait == thread->m_events_waits_current);
}
}
}
@@ -3670,6 +3678,8 @@ static void end_rwlock_wrwait_v1(PSI_rwlock_locker* locker, int rc)
if (flag_events_waits_history_long)
insert_events_waits_history_long(wait);
thread->m_events_waits_current--;
+
+ DBUG_ASSERT(wait == thread->m_events_waits_current);
}
}
}
@@ -3734,6 +3744,8 @@ static void end_cond_wait_v1(PSI_cond_locker* locker, int rc)
if (flag_events_waits_history_long)
insert_events_waits_history_long(wait);
thread->m_events_waits_current--;
+
+ DBUG_ASSERT(wait == thread->m_events_waits_current);
}
}
}
@@ -3828,6 +3840,8 @@ static void end_table_io_wait_v1(PSI_table_locker* locker)
if (flag_events_waits_history_long)
insert_events_waits_history_long(wait);
thread->m_events_waits_current--;
+
+ DBUG_ASSERT(wait == thread->m_events_waits_current);
}
}
@@ -3897,6 +3911,8 @@ static void end_table_lock_wait_v1(PSI_table_locker* locker)
if (flag_events_waits_history_long)
insert_events_waits_history_long(wait);
thread->m_events_waits_current--;
+
+ DBUG_ASSERT(wait == thread->m_events_waits_current);
}
}
@@ -4145,6 +4161,8 @@ static void end_file_wait_v1(PSI_file_locker *locker,
if (flag_events_waits_history_long)
insert_events_waits_history_long(wait);
thread->m_events_waits_current--;
+
+ DBUG_ASSERT(wait == thread->m_events_waits_current);
}
}
}
@@ -5074,6 +5092,8 @@ static void end_socket_wait_v1(PSI_socket_locker *locker, size_t byte_count)
if (flag_events_waits_history_long)
insert_events_waits_history_long(wait);
thread->m_events_waits_current--;
+
+ DBUG_ASSERT(wait == thread->m_events_waits_current);
}
}
diff --git a/storage/perfschema/pfs_digest.cc b/storage/perfschema/pfs_digest.cc
index 0a01ee08993..3330c29795f 100644
--- a/storage/perfschema/pfs_digest.cc
+++ b/storage/perfschema/pfs_digest.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2008, 2016, 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
@@ -47,7 +47,7 @@ bool flag_statements_digest= true;
Current index in Stat array where new record is to be inserted.
index 0 is reserved for "all else" case when entire array is full.
*/
-volatile uint32 digest_index;
+volatile uint32 PFS_ALIGNED digest_monotonic_index;
bool digest_full= false;
LF_HASH digest_hash;
@@ -65,7 +65,7 @@ int init_digest(const PFS_global_param *param)
*/
digest_max= param->m_digest_sizing;
digest_lost= 0;
- digest_index= 1;
+ PFS_atomic::store_u32(& digest_monotonic_index, 1);
digest_full= false;
if (digest_max == 0)
@@ -107,6 +107,9 @@ int init_digest(const PFS_global_param *param)
+ index * pfs_max_digest_length, pfs_max_digest_length);
}
+ /* Set record[0] as allocated. */
+ statements_digest_stat_array[0].m_lock.set_allocated();
+
return 0;
}
@@ -209,9 +212,10 @@ find_or_create_digest(PFS_thread *thread,
memcpy(hash_key.m_schema_name, schema_name, schema_name_length);
int res;
- ulong safe_index;
uint retry_count= 0;
const uint retry_max= 3;
+ size_t safe_index;
+ size_t attempts= 0;
PFS_statements_digest_stat **entry;
PFS_statements_digest_stat *pfs= NULL;
@@ -247,55 +251,70 @@ search:
return & pfs->m_stat;
}
- safe_index= PFS_atomic::add_u32(& digest_index, 1);
- if (safe_index >= digest_max)
+ while (++attempts <= digest_max)
{
- /* The digest array is now full. */
- digest_full= true;
- pfs= &statements_digest_stat_array[0];
-
- if (pfs->m_first_seen == 0)
- pfs->m_first_seen= now;
- pfs->m_last_seen= now;
- return & pfs->m_stat;
- }
-
- /* Add a new record in digest stat array. */
- pfs= &statements_digest_stat_array[safe_index];
-
- /* Copy digest hash/LF Hash search key. */
- memcpy(& pfs->m_digest_key, &hash_key, sizeof(PFS_digest_key));
-
- /*
- Copy digest storage to statement_digest_stat_array so that it could be
- used later to generate digest text.
- */
- pfs->m_digest_storage.copy(digest_storage);
-
- pfs->m_first_seen= now;
- pfs->m_last_seen= now;
+ safe_index= PFS_atomic::add_u32(& digest_monotonic_index, 1) % digest_max;
+ if (safe_index == 0)
+ {
+ /* Record [0] is reserved. */
+ safe_index= 1;
+ }
- res= lf_hash_insert(&digest_hash, pins, &pfs);
- if (likely(res == 0))
- {
- return & pfs->m_stat;
- }
+ /* Add a new record in digest stat array. */
+ pfs= &statements_digest_stat_array[safe_index];
- if (res > 0)
- {
- /* Duplicate insert by another thread */
- if (++retry_count > retry_max)
+ if (pfs->m_lock.is_free())
{
- /* Avoid infinite loops */
- digest_lost++;
- return NULL;
+ if (pfs->m_lock.free_to_dirty())
+ {
+ /* Copy digest hash/LF Hash search key. */
+ memcpy(& pfs->m_digest_key, &hash_key, sizeof(PFS_digest_key));
+
+ /*
+ Copy digest storage to statement_digest_stat_array so that it could be
+ used later to generate digest text.
+ */
+ pfs->m_digest_storage.copy(digest_storage);
+
+ pfs->m_first_seen= now;
+ pfs->m_last_seen= now;
+
+ res= lf_hash_insert(&digest_hash, pins, &pfs);
+ if (likely(res == 0))
+ {
+ pfs->m_lock.dirty_to_allocated();
+ return & pfs->m_stat;
+ }
+
+ pfs->m_lock.dirty_to_free();
+
+ if (res > 0)
+ {
+ /* Duplicate insert by another thread */
+ if (++retry_count > retry_max)
+ {
+ /* Avoid infinite loops */
+ digest_lost++;
+ return NULL;
+ }
+ goto search;
+ }
+
+ /* OOM in lf_hash_insert */
+ digest_lost++;
+ return NULL;
+ }
}
- goto search;
}
- /* OOM in lf_hash_insert */
- digest_lost++;
- return NULL;
+ /* The digest array is now full. */
+ digest_full= true;
+ pfs= &statements_digest_stat_array[0];
+
+ if (pfs->m_first_seen == 0)
+ pfs->m_first_seen= now;
+ pfs->m_last_seen= now;
+ return & pfs->m_stat;
}
void purge_digest(PFS_thread* thread, PFS_digest_key *hash_key)
@@ -322,10 +341,12 @@ void purge_digest(PFS_thread* thread, PFS_digest_key *hash_key)
void PFS_statements_digest_stat::reset_data(unsigned char *token_array, uint length)
{
+ m_lock.set_dirty();
m_digest_storage.reset(token_array, length);
m_stat.reset();
m_first_seen= 0;
m_last_seen= 0;
+ m_lock.dirty_to_free();
}
void PFS_statements_digest_stat::reset_index(PFS_thread *thread)
@@ -353,11 +374,14 @@ void reset_esms_by_digest()
statements_digest_stat_array[index].reset_data(statements_digest_token_array + index * pfs_max_digest_length, pfs_max_digest_length);
}
+ /* Mark record[0] as allocated again. */
+ statements_digest_stat_array[0].m_lock.set_allocated();
+
/*
Reset index which indicates where the next calculated digest information
to be inserted in statements_digest_stat_array.
*/
- digest_index= 1;
+ PFS_atomic::store_u32(& digest_monotonic_index, 1);
digest_full= false;
}
diff --git a/storage/perfschema/pfs_digest.h b/storage/perfschema/pfs_digest.h
index 76d6c33d984..429a9f4250a 100644
--- a/storage/perfschema/pfs_digest.h
+++ b/storage/perfschema/pfs_digest.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2011, 2016, 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
@@ -44,6 +44,9 @@ struct PFS_digest_key
/** A statement digest stat record. */
struct PFS_ALIGNED PFS_statements_digest_stat
{
+ /** Internal lock. */
+ pfs_lock m_lock;
+
/** Digest Schema + MD5 Hash. */
PFS_digest_key m_digest_key;
diff --git a/storage/perfschema/pfs_lock.h b/storage/perfschema/pfs_lock.h
index 09efecd1c5f..be84d0f7fb4 100644
--- a/storage/perfschema/pfs_lock.h
+++ b/storage/perfschema/pfs_lock.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2009, 2016, 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
@@ -156,6 +156,18 @@ struct pfs_lock
}
/**
+ Initialize a lock to dirty.
+ */
+ void set_dirty(void)
+ {
+ /* Do not set the version to 0, read the previous value. */
+ uint32 copy= PFS_atomic::load_u32(&m_version_state);
+ /* Increment the version, set the DIRTY state */
+ uint32 new_val= (copy & VERSION_MASK) + VERSION_INC + PFS_LOCK_DIRTY;
+ PFS_atomic::store_u32(&m_version_state, new_val);
+ }
+
+ /**
Execute a dirty to free transition.
This transition should be executed by the writer that owns the record.
*/
diff --git a/storage/perfschema/table_esms_by_digest.cc b/storage/perfschema/table_esms_by_digest.cc
index 88860a77c5d..6c2b173d000 100644
--- a/storage/perfschema/table_esms_by_digest.cc
+++ b/storage/perfschema/table_esms_by_digest.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2010, 2016, 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
@@ -113,11 +113,14 @@ int table_esms_by_digest::rnd_next(void)
m_pos.next())
{
digest_stat= &statements_digest_stat_array[m_pos.m_index];
- if (digest_stat->m_first_seen != 0)
+ if (digest_stat->m_lock.is_populated())
{
- make_row(digest_stat);
- m_next_pos.set_after(&m_pos);
- return 0;
+ if (digest_stat->m_first_seen != 0)
+ {
+ make_row(digest_stat);
+ m_next_pos.set_after(&m_pos);
+ return 0;
+ }
}
}
@@ -135,10 +138,13 @@ table_esms_by_digest::rnd_pos(const void *pos)
set_position(pos);
digest_stat= &statements_digest_stat_array[m_pos.m_index];
- if (digest_stat->m_first_seen != 0)
+ if (digest_stat->m_lock.is_populated())
{
- make_row(digest_stat);
- return 0;
+ if (digest_stat->m_first_seen != 0)
+ {
+ make_row(digest_stat);
+ return 0;
+ }
}
return HA_ERR_RECORD_DELETED;
diff --git a/storage/perfschema/unittest/pfs-t.cc b/storage/perfschema/unittest/pfs-t.cc
index 6121fac098f..f76b1aa2e75 100644
--- a/storage/perfschema/unittest/pfs-t.cc
+++ b/storage/perfschema/unittest/pfs-t.cc
@@ -1316,6 +1316,7 @@ void test_locker_disabled()
/* Pretend the socket does not have a thread owner */
/* ---------------------------------------------- */
+ psi->delete_current_thread();
socket_class_A->m_enabled= true;
socket_A1= psi->init_socket(socket_key_A, NULL, NULL, 0);
ok(socket_A1 != NULL, "instrumented");
diff --git a/storage/xtradb/buf/buf0dblwr.cc b/storage/xtradb/buf/buf0dblwr.cc
index 7f6b6caee9d..68bb83e4903 100644
--- a/storage/xtradb/buf/buf0dblwr.cc
+++ b/storage/xtradb/buf/buf0dblwr.cc
@@ -455,8 +455,11 @@ buf_dblwr_init_or_load_pages(
os_file_write(path, file, page,
source_page_no * UNIV_PAGE_SIZE,
UNIV_PAGE_SIZE);
- } else if (load_corrupt_pages) {
-
+ } else if (load_corrupt_pages
+ && !buf_page_is_zeroes(page, FIL_PAGE_DATA)) {
+ /* Each valid page header must contain some
+ nonzero bytes, such as FIL_PAGE_OFFSET
+ or FIL_PAGE_LSN. */
recv_dblwr.add(page);
}
@@ -492,8 +495,6 @@ buf_dblwr_process()
for (std::list<byte*>::iterator i = recv_dblwr.pages.begin();
i != recv_dblwr.pages.end(); ++i, ++page_no_dblwr ) {
- bool is_compressed = false;
-
page = *i;
page_no = mach_read_from_4(page + FIL_PAGE_OFFSET);
space_id = mach_read_from_4(page + FIL_PAGE_SPACE_ID);
@@ -501,138 +502,119 @@ buf_dblwr_process()
if (!fil_tablespace_exists_in_mem(space_id)) {
/* Maybe we have dropped the single-table tablespace
and this page once belonged to it: do nothing */
+ continue;
+ }
- } else if (!fil_check_adress_in_tablespace(space_id,
- page_no)) {
+ if (!fil_check_adress_in_tablespace(space_id, page_no)) {
ib_logf(IB_LOG_LEVEL_WARN,
- "A page in the doublewrite buffer is not "
- "within space bounds; space id %lu "
- "page number %lu, page %lu in "
- "doublewrite buf.",
- (ulong) space_id, (ulong) page_no,
- page_no_dblwr);
+ "A copy of page " ULINTPF ":" ULINTPF
+ " in the doublewrite buffer slot " ULINTPF
+ " is not within space bounds",
+ space_id, page_no, page_no_dblwr);
+ continue;
+ }
+
+ ulint zip_size = fil_space_get_zip_size(space_id);
+ ut_ad(!buf_page_is_zeroes(page, zip_size));
+
+ /* Read in the actual page from the file */
+ fil_io(OS_FILE_READ,
+ true,
+ space_id,
+ zip_size,
+ page_no,
+ 0,
+ zip_size ? zip_size : UNIV_PAGE_SIZE,
+ read_buf,
+ NULL,
+ 0);
+
+ const bool is_all_zero = buf_page_is_zeroes(
+ read_buf, zip_size);
+
+ if (is_all_zero) {
+ /* We will check if the copy in the
+ doublewrite buffer is valid. If not, we will
+ ignore this page (there should be redo log
+ records to initialize it). */
} else {
- ulint zip_size = fil_space_get_zip_size(space_id);
-
- /* Read in the actual page from the file */
- fil_io(OS_FILE_READ,
- true,
- space_id,
- zip_size,
- page_no,
- 0,
- zip_size ? zip_size : UNIV_PAGE_SIZE,
- read_buf,
- NULL,
- 0);
-
- /* Is page compressed ? */
- is_compressed = fil_page_is_compressed_encrypted(read_buf) |
- fil_page_is_compressed(read_buf);
-
- /* If page was compressed, decompress it before we
- check checksum. */
- if (is_compressed) {
- fil_decompress_page(NULL, read_buf, UNIV_PAGE_SIZE, NULL, true);
+ if (fil_page_is_compressed_encrypted(read_buf) ||
+ fil_page_is_compressed(read_buf)) {
+ /* Decompress the page before
+ validating the checksum. */
+ fil_decompress_page(
+ NULL, read_buf, UNIV_PAGE_SIZE,
+ NULL, true);
}
- if (fil_space_verify_crypt_checksum(read_buf, zip_size)) {
- /* page is encrypted and checksum is OK */
- } else if (buf_page_is_corrupted(true, read_buf, zip_size)) {
-
- fprintf(stderr,
- "InnoDB: Database page"
- " corruption or a failed\n"
- "InnoDB: file read of"
- " space %lu page %lu.\n"
- "InnoDB: Trying to recover it from"
- " the doublewrite buffer.\n",
- (ulong) space_id, (ulong) page_no);
-
- /* Is page compressed ? */
- is_compressed = fil_page_is_compressed_encrypted(page) |
- fil_page_is_compressed(page);
-
- /* If page was compressed, decompress it before we
- check checksum. */
- if (is_compressed) {
- fil_decompress_page(NULL, page, UNIV_PAGE_SIZE, NULL, true);
- }
+ if (fil_space_verify_crypt_checksum(
+ read_buf, zip_size)
+ || !buf_page_is_corrupted(
+ true, read_buf, zip_size)) {
+ /* The page is good; there is no need
+ to consult the doublewrite buffer. */
+ continue;
+ }
- if (fil_space_verify_crypt_checksum(page, zip_size)) {
- /* the doublewrite buffer page is encrypted and OK */
- } else if (buf_page_is_corrupted(true,
- page,
- zip_size)) {
- fprintf(stderr,
- "InnoDB: Dump of the page:\n");
- buf_page_print(
- read_buf, zip_size,
- BUF_PAGE_PRINT_NO_CRASH);
- fprintf(stderr,
- "InnoDB: Dump of"
- " corresponding page"
- " in doublewrite buffer:\n");
- buf_page_print(
- page, zip_size,
- BUF_PAGE_PRINT_NO_CRASH);
-
- fprintf(stderr,
- "InnoDB: Also the page in the"
- " doublewrite buffer"
- " is corrupt.\n"
- "InnoDB: Cannot continue"
- " operation.\n"
- "InnoDB: You can try to"
- " recover the database"
- " with the my.cnf\n"
- "InnoDB: option:\n"
- "InnoDB:"
- " innodb_force_recovery=6\n");
- ut_error;
- }
+ /* We intentionally skip this message for
+ is_all_zero pages. */
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Trying to recover page " ULINTPF ":" ULINTPF
+ " from the doublewrite buffer.",
+ space_id, page_no);
+ }
- /* Write the good page from the
- doublewrite buffer to the intended
- position */
-
- fil_io(OS_FILE_WRITE,
- true,
- space_id,
- zip_size,
- page_no,
- 0,
- zip_size ? zip_size : UNIV_PAGE_SIZE,
- page,
- NULL,
- 0);
-
- ib_logf(IB_LOG_LEVEL_INFO,
- "Recovered the page from"
- " the doublewrite buffer.");
-
- } else if (buf_page_is_zeroes(read_buf, zip_size)) {
-
- if (!buf_page_is_zeroes(page, zip_size)
- && !buf_page_is_corrupted(true, page,
- zip_size)) {
-
- /* Database page contained only
- zeroes, while a valid copy is
- available in dblwr buffer. */
-
- fil_io(OS_FILE_WRITE,
- true,
- space_id,
- zip_size,
- page_no, 0,
- zip_size ? zip_size : UNIV_PAGE_SIZE,
- page,
- NULL,
- 0);
- }
+ /* Next, validate the doublewrite page. */
+ if (fil_page_is_compressed_encrypted(page) ||
+ fil_page_is_compressed(page)) {
+ /* Decompress the page before
+ validating the checksum. */
+ fil_decompress_page(
+ NULL, page, UNIV_PAGE_SIZE, NULL, true);
+ }
+
+ if (!fil_space_verify_crypt_checksum(page, zip_size)
+ && buf_page_is_corrupted(true, page, zip_size)) {
+ if (!is_all_zero) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "A doublewrite copy of page "
+ ULINTPF ":" ULINTPF " is corrupted.",
+ space_id, page_no);
}
+ /* Theoretically we could have another good
+ copy for this page in the doublewrite
+ buffer. If not, we will report a fatal error
+ for a corrupted page somewhere else if that
+ page was truly needed. */
+ continue;
}
+
+ if (page_no == 0) {
+ /* Check the FSP_SPACE_FLAGS. */
+ ulint flags = fsp_header_get_flags(page);
+ if (!fsp_flags_is_valid(flags)
+ && fsp_flags_convert_from_101(flags)
+ == ULINT_UNDEFINED) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Ignoring a doublewrite copy of page "
+ ULINTPF ":0 due to invalid flags 0x%x",
+ space_id, int(flags));
+ continue;
+ }
+ /* The flags on the page should be converted later. */
+ }
+
+ /* Write the good page from the doublewrite buffer to
+ the intended position. */
+
+ fil_io(OS_FILE_WRITE, true, space_id, zip_size, page_no, 0,
+ zip_size ? zip_size : UNIV_PAGE_SIZE,
+ page, NULL, 0);
+
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Recovered page " ULINTPF ":" ULINTPF " from"
+ " the doublewrite buffer.",
+ space_id, page_no);
}
ut_free(unaligned_read_buf);
diff --git a/storage/xtradb/dict/dict0load.cc b/storage/xtradb/dict/dict0load.cc
index 13c4ac467e3..b843891f16c 100644
--- a/storage/xtradb/dict/dict0load.cc
+++ b/storage/xtradb/dict/dict0load.cc
@@ -1052,8 +1052,6 @@ loop:
btr_pcur_store_position(&pcur, &mtr);
- mtr_commit(&mtr);
-
/* For tables created with old versions of InnoDB,
SYS_TABLES.MIX_LEN may contain garbage. Such tables
would always be in ROW_FORMAT=REDUNDANT. Pretend that
@@ -1087,16 +1085,19 @@ loop:
if (space_id == 0) {
/* The system tablespace always exists. */
ut_ad(!discarded);
- goto next_tablespace;
+ mem_free(name);
+ goto loop;
}
+ mtr_commit(&mtr);
+
switch (dict_check) {
case DICT_CHECK_ALL_LOADED:
/* All tablespaces should have been found in
fil_load_single_table_tablespaces(). */
if (fil_space_for_table_exists_in_mem(
- space_id, name, TRUE, !(is_temp || discarded),
- false, NULL, 0)
+ space_id, name, !(is_temp || discarded),
+ false, NULL, 0, flags)
&& !(is_temp || discarded)) {
/* If user changes the path of .ibd files in
*.isl files before doing crash recovery ,
@@ -1128,8 +1129,8 @@ loop:
/* Some tablespaces may have been opened in
trx_resurrect_table_locks(). */
if (fil_space_for_table_exists_in_mem(
- space_id, name, FALSE, FALSE,
- false, NULL, 0)) {
+ space_id, name, false,
+ false, NULL, 0, flags)) {
break;
}
/* fall through */
@@ -1191,7 +1192,6 @@ loop:
max_space_id = space_id;
}
-next_tablespace:
mem_free(name);
mtr_start(&mtr);
@@ -2383,8 +2383,8 @@ err_exit:
table->ibd_file_missing = TRUE;
} else if (!fil_space_for_table_exists_in_mem(
- table->space, name, FALSE, FALSE, true, heap,
- table->id)) {
+ table->space, name, false, true, heap,
+ table->id, table->flags)) {
if (DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY)) {
/* Do not bother to retry opening temporary tables. */
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index 133960ae8b4..f4301d47028 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2013, 2017, MariaDB Corporation.
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
@@ -601,10 +601,7 @@ fil_node_open_file(
ibool success;
byte* buf2;
byte* page;
- ulint space_id;
- ulint flags=0;
ulint page_size;
- ulint atomic_writes=0;
ut_ad(mutex_own(&(system->mutex)));
ut_a(node->n_pending == 0);
@@ -626,8 +623,6 @@ fil_node_open_file(
/* The following call prints an error message */
os_file_get_last_error(true);
- ut_print_timestamp(stderr);
-
ib_logf(IB_LOG_LEVEL_WARN, "InnoDB: Error: cannot "
"open %s\n. InnoDB: Have you deleted .ibd "
"files under a running mysqld server?\n",
@@ -653,17 +648,13 @@ fil_node_open_file(
ut_a(fil_is_user_tablespace_id(space->id));
if (size_bytes < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
- fprintf(stderr,
- "InnoDB: Error: the size of single-table"
- " tablespace file %s\n"
- "InnoDB: is only " UINT64PF ","
- " should be at least %lu!\n",
- node->name,
- size_bytes,
- (ulong) (FIL_IBD_FILE_INITIAL_SIZE
- * UNIV_PAGE_SIZE));
-
- ut_a(0);
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "The size of the file %s is only " UINT64PF
+ " bytes, should be at least " ULINTPF,
+ node->name, size_bytes,
+ FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE);
+ os_file_close(node->handle);
+ return(false);
}
/* Read the first page of the tablespace */
@@ -676,77 +667,34 @@ fil_node_open_file(
success = os_file_read(node->handle, page, 0, UNIV_PAGE_SIZE);
srv_stats.page0_read.add(1);
- space_id = fsp_header_get_space_id(page);
- flags = fsp_header_get_flags(page);
-
- page_size = fsp_flags_get_page_size(flags);
- atomic_writes = fsp_flags_get_atomic_writes(flags);
+ const ulint space_id = fsp_header_get_space_id(page);
+ ulint flags = fsp_header_get_flags(page);
ut_free(buf2);
-
- /* Close the file now that we have read the space id from it */
-
os_file_close(node->handle);
- if (UNIV_UNLIKELY(space_id != space->id)) {
- fprintf(stderr,
- "InnoDB: Error: tablespace id is %lu"
- " in the data dictionary\n"
- "InnoDB: but in file %s it is %lu!\n",
- space->id, node->name, space_id);
-
- ut_error;
- }
-
- if (UNIV_UNLIKELY(space_id == ULINT_UNDEFINED
- || space_id == 0)) {
- fprintf(stderr,
- "InnoDB: Error: tablespace id %lu"
- " in file %s is not sensible\n",
- (ulong) space_id, node->name);
-
- ut_error;
- }
-
- if (UNIV_UNLIKELY(fsp_flags_get_page_size(space->flags)
- != page_size)) {
- fprintf(stderr,
- "InnoDB: Error: tablespace file %s"
- " has page size 0x%lx\n"
- "InnoDB: but the data dictionary"
- " expects page size 0x%lx!\n",
- node->name, flags,
- fsp_flags_get_page_size(space->flags));
+ if (!fsp_flags_is_valid(flags)) {
+ ulint cflags = fsp_flags_convert_from_101(flags);
+ if (cflags == ULINT_UNDEFINED) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Expected tablespace flags 0x%x"
+ " but found 0x%x in the file %s",
+ int(space->flags), int(flags),
+ node->name);
+ return(false);
+ }
- ut_error;
+ flags = cflags;
}
- if (UNIV_UNLIKELY(space->flags != flags)) {
- ulint sflags = (space->flags & ~FSP_FLAGS_MASK_DATA_DIR);
- ulint fflags = (flags & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE);
-
- /* DATA_DIR option is on different place on MariaDB
- compared to MySQL. If this is the difference. Fix
- it. */
-
- if (sflags == fflags) {
- fprintf(stderr,
- "InnoDB: Warning: Table flags 0x%lx"
- " in the data dictionary but in file %s are 0x%lx!\n"
- " Temporally corrected because DATA_DIR option to 0x%lx.\n",
- space->flags, node->name, flags, space->flags);
-
- flags = space->flags;
- }
+ page_size = fsp_flags_get_page_size(flags);
- if (!dict_tf_verify_flags(space->flags, flags)) {
- fprintf(stderr,
- "InnoDB: Error: table flags are 0x%lx"
- " in the data dictionary\n"
- "InnoDB: but the flags in file %s are 0x%lx!\n",
- space->flags, node->name, flags);
- ut_error;
- }
+ if (UNIV_UNLIKELY(space_id != space->id)) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "tablespace id is " ULINTPF " in the data dictionary"
+ " but in file %s it is " ULINTPF "!\n",
+ space->id, node->name, space_id);
+ return(false);
}
if (size_bytes >= (1024*1024)) {
@@ -768,7 +716,7 @@ add_size:
space->size += node->size;
}
- atomic_writes = fsp_flags_get_atomic_writes(space->flags);
+ ulint atomic_writes = fsp_flags_get_atomic_writes(space->flags);
/* printf("Opening file %s\n", node->name); */
@@ -1572,7 +1520,6 @@ fil_space_create(
fil_system->tablespace_version++;
space->tablespace_version = fil_system->tablespace_version;
- space->mark = FALSE;
if (purpose == FIL_TABLESPACE && !recv_recovery_on
&& id > fil_system->max_assigned_id) {
@@ -2324,27 +2271,21 @@ fil_write_flushed_lsn_to_data_files(
return(DB_SUCCESS);
}
-/*******************************************************************//**
-Checks the consistency of the first data page of a tablespace
+/** Check the consistency of the first data page of a tablespace
at database startup.
+@param[in] page page frame
+@param[in] space_id tablespace identifier
+@param[in] flags tablespace flags
@retval NULL on success, or if innodb_force_recovery is set
@return pointer to an error message string */
static MY_ATTRIBUTE((warn_unused_result))
const char*
-fil_check_first_page(
-/*=================*/
- const page_t* page) /*!< in: data page */
+fil_check_first_page(const page_t* page, ulint space_id, ulint flags)
{
- ulint space_id;
- ulint flags;
-
if (srv_force_recovery >= SRV_FORCE_IGNORE_CORRUPT) {
return(NULL);
}
- space_id = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_ID + page);
- flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page);
-
if (UNIV_PAGE_SIZE != fsp_flags_get_page_size(flags)) {
fprintf(stderr,
"InnoDB: Error: Current page size %lu != "
@@ -2393,7 +2334,7 @@ fil_read_first_page(
ibool one_read_already, /*!< in: TRUE if min and max
parameters below already
contain sensible data */
- ulint* flags, /*!< out: tablespace flags */
+ ulint* flags, /*!< out: FSP_SPACE_FLAGS */
ulint* space_id, /*!< out: tablespace ID */
lsn_t* min_flushed_lsn, /*!< out: min of flushed
lsn values in data files */
@@ -2423,12 +2364,22 @@ fil_read_first_page(
*flags and *space_id as they were read from the first file and
do not validate the first page. */
if (!one_read_already) {
- *flags = fsp_header_get_flags(page);
*space_id = fsp_header_get_space_id(page);
- }
+ *flags = fsp_header_get_flags(page);
- if (!one_read_already) {
- check_msg = fil_check_first_page(page);
+ if (!fsp_flags_is_valid(*flags)) {
+ ulint cflags = fsp_flags_convert_from_101(*flags);
+ if (cflags == ULINT_UNDEFINED) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Invalid flags 0x%x in tablespace %u",
+ unsigned(*flags), unsigned(*space_id));
+ return "invalid tablespace flags";
+ } else {
+ *flags = cflags;
+ }
+ }
+
+ check_msg = fil_check_first_page(page, *space_id, *flags);
}
flushed_lsn = mach_read_from_8(page +
@@ -2612,6 +2563,7 @@ fil_op_write_log(
ulint len;
log_ptr = mlog_open(mtr, 11 + 2 + 1);
+ ut_ad(fsp_flags_is_valid(flags));
if (!log_ptr) {
/* Logging in mtr is switched off during crash recovery:
@@ -3823,7 +3775,7 @@ fil_create_new_single_table_tablespace(
ibool success;
/* TRUE if a table is created with CREATE TEMPORARY TABLE */
bool is_temp = !!(flags2 & DICT_TF2_TEMPORARY);
- bool has_data_dir = FSP_FLAGS_HAS_DATA_DIR(flags);
+ bool has_data_dir = FSP_FLAGS_HAS_DATA_DIR(flags) != 0;
ulint atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(flags);
fil_space_crypt_t *crypt_data = NULL;
@@ -3831,7 +3783,7 @@ fil_create_new_single_table_tablespace(
ut_ad(!srv_read_only_mode);
ut_a(space_id < SRV_LOG_SPACE_FIRST_ID);
ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE);
- ut_a(fsp_flags_is_valid(flags));
+ ut_a(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK));
if (is_temp) {
/* Temporary table filepath */
@@ -3924,12 +3876,9 @@ fil_create_new_single_table_tablespace(
memset(page, '\0', UNIV_PAGE_SIZE);
- /* Add the UNIV_PAGE_SIZE to the table flags and write them to the
- tablespace header. */
- flags = fsp_flags_set_page_size(flags, UNIV_PAGE_SIZE);
+ flags |= FSP_FLAGS_PAGE_SSIZE();
fsp_header_init_fields(page, space_id, flags);
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, space_id);
- ut_ad(fsp_flags_is_valid(flags));
if (!(fsp_flags_is_compressed(flags))) {
buf_flush_init_for_writing(page, NULL, 0);
@@ -4008,7 +3957,8 @@ fil_create_new_single_table_tablespace(
fil_op_write_log(flags
? MLOG_FILE_CREATE2
: MLOG_FILE_CREATE,
- space_id, mlog_file_flag, flags,
+ space_id, mlog_file_flag,
+ flags & ~FSP_FLAGS_MEM_MASK,
tablename, NULL, &mtr);
mtr_commit(&mtr);
@@ -4072,6 +4022,39 @@ fil_report_bad_tablespace(
(ulong) expected_id, (ulong) expected_flags);
}
+/** Try to adjust FSP_SPACE_FLAGS if they differ from the expectations.
+(Typically when upgrading from MariaDB 10.1.0..10.1.20.)
+@param[in] space_id tablespace ID
+@param[in] flags desired tablespace flags */
+UNIV_INTERN
+void
+fsp_flags_try_adjust(ulint space_id, ulint flags)
+{
+ ut_ad(!srv_read_only_mode);
+ ut_ad(fsp_flags_is_valid(flags));
+
+ mtr_t mtr;
+ mtr_start(&mtr);
+ if (buf_block_t* b = buf_page_get(
+ space_id, fsp_flags_get_zip_size(flags), 0, RW_X_LATCH,
+ &mtr)) {
+ ulint f = fsp_header_get_flags(b->frame);
+ /* Suppress the message if only the DATA_DIR flag to differs. */
+ if ((f ^ flags) & ~(1U << FSP_FLAGS_POS_RESERVED)) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "adjusting FSP_SPACE_FLAGS of tablespace "
+ ULINTPF " from 0x%x to 0x%x",
+ space_id, int(f), int(flags));
+ }
+ if (f != flags) {
+ mlog_write_ulint(FSP_HEADER_OFFSET
+ + FSP_SPACE_FLAGS + b->frame,
+ flags, MLOG_4BYTES, &mtr);
+ }
+ }
+ mtr_commit(&mtr);
+}
+
/********************************************************************//**
Tries to open a single-table tablespace and optionally checks that the
space id in it is correct. If this does not succeed, print an error message
@@ -4101,7 +4084,7 @@ fil_open_single_table_tablespace(
bool validate, /*!< in: Do we validate tablespace? */
bool fix_dict, /*!< in: Can we fix the dictionary? */
ulint id, /*!< in: space id */
- ulint flags, /*!< in: tablespace flags */
+ ulint flags, /*!< in: expected FSP_SPACE_FLAGS */
const char* tablename, /*!< in: table name in the
databasename/tablename format */
const char* path_in, /*!< in: tablespace filepath */
@@ -4126,20 +4109,13 @@ fil_open_single_table_tablespace(
/* Table flags can be ULINT_UNDEFINED if
dict_tf_to_fsp_flags_failure is set. */
- if (flags != ULINT_UNDEFINED) {
- if (!fsp_flags_is_valid(flags)) {
- return(DB_CORRUPTION);
- }
- } else {
+ if (flags == ULINT_UNDEFINED) {
return(DB_CORRUPTION);
}
+ ut_ad(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK));
atomic_writes = fsp_flags_get_atomic_writes(flags);
- /* If the tablespace was relocated, we do not
- compare the DATA_DIR flag */
- ulint mod_flags = flags & ~FSP_FLAGS_MASK_DATA_DIR;
-
memset(&def, 0, sizeof(def));
memset(&dict, 0, sizeof(dict));
memset(&remote, 0, sizeof(remote));
@@ -4217,31 +4193,17 @@ fil_open_single_table_tablespace(
def.check_msg = fil_read_first_page(
def.file, FALSE, &def.flags, &def.id,
&def.lsn, &def.lsn, &def.crypt_data);
- def.valid = !def.check_msg;
if (table) {
table->crypt_data = def.crypt_data;
table->page_0_read = true;
}
- /* Validate this single-table-tablespace with SYS_TABLES,
- but do not compare the DATA_DIR flag, in case the
- tablespace was relocated. */
-
- ulint newf = def.flags;
- if (newf != mod_flags) {
- if (FSP_FLAGS_HAS_DATA_DIR(newf)) {
- newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR);
- } else if(FSP_FLAGS_HAS_DATA_DIR_ORACLE(newf)) {
- newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE);
- }
- }
-
- if (def.valid && def.id == id
- && newf == mod_flags) {
+ def.valid = !def.check_msg && def.id == id
+ && fsp_flags_match(flags, def.flags);
+ if (def.valid) {
valid_tablespaces_found++;
} else {
- def.valid = false;
/* Do not use this tablespace. */
fil_report_bad_tablespace(
def.filepath, def.check_msg, def.id,
@@ -4254,30 +4216,18 @@ fil_open_single_table_tablespace(
remote.check_msg = fil_read_first_page(
remote.file, FALSE, &remote.flags, &remote.id,
&remote.lsn, &remote.lsn, &remote.crypt_data);
- remote.valid = !remote.check_msg;
if (table) {
table->crypt_data = remote.crypt_data;
table->page_0_read = true;
}
- /* Validate this single-table-tablespace with SYS_TABLES,
- but do not compare the DATA_DIR flag, in case the
- tablespace was relocated. */
- ulint newf = remote.flags;
- if (newf != mod_flags) {
- if (FSP_FLAGS_HAS_DATA_DIR(newf)) {
- newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR);
- } else if(FSP_FLAGS_HAS_DATA_DIR_ORACLE(newf)) {
- newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE);
- }
- }
-
- if (remote.valid && remote.id == id
- && newf == mod_flags) {
+ /* Validate this single-table-tablespace with SYS_TABLES. */
+ remote.valid = !remote.check_msg && remote.id == id
+ && fsp_flags_match(flags, remote.flags);
+ if (remote.valid) {
valid_tablespaces_found++;
} else {
- remote.valid = false;
/* Do not use this linked tablespace. */
fil_report_bad_tablespace(
remote.filepath, remote.check_msg, remote.id,
@@ -4291,30 +4241,19 @@ fil_open_single_table_tablespace(
dict.check_msg = fil_read_first_page(
dict.file, FALSE, &dict.flags, &dict.id,
&dict.lsn, &dict.lsn, &dict.crypt_data);
- dict.valid = !dict.check_msg;
if (table) {
table->crypt_data = dict.crypt_data;
table->page_0_read = true;
}
- /* Validate this single-table-tablespace with SYS_TABLES,
- but do not compare the DATA_DIR flag, in case the
- tablespace was relocated. */
- ulint newf = dict.flags;
- if (newf != mod_flags) {
- if (FSP_FLAGS_HAS_DATA_DIR(newf)) {
- newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR);
- } else if(FSP_FLAGS_HAS_DATA_DIR_ORACLE(newf)) {
- newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE);
- }
- }
+ /* Validate this single-table-tablespace with SYS_TABLES. */
+ dict.valid = !dict.check_msg && dict.id == id
+ && fsp_flags_match(flags, dict.flags);
- if (dict.valid && dict.id == id
- && newf == mod_flags) {
+ if (dict.valid) {
valid_tablespaces_found++;
} else {
- dict.valid = false;
/* Do not use this tablespace. */
fil_report_bad_tablespace(
dict.filepath, dict.check_msg, dict.id,
@@ -4512,6 +4451,10 @@ cleanup_and_exit:
mem_free(def.filepath);
+ if (err == DB_SUCCESS && !srv_read_only_mode) {
+ fsp_flags_try_adjust(id, flags & ~FSP_FLAGS_MEM_MASK);
+ }
+
return(err);
}
#endif /* !UNIV_HOTBACKUP */
@@ -4693,7 +4636,23 @@ fil_user_tablespace_restore_page(
goto out;
}
- flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page);
+ flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page);
+
+ if (!fsp_flags_is_valid(flags)) {
+ ulint cflags = fsp_flags_convert_from_101(flags);
+ if (cflags == ULINT_UNDEFINED) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Ignoring a doublewrite copy of page "
+ ULINTPF ":" ULINTPF
+ " due to invalid flags 0x%x",
+ fsp->id, page_no, int(flags));
+ err = false;
+ goto out;
+ }
+ flags = cflags;
+ /* The flags on the page should be converted later. */
+ }
+
zip_size = fsp_flags_get_zip_size(flags);
page_size = fsp_flags_get_page_size(flags);
@@ -5071,6 +5030,16 @@ will_not_choose:
}
mutex_exit(&fil_system->mutex);
#endif /* UNIV_HOTBACKUP */
+ /* Adjust the memory-based flags that would normally be set by
+ dict_tf_to_fsp_flags(). In recovery, we have no data dictionary. */
+ if (FSP_FLAGS_HAS_PAGE_COMPRESSION(fsp->flags)) {
+ fsp->flags |= page_zip_level
+ << FSP_FLAGS_MEM_COMPRESSION_LEVEL;
+ }
+ remote.flags |= 1U << FSP_FLAGS_MEM_DATA_DIR;
+ /* We will leave atomic_writes at ATOMIC_WRITES_DEFAULT.
+ That will be adjusted in fil_space_for_table_exists_in_mem(). */
+
ibool file_space_create_success = fil_space_create(
tablename, fsp->id, fsp->flags, FIL_TABLESPACE,
fsp->crypt_data, false);
@@ -5380,13 +5349,12 @@ fil_report_missing_tablespace(
name, space_id);
}
-/*******************************************************************//**
-Returns TRUE if a matching tablespace exists in the InnoDB tablespace memory
+/** Check if a matching tablespace exists in the InnoDB tablespace memory
cache. Note that if we have not done a crash recovery at the database startup,
there may be many tablespaces which are not yet in the memory cache.
-@return TRUE if a matching tablespace exists in the memory cache */
+@return whether a matching tablespace exists in the memory cache */
UNIV_INTERN
-ibool
+bool
fil_space_for_table_exists_in_mem(
/*==============================*/
ulint id, /*!< in: space id */
@@ -5394,13 +5362,7 @@ fil_space_for_table_exists_in_mem(
fil_space_create(). Either the
standard 'dbname/tablename' format
or table->dir_path_of_temp_table */
- ibool mark_space, /*!< in: in crash recovery, at database
- startup we mark all spaces which have
- an associated table in the InnoDB
- data dictionary, so that
- we can print a warning about orphaned
- tablespaces */
- ibool print_error_if_does_not_exist,
+ bool print_error_if_does_not_exist,
/*!< in: print detailed error
information to the .err log if a
matching tablespace is not found from
@@ -5408,12 +5370,13 @@ fil_space_for_table_exists_in_mem(
bool adjust_space, /*!< in: whether to adjust space id
when find table space mismatch */
mem_heap_t* heap, /*!< in: heap memory */
- table_id_t table_id) /*!< in: table id */
+ table_id_t table_id, /*!< in: table id */
+ ulint table_flags) /*!< in: table flags */
{
fil_space_t* fnamespace;
fil_space_t* space;
- ut_ad(fil_system);
+ const ulint expected_flags = dict_tf_to_fsp_flags(table_flags);
mutex_enter(&fil_system->mutex);
@@ -5425,42 +5388,31 @@ fil_space_for_table_exists_in_mem(
directory path from the datadir to the file */
fnamespace = fil_space_get_by_name(name);
- if (space && space == fnamespace) {
- /* Found */
-
- if (mark_space) {
- space->mark = TRUE;
- }
-
- mutex_exit(&fil_system->mutex);
-
- return(TRUE);
- }
-
- /* Info from "fnamespace" comes from the ibd file itself, it can
- be different from data obtained from System tables since it is
- not transactional. If adjust_space is set, and the mismatching
- space are between a user table and its temp table, we shall
- adjust the ibd file name according to system table info */
- if (adjust_space
- && space != NULL
- && row_is_mysql_tmp_table_name(space->name)
- && !row_is_mysql_tmp_table_name(name)) {
+ bool valid = space && !((space->flags ^ expected_flags)
+ & ~FSP_FLAGS_MEM_MASK);
+ if (!space) {
+ } else if (!valid || space == fnamespace) {
+ /* Found with the same file name, or got a flag mismatch. */
+ goto func_exit;
+ } else if (adjust_space
+ && row_is_mysql_tmp_table_name(space->name)
+ && !row_is_mysql_tmp_table_name(name)) {
+ /* Info from fnamespace comes from the ibd file
+ itself, it can be different from data obtained from
+ System tables since renaming files is not
+ transactional. We shall adjust the ibd file name
+ according to system table info. */
mutex_exit(&fil_system->mutex);
DBUG_EXECUTE_IF("ib_crash_before_adjust_fil_space",
DBUG_SUICIDE(););
- if (fnamespace) {
- char* tmp_name;
+ char* tmp_name = dict_mem_create_temporary_tablename(
+ heap, name, table_id);
- tmp_name = dict_mem_create_temporary_tablename(
- heap, name, table_id);
-
- fil_rename_tablespace(fnamespace->name, fnamespace->id,
- tmp_name, NULL);
- }
+ fil_rename_tablespace(fnamespace->name, fnamespace->id,
+ tmp_name, NULL);
DBUG_EXECUTE_IF("ib_crash_after_adjust_one_fil_space",
DBUG_SUICIDE(););
@@ -5473,16 +5425,12 @@ fil_space_for_table_exists_in_mem(
mutex_enter(&fil_system->mutex);
fnamespace = fil_space_get_by_name(name);
ut_ad(space == fnamespace);
- mutex_exit(&fil_system->mutex);
-
- return(TRUE);
+ goto func_exit;
}
if (!print_error_if_does_not_exist) {
-
- mutex_exit(&fil_system->mutex);
-
- return(FALSE);
+ valid = false;
+ goto func_exit;
}
if (space == NULL) {
@@ -5509,10 +5457,8 @@ error_exit:
fputs("InnoDB: Please refer to\n"
"InnoDB: " REFMAN "innodb-troubleshooting-datadict.html\n"
"InnoDB: for how to resolve the issue.\n", stderr);
-
- mutex_exit(&fil_system->mutex);
-
- return(FALSE);
+ valid = false;
+ goto func_exit;
}
if (0 != strcmp(space->name, name)) {
@@ -5539,9 +5485,19 @@ error_exit:
goto error_exit;
}
+func_exit:
+ if (valid) {
+ /* Adjust the flags that are in FSP_FLAGS_MEM_MASK.
+ FSP_SPACE_FLAGS will not be written back here. */
+ space->flags = expected_flags;
+ }
mutex_exit(&fil_system->mutex);
- return(FALSE);
+ if (valid && !srv_read_only_mode) {
+ fsp_flags_try_adjust(id, expected_flags & ~FSP_FLAGS_MEM_MASK);
+ }
+
+ return(valid);
}
/*******************************************************************//**
@@ -7444,9 +7400,8 @@ fil_space_get_crypt_data(
byte *page = static_cast<byte*>(ut_align(buf, UNIV_PAGE_SIZE));
fil_read(true, space_id, 0, 0, 0, UNIV_PAGE_SIZE, page,
NULL, NULL);
- ulint flags = fsp_header_get_flags(page);
ulint offset = fsp_header_get_crypt_offset(
- fsp_flags_get_zip_size(flags), NULL);
+ fsp_header_get_zip_size(page), NULL);
space->crypt_data = fil_space_read_crypt_data(space_id, page, offset);
ut_free(buf);
diff --git a/storage/xtradb/fsp/fsp0fsp.cc b/storage/xtradb/fsp/fsp0fsp.cc
index 4acfd134c1f..c32fddaabbe 100644
--- a/storage/xtradb/fsp/fsp0fsp.cc
+++ b/storage/xtradb/fsp/fsp0fsp.cc
@@ -663,6 +663,7 @@ fsp_header_init_fields(
ulint space_id, /*!< in: space id */
ulint flags) /*!< in: tablespace flags (FSP_SPACE_FLAGS) */
{
+ flags &= ~FSP_FLAGS_MEM_MASK;
ut_a(fsp_flags_is_valid(flags));
mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_ID + page,
@@ -713,7 +714,7 @@ fsp_header_init(
mlog_write_ulint(header + FSP_SIZE, size, MLOG_4BYTES, mtr);
mlog_write_ulint(header + FSP_FREE_LIMIT, 0, MLOG_4BYTES, mtr);
- mlog_write_ulint(header + FSP_SPACE_FLAGS, flags,
+ mlog_write_ulint(header + FSP_SPACE_FLAGS, flags & ~FSP_FLAGS_MEM_MASK,
MLOG_4BYTES, mtr);
mlog_write_ulint(header + FSP_FRAG_N_USED, 0, MLOG_4BYTES, mtr);
diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic
index d9d40b809d1..2b63ddea51d 100644
--- a/storage/xtradb/include/dict0dict.ic
+++ b/storage/xtradb/include/dict0dict.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2016, MariaDB
+Copyright (c) 2013, 2017, MariaDB Corporation.
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
@@ -918,10 +918,13 @@ dict_tf_to_fsp_flags(
ulint table_flags) /*!< in: dict_table_t::flags */
{
ulint fsp_flags;
- ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags);
- ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags);
+ ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(
+ table_flags);
ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags);
+ ut_ad((DICT_TF_GET_PAGE_COMPRESSION(table_flags) == 0)
+ == (page_compression_level == 0));
+
DBUG_EXECUTE_IF("dict_tf_to_fsp_flags_failure",
return(ULINT_UNDEFINED););
@@ -929,30 +932,23 @@ dict_tf_to_fsp_flags(
fsp_flags = DICT_TF_HAS_ATOMIC_BLOBS(table_flags) ? 1 : 0;
/* ZIP_SSIZE and ATOMIC_BLOBS are at the same position. */
- fsp_flags |= table_flags & DICT_TF_MASK_ZIP_SSIZE;
- fsp_flags |= table_flags & DICT_TF_MASK_ATOMIC_BLOBS;
-
- /* In addition, tablespace flags also contain the page size. */
- fsp_flags |= fsp_flags_set_page_size(fsp_flags, UNIV_PAGE_SIZE);
+ fsp_flags |= table_flags
+ & (DICT_TF_MASK_ZIP_SSIZE | DICT_TF_MASK_ATOMIC_BLOBS);
- /* The DATA_DIR flag is in a different position in fsp_flag */
- fsp_flags |= DICT_TF_HAS_DATA_DIR(table_flags)
- ? FSP_FLAGS_MASK_DATA_DIR : 0;
+ fsp_flags |= FSP_FLAGS_PAGE_SSIZE();
- /* In addition, tablespace flags also contain if the page
- compression is used for this table. */
- fsp_flags |= FSP_FLAGS_SET_PAGE_COMPRESSION(fsp_flags, page_compression);
+ if (page_compression_level) {
+ fsp_flags |= FSP_FLAGS_MASK_PAGE_COMPRESSION;
+ }
- /* In addition, tablespace flags also contain page compression level
- if page compression is used for this table. */
- fsp_flags |= FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(fsp_flags, page_compression_level);
+ ut_a(fsp_flags_is_valid(fsp_flags));
- /* In addition, tablespace flags also contain flag if atomic writes
- is used for this table */
- fsp_flags |= FSP_FLAGS_SET_ATOMIC_WRITES(fsp_flags, atomic_writes);
+ if (DICT_TF_HAS_DATA_DIR(table_flags)) {
+ fsp_flags |= 1U << FSP_FLAGS_MEM_DATA_DIR;
+ }
- ut_a(fsp_flags_is_valid(fsp_flags));
- ut_a(dict_tf_verify_flags(table_flags, fsp_flags));
+ fsp_flags |= atomic_writes << FSP_FLAGS_MEM_ATOMIC_WRITES;
+ fsp_flags |= page_compression_level << FSP_FLAGS_MEM_COMPRESSION_LEVEL;
return(fsp_flags);
}
diff --git a/storage/xtradb/include/dict0pagecompress.h b/storage/xtradb/include/dict0pagecompress.h
index 19a2a6c52f3..6503c86ffa2 100644
--- a/storage/xtradb/include/dict0pagecompress.h
+++ b/storage/xtradb/include/dict0pagecompress.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013 SkySQL Ab. All Rights Reserved.
+Copyright (C) 2013, 2017, MariaDB Corporation. 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
@@ -57,17 +57,6 @@ dict_table_page_compression_level(
__attribute__((const));
/********************************************************************//**
-Verify that dictionary flags match tablespace flags
-@return true if flags match, false if not */
-UNIV_INLINE
-ibool
-dict_tf_verify_flags(
-/*=================*/
- ulint table_flags, /*!< in: dict_table_t::flags */
- ulint fsp_flags) /*!< in: fil_space_t::flags */
- __attribute__((const));
-
-/********************************************************************//**
Extract the atomic writes flag from table flags.
@return true if atomic writes are used, false if not used */
UNIV_INLINE
diff --git a/storage/xtradb/include/dict0pagecompress.ic b/storage/xtradb/include/dict0pagecompress.ic
index 811976434a8..13c2b46c51c 100644
--- a/storage/xtradb/include/dict0pagecompress.ic
+++ b/storage/xtradb/include/dict0pagecompress.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013 SkySQL Ab. All Rights Reserved.
+Copyright (C) 2013, 2017, MariaDB Corporation. 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
@@ -25,92 +25,6 @@ Created 11/12/2013 Jan Lindström jan.lindstrom@skysql.com
***********************************************************************/
/********************************************************************//**
-Verify that dictionary flags match tablespace flags
-@return true if flags match, false if not */
-UNIV_INLINE
-ibool
-dict_tf_verify_flags(
-/*=================*/
- ulint table_flags, /*!< in: dict_table_t::flags */
- ulint fsp_flags) /*!< in: fil_space_t::flags */
-{
- ulint table_unused = DICT_TF_GET_UNUSED(table_flags);
- ulint compact = DICT_TF_GET_COMPACT(table_flags);
- ulint ssize = DICT_TF_GET_ZIP_SSIZE(table_flags);
- ulint atomic_blobs = DICT_TF_HAS_ATOMIC_BLOBS(table_flags);
- ulint data_dir = DICT_TF_HAS_DATA_DIR(table_flags);
- ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags);
- ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags);
- ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags);
- ulint post_antelope = FSP_FLAGS_GET_POST_ANTELOPE(fsp_flags);
- ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(fsp_flags);
- ulint fsp_atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(fsp_flags);
- ulint page_ssize = FSP_FLAGS_GET_PAGE_SSIZE(fsp_flags);
- ulint fsp_unused = FSP_FLAGS_GET_UNUSED(fsp_flags);
- ulint fsp_page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(fsp_flags);
- ulint fsp_page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(fsp_flags);
- ulint fsp_atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(fsp_flags);
-
- DBUG_EXECUTE_IF("dict_tf_verify_flags_failure",
- return(ULINT_UNDEFINED););
-
- ut_a(!table_unused);
- ut_a(!fsp_unused);
- ut_a(page_ssize == 0 || page_ssize != 0); /* silence compiler */
- ut_a(compact == 0 || compact == 1); /* silence compiler */
- ut_a(data_dir == 0 || data_dir == 1); /* silence compiler */
- ut_a(post_antelope == 0 || post_antelope == 1); /* silence compiler */
-
- if (ssize != zip_ssize) {
- fprintf(stderr,
- "InnoDB: Error: table flags has zip_ssize %ld"
- " in the data dictionary\n"
- "InnoDB: but the flags in file has zip_ssize %ld\n",
- ssize, zip_ssize);
- return (FALSE);
- }
- if (atomic_blobs != fsp_atomic_blobs) {
- fprintf(stderr,
- "InnoDB: Error: table flags has atomic_blobs %ld"
- " in the data dictionary\n"
- "InnoDB: but the flags in file has atomic_blobs %ld\n",
- atomic_blobs, fsp_atomic_blobs);
-
- return (FALSE);
- }
- if (page_compression != fsp_page_compression) {
- fprintf(stderr,
- "InnoDB: Error: table flags has page_compression %ld"
- " in the data dictionary\n"
- "InnoDB: but the flags in file ahas page_compression %ld\n",
- page_compression, fsp_page_compression);
-
- return (FALSE);
- }
- if (page_compression_level != fsp_page_compression_level) {
- fprintf(stderr,
- "InnoDB: Error: table flags has page_compression_level %ld"
- " in the data dictionary\n"
- "InnoDB: but the flags in file has page_compression_level %ld\n",
- page_compression_level, fsp_page_compression_level);
-
- return (FALSE);
- }
-
- if (atomic_writes != fsp_atomic_writes) {
- fprintf(stderr,
- "InnoDB: Error: table flags has atomic writes %ld"
- " in the data dictionary\n"
- "InnoDB: but the flags in file has atomic_writes %ld\n",
- atomic_writes, fsp_atomic_writes);
-
- return (FALSE);
- }
-
- return(TRUE);
-}
-
-/********************************************************************//**
Extract the page compression level from dict_table_t::flags.
These flags are in memory, so assert that they are valid.
@return page compression level, or 0 if not compressed */
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index 38cc09bced3..41e38794ea9 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2016, MariaDB Corporation.
+Copyright (c) 2013, 2017, MariaDB Corporation.
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
@@ -45,7 +45,6 @@ Created 10/25/1995 Heikki Tuuri
// Forward declaration
struct trx_t;
-struct fil_space_t;
typedef std::list<const char*> space_name_list_t;
@@ -264,10 +263,6 @@ struct fil_space_t {
an insert buffer merge request for a
page because it actually was for the
previous incarnation of the space */
- ibool mark; /*!< this is set to TRUE at database startup if
- the space corresponds to a table in the InnoDB
- data dictionary; so we can print a warning of
- orphaned tablespaces */
ibool stop_ios;/*!< TRUE if we want to rename the
.ibd file of tablespace and want to
stop temporarily posting of new i/o
@@ -296,7 +291,8 @@ struct fil_space_t {
/*!< recovered tablespace size in pages;
0 if no size change was read from the redo log,
or if the size change was implemented */
- ulint flags; /*!< tablespace flags; see
+ ulint flags; /*!< FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags;
+ see fsp0fsp.h,
fsp_flags_is_valid(),
fsp_flags_get_zip_size() */
ulint n_reserved_extents;
@@ -449,6 +445,7 @@ fil_node_create(
ibool is_raw) /*!< in: TRUE if a raw device or
a raw disk partition */
MY_ATTRIBUTE((nonnull, warn_unused_result));
+
#ifdef UNIV_LOG_ARCHIVE
/****************************************************************//**
Drops files from the start of a file space, so that its size is cut by
@@ -620,7 +617,7 @@ fil_read_first_page(
ibool one_read_already, /*!< in: TRUE if min and max
parameters below already
contain sensible data */
- ulint* flags, /*!< out: tablespace flags */
+ ulint* flags, /*!< out: FSP_SPACE_FLAGS */
ulint* space_id, /*!< out: tablespace ID */
lsn_t* min_flushed_lsn, /*!< out: min of flushed
lsn values in data files */
@@ -832,6 +829,14 @@ fil_create_new_single_table_tablespace(
ulint key_id) /*!< in: encryption key_id */
__attribute__((nonnull, warn_unused_result));
#ifndef UNIV_HOTBACKUP
+/** Try to adjust FSP_SPACE_FLAGS if they differ from the expectations.
+(Typically when upgrading from MariaDB 10.1.0..10.1.20.)
+@param[in] space_id tablespace ID
+@param[in] flags desired tablespace flags */
+UNIV_INTERN
+void
+fsp_flags_try_adjust(ulint space_id, ulint flags);
+
/********************************************************************//**
Tries to open a single-table tablespace and optionally checks the space id is
right in it. If does not succeed, prints an error message to the .err log. This
@@ -860,7 +865,7 @@ fil_open_single_table_tablespace(
bool validate, /*!< in: Do we validate tablespace? */
bool fix_dict, /*!< in: Can we fix the dictionary? */
ulint id, /*!< in: space id */
- ulint flags, /*!< in: tablespace flags */
+ ulint flags, /*!< in: expected FSP_SPACE_FLAGS */
const char* tablename, /*!< in: table name in the
databasename/tablename format */
const char* filepath, /*!< in: tablespace filepath */
@@ -901,25 +906,18 @@ fil_tablespace_exists_in_mem(
/*=========================*/
ulint id); /*!< in: space id */
#ifndef UNIV_HOTBACKUP
-/*******************************************************************//**
-Returns TRUE if a matching tablespace exists in the InnoDB tablespace memory
+/** Check if a matching tablespace exists in the InnoDB tablespace memory
cache. Note that if we have not done a crash recovery at the database startup,
there may be many tablespaces which are not yet in the memory cache.
-@return TRUE if a matching tablespace exists in the memory cache */
+@return whether a matching tablespace exists in the memory cache */
UNIV_INTERN
-ibool
+bool
fil_space_for_table_exists_in_mem(
/*==============================*/
ulint id, /*!< in: space id */
const char* name, /*!< in: table name in the standard
'databasename/tablename' format */
- ibool mark_space, /*!< in: in crash recovery, at database
- startup we mark all spaces which have
- an associated table in the InnoDB
- data dictionary, so that
- we can print a warning about orphaned
- tablespaces */
- ibool print_error_if_does_not_exist,
+ bool print_error_if_does_not_exist,
/*!< in: print detailed error
information to the .err log if a
matching tablespace is not found from
@@ -927,7 +925,8 @@ fil_space_for_table_exists_in_mem(
bool adjust_space, /*!< in: whether to adjust space id
when find table space mismatch */
mem_heap_t* heap, /*!< in: heap memory */
- table_id_t table_id); /*!< in: table id */
+ table_id_t table_id, /*!< in: table id */
+ ulint table_flags); /*!< in: table flags */
#else /* !UNIV_HOTBACKUP */
/********************************************************************//**
Extends all tablespaces to the size stored in the space header. During the
diff --git a/storage/xtradb/include/fil0pagecompress.h b/storage/xtradb/include/fil0pagecompress.h
index 10db59fb218..1fe5cb66bf6 100644
--- a/storage/xtradb/include/fil0pagecompress.h
+++ b/storage/xtradb/include/fil0pagecompress.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2016 MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2013, 2017 MariaDB Corporation. 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
@@ -44,20 +44,11 @@ Returns the page compression flag of the space, or false if the space
is not compressed. The tablespace must be cached in the memory cache.
@return true if page compressed, false if not or space not found */
UNIV_INLINE
-ibool
+bool
fil_space_is_page_compressed(
/*=========================*/
ulint id); /*!< in: space id */
/*******************************************************************//**
-Returns the page compression flag of the space, or false if the space
-is not compressed. The tablespace must be cached in the memory cache.
-@return true if page compressed, false if not or space not found */
-UNIV_INTERN
-ibool
-fil_space_get_page_compressed(
-/*=========================*/
- fil_space_t* space); /*!< in: space id */
-/*******************************************************************//**
Returns the atomic writes flag of the space, or false if the space
is not using atomic writes. The tablespace must be cached in the memory cache.
@return atomic write table option value */
diff --git a/storage/xtradb/include/fsp0fsp.h b/storage/xtradb/include/fsp0fsp.h
index 551a8c9ef97..93f98eb0b0b 100644
--- a/storage/xtradb/include/fsp0fsp.h
+++ b/storage/xtradb/include/fsp0fsp.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2013, 2017, MariaDB Corporation. 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
@@ -51,28 +51,67 @@ to the two Barracuda row formats COMPRESSED and DYNAMIC. */
#define FSP_FLAGS_WIDTH_ATOMIC_BLOBS 1
/** Number of flag bits used to indicate the tablespace page size */
#define FSP_FLAGS_WIDTH_PAGE_SSIZE 4
-/** Width of the DATA_DIR flag. This flag indicates that the tablespace
-is found in a remote location, not the default data directory. */
-#define FSP_FLAGS_WIDTH_DATA_DIR 1
-/** Number of flag bits used to indicate the page compression and compression level */
-#define FSP_FLAGS_WIDTH_PAGE_COMPRESSION 1
-#define FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL 4
+/** Number of reserved bits */
+#define FSP_FLAGS_WIDTH_RESERVED 6
+/** Number of flag bits used to indicate the page compression */
+#define FSP_FLAGS_WIDTH_PAGE_COMPRESSION 1
-/** Number of flag bits used to indicate atomic writes for this tablespace */
-#define FSP_FLAGS_WIDTH_ATOMIC_WRITES 2
-
-/** Width of all the currently known tablespace flags */
+/** Width of all the currently known persistent tablespace flags */
#define FSP_FLAGS_WIDTH (FSP_FLAGS_WIDTH_POST_ANTELOPE \
+ FSP_FLAGS_WIDTH_ZIP_SSIZE \
+ FSP_FLAGS_WIDTH_ATOMIC_BLOBS \
+ FSP_FLAGS_WIDTH_PAGE_SSIZE \
- + FSP_FLAGS_WIDTH_DATA_DIR \
- + FSP_FLAGS_WIDTH_PAGE_COMPRESSION \
- + FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL \
- + FSP_FLAGS_WIDTH_ATOMIC_WRITES )
-
-/** A mask of all the known/used bits in tablespace flags */
-#define FSP_FLAGS_MASK (~(~0 << FSP_FLAGS_WIDTH))
+ + FSP_FLAGS_WIDTH_RESERVED \
+ + FSP_FLAGS_WIDTH_PAGE_COMPRESSION)
+
+/** A mask of all the known/used bits in FSP_SPACE_FLAGS */
+#define FSP_FLAGS_MASK (~(~0U << FSP_FLAGS_WIDTH))
+
+/* FSP_SPACE_FLAGS position and name in MySQL 5.6/MariaDB 10.0 or older
+and MariaDB 10.1.20 or older MariaDB 10.1 and in MariaDB 10.1.21
+or newer.
+MySQL 5.6 MariaDB 10.1.x MariaDB 10.1.21
+====================================================================
+Below flags in same offset
+====================================================================
+0: POST_ANTELOPE 0:POST_ANTELOPE 0: POST_ANTELOPE
+1..4: ZIP_SSIZE(0..5) 1..4:ZIP_SSIZE(0..5) 1..4: ZIP_SSIZE(0..5)
+(NOTE: bit 4 is always 0)
+5: ATOMIC_BLOBS 5:ATOMIC_BLOBS 5: ATOMIC_BLOBS
+=====================================================================
+Below note the order difference:
+=====================================================================
+6..9: PAGE_SSIZE(3..7) 6: COMPRESSION 6..9: PAGE_SSIZE(3..7)
+10: DATA_DIR 7..10: COMP_LEVEL(0..9) 10: RESERVED (5.6 DATA_DIR)
+=====================================================================
+The flags below were in incorrect position in MariaDB 10.1,
+or have been introduced in MySQL 5.7 or 8.0:
+=====================================================================
+11: UNUSED 11..12:ATOMIC_WRITES 11: RESERVED (5.7 SHARED)
+ 12: RESERVED (5.7 TEMPORARY)
+ 13..15:PAGE_SSIZE(3..7) 13: RESERVED (5.7 ENCRYPTION)
+ 14: RESERVED (8.0 SDI)
+ 15: RESERVED
+ 16: PAGE_SSIZE_msb(0) 16: COMPRESSION
+ 17: DATA_DIR 17: UNUSED
+ 18: UNUSED
+=====================================================================
+The flags below only exist in fil_space_t::flags, not in FSP_SPACE_FLAGS:
+=====================================================================
+ 25: DATA_DIR
+ 26..27: ATOMIC_WRITES
+ 28..31: COMPRESSION_LEVEL
+*/
+
+/** A mask of the memory-only flags in fil_space_t::flags */
+#define FSP_FLAGS_MEM_MASK (~0U << FSP_FLAGS_MEM_DATA_DIR)
+
+/** Zero relative shift position of the DATA_DIR flag */
+#define FSP_FLAGS_MEM_DATA_DIR 25
+/** Zero relative shift position of the ATOMIC_WRITES field */
+#define FSP_FLAGS_MEM_ATOMIC_WRITES 26
+/** Zero relative shift position of the COMPRESSION_LEVEL field */
+#define FSP_FLAGS_MEM_COMPRESSION_LEVEL 28
/** Zero relative shift position of the POST_ANTELOPE field */
#define FSP_FLAGS_POS_POST_ANTELOPE 0
@@ -82,29 +121,16 @@ is found in a remote location, not the default data directory. */
/** Zero relative shift position of the ATOMIC_BLOBS field */
#define FSP_FLAGS_POS_ATOMIC_BLOBS (FSP_FLAGS_POS_ZIP_SSIZE \
+ FSP_FLAGS_WIDTH_ZIP_SSIZE)
-/** Note that these need to be before the page size to be compatible with
-dictionary */
-/** Zero relative shift position of the PAGE_COMPRESSION field */
-#define FSP_FLAGS_POS_PAGE_COMPRESSION (FSP_FLAGS_POS_ATOMIC_BLOBS \
- + FSP_FLAGS_WIDTH_ATOMIC_BLOBS)
-/** Zero relative shift position of the PAGE_COMPRESSION_LEVEL field */
-#define FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL (FSP_FLAGS_POS_PAGE_COMPRESSION \
- + FSP_FLAGS_WIDTH_PAGE_COMPRESSION)
-/** Zero relative shift position of the ATOMIC_WRITES field */
-#define FSP_FLAGS_POS_ATOMIC_WRITES (FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL \
- + FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL)
-/** Zero relative shift position of the PAGE_SSIZE field */
-#define FSP_FLAGS_POS_PAGE_SSIZE (FSP_FLAGS_POS_ATOMIC_WRITES \
- + FSP_FLAGS_WIDTH_ATOMIC_WRITES)
-/** Zero relative shift position of the start of the DATA DIR bits */
-#define FSP_FLAGS_POS_DATA_DIR (FSP_FLAGS_POS_PAGE_SSIZE \
- + FSP_FLAGS_WIDTH_PAGE_SSIZE)
-#define FSP_FLAGS_POS_DATA_DIR_ORACLE (FSP_FLAGS_POS_ATOMIC_BLOBS \
- + FSP_FLAGS_WIDTH_ATOMIC_BLOBS \
+/** Zero relative shift position of the start of the PAGE_SSIZE bits */
+#define FSP_FLAGS_POS_PAGE_SSIZE (FSP_FLAGS_POS_ATOMIC_BLOBS \
+ + FSP_FLAGS_WIDTH_ATOMIC_BLOBS)
+/** Zero relative shift position of the start of the RESERVED bits
+these are only used in MySQL 5.7 and used for compatibility. */
+#define FSP_FLAGS_POS_RESERVED (FSP_FLAGS_POS_PAGE_SSIZE \
+ FSP_FLAGS_WIDTH_PAGE_SSIZE)
-/** Zero relative shift position of the start of the UNUSED bits */
-#define FSP_FLAGS_POS_UNUSED (FSP_FLAGS_POS_DATA_DIR\
- + FSP_FLAGS_WIDTH_DATA_DIR)
+/** Zero relative shift position of the PAGE_COMPRESSION field */
+#define FSP_FLAGS_POS_PAGE_COMPRESSION (FSP_FLAGS_POS_RESERVED \
+ + FSP_FLAGS_WIDTH_RESERVED)
/** Bit mask of the POST_ANTELOPE field */
#define FSP_FLAGS_MASK_POST_ANTELOPE \
@@ -122,26 +148,23 @@ dictionary */
#define FSP_FLAGS_MASK_PAGE_SSIZE \
((~(~0U << FSP_FLAGS_WIDTH_PAGE_SSIZE)) \
<< FSP_FLAGS_POS_PAGE_SSIZE)
-/** Bit mask of the DATA_DIR field */
-#define FSP_FLAGS_MASK_DATA_DIR \
- ((~(~0U << FSP_FLAGS_WIDTH_DATA_DIR)) \
- << FSP_FLAGS_POS_DATA_DIR)
-/** Bit mask of the DATA_DIR field */
-#define FSP_FLAGS_MASK_DATA_DIR_ORACLE \
- ((~(~0U << FSP_FLAGS_WIDTH_DATA_DIR)) \
- << FSP_FLAGS_POS_DATA_DIR_ORACLE)
+/** Bit mask of the RESERVED1 field */
+#define FSP_FLAGS_MASK_RESERVED \
+ ((~(~0U << FSP_FLAGS_WIDTH_RESERVED)) \
+ << FSP_FLAGS_POS_RESERVED)
/** Bit mask of the PAGE_COMPRESSION field */
-#define FSP_FLAGS_MASK_PAGE_COMPRESSION \
+#define FSP_FLAGS_MASK_PAGE_COMPRESSION \
((~(~0U << FSP_FLAGS_WIDTH_PAGE_COMPRESSION)) \
<< FSP_FLAGS_POS_PAGE_COMPRESSION)
-/** Bit mask of the PAGE_COMPRESSION_LEVEL field */
-#define FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL \
- ((~(~0U << FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL)) \
- << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL)
-/** Bit mask of the ATOMIC_WRITES field */
-#define FSP_FLAGS_MASK_ATOMIC_WRITES \
- ((~(~0U << FSP_FLAGS_WIDTH_ATOMIC_WRITES)) \
- << FSP_FLAGS_POS_ATOMIC_WRITES)
+
+/** Bit mask of the in-memory ATOMIC_WRITES field */
+#define FSP_FLAGS_MASK_MEM_ATOMIC_WRITES \
+ (3U << FSP_FLAGS_MEM_ATOMIC_WRITES)
+
+/** Bit mask of the in-memory COMPRESSION_LEVEL field */
+#define FSP_FLAGS_MASK_MEM_COMPRESSION_LEVEL \
+ (15U << FSP_FLAGS_MEM_COMPRESSION_LEVEL)
+
/** Return the value of the POST_ANTELOPE field */
#define FSP_FLAGS_GET_POST_ANTELOPE(flags) \
((flags & FSP_FLAGS_MASK_POST_ANTELOPE) \
@@ -158,48 +181,78 @@ dictionary */
#define FSP_FLAGS_GET_PAGE_SSIZE(flags) \
((flags & FSP_FLAGS_MASK_PAGE_SSIZE) \
>> FSP_FLAGS_POS_PAGE_SSIZE)
-/** Return the value of the DATA_DIR field */
-#define FSP_FLAGS_HAS_DATA_DIR(flags) \
- ((flags & FSP_FLAGS_MASK_DATA_DIR) \
- >> FSP_FLAGS_POS_DATA_DIR)
-#define FSP_FLAGS_HAS_DATA_DIR_ORACLE(flags) \
- ((flags & FSP_FLAGS_MASK_DATA_DIR_ORACLE) \
- >> FSP_FLAGS_POS_DATA_DIR_ORACLE)
+/** @return the RESERVED flags */
+#define FSP_FLAGS_GET_RESERVED(flags) \
+ ((flags & FSP_FLAGS_MASK_RESERVED) \
+ >> FSP_FLAGS_POS_RESERVED)
+/** @return the PAGE_COMPRESSION flag */
+#define FSP_FLAGS_HAS_PAGE_COMPRESSION(flags) \
+ ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION) \
+ >> FSP_FLAGS_POS_PAGE_COMPRESSION)
+
/** Return the contents of the UNUSED bits */
#define FSP_FLAGS_GET_UNUSED(flags) \
(flags >> FSP_FLAGS_POS_UNUSED)
+
+/** @return the PAGE_SSIZE flags for the current innodb_page_size */
+#define FSP_FLAGS_PAGE_SSIZE() \
+ ((UNIV_PAGE_SIZE == UNIV_PAGE_SIZE_ORIG) ? \
+ 0 : (UNIV_PAGE_SIZE_SHIFT - UNIV_ZIP_SIZE_SHIFT_MIN + 1) \
+ << FSP_FLAGS_POS_PAGE_SSIZE)
+
+/** @return the value of the DATA_DIR field */
+#define FSP_FLAGS_HAS_DATA_DIR(flags) \
+ (flags & 1U << FSP_FLAGS_MEM_DATA_DIR)
+/** @return the COMPRESSION_LEVEL field */
+#define FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags) \
+ ((flags & FSP_FLAGS_MASK_MEM_COMPRESSION_LEVEL) \
+ >> FSP_FLAGS_MEM_COMPRESSION_LEVEL)
+/** @return the ATOMIC_WRITES field */
+#define FSP_FLAGS_GET_ATOMIC_WRITES(flags) \
+ ((flags & FSP_FLAGS_MASK_MEM_ATOMIC_WRITES) \
+ >> FSP_FLAGS_MEM_ATOMIC_WRITES)
+
+/* Compatibility macros for MariaDB 10.1.20 or older 10.1 see
+table above. */
+/** Zero relative shift position of the PAGE_COMPRESSION field */
+#define FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101 \
+ (FSP_FLAGS_POS_ATOMIC_BLOBS \
+ + FSP_FLAGS_WIDTH_ATOMIC_BLOBS)
+/** Zero relative shift position of the PAGE_COMPRESSION_LEVEL field */
+#define FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101 \
+ (FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101 + 1)
+/** Zero relative shift position of the ATOMIC_WRITES field */
+#define FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101 \
+ (FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101 + 4)
+/** Zero relative shift position of the PAGE_SSIZE field */
+#define FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101 \
+ (FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101 + 2)
+
+/** Bit mask of the PAGE_COMPRESSION field */
+#define FSP_FLAGS_MASK_PAGE_COMPRESSION_MARIADB101 \
+ (1U << FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101)
+/** Bit mask of the PAGE_COMPRESSION_LEVEL field */
+#define FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL_MARIADB101 \
+ (15U << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101)
+/** Bit mask of the ATOMIC_WRITES field */
+#define FSP_FLAGS_MASK_ATOMIC_WRITES_MARIADB101 \
+ (3U << FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101)
+/** Bit mask of the PAGE_SSIZE field */
+#define FSP_FLAGS_MASK_PAGE_SSIZE_MARIADB101 \
+ (15U << FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101)
+
/** Return the value of the PAGE_COMPRESSION field */
-#define FSP_FLAGS_GET_PAGE_COMPRESSION(flags) \
- ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION) \
- >> FSP_FLAGS_POS_PAGE_COMPRESSION)
+#define FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags) \
+ ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_MARIADB101) \
+ >> FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101)
/** Return the value of the PAGE_COMPRESSION_LEVEL field */
-#define FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags) \
- ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL) \
- >> FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL)
-/** Return the value of the ATOMIC_WRITES field */
-#define FSP_FLAGS_GET_ATOMIC_WRITES(flags) \
- ((flags & FSP_FLAGS_MASK_ATOMIC_WRITES) \
- >> FSP_FLAGS_POS_ATOMIC_WRITES)
-
-/** Set a PAGE_SSIZE into the correct bits in a given
-tablespace flags. */
-#define FSP_FLAGS_SET_PAGE_SSIZE(flags, ssize) \
- (flags | (ssize << FSP_FLAGS_POS_PAGE_SSIZE))
-
-/** Set a PAGE_COMPRESSION into the correct bits in a given
-tablespace flags. */
-#define FSP_FLAGS_SET_PAGE_COMPRESSION(flags, compression) \
- (flags | (compression << FSP_FLAGS_POS_PAGE_COMPRESSION))
-
-/** Set a PAGE_COMPRESSION_LEVEL into the correct bits in a given
-tablespace flags. */
-#define FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(flags, level) \
- (flags | (level << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL))
-
-/** Set a ATOMIC_WRITES into the correct bits in a given
-tablespace flags. */
-#define FSP_FLAGS_SET_ATOMIC_WRITES(flags, atomics) \
- (flags | (atomics << FSP_FLAGS_POS_ATOMIC_WRITES))
+#define FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL_MARIADB101(flags) \
+ ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL_MARIADB101) \
+ >> FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101)
+/** Return the value of the PAGE_SSIZE field */
+#define FSP_FLAGS_GET_PAGE_SSIZE_MARIADB101(flags) \
+ ((flags & FSP_FLAGS_MASK_PAGE_SSIZE_MARIADB101) \
+ >> FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101)
/* @} */
@@ -733,19 +786,193 @@ fseg_print(
mtr_t* mtr); /*!< in/out: mini-transaction */
#endif /* UNIV_BTR_PRINT */
-/********************************************************************//**
-Validate and return the tablespace flags, which are stored in the
-tablespace header at offset FSP_SPACE_FLAGS. They should be 0 for
-ROW_FORMAT=COMPACT and ROW_FORMAT=REDUNDANT. The newer row formats,
-COMPRESSED and DYNAMIC, use a file format > Antelope so they should
-have a file format number plus the DICT_TF_COMPACT bit set.
-@return true if check ok */
+/** Validate the tablespace flags, which are stored in the
+tablespace header at offset FSP_SPACE_FLAGS.
+@param[in] flags the contents of FSP_SPACE_FLAGS
+@return whether the flags are correct (not in the buggy 10.1) format */
+MY_ATTRIBUTE((warn_unused_result, const))
UNIV_INLINE
bool
-fsp_flags_is_valid(
-/*===============*/
- ulint flags) /*!< in: tablespace flags */
- MY_ATTRIBUTE((warn_unused_result, const));
+fsp_flags_is_valid(ulint flags)
+{
+ DBUG_EXECUTE_IF("fsp_flags_is_valid_failure",
+ return(false););
+ if (flags == 0) {
+ return(true);
+ }
+ if (flags & ~FSP_FLAGS_MASK) {
+ return(false);
+ }
+ if ((flags & (FSP_FLAGS_MASK_POST_ANTELOPE | FSP_FLAGS_MASK_ATOMIC_BLOBS))
+ == FSP_FLAGS_MASK_ATOMIC_BLOBS) {
+ /* If the "atomic blobs" flag (indicating
+ ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED) flag
+ is set, then the "post Antelope" (ROW_FORMAT!=REDUNDANT) flag
+ must also be set. */
+ return(false);
+ }
+ /* Bits 10..14 should be 0b0000d where d is the DATA_DIR flag
+ of MySQL 5.6 and MariaDB 10.0, which we ignore.
+ In the buggy FSP_SPACE_FLAGS written by MariaDB 10.1.0 to 10.1.20,
+ bits 10..14 would be nonzero 0bsssaa where sss is
+ nonzero PAGE_SSIZE (3, 4, 6, or 7)
+ and aa is ATOMIC_WRITES (not 0b11). */
+ if (FSP_FLAGS_GET_RESERVED(flags) & ~1) {
+ return(false);
+ }
+
+ const ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags);
+ if (ssize == 1 || ssize == 2 || ssize == 5 || ssize & 8) {
+ /* the page_size is not between 4k and 64k;
+ 16k should be encoded as 0, not 5 */
+ return(false);
+ }
+ const ulint zssize = FSP_FLAGS_GET_ZIP_SSIZE(flags);
+ if (zssize == 0) {
+ /* not ROW_FORMAT=COMPRESSED */
+ } else if (zssize > (ssize ? ssize : 5)) {
+ /* invalid KEY_BLOCK_SIZE */
+ return(false);
+ } else if (~flags & (FSP_FLAGS_MASK_POST_ANTELOPE
+ | FSP_FLAGS_MASK_ATOMIC_BLOBS)) {
+ /* both these flags should be set for
+ ROW_FORMAT=COMPRESSED */
+ return(false);
+ }
+
+ return(true);
+}
+
+/** Convert FSP_SPACE_FLAGS from the buggy MariaDB 10.1.0..10.1.20 format.
+@param[in] flags the contents of FSP_SPACE_FLAGS
+@return the flags corrected from the buggy MariaDB 10.1 format
+@retval ULINT_UNDEFINED if the flags are not in the buggy 10.1 format */
+MY_ATTRIBUTE((warn_unused_result, const))
+UNIV_INLINE
+ulint
+fsp_flags_convert_from_101(ulint flags)
+{
+ DBUG_EXECUTE_IF("fsp_flags_is_valid_failure",
+ return(ULINT_UNDEFINED););
+ if (flags == 0) {
+ return(flags);
+ }
+
+ if (flags >> 18) {
+ /* The most significant FSP_SPACE_FLAGS bit that was ever set
+ by MariaDB 10.1.0 to 10.1.20 was bit 17 (misplaced DATA_DIR flag).
+ The flags must be less than 1<<18 in order to be valid. */
+ return(ULINT_UNDEFINED);
+ }
+
+ if ((flags & (FSP_FLAGS_MASK_POST_ANTELOPE | FSP_FLAGS_MASK_ATOMIC_BLOBS))
+ == FSP_FLAGS_MASK_ATOMIC_BLOBS) {
+ /* If the "atomic blobs" flag (indicating
+ ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED) flag
+ is set, then the "post Antelope" (ROW_FORMAT!=REDUNDANT) flag
+ must also be set. */
+ return(ULINT_UNDEFINED);
+ }
+
+ /* Bits 6..10 denote compression in MariaDB 10.1.0 to 10.1.20.
+ They must be either 0b00000 or 0b00011 through 0b10011.
+ In correct versions, these bits would be
+ 0bd0sss where d is the DATA_DIR flag (garbage bit) and
+ sss is the PAGE_SSIZE (3, 4, 6, or 7).
+
+ NOTE: MariaDB 10.1.0 to 10.1.20 can misinterpret
+ uncompressed data files with innodb_page_size=4k or 64k as
+ compressed innodb_page_size=16k files. Below is an exhaustive
+ state space analysis.
+
+ -0by1zzz: impossible (the bit 4 must be clean; see above)
+ -0b101xx: DATA_DIR, innodb_page_size>4k: invalid (COMPRESSION_LEVEL>9)
+ +0bx0011: innodb_page_size=4k:
+ !!! Misinterpreted as COMPRESSION_LEVEL=9 or 1, COMPRESSION=1.
+ -0bx0010: impossible, because sss must be 0b011 or 0b1xx
+ -0bx0001: impossible, because sss must be 0b011 or 0b1xx
+ -0b10000: DATA_DIR, innodb_page_size=16:
+ invalid (COMPRESSION_LEVEL=8 but COMPRESSION=0)
+ +0b00111: no DATA_DIR, innodb_page_size=64k:
+ !!! Misinterpreted as COMPRESSION_LEVEL=3, COMPRESSION=1.
+ -0b00101: impossible, because sss must be 0 for 16k, not 0b101
+ -0b001x0: no DATA_DIR, innodb_page_size=32k or 8k:
+ invalid (COMPRESSION_LEVEL=3 but COMPRESSION=0)
+ +0b00000: innodb_page_size=16k (looks like COMPRESSION=0)
+ ??? Could actually be compressed; see PAGE_SSIZE below */
+ const ulint level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL_MARIADB101(
+ flags);
+ if (FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags) != (level != 0)
+ || level > 9) {
+ /* The compression flags are not in the buggy MariaDB
+ 10.1 format. */
+ return(ULINT_UNDEFINED);
+ }
+ if (!(~flags & FSP_FLAGS_MASK_ATOMIC_WRITES_MARIADB101)) {
+ /* The ATOMIC_WRITES flags cannot be 0b11.
+ (The bits 11..12 should actually never be 0b11,
+ because in MySQL they would be SHARED|TEMPORARY.) */
+ return(ULINT_UNDEFINED);
+ }
+
+ /* Bits 13..16 are the wrong position for PAGE_SSIZE, and they
+ should contain one of the values 3,4,6,7, that is, be of the form
+ 0b0011 or 0b01xx (except 0b0110).
+ In correct versions, these bits should be 0bc0se
+ where c is the MariaDB COMPRESSED flag
+ and e is the MySQL 5.7 ENCRYPTION flag
+ and s is the MySQL 8.0 SDI flag. MariaDB can only support s=0, e=0.
+
+ Compressed innodb_page_size=16k tables with correct FSP_SPACE_FLAGS
+ will be properly rejected by older MariaDB 10.1.x because they
+ would read as PAGE_SSIZE>=8 which is not valid. */
+
+ const ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE_MARIADB101(flags);
+ if (ssize == 1 || ssize == 2 || ssize == 5 || ssize & 8) {
+ /* the page_size is not between 4k and 64k;
+ 16k should be encoded as 0, not 5 */
+ return(ULINT_UNDEFINED);
+ }
+ const ulint zssize = FSP_FLAGS_GET_ZIP_SSIZE(flags);
+ if (zssize == 0) {
+ /* not ROW_FORMAT=COMPRESSED */
+ } else if (zssize > (ssize ? ssize : 5)) {
+ /* invalid KEY_BLOCK_SIZE */
+ return(ULINT_UNDEFINED);
+ } else if (~flags & (FSP_FLAGS_MASK_POST_ANTELOPE
+ | FSP_FLAGS_MASK_ATOMIC_BLOBS)) {
+ /* both these flags should be set for
+ ROW_FORMAT=COMPRESSED */
+ return(ULINT_UNDEFINED);
+ }
+
+ flags = ((flags & 0x3f) | ssize << FSP_FLAGS_POS_PAGE_SSIZE
+ | FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags)
+ << FSP_FLAGS_POS_PAGE_COMPRESSION);
+ ut_ad(fsp_flags_is_valid(flags));
+ return(flags);
+}
+
+/** Compare tablespace flags.
+@param[in] expected expected flags from dict_tf_to_fsp_flags()
+@param[in] actual flags read from FSP_SPACE_FLAGS
+@return whether the flags match */
+MY_ATTRIBUTE((warn_unused_result))
+UNIV_INLINE
+bool
+fsp_flags_match(ulint expected, ulint actual)
+{
+ expected &= ~FSP_FLAGS_MEM_MASK;
+ ut_ad(fsp_flags_is_valid(expected));
+
+ if (actual == expected) {
+ return(true);
+ }
+
+ actual = fsp_flags_convert_from_101(actual);
+ return(actual == expected);
+}
+
/********************************************************************//**
Determine if the tablespace is compressed from dict_table_t::flags.
@return TRUE if compressed, FALSE if not compressed */
diff --git a/storage/xtradb/include/fsp0fsp.ic b/storage/xtradb/include/fsp0fsp.ic
index ddcb87b0e57..ee4cb1f32c7 100644
--- a/storage/xtradb/include/fsp0fsp.ic
+++ b/storage/xtradb/include/fsp0fsp.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, SkySQL Ab. All Rights Reserved.
+Copyright (c) 2013, 2017, MariaDB Corporation.
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,107 +47,6 @@ fsp_descr_page(
}
/********************************************************************//**
-Validate and return the tablespace flags, which are stored in the
-tablespace header at offset FSP_SPACE_FLAGS. They should be 0 for
-ROW_FORMAT=COMPACT and ROW_FORMAT=REDUNDANT. The newer row formats,
-COMPRESSED and DYNAMIC, use a file format > Antelope so they should
-have a file format number plus the DICT_TF_COMPACT bit set.
-@return true if check ok */
-UNIV_INLINE
-bool
-fsp_flags_is_valid(
-/*===============*/
- ulint flags) /*!< in: tablespace flags */
-{
- ulint post_antelope = FSP_FLAGS_GET_POST_ANTELOPE(flags);
- ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(flags);
- ulint atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(flags);
- ulint page_ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags);
- ulint unused = FSP_FLAGS_GET_UNUSED(flags);
- ulint page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(flags);
- ulint page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags);
- ulint atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(flags);
-
- DBUG_EXECUTE_IF("fsp_flags_is_valid_failure", return(false););
-
- /* fsp_flags is zero unless atomic_blobs is set. */
- /* Make sure there are no bits that we do not know about. */
- if (unused != 0 || flags == 1) {
- fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted unused %lu\n",
- flags, unused);
- return(false);
- } else if (post_antelope) {
- /* The Antelope row formats REDUNDANT and COMPACT did
- not use tablespace flags, so this flag and the entire
- 4-byte field is zero for Antelope row formats. */
-
- if (!atomic_blobs) {
- fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted atomic_blobs %lu\n",
- flags, atomic_blobs);
- return(false);
- }
- }
-
- if (!atomic_blobs) {
- /* Barracuda row formats COMPRESSED and DYNAMIC build on
- the page structure introduced for the COMPACT row format
- by allowing long fields to be broken into prefix and
- externally stored parts. */
-
- if (post_antelope || zip_ssize != 0) {
- fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted zip_ssize %lu atomic_blobs %lu\n",
- flags, zip_ssize, atomic_blobs);
- return(false);
- }
-
- } else if (!post_antelope || zip_ssize > PAGE_ZIP_SSIZE_MAX) {
- fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted zip_ssize %lu max %d\n",
- flags, zip_ssize, PAGE_ZIP_SSIZE_MAX);
- return(false);
- } else if (page_ssize > UNIV_PAGE_SSIZE_MAX) {
-
- /* The page size field can be used for any row type, or it may
- be zero for an original 16k page size.
- Validate the page shift size is within allowed range. */
-
- fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted page_ssize %lu max %lu\n",
- flags, page_ssize, UNIV_PAGE_SSIZE_MAX);
- return(false);
-
- } else if (UNIV_PAGE_SIZE != UNIV_PAGE_SIZE_ORIG && !page_ssize) {
- fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted page_ssize %lu max %lu:%d\n",
- flags, page_ssize, UNIV_PAGE_SIZE, UNIV_PAGE_SIZE_ORIG);
- return(false);
- }
-
-#if UNIV_FORMAT_MAX != UNIV_FORMAT_B
-# error "UNIV_FORMAT_MAX != UNIV_FORMAT_B, Add more validations."
-#endif
-
- /* Page compression level requires page compression and atomic blobs
- to be set */
- if (page_compression_level || page_compression) {
- if (!page_compression || !atomic_blobs) {
- fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted page_compression %lu\n"
- "InnoDB: Error: page_compression_level %lu atomic_blobs %lu\n",
- flags, page_compression, page_compression_level, atomic_blobs);
- return(false);
- }
- }
-
- if (atomic_writes > ATOMIC_WRITES_OFF) {
- fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted atomic_writes %lu\n",
- flags, atomic_writes);
- return (false);
- }
-
- /* The DATA_DIR field can be used for any row type so there is
- nothing here to validate. */
-
- return(true);
-}
-
-/********************************************************************//**
Determine if the tablespace is compressed from dict_table_t::flags.
@return TRUE if compressed, FALSE if not compressed */
UNIV_INLINE
@@ -191,10 +90,10 @@ UNIV_INLINE
ulint
fsp_flags_get_page_size(
/*====================*/
- ulint flags) /*!< in: tablespace flags */
+ ulint flags) /*!< in: tablespace flags */
{
- ulint page_size = 0;
- ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags);
+ ulint page_size = 0;
+ ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags);
/* Convert from a 'log2 minus 9' to a page size in bytes. */
if (UNIV_UNLIKELY(ssize)) {
@@ -211,50 +110,6 @@ fsp_flags_get_page_size(
}
#ifndef UNIV_INNOCHECKSUM
-
-/********************************************************************//**
-Add the page size to the tablespace flags.
-@return tablespace flags after page size is added */
-UNIV_INLINE
-ulint
-fsp_flags_set_page_size(
-/*====================*/
- ulint flags, /*!< in: tablespace flags */
- ulint page_size) /*!< in: page size in bytes */
-{
- ulint ssize = 0;
- ulint shift;
-
- /* Page size should be > UNIV_PAGE_SIZE_MIN */
- ut_ad(page_size >= UNIV_PAGE_SIZE_MIN);
- ut_ad(page_size <= UNIV_PAGE_SIZE_MAX);
-
- if (page_size == UNIV_PAGE_SIZE_ORIG) {
- ut_ad(0 == FSP_FLAGS_GET_PAGE_SSIZE(flags));
- return(flags);
- }
-
- for (shift = UNIV_PAGE_SIZE_SHIFT_MAX;
- shift >= UNIV_PAGE_SIZE_SHIFT_MIN;
- shift--) {
- ulint mask = (1 << shift);
- if (page_size & mask) {
- ut_ad(!(page_size & ~mask));
- ssize = shift - UNIV_ZIP_SIZE_SHIFT_MIN + 1;
- break;
- }
- }
-
- ut_ad(ssize);
- ut_ad(ssize <= UNIV_PAGE_SSIZE_MAX);
-
- flags = FSP_FLAGS_SET_PAGE_SSIZE(flags, ssize);
-
- ut_ad(fsp_flags_is_valid(flags));
-
- return(flags);
-}
-
/********************************************************************//**
Calculates the descriptor index within a descriptor page.
@return descriptor index */
diff --git a/storage/xtradb/include/fsp0pagecompress.h b/storage/xtradb/include/fsp0pagecompress.h
index 5f943ee2b83..c623d11c326 100644
--- a/storage/xtradb/include/fsp0pagecompress.h
+++ b/storage/xtradb/include/fsp0pagecompress.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2013, 2017, MariaDB Corporation. 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
@@ -48,15 +48,6 @@ fsp_header_get_compression_level(
const page_t* page); /*!< in: first page of a tablespace */
/********************************************************************//**
-Determine if the tablespace is page compressed from dict_table_t::flags.
-@return TRUE if page compressed, FALSE if not compressed */
-UNIV_INLINE
-ibool
-fsp_flags_is_page_compressed(
-/*=========================*/
- ulint flags); /*!< in: tablespace flags */
-
-/********************************************************************//**
Extract the page compression level from tablespace flags.
A tablespace has only one physical page compression level
whether that page is compressed or not.
diff --git a/storage/xtradb/include/fsp0pagecompress.ic b/storage/xtradb/include/fsp0pagecompress.ic
index e879aa2c16e..48163277feb 100644
--- a/storage/xtradb/include/fsp0pagecompress.ic
+++ b/storage/xtradb/include/fsp0pagecompress.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2013, 2017, MariaDB Corporation. 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
@@ -26,18 +26,6 @@ Created 11/12/2013 Jan Lindström jan.lindstrom@mariadb.com
***********************************************************************/
/********************************************************************//**
-Determine if the tablespace is page compressed from dict_table_t::flags.
-@return TRUE if page compressed, FALSE if not page compressed */
-UNIV_INLINE
-ibool
-fsp_flags_is_page_compressed(
-/*=========================*/
- ulint flags) /*!< in: tablespace flags */
-{
- return(FSP_FLAGS_GET_PAGE_COMPRESSION(flags));
-}
-
-/********************************************************************//**
Determine the tablespace is page compression level from dict_table_t::flags.
@return page compression level or 0 if not compressed*/
UNIV_INLINE
@@ -125,21 +113,15 @@ Extract the page compression from space.
@return true if space is page compressed, false if space is not found
or space is not page compressed. */
UNIV_INLINE
-ibool
+bool
fil_space_is_page_compressed(
/*=========================*/
ulint id) /*!< in: space id */
{
- ulint flags;
-
- flags = fil_space_get_flags(id);
-
- if (flags && flags != ULINT_UNDEFINED) {
-
- return(fsp_flags_is_page_compressed(flags));
- }
+ ulint flags = fil_space_get_flags(id);
- return(0);
+ return(flags != ULINT_UNDEFINED
+ && FSP_FLAGS_HAS_PAGE_COMPRESSION(flags));
}
#endif /* UNIV_INNOCHECKSUM */
diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc
index d45ce907304..6170eb66195 100644
--- a/storage/xtradb/row/row0import.cc
+++ b/storage/xtradb/row/row0import.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, MariaDB Corporation.
+Copyright (c) 2015, 2017, MariaDB Corporation.
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
@@ -371,8 +371,7 @@ public:
m_space(ULINT_UNDEFINED),
m_xdes(),
m_xdes_page_no(ULINT_UNDEFINED),
- m_space_flags(ULINT_UNDEFINED),
- m_table_flags(ULINT_UNDEFINED) UNIV_NOTHROW { }
+ m_space_flags(ULINT_UNDEFINED) UNIV_NOTHROW { }
/**
Free any extent descriptor instance */
@@ -535,10 +534,6 @@ protected:
/** Flags value read from the header page */
ulint m_space_flags;
-
- /** Derived from m_space_flags and row format type, the row format
- type is determined from the page header. */
- ulint m_table_flags;
};
/** Determine the page size to use for traversing the tablespace
@@ -553,6 +548,19 @@ AbstractCallback::init(
const page_t* page = block->frame;
m_space_flags = fsp_header_get_flags(page);
+ if (!fsp_flags_is_valid(m_space_flags)) {
+ ulint cflags = fsp_flags_convert_from_101(m_space_flags);
+ if (cflags == ULINT_UNDEFINED) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Invalid FSP_SPACE_FLAGS=0x%x",
+ int(m_space_flags));
+ return(DB_CORRUPTION);
+ }
+ m_space_flags = cflags;
+ }
+
+ /* Clear the DATA_DIR flag, which is basically garbage. */
+ m_space_flags &= ~(1U << FSP_FLAGS_POS_RESERVED);
/* Since we don't know whether it is a compressed table
or not, the data is always read into the block->frame. */
@@ -641,46 +649,6 @@ struct FetchIndexRootPages : public AbstractCallback {
}
/**
- Check if the .ibd file row format is the same as the table's.
- @param ibd_table_flags - determined from space and page.
- @return DB_SUCCESS or error code. */
- dberr_t check_row_format(ulint ibd_table_flags) UNIV_NOTHROW
- {
- dberr_t err;
- rec_format_t ibd_rec_format;
- rec_format_t table_rec_format;
-
- if (!dict_tf_is_valid(ibd_table_flags)) {
-
- ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR,
- ER_TABLE_SCHEMA_MISMATCH,
- ".ibd file has invlad table flags: %lx",
- ibd_table_flags);
-
- return(DB_CORRUPTION);
- }
-
- ibd_rec_format = dict_tf_get_rec_format(ibd_table_flags);
- table_rec_format = dict_tf_get_rec_format(m_table->flags);
-
- if (table_rec_format != ibd_rec_format) {
-
- ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR,
- ER_TABLE_SCHEMA_MISMATCH,
- "Table has %s row format, .ibd "
- "file has %s row format.",
- dict_tf_to_row_format_string(m_table->flags),
- dict_tf_to_row_format_string(ibd_table_flags));
-
- err = DB_CORRUPTION;
- } else {
- err = DB_SUCCESS;
- }
-
- return(err);
- }
-
- /**
Called for each block as it is read from the file.
@param offset - physical offset in the file
@param block - block to convert, it is not from the buffer pool.
@@ -743,12 +711,17 @@ FetchIndexRootPages::operator() (
m_indexes.push_back(Index(id, page_no));
if (m_indexes.size() == 1) {
-
- m_table_flags = dict_sys_tables_type_to_tf(
- m_space_flags,
- page_is_comp(page) ? DICT_N_COLS_COMPACT : 0);
-
- err = check_row_format(m_table_flags);
+ /* Check that the tablespace flags match the table flags. */
+ ulint expected = dict_tf_to_fsp_flags(m_table->flags);
+ if (!fsp_flags_match(expected, m_space_flags)) {
+ ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR,
+ ER_TABLE_SCHEMA_MISMATCH,
+ "Expected FSP_SPACE_FLAGS=0x%x, .ibd "
+ "file contains 0x%x.",
+ unsigned(expected),
+ unsigned(m_space_flags));
+ return(DB_CORRUPTION);
+ }
}
}
@@ -1968,21 +1941,14 @@ PageConverter::update_header(
"- ignored");
}
- ulint space_flags = fsp_header_get_flags(get_frame(block));
-
- if (!fsp_flags_is_valid(space_flags)) {
-
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Unsupported tablespace format %lu",
- (ulong) space_flags);
-
- return(DB_UNSUPPORTED);
- }
-
mach_write_to_8(
get_frame(block) + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
m_current_lsn);
+ /* Write back the adjusted flags. */
+ mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS
+ + get_frame(block), m_space_flags);
+
/* Write space_id to the tablespace header, page 0. */
mach_write_to_4(
get_frame(block) + FSP_HEADER_OFFSET + FSP_SPACE_ID,
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index aff7b758249..c81b10b93f1 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -4362,6 +4362,7 @@ row_drop_table_for_mysql(
switch (err) {
ibool is_temp;
+ ulint table_flags;
case DB_SUCCESS:
/* Clone the name, in case it has been allocated
@@ -4370,6 +4371,7 @@ row_drop_table_for_mysql(
space_id = table->space;
ibd_file_missing = table->ibd_file_missing;
+ table_flags = table->flags;
is_temp = DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY);
/* If there is a temp path then the temp flag is set.
@@ -4385,9 +4387,9 @@ row_drop_table_for_mysql(
}
/* We do not allow temporary tables with a remote path. */
- ut_a(!(is_temp && DICT_TF_HAS_DATA_DIR(table->flags)));
+ ut_a(!(is_temp && DICT_TF_HAS_DATA_DIR(table_flags)));
- if (space_id && DICT_TF_HAS_DATA_DIR(table->flags)) {
+ if (space_id && DICT_TF_HAS_DATA_DIR(table_flags)) {
dict_get_and_save_data_dir_path(table, true);
ut_a(table->data_dir_path);
@@ -4453,8 +4455,9 @@ row_drop_table_for_mysql(
if (err == DB_SUCCESS && space_id > TRX_SYS_SPACE) {
if (!is_temp
&& !fil_space_for_table_exists_in_mem(
- space_id, tablename, FALSE,
- print_msg, false, NULL, 0)) {
+ space_id, tablename,
+ print_msg, false, NULL, 0,
+ table_flags)) {
/* This might happen if we are dropping a
discarded tablespace */
err = DB_SUCCESS;
diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc
index bb07aea7720..70aec8767ad 100644
--- a/storage/xtradb/srv/srv0start.cc
+++ b/storage/xtradb/srv/srv0start.cc
@@ -703,8 +703,7 @@ create_log_files(
sprintf(logfilename + dirnamelen, "ib_logfile%u", INIT_LOG_FILE0);
fil_space_create(
- logfilename, SRV_LOG_SPACE_FIRST_ID,
- fsp_flags_set_page_size(0, UNIV_PAGE_SIZE),
+ logfilename, SRV_LOG_SPACE_FIRST_ID, 0,
FIL_LOG,
NULL /* no encryption yet */,
true /* this is create */);
@@ -1193,7 +1192,7 @@ check_first_page:
crypt_data = fil_space_create_crypt_data(FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
}
- flags = fsp_flags_set_page_size(0, UNIV_PAGE_SIZE);
+ flags = FSP_FLAGS_PAGE_SSIZE();
fil_space_create(name, 0, flags, FIL_TABLESPACE,
crypt_data, (*create_new_db) == true);
@@ -1341,7 +1340,7 @@ srv_undo_tablespace_open(
fil_set_max_space_id_if_bigger(space);
/* Set the compressed page size to 0 (non-compressed) */
- flags = fsp_flags_set_page_size(0, UNIV_PAGE_SIZE);
+ flags = FSP_FLAGS_PAGE_SSIZE();
fil_space_create(name, space, flags, FIL_TABLESPACE,
NULL /* no encryption */,
true /* create */);
@@ -2343,9 +2342,7 @@ innobase_start_or_create_for_mysql(void)
sprintf(logfilename + dirnamelen, "ib_logfile%u", 0);
fil_space_create(logfilename,
- SRV_LOG_SPACE_FIRST_ID,
- fsp_flags_set_page_size(0, UNIV_PAGE_SIZE),
- FIL_LOG,
+ SRV_LOG_SPACE_FIRST_ID, 0, FIL_LOG,
NULL /* no encryption yet */,
true /* create */);
@@ -2740,6 +2737,13 @@ files_checked:
}
if (!srv_read_only_mode) {
+ const ulint flags = FSP_FLAGS_PAGE_SSIZE();
+ for (ulint id = 0; id <= srv_undo_tablespaces; id++) {
+ if (fil_space_get(id)) {
+ fsp_flags_try_adjust(id, flags);
+ }
+ }
+
/* Create the thread which watches the timeouts
for lock waits */
thread_handles[2 + SRV_MAX_N_IO_THREADS] = os_thread_create(
diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt
index eceff5fcf18..c80de04d069 100644
--- a/support-files/CMakeLists.txt
+++ b/support-files/CMakeLists.txt
@@ -56,9 +56,28 @@ IF(UNIX)
INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${script}
DESTINATION ${inst_location} COMPONENT Server_Scripts)
ENDFOREACH()
+
IF(INSTALL_SUPPORTFILESDIR)
INSTALL(FILES magic DESTINATION ${inst_location} COMPONENT SupportFiles)
INSTALL(DIRECTORY policy DESTINATION ${inst_location} COMPONENT SupportFiles)
+ FIND_PROGRAM(CHECKMODULE checkmodule)
+ FIND_PROGRAM(SEMODULE_PACKAGE semodule_package)
+ MARK_AS_ADVANCED(CHECKMODULE SEMODULE_PACKAGE)
+
+ # Build pp files in policy/selinux
+ IF(CHECKMODULE AND SEMODULE_PACKAGE)
+ FOREACH(pol mariadb)
+ SET(src ${CMAKE_CURRENT_SOURCE_DIR}/policy/selinux/${pol}.te)
+ SET(tmp ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${pol}-pp.dir/${pol}.mod)
+ SET(out ${CMAKE_CURRENT_BINARY_DIR}/${pol}.pp)
+ ADD_CUSTOM_COMMAND(OUTPUT ${out}
+ COMMAND ${CHECKMODULE} -M -m ${src} -o ${tmp}
+ COMMAND ${SEMODULE_PACKAGE} -m ${tmp} -o ${out}
+ DEPENDS ${src})
+ ADD_CUSTOM_TARGET(${pol}-pp ALL DEPENDS ${out})
+ INSTALL(FILES ${out} DESTINATION ${inst_location}/policy/selinux COMPONENT SupportFiles)
+ ENDFOREACH()
+ ENDIF()
ENDIF()
CONFIGURE_FILE(mariadb.pc.in ${CMAKE_CURRENT_BINARY_DIR}/mariadb.pc @ONLY)
diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh
index c934f7a47a5..9162cf7d716 100644
--- a/support-files/mysql.server.sh
+++ b/support-files/mysql.server.sh
@@ -156,15 +156,9 @@ parse_server_arguments() {
# Get arguments from the my.cnf file,
# the only group, which is read from now on is [mysqld]
-if test -x ./bin/my_print_defaults
-then
- print_defaults="./bin/my_print_defaults"
-elif test -x $bindir/my_print_defaults
+if test -x $bindir/my_print_defaults
then
print_defaults="$bindir/my_print_defaults"
-elif test -x $bindir/mysql_print_defaults
-then
- print_defaults="$bindir/mysql_print_defaults"
else
# Try to find basedir in /etc/my.cnf
conf=/etc/my.cnf
diff --git a/support-files/policy/selinux/mariadb.te b/support-files/policy/selinux/mariadb.te
new file mode 100644
index 00000000000..1d3de52c700
--- /dev/null
+++ b/support-files/policy/selinux/mariadb.te
@@ -0,0 +1,9 @@
+module mariadb 1.0;
+
+require {
+ type mysqld_safe_t;
+ class capability { setuid setgid };
+}
+
+#============= mysqld_safe_t ==============
+allow mysqld_safe_t self:capability { setuid setgid };
diff --git a/support-files/rpm/server-postin.sh b/support-files/rpm/server-postin.sh
index 5b95b751212..9ef9bec3e0d 100644
--- a/support-files/rpm/server-postin.sh
+++ b/support-files/rpm/server-postin.sh
@@ -93,7 +93,12 @@ if [ -f /etc/redhat-release ] ; then
echo ' make load'
echo
echo
- fi
+ fi
+ if grep 'CentOS release 6' /etc/redhat-release >/dev/null 2>&1; then
+ if [ -x /usr/sbin/semodule ] ; then
+ /usr/sbin/semodule -i /usr/share/mysql/policy/selinux/mariadb.pp
+ fi
+ fi
fi
if [ -x sbin/restorecon ] ; then