summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt21
-rw-r--r--cmake/aws_sdk.cmake3
-rw-r--r--cmake/for_clients.cmake2
-rw-r--r--cmake/jemalloc.cmake1
-rw-r--r--cmake/numa.cmake1
-rw-r--r--cmake/plugin.cmake16
-rw-r--r--cmake/readline.cmake2
-rw-r--r--cmake/ssl.cmake1
-rw-r--r--cmake/systemd.cmake1
-rw-r--r--cmake/wsrep.cmake3
-rw-r--r--configure.cmake1
-rw-r--r--debian/control4
-rw-r--r--extra/innochecksum.cc202
-rw-r--r--extra/mariabackup/CMakeLists.txt1
-rw-r--r--extra/mariabackup/innobackupex.cc2
-rw-r--r--extra/mariabackup/xtrabackup.cc2
-rw-r--r--include/my_sys.h5
m---------libmariadb0
-rwxr-xr-xmysql-test/dgcov.pl38
-rw-r--r--mysql-test/include/wait_until_disconnected.inc2
-rw-r--r--mysql-test/lib/My/SafeProcess.pm18
-rw-r--r--mysql-test/lib/mtr_process.pl8
-rw-r--r--mysql-test/main/cte_nonrecursive.result67
-rw-r--r--mysql-test/main/cte_nonrecursive.test50
-rw-r--r--mysql-test/main/cte_recursive.result95
-rw-r--r--mysql-test/main/cte_recursive.test83
-rw-r--r--mysql-test/main/func_str.result16
-rw-r--r--mysql-test/main/func_str.test18
-rw-r--r--mysql-test/main/grant5.result21
-rw-r--r--mysql-test/main/grant5.test14
-rw-r--r--mysql-test/main/lock_multi_bug38499.test3
-rw-r--r--mysql-test/main/lock_multi_bug38691.test2
-rw-r--r--mysql-test/main/mysql_client_test.result5
-rw-r--r--mysql-test/main/mysql_client_test.test4
-rw-r--r--mysql-test/main/mysql_upgrade.result2
-rw-r--r--mysql-test/main/order_by_innodb.result52
-rw-r--r--mysql-test/main/order_by_innodb.test51
-rw-r--r--mysql-test/main/prepare.result14
-rw-r--r--mysql-test/main/prepare.test12
-rw-r--r--mysql-test/main/ps.result14
-rw-r--r--mysql-test/main/ps.test16
-rw-r--r--mysql-test/main/selectivity_innodb.result51
-rw-r--r--mysql-test/main/selectivity_innodb.test55
-rw-r--r--mysql-test/main/selectivity_no_engine.result20
-rw-r--r--mysql-test/main/selectivity_no_engine.test21
-rw-r--r--mysql-test/main/skip_name_resolve.result22
-rw-r--r--mysql-test/main/skip_name_resolve.test26
-rw-r--r--mysql-test/main/table_value_constr.result38
-rw-r--r--mysql-test/main/table_value_constr.test22
-rw-r--r--mysql-test/main/union.result31
-rw-r--r--mysql-test/main/union.test25
-rw-r--r--mysql-test/main/win.result287
-rw-r--r--mysql-test/main/win.test147
-rwxr-xr-xmysql-test/mysql-test-run.pl109
-rw-r--r--mysql-test/suite/binlog/include/binlog.test18
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_binlog.result23
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_binlog.result24
-rw-r--r--mysql-test/suite/binlog_encryption/encrypted_master.test3
-rw-r--r--mysql-test/suite/encryption/r/tempfiles_encrypted.result287
-rw-r--r--mysql-test/suite/encryption/t/innodb-page_encryption.test3
-rw-r--r--mysql-test/suite/galera/r/galera_fk_lock_wait.result54
-rw-r--r--mysql-test/suite/galera/t/galera_fk_lock_wait.test40
-rw-r--r--mysql-test/suite/gcol/inc/gcol_ins_upd.inc74
-rw-r--r--mysql-test/suite/gcol/inc/gcol_keys.inc2
-rw-r--r--mysql-test/suite/gcol/inc/gcol_partition.inc16
-rw-r--r--mysql-test/suite/gcol/inc/gcol_view.inc55
-rw-r--r--mysql-test/suite/gcol/r/gcol_ins_upd_innodb.result225
-rw-r--r--mysql-test/suite/gcol/r/gcol_ins_upd_myisam.result70
-rw-r--r--mysql-test/suite/gcol/r/gcol_keys_innodb.result2
-rw-r--r--mysql-test/suite/gcol/r/gcol_keys_myisam.result2
-rw-r--r--mysql-test/suite/gcol/r/gcol_partition_innodb.result15
-rw-r--r--mysql-test/suite/gcol/r/gcol_partition_myisam.result15
-rw-r--r--mysql-test/suite/gcol/r/gcol_view_innodb.result41
-rw-r--r--mysql-test/suite/gcol/r/gcol_view_myisam.result41
-rw-r--r--mysql-test/suite/gcol/r/innodb_virtual_fk.result3
-rw-r--r--mysql-test/suite/gcol/t/gcol_ins_upd_innodb.test2
-rw-r--r--mysql-test/suite/gcol/t/innodb_virtual_fk.test3
-rw-r--r--mysql-test/suite/innodb/r/default_row_format_alter.result17
-rw-r--r--mysql-test/suite/innodb/t/default_row_format_alter.test33
-rw-r--r--mysql-test/suite/innodb/t/innodb-page_compression_lz4.test2
-rw-r--r--mysql-test/suite/innodb/t/innodb_sys_semaphore_waits.test2
-rw-r--r--mysql-test/suite/innodb_zip/r/innochecksum_3.result8
-rw-r--r--mysql-test/suite/innodb_zip/t/innochecksum_3.test5
-rw-r--r--mysql-test/suite/roles/set_default_role_clear.result2
-rw-r--r--mysql-test/suite/roles/set_default_role_for.result8
-rw-r--r--mysql-test/suite/roles/set_default_role_invalid.result12
-rw-r--r--mysql-test/suite/roles/set_default_role_new_connection.result4
-rw-r--r--mysql-test/suite/roles/set_role-recursive.result2
-rw-r--r--mysql-test/suite/rpl/r/create_or_replace_mix.result3
-rw-r--r--mysql-test/suite/rpl/r/create_or_replace_row.result3
-rw-r--r--mysql-test/suite/rpl/r/create_or_replace_statement.result2
-rw-r--r--mysql-test/suite/rpl/t/rpl_trunc_temp.test2
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_embedded.result2
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result2
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_fatal_semaphore_wait_threshold.test2
-rw-r--r--mysql-test/suite/vcol/r/binlog.result14
-rw-r--r--mysql-test/suite/vcol/t/binlog.test14
-rw-r--r--mysql-test/suite/versioning/r/create.result19
-rw-r--r--mysql-test/suite/versioning/r/partition.result21
-rw-r--r--mysql-test/suite/versioning/r/sysvars-notembedded.result30
-rw-r--r--mysql-test/suite/versioning/r/sysvars.result108
-rw-r--r--mysql-test/suite/versioning/t/create.test12
-rw-r--r--mysql-test/suite/versioning/t/partition.test21
-rw-r--r--mysql-test/suite/versioning/t/sysvars-notembedded.test31
-rw-r--r--mysql-test/suite/versioning/t/sysvars.test71
-rw-r--r--mysys/mf_qsort.c2
-rw-r--r--pcre/AUTHORS10
-rw-r--r--pcre/CMakeLists.txt15
-rw-r--r--pcre/ChangeLog21
-rw-r--r--pcre/LICENCE10
-rw-r--r--pcre/NEWS10
-rw-r--r--pcre/NON-AUTOTOOLS-BUILD10
-rw-r--r--pcre/README11
-rw-r--r--pcre/configure.ac10
-rw-r--r--pcre/doc/html/NON-AUTOTOOLS-BUILD.txt10
-rw-r--r--pcre/doc/html/README.txt11
-rw-r--r--pcre/doc/html/pcre.html17
-rw-r--r--pcre/doc/html/pcreapi.html10
-rw-r--r--pcre/doc/html/pcrepattern.html6
-rw-r--r--pcre/doc/html/pcresyntax.html2
-rw-r--r--pcre/doc/pcre.319
-rw-r--r--pcre/doc/pcre.txt36
-rw-r--r--pcre/doc/pcreapi.310
-rw-r--r--pcre/doc/pcrepattern.36
-rw-r--r--pcre/doc/pcresyntax.32
-rw-r--r--pcre/pcre_compile.c9
-rw-r--r--pcre/pcre_exec.c4
-rw-r--r--pcre/testdata/testinput13
-rw-r--r--pcre/testdata/testoutput15
-rw-r--r--plugin/auth_gssapi/CMakeLists.txt1
-rw-r--r--plugin/aws_key_management/CMakeLists.txt3
-rw-r--r--plugin/win_auth_client/CMakeLists.txt2
-rw-r--r--scripts/mysql_install_db.sh6
-rw-r--r--scripts/mysqld_safe.sh4
-rw-r--r--sql/field.cc10
-rw-r--r--sql/ha_partition.cc3
-rw-r--r--sql/item.cc8
-rw-r--r--sql/item.h11
-rw-r--r--sql/item_func.cc16
-rw-r--r--sql/item_strfunc.cc33
-rw-r--r--sql/key.cc2
-rw-r--r--sql/mysqld.h3
-rw-r--r--sql/set_var.cc16
-rw-r--r--sql/set_var.h27
-rw-r--r--sql/sql_acl.cc22
-rw-r--r--sql/sql_admin.cc4
-rw-r--r--sql/sql_base.cc2
-rw-r--r--sql/sql_class.cc4
-rw-r--r--sql/sql_cte.cc24
-rw-r--r--sql/sql_cte.h2
-rw-r--r--sql/sql_insert.cc9
-rw-r--r--sql/sql_partition.cc11
-rw-r--r--sql/sql_plugin.cc24
-rw-r--r--sql/sql_prepare.cc9
-rw-r--r--sql/sql_select.cc78
-rw-r--r--sql/sql_show.cc85
-rw-r--r--sql/sql_type.cc15
-rw-r--r--sql/sql_type.h8
-rw-r--r--sql/sql_union.cc35
-rw-r--r--sql/sql_update.cc2
-rw-r--r--sql/sql_window.cc12
-rw-r--r--sql/sql_window.h5
-rw-r--r--sql/sql_yacc.yy48
-rw-r--r--sql/sql_yacc_ora.yy48
-rw-r--r--sql/sys_vars.cc39
-rw-r--r--sql/sys_vars.ic274
-rw-r--r--sql/table.cc49
-rw-r--r--sql/table.h5
-rw-r--r--storage/connect/CMakeLists.txt23
-rw-r--r--storage/connect/Client2.java130
-rw-r--r--storage/connect/Client3.java154
-rw-r--r--storage/connect/Mongo2Interface.java136
-rw-r--r--storage/connect/Mongo3Interface.java190
-rw-r--r--storage/connect/TestInsert2.java131
-rw-r--r--storage/connect/TestInsert3.java131
-rw-r--r--storage/connect/array.cpp6
-rw-r--r--storage/connect/blkfil.cpp6
-rw-r--r--storage/connect/block.h6
-rw-r--r--storage/connect/bson.cpp13
-rw-r--r--storage/connect/bsonudf.cpp25
-rw-r--r--storage/connect/cmgfam.cpp5
-rw-r--r--storage/connect/cmgoconn.cpp574
-rw-r--r--storage/connect/cmgoconn.h22
-rw-r--r--storage/connect/colblk.cpp4
-rw-r--r--storage/connect/colblk.h3
-rw-r--r--storage/connect/domdoc.cpp2
-rw-r--r--storage/connect/filamap.cpp16
-rw-r--r--storage/connect/filamdbf.cpp10
-rw-r--r--storage/connect/filamfix.cpp40
-rw-r--r--storage/connect/filamgz.cpp16
-rw-r--r--storage/connect/filamtxt.cpp26
-rw-r--r--storage/connect/filamvct.cpp72
-rw-r--r--storage/connect/filamzip.cpp18
-rw-r--r--storage/connect/filter.cpp6
-rw-r--r--storage/connect/filter.h2
-rw-r--r--storage/connect/fmdlex.c4
-rw-r--r--storage/connect/global.h16
-rw-r--r--storage/connect/ha_connect.cc125
-rw-r--r--storage/connect/javaconn.cpp45
-rw-r--r--storage/connect/javaconn.h10
-rw-r--r--storage/connect/jdbconn.cpp14
-rw-r--r--storage/connect/jmgfam.cpp18
-rw-r--r--storage/connect/jmgoconn.cpp151
-rw-r--r--storage/connect/jmgoconn.h11
-rw-r--r--storage/connect/json.cpp60
-rw-r--r--storage/connect/json.h8
-rw-r--r--storage/connect/jsonudf.cpp23
-rw-r--r--storage/connect/macutil.cpp6
-rw-r--r--storage/connect/macutil.h6
-rw-r--r--storage/connect/maputil.cpp2
-rw-r--r--storage/connect/mongo.cpp8
-rw-r--r--storage/connect/mongo.h5
-rw-r--r--storage/connect/mycat.cc31
-rw-r--r--storage/connect/mycat.h3
-rw-r--r--storage/connect/myconn.cpp12
-rw-r--r--storage/connect/myconn.h12
-rw-r--r--storage/connect/mysql-test/connect/r/bson_mongo_c.result2
-rw-r--r--storage/connect/mysql-test/connect/r/jdbc.result18
-rw-r--r--storage/connect/mysql-test/connect/r/jdbc_new.result50
-rw-r--r--storage/connect/mysql-test/connect/r/jdbc_oracle.result8
-rw-r--r--storage/connect/mysql-test/connect/r/json_java_2.result2
-rw-r--r--storage/connect/mysql-test/connect/r/json_java_3.result2
-rw-r--r--storage/connect/mysql-test/connect/r/json_mongo_c.result8
-rw-r--r--storage/connect/mysql-test/connect/r/mongo_c.result60
-rw-r--r--storage/connect/mysql-test/connect/r/mongo_java_2.result24
-rw-r--r--storage/connect/mysql-test/connect/r/mongo_java_3.result24
-rw-r--r--storage/connect/mysql-test/connect/r/odbc_oracle.result38
-rw-r--r--storage/connect/mysql-test/connect/std_data/Mongo2.jarbin623907 -> 624130 bytes
-rw-r--r--storage/connect/mysql-test/connect/std_data/Mongo3.jarbin1705776 -> 1706057 bytes
-rw-r--r--storage/connect/mysql-test/connect/t/jdbc.test10
-rw-r--r--storage/connect/mysql-test/connect/t/jdbc_new.test32
-rw-r--r--storage/connect/mysql-test/connect/t/jdbc_oracle.test8
-rw-r--r--storage/connect/mysql-test/connect/t/odbc_oracle.test30
-rw-r--r--storage/connect/myutil.cpp6
-rw-r--r--storage/connect/odbconn.cpp16
-rw-r--r--storage/connect/odbconn.h4
-rw-r--r--storage/connect/os.h10
-rw-r--r--storage/connect/osutil.c2
-rw-r--r--storage/connect/plgdbsem.h6
-rw-r--r--storage/connect/plgdbutl.cpp30
-rw-r--r--storage/connect/plugutil.cpp26
-rw-r--r--storage/connect/rcmsg.c4
-rw-r--r--storage/connect/reldef.cpp39
-rw-r--r--storage/connect/reldef.h6
-rw-r--r--storage/connect/tabbson.cpp121
-rw-r--r--storage/connect/tabbson.h8
-rw-r--r--storage/connect/tabcmg.cpp159
-rw-r--r--storage/connect/tabcmg.h7
-rw-r--r--storage/connect/tabdos.cpp69
-rw-r--r--storage/connect/tabext.cpp2
-rw-r--r--storage/connect/tabfix.cpp6
-rw-r--r--storage/connect/tabfmt.cpp8
-rw-r--r--storage/connect/tabjdbc.cpp5
-rw-r--r--storage/connect/tabjmg.cpp39
-rw-r--r--storage/connect/tabjmg.h8
-rw-r--r--storage/connect/tabjson.cpp148
-rw-r--r--storage/connect/tabjson.h6
-rw-r--r--storage/connect/tabmac.cpp6
-rw-r--r--storage/connect/tabmac.h6
-rw-r--r--storage/connect/tabmul.cpp80
-rw-r--r--storage/connect/tabmul.h22
-rw-r--r--storage/connect/tabmysql.cpp6
-rw-r--r--storage/connect/taboccur.cpp76
-rw-r--r--storage/connect/tabodbc.cpp2
-rw-r--r--storage/connect/tabpivot.cpp2
-rw-r--r--storage/connect/tabrest.cpp22
-rw-r--r--storage/connect/tabrest.h6
-rw-r--r--storage/connect/tabsys.cpp20
-rw-r--r--storage/connect/tabtbl.cpp8
-rw-r--r--storage/connect/tabutil.cpp2
-rw-r--r--storage/connect/tabvct.cpp6
-rw-r--r--storage/connect/tabwmi.cpp4
-rw-r--r--storage/connect/tabxcl.cpp2
-rw-r--r--storage/connect/tabxml.cpp30
-rw-r--r--storage/connect/valblk.cpp2
-rw-r--r--storage/connect/value.cpp42
-rw-r--r--storage/connect/value.h4
-rw-r--r--storage/connect/xindex.cpp28
-rw-r--r--storage/connect/xindex.h2
-rw-r--r--storage/innobase/btr/btr0scrub.cc18
-rw-r--r--storage/innobase/buf/buf0buf.cc47
-rw-r--r--storage/innobase/bzip2.cmake5
-rw-r--r--storage/innobase/fil/fil0crypt.cc34
-rw-r--r--storage/innobase/fts/fts0fts.cc12
-rw-r--r--storage/innobase/handler/ha_innodb.cc50
-rw-r--r--storage/innobase/handler/handler0alter.cc18
-rw-r--r--storage/innobase/include/btr0scrub.h7
-rw-r--r--storage/innobase/include/buf0buf.h6
-rw-r--r--storage/innobase/include/trx0i_s.h6
-rw-r--r--storage/innobase/include/trx0sys.h2
-rw-r--r--storage/innobase/include/trx0trx.h74
-rw-r--r--storage/innobase/include/trx0trx.ic10
-rw-r--r--storage/innobase/include/univ.i2
-rw-r--r--storage/innobase/innodb.cmake12
-rw-r--r--storage/innobase/lock/lock0lock.cc36
-rw-r--r--storage/innobase/lz4.cmake26
-rw-r--r--storage/innobase/lzma.cmake4
-rw-r--r--storage/innobase/lzo.cmake20
-rw-r--r--storage/innobase/os/os0file.cc4
-rw-r--r--storage/innobase/page/page0zip.cc14
-rw-r--r--storage/innobase/read/read0read.cc4
-rw-r--r--storage/innobase/row/row0ins.cc4
-rw-r--r--storage/innobase/row/row0upd.cc76
-rw-r--r--storage/innobase/snappy.cmake4
-rw-r--r--storage/innobase/trx/trx0i_s.cc21
-rw-r--r--storage/innobase/trx/trx0roll.cc25
-rw-r--r--storage/innobase/trx/trx0trx.cc52
-rw-r--r--storage/mroonga/CMakeLists.txt2
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/CMakeLists.txt2
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version_full (renamed from storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version)0
-rw-r--r--storage/mroonga/version_full (renamed from storage/mroonga/version)0
-rw-r--r--storage/oqgraph/CMakeLists.txt8
-rw-r--r--storage/oqgraph/mysql-test/oqgraph/social.test3
-rw-r--r--storage/rocksdb/CMakeLists.txt1
-rw-r--r--storage/rocksdb/build_rocksdb.cmake3
-rw-r--r--storage/spider/mysql-test/spider/bugfix/include/mdev_24020_deinit.inc11
-rw-r--r--storage/spider/mysql-test/spider/bugfix/include/mdev_24020_init.inc43
-rw-r--r--storage/spider/mysql-test/spider/bugfix/include/mdev_24517_deinit.inc11
-rw-r--r--storage/spider/mysql-test/spider/bugfix/include/mdev_24517_init.inc43
-rw-r--r--storage/spider/mysql-test/spider/bugfix/r/mdev_24020.result97
-rw-r--r--storage/spider/mysql-test/spider/bugfix/r/mdev_24517.result78
-rw-r--r--storage/spider/mysql-test/spider/bugfix/r/mdev_24760.result49
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/mdev_24020.cnf3
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/mdev_24020.test90
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/mdev_24517.cnf3
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/mdev_24517.test80
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/mdev_24760.cnf3
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/mdev_24760.test49
-rw-r--r--storage/spider/mysql-test/spider/include/init_master_1.inc5
-rw-r--r--storage/spider/mysql-test/spider/r/spider_fixes_part.result34
-rw-r--r--storage/spider/mysql-test/spider/t/spider_fixes_part.test35
-rw-r--r--storage/spider/spd_db_conn.cc42
-rw-r--r--storage/spider/spd_db_conn.h9
-rw-r--r--storage/spider/spd_db_mysql.cc225
-rw-r--r--storage/tokudb/ha_tokudb.cc4
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/bug-23786.result10
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/bug-23786.test14
-rw-r--r--support-files/CMakeLists.txt2
-rw-r--r--tests/mysql_client_test.c66
339 files changed, 7428 insertions, 2361 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c4c43d27609..3671ce8e321 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -145,6 +145,7 @@ IF (NOT CPACK_GENERATOR)
ENDIF(WIN32)
ENDIF(NOT CPACK_GENERATOR)
+INCLUDE(FeatureSummary)
INCLUDE(misc)
INCLUDE(mysql_version)
INCLUDE(cpack_source_ignore_files)
@@ -428,12 +429,15 @@ ADD_SUBDIRECTORY(sql/share)
IF(NOT WITHOUT_SERVER)
ADD_SUBDIRECTORY(tests)
ADD_SUBDIRECTORY(sql)
- OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
- IF(WITH_EMBEDDED_SERVER)
- ADD_SUBDIRECTORY(libmysqld)
- ADD_SUBDIRECTORY(libmysqld/examples)
- ADD_SUBDIRECTORY(unittest/embedded)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MariaDB with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ADD_SUBDIRECTORY(unittest/embedded)
ENDIF(WITH_EMBEDDED_SERVER)
+ IF(NOT WIN32)
+ ADD_FEATURE_INFO(EMBEDDED_SERVER WITH_EMBEDDED_SERVER "Embedded MariaDB Server Library")
+ ENDIF()
ADD_SUBDIRECTORY(mysql-test)
ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess)
@@ -527,6 +531,13 @@ IF(WIN32 AND SIGNCODE)
INSTALL(SCRIPT ${PROJECT_BINARY_DIR}/sign.cmake)
ENDIF()
+FEATURE_SUMMARY(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES VAR MARIADB_FEATURE_SUMMARY)
+
+OPTION(FEATURE_SUMMARY "Print feature summary at the end of configure step" ON)
+IF (FEATURE_SUMMARY)
+ MESSAGE_ONCE(SUMMARY "${MARIADB_FEATURE_SUMMARY}")
+ENDIF()
+
IF(NON_DISTRIBUTABLE_WARNING)
MESSAGE(WARNING "
You have linked MariaDB with ${NON_DISTRIBUTABLE_WARNING} libraries! You may not distribute the resulting binary. If you do, you will put yourself into a legal problem with the Free Software Foundation.")
diff --git a/cmake/aws_sdk.cmake b/cmake/aws_sdk.cmake
index 7abd9974c1e..f6f88f2b880 100644
--- a/cmake/aws_sdk.cmake
+++ b/cmake/aws_sdk.cmake
@@ -45,6 +45,7 @@ FUNCTION (CHECK_AWS_SDK RETVAL REASON)
IF(UNIX)
# Check librairies required for building SDK
FIND_PACKAGE(CURL)
+ SET_PACKAGE_PROPERTIES(CURL PROPERTIES TYPE REQUIRED)
IF(NOT CURL_FOUND)
SKIP_AWS_SDK("AWS C++ SDK requires libcurl development package")
ENDIF()
@@ -54,10 +55,12 @@ FUNCTION (CHECK_AWS_SDK RETVAL REASON)
ENDIF()
IF(NOT APPLE)
FIND_LIBRARY(UUID_LIBRARIES uuid)
+ SET_PACKAGE_PROPERTIES(UUID_LIBRARIES PROPERTIES TYPE REQUIRED)
IF(NOT UUID_LIBRARIES)
SKIP_AWS_SDK("AWS C++ SDK requires uuid development package")
ENDIF()
FIND_PACKAGE(OpenSSL)
+ SET_PACKAGE_PROPERTIES(OpenSSL PROPERTIES TYPE REQUIRED)
IF(NOT OPENSSL_FOUND)
SKIP_AWS_SDK("AWS C++ SDK requires openssl development package")
ENDIF()
diff --git a/cmake/for_clients.cmake b/cmake/for_clients.cmake
index 2c2c965df64..27b1430f33e 100644
--- a/cmake/for_clients.cmake
+++ b/cmake/for_clients.cmake
@@ -21,7 +21,7 @@ MACRO(EXTRACT_LINK_LIBRARIES target var)
FOREACH(lib ${${target}_LIB_DEPENDS})
# Filter out "general", it is not a library, just CMake hint
# Also, remove duplicates
- IF(NOT lib STREQUAL "general" AND NOT ${var} MATCHES "-l${lib} ")
+ IF(NOT lib STREQUAL "general" AND NOT ${var} MATCHES "-l${lib} " AND NOT lib STREQUAL "zlib")
IF (lib MATCHES "^\\-")
SET(${var} "${${var}} ${lib} ")
ELSEIF(lib MATCHES "^/")
diff --git a/cmake/jemalloc.cmake b/cmake/jemalloc.cmake
index b94a880cf05..55369157689 100644
--- a/cmake/jemalloc.cmake
+++ b/cmake/jemalloc.cmake
@@ -37,5 +37,6 @@ MACRO (CHECK_JEMALLOC)
IF (NOT LIBJEMALLOC AND NOT WITH_JEMALLOC STREQUAL "auto")
MESSAGE(FATAL_ERROR "jemalloc is not found")
ENDIF()
+ ADD_FEATURE_INFO(JEMALLOC LIBJEMALLOC "Use the JeMalloc memory allocator")
ENDIF()
ENDMACRO()
diff --git a/cmake/numa.cmake b/cmake/numa.cmake
index d24318634c3..0ccb560d378 100644
--- a/cmake/numa.cmake
+++ b/cmake/numa.cmake
@@ -33,6 +33,7 @@ MACRO (MYSQL_CHECK_NUMA)
ENDIF()
ENDIF()
+ ADD_FEATURE_INFO(NUMA HAVE_LIBNUMA "NUMA memory allocation policy")
IF(WITH_NUMA_LOWERCASE STREQUAL "auto" AND HAVE_LIBNUMA)
MESSAGE_ONCE(numa "WITH_NUMA=AUTO: NUMA memory allocation policy enabled")
ELSEIF(WITH_NUMA_LOWERCASE STREQUAL "auto" AND NOT HAVE_LIBNUMA)
diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake
index 486f5b00590..ff911008939 100644
--- a/cmake/plugin.cmake
+++ b/cmake/plugin.cmake
@@ -49,7 +49,7 @@ MACRO(MYSQL_ADD_PLUGIN)
LIST(REMOVE_AT SOURCES 0)
STRING(TOUPPER ${plugin} plugin)
STRING(TOLOWER ${plugin} target)
-
+
IF (ARG_MANDATORY)
UNSET(PLUGIN_${plugin} CACHE)
SET(PLUGIN_${plugin} "YES")
@@ -110,11 +110,11 @@ MACRO(MYSQL_ADD_PLUGIN)
SET(with_var "WITH_${plugin}")
ENDIF()
UNSET(${with_var} CACHE)
-
+
IF(NOT ARG_DEPENDENCIES)
SET(ARG_DEPENDENCIES)
ENDIF()
-
+
IF(NOT ARG_MODULE_OUTPUT_NAME)
IF(ARG_STORAGE_ENGINE)
SET(ARG_MODULE_OUTPUT_NAME "ha_${target}")
@@ -256,6 +256,16 @@ MACRO(MYSQL_ADD_PLUGIN)
INSTALL_MYSQL_TEST("${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/" "plugin/${subpath}")
ENDIF()
+ GET_TARGET_PROPERTY(plugin_type ${target} TYPE)
+ STRING(REGEX REPLACE "_LIBRARY$" "" plugin_type ${plugin_type})
+ STRING(REGEX REPLACE "^NO$" "" plugin_type ${plugin_type})
+ IF(ARG_STORAGE_ENGINE)
+ ADD_FEATURE_INFO(${plugin} PLUGIN_${plugin} "Storage Engine ${plugin_type}")
+ ELSEIF(ARG_CLIENT)
+ ADD_FEATURE_INFO(${plugin} PLUGIN_${plugin} "Client plugin ${plugin_type}")
+ ELSE()
+ ADD_FEATURE_INFO(${plugin} PLUGIN_${plugin} "Server plugin ${plugin_type}")
+ ENDIF()
ENDIF(NOT WITHOUT_SERVER OR ARG_CLIENT)
ENDMACRO()
diff --git a/cmake/readline.cmake b/cmake/readline.cmake
index 69a51d8a156..c8bbc7fc259 100644
--- a/cmake/readline.cmake
+++ b/cmake/readline.cmake
@@ -52,7 +52,7 @@ MACRO (MYSQL_CHECK_MULTIBYTE)
ENDMACRO()
MACRO (FIND_CURSES)
- FIND_PACKAGE(Curses)
+ FIND_PACKAGE(Curses REQUIRED)
MARK_AS_ADVANCED(CURSES_CURSES_H_PATH CURSES_FORM_LIBRARY CURSES_HAVE_CURSES_H)
IF(NOT CURSES_FOUND)
SET(ERRORMSG "Curses library not found. Please install appropriate package,
diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake
index 5f54d77752c..7c2488be8bd 100644
--- a/cmake/ssl.cmake
+++ b/cmake/ssl.cmake
@@ -117,6 +117,7 @@ MACRO (MYSQL_CHECK_SSL)
ENDIF()
ENDIF()
FIND_PACKAGE(OpenSSL)
+ SET_PACKAGE_PROPERTIES(OpenSSL PROPERTIES TYPE RECOMMENDED)
IF(OPENSSL_FOUND)
SET(OPENSSL_LIBRARY ${OPENSSL_SSL_LIBRARY})
INCLUDE(CheckSymbolExists)
diff --git a/cmake/systemd.cmake b/cmake/systemd.cmake
index e353004e7d2..978be0b9f98 100644
--- a/cmake/systemd.cmake
+++ b/cmake/systemd.cmake
@@ -65,5 +65,6 @@ MACRO(CHECK_SYSTEMD)
ELSEIF(NOT WITH_SYSTEMD STREQUAL "no")
MESSAGE(FATAL_ERROR "Invalid value for WITH_SYSTEMD. Must be 'yes', 'no', or 'auto'.")
ENDIF()
+ ADD_FEATURE_INFO(SYSTEMD LIBSYSTEMD "Systemd scripts and notification support")
ENDIF()
ENDMACRO()
diff --git a/cmake/wsrep.cmake b/cmake/wsrep.cmake
index a6d843e5591..368ae61d1d3 100644
--- a/cmake/wsrep.cmake
+++ b/cmake/wsrep.cmake
@@ -64,4 +64,7 @@ Then restart the build.
ADD_SUBDIRECTORY(wsrep-lib)
SET(BUILD_SHARED_LIBS ${old_BUILD_SHARED_LIBS})
ENDIF()
+IF (NOT WIN32)
+ ADD_FEATURE_INFO(WSREP WITH_WSREP "WSREP replication API (to use, e.g. Galera Replication library)")
+ENDIF()
ENDIF(NOT WITHOUT_SERVER)
diff --git a/configure.cmake b/configure.cmake
index a88868eb83a..c7d992812bf 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -170,6 +170,7 @@ IF(UNIX)
SET(LIBWRAP "wrap")
ENDIF()
ENDIF()
+ ADD_FEATURE_INFO(LIBWRAP HAVE_LIBWRAP "Support for tcp wrappers")
ENDIF()
#
diff --git a/debian/control b/debian/control
index fbab7ff862e..d995bf2ba8d 100644
--- a/debian/control
+++ b/debian/control
@@ -224,14 +224,14 @@ Architecture: all
Depends: mysql-common,
${misc:Depends},
${shlibs:Depends}
-Description: MariaDB database common files (e.g. /etc/mysql/conf.d/mariadb.cnf)
+Description: MariaDB database common files (e.g. /etc/mysql/mariadb.conf.d/)
MariaDB is a fast, stable and true multi-user, multi-threaded SQL database
server. SQL (Structured Query Language) is the most popular database query
language in the world. The main goals of MariaDB are speed, robustness and
ease of use.
.
This package includes files needed by all versions of the client library
- (e.g. /etc/mysql/conf.d/mariadb.cnf).
+ (e.g. /etc/mysql/mariadb.conf.d/ or /etc/mysql/mariadb.cnf).
Package: mariadb-client-core-10.4
Architecture: any
diff --git a/extra/innochecksum.cc b/extra/innochecksum.cc
index bd700efecae..87451037995 100644
--- a/extra/innochecksum.cc
+++ b/extra/innochecksum.cc
@@ -61,9 +61,9 @@ The parts not included are excluded by #ifndef UNIV_INNOCHECKSUM. */
/* Global variables */
static bool verbose;
static bool just_count;
-static unsigned long long start_page;
-static unsigned long long end_page;
-static unsigned long long do_page;
+static uint32_t start_page;
+static uint32_t end_page;
+static uint32_t do_page;
static bool use_end_page;
static bool do_one_page;
static my_bool do_leaf;
@@ -74,9 +74,9 @@ static ulint physical_page_size; /* Page size in bytes on disk. */
ulong srv_page_size;
ulong srv_page_size_shift;
/* Current page number (0 based). */
-unsigned long long cur_page_num;
+uint32_t cur_page_num;
/* Current space. */
-unsigned long long cur_space;
+uint32_t cur_space;
/* Skip the checksum verification. */
static bool no_check;
/* Enabled for strict checksum verification. */
@@ -463,11 +463,11 @@ is_page_corrupted(
/* enable if page is corrupted. */
bool is_corrupted;
/* use to store LSN values. */
- ulint logseq;
- ulint logseqfield;
+ uint32_t logseq;
+ uint32_t logseqfield;
ulint page_type = mach_read_from_2(buf+FIL_PAGE_TYPE);
- uint key_version = buf_page_get_key_version(buf, flags);
- ulint space_id = mach_read_from_4(
+ uint32_t key_version = buf_page_get_key_version(buf, flags);
+ uint32_t space_id = mach_read_from_4(
buf + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
ulint zip_size = fil_space_t::zip_size(flags);
ulint is_compressed = fil_space_t::is_compressed(flags);
@@ -485,8 +485,8 @@ is_page_corrupted(
if (is_log_enabled) {
fprintf(log_file,
- "page id mismatch space::" ULINTPF
- " page::%llu \n",
+ "page id mismatch space::" UINT32PF
+ " page::" UINT32PF " \n",
space_id, cur_page_num);
}
@@ -515,13 +515,14 @@ is_page_corrupted(
if (is_log_enabled) {
fprintf(log_file,
- "space::" ULINTPF " page::%llu"
- "; log sequence number:first = " ULINTPF
- "; second = " ULINTPF "\n",
+ "space::" UINT32PF " page::" UINT32PF
+ "; log sequence number:first = " UINT32PF
+ "; second = " UINT32PF "\n",
space_id, cur_page_num, logseq, logseqfield);
if (logseq != logseqfield) {
fprintf(log_file,
- "Fail; space::" ULINTPF " page::%llu"
+ "Fail; space::" UINT32PF
+ " page::" UINT32PF
" invalid (fails log "
"sequence number check)\n",
space_id, cur_page_num);
@@ -545,9 +546,9 @@ is_page_corrupted(
if (is_corrupted && log_file) {
fprintf(log_file,
- "[page id: space=" ULINTPF
- ", page_number=%llu] may be corrupted;"
- " key_version=%u\n",
+ "[page id: space=" UINT32PF
+ ", page_number=" UINT32PF "] may be corrupted;"
+ " key_version=" UINT32PF "\n",
space_id, cur_page_num, key_version);
}
} else {
@@ -651,8 +652,8 @@ static bool update_checksum(byte* page, ulint flags)
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum);
if (is_log_enabled) {
- fprintf(log_file, "page::%llu; Updated checksum ="
- " %u\n", cur_page_num, checksum);
+ fprintf(log_file, "page::" UINT32PF "; Updated checksum ="
+ " " UINT32PF "\n", cur_page_num, checksum);
}
} else if (use_full_crc32) {
@@ -663,7 +664,7 @@ static bool update_checksum(byte* page, ulint flags)
if (mach_read_from_4(c) == checksum) return false;
mach_write_to_4(c, checksum);
if (is_log_enabled) {
- fprintf(log_file, "page::%llu; Updated checksum"
+ fprintf(log_file, "page::" UINT32PF "; Updated checksum"
" = %u\n", cur_page_num, checksum);
}
return true;
@@ -697,8 +698,8 @@ static bool update_checksum(byte* page, ulint flags)
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum);
if (is_log_enabled) {
- fprintf(log_file, "page::%llu; Updated checksum field1"
- " = %u\n", cur_page_num, checksum);
+ fprintf(log_file, "page::" UINT32PF "; Updated checksum field1"
+ " = " UINT32PF "\n", cur_page_num, checksum);
}
if (write_check == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB
@@ -711,8 +712,8 @@ static bool update_checksum(byte* page, ulint flags)
FIL_PAGE_END_LSN_OLD_CHKSUM,checksum);
if (is_log_enabled) {
- fprintf(log_file, "page::%llu; Updated checksum "
- "field2 = %u\n", cur_page_num, checksum);
+ fprintf(log_file, "page::" UINT32PF "; Updated checksum "
+ "field2 = " UINT32PF "\n", cur_page_num, checksum);
}
}
@@ -784,7 +785,8 @@ write_file(
if (physical_page_size
!= fwrite(buf, 1, physical_page_size,
file == stdin ? stdout : file)) {
- fprintf(stderr, "Failed to write page::%llu to %s: %s\n",
+ fprintf(stderr,
+ "Failed to write page::" UINT32PF " to %s: %s\n",
cur_page_num, filename, strerror(errno));
return(false);
@@ -801,6 +803,16 @@ write_file(
return(true);
}
+// checks using current xdes page whether the page is free
+static inline bool is_page_free(const byte *xdes, ulint physical_page_size,
+ uint32_t page_no)
+{
+ const byte *des=
+ xdes + XDES_ARR_OFFSET +
+ XDES_SIZE * ((page_no & (physical_page_size - 1)) / FSP_EXTENT_SIZE);
+ return xdes_get_bit(des, XDES_FREE_BIT, page_no % FSP_EXTENT_SIZE);
+}
+
/*
Parse the page and collect/dump the information about page type
@param [in] page buffer page
@@ -816,12 +828,10 @@ parse_page(
bool is_encrypted)
{
unsigned long long id;
- ulint undo_page_type;
+ uint16_t undo_page_type;
char str[20]={'\0'};
ulint n_recs;
- ulint page_no;
- ulint left_page_no;
- ulint right_page_no;
+ uint32_t page_no, left_page_no, right_page_no;
ulint data_bytes;
bool is_leaf;
ulint size_range_id;
@@ -836,7 +846,7 @@ parse_page(
switch (mach_read_from_2(page + FIL_PAGE_TYPE)) {
case FIL_PAGE_INDEX: {
- uint key_version = mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
+ uint32_t key_version = mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
page_type.n_fil_page_index++;
/* If page is encrypted we can't read index header */
@@ -860,7 +870,7 @@ parse_page(
is_leaf = (!*(const uint16*) (page + (PAGE_HEADER + PAGE_LEVEL)));
if (page_type_dump) {
- fprintf(file, "#::%llu\t\t|\t\tIndex page\t\t\t|"
+ fprintf(file, "#::" UINT32PF "\t\t|\t\tIndex page\t\t\t|"
"\tindex id=%llu,", cur_page_num, id);
fprintf(file,
@@ -878,22 +888,14 @@ parse_page(
size_range_id = SIZE_RANGES_FOR_PAGE + 1;
}
if (per_page_details) {
- printf("index id=%llu page " ULINTPF " leaf %d n_recs " ULINTPF " data_bytes " ULINTPF
+ printf("index id=%llu page " UINT32PF " leaf %d n_recs " ULINTPF " data_bytes " ULINTPF
"\n", id, page_no, is_leaf, n_recs, data_bytes);
}
/* update per-index statistics */
{
- if (index_ids.count(id) == 0) {
- index_ids[id] = per_index_stats();
- }
- std::map<unsigned long long, per_index_stats>::iterator it;
- it = index_ids.find(id);
- per_index_stats &index = (it->second);
- const byte* des = xdes + XDES_ARR_OFFSET
- + XDES_SIZE * ((page_no & (physical_page_size - 1))
- / FSP_EXTENT_SIZE);
- if (xdes_get_bit(des, XDES_FREE_BIT,
- page_no % FSP_EXTENT_SIZE)) {
+ per_index_stats &index = index_ids[id];
+ if (is_page_free(xdes, physical_page_size,
+ page_no)) {
index.free_pages++;
return;
}
@@ -921,8 +923,8 @@ parse_page(
index.pages_in_size_range[size_range_id] ++;
}
} else {
- fprintf(file, "#::%llu\t\t|\t\tEncrypted Index page\t\t\t|"
- "\tkey_version %u,%s\n", cur_page_num, key_version, str);
+ fprintf(file, "#::" UINT32PF "\t\t|\t\tEncrypted Index page\t\t\t|"
+ "\tkey_version " UINT32PF ",%s\n", cur_page_num, key_version, str);
}
break;
@@ -932,7 +934,7 @@ parse_page(
undo_page_type = mach_read_from_2(page +
TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE);
if (page_type_dump) {
- fprintf(file, "#::%llu\t\t|\t\tUndo log page\t\t\t|",
+ fprintf(file, "#::" UINT32PF "\t\t|\t\tUndo log page\t\t\t|",
cur_page_num);
}
page_type.n_undo++;
@@ -984,7 +986,7 @@ parse_page(
case FIL_PAGE_INODE:
page_type.n_fil_page_inode++;
if (page_type_dump) {
- fprintf(file, "#::%llu\t\t|\t\tInode page\t\t\t|"
+ fprintf(file, "#::" UINT32PF "\t\t|\t\tInode page\t\t\t|"
"\t%s\n",cur_page_num, str);
}
break;
@@ -992,7 +994,7 @@ parse_page(
case FIL_PAGE_IBUF_FREE_LIST:
page_type.n_fil_page_ibuf_free_list++;
if (page_type_dump) {
- fprintf(file, "#::%llu\t\t|\t\tInsert buffer free list"
+ fprintf(file, "#::" UINT32PF "\t\t|\t\tInsert buffer free list"
" page\t|\t%s\n", cur_page_num, str);
}
break;
@@ -1000,7 +1002,7 @@ parse_page(
case FIL_PAGE_TYPE_ALLOCATED:
page_type.n_fil_page_type_allocated++;
if (page_type_dump) {
- fprintf(file, "#::%llu\t\t|\t\tFreshly allocated "
+ fprintf(file, "#::" UINT32PF "\t\t|\t\tFreshly allocated "
"page\t\t|\t%s\n", cur_page_num, str);
}
break;
@@ -1008,7 +1010,7 @@ parse_page(
case FIL_PAGE_IBUF_BITMAP:
page_type.n_fil_page_ibuf_bitmap++;
if (page_type_dump) {
- fprintf(file, "#::%llu\t\t|\t\tInsert Buffer "
+ fprintf(file, "#::" UINT32PF "\t\t|\t\tInsert Buffer "
"Bitmap\t\t|\t%s\n", cur_page_num, str);
}
break;
@@ -1016,33 +1018,31 @@ parse_page(
case FIL_PAGE_TYPE_SYS:
page_type.n_fil_page_type_sys++;
if (page_type_dump) {
- fprintf(file, "#::%llu\t\t|\t\tSystem page\t\t\t|"
- "\t%s\n",cur_page_num, str);
+ fprintf(file, "#::" UINT32PF "\t\t|\t\tSystem page\t\t\t|"
+ "\t%s\n", cur_page_num, str);
}
break;
case FIL_PAGE_TYPE_TRX_SYS:
page_type.n_fil_page_type_trx_sys++;
if (page_type_dump) {
- fprintf(file, "#::%llu\t\t|\t\tTransaction system "
+ fprintf(file, "#::" UINT32PF "\t\t|\t\tTransaction system "
"page\t\t|\t%s\n", cur_page_num, str);
}
break;
case FIL_PAGE_TYPE_FSP_HDR:
page_type.n_fil_page_type_fsp_hdr++;
- memcpy(xdes, page, physical_page_size);
if (page_type_dump) {
- fprintf(file, "#::%llu\t\t|\t\tFile Space "
+ fprintf(file, "#::" UINT32PF "\t\t|\t\tFile Space "
"Header\t\t|\t%s\n", cur_page_num, str);
}
break;
case FIL_PAGE_TYPE_XDES:
page_type.n_fil_page_type_xdes++;
- memcpy(xdes, page, physical_page_size);
if (page_type_dump) {
- fprintf(file, "#::%llu\t\t|\t\tExtent descriptor "
+ fprintf(file, "#::" UINT32PF "\t\t|\t\tExtent descriptor "
"page\t\t|\t%s\n", cur_page_num, str);
}
break;
@@ -1050,7 +1050,7 @@ parse_page(
case FIL_PAGE_TYPE_BLOB:
page_type.n_fil_page_type_blob++;
if (page_type_dump) {
- fprintf(file, "#::%llu\t\t|\t\tBLOB page\t\t\t|\t%s\n",
+ fprintf(file, "#::" UINT32PF "\t\t|\t\tBLOB page\t\t\t|\t%s\n",
cur_page_num, str);
}
break;
@@ -1058,7 +1058,7 @@ parse_page(
case FIL_PAGE_TYPE_ZBLOB:
page_type.n_fil_page_type_zblob++;
if (page_type_dump) {
- fprintf(file, "#::%llu\t\t|\t\tCompressed BLOB "
+ fprintf(file, "#::" UINT32PF "\t\t|\t\tCompressed BLOB "
"page\t\t|\t%s\n", cur_page_num, str);
}
break;
@@ -1066,7 +1066,7 @@ parse_page(
case FIL_PAGE_TYPE_ZBLOB2:
page_type.n_fil_page_type_zblob2++;
if (page_type_dump) {
- fprintf(file, "#::%llu\t\t|\t\tSubsequent Compressed "
+ fprintf(file, "#::" UINT32PF "\t\t|\t\tSubsequent Compressed "
"BLOB page\t|\t%s\n", cur_page_num, str);
}
break;
@@ -1074,7 +1074,7 @@ parse_page(
case FIL_PAGE_PAGE_COMPRESSED:
page_type.n_fil_page_type_page_compressed++;
if (page_type_dump) {
- fprintf(file, "#::%llu\t\t|\t\tPage compressed "
+ fprintf(file, "#::" UINT32PF "\t\t|\t\tPage compressed "
"page\t|\t%s\n", cur_page_num, str);
}
break;
@@ -1082,7 +1082,7 @@ parse_page(
case FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED:
page_type.n_fil_page_type_page_compressed_encrypted++;
if (page_type_dump) {
- fprintf(file, "#::%llu\t\t|\t\tPage compressed encrypted "
+ fprintf(file, "#::" UINT32PF "\t\t|\t\tPage compressed encrypted "
"page\t|\t%s\n", cur_page_num, str);
}
break;
@@ -1234,14 +1234,14 @@ static struct my_option innochecksum_options[] = {
{"count", 'c', "Print the count of pages in the file and exits.",
&just_count, &just_count, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"start_page", 's', "Start on this page number (0 based).",
- &start_page, &start_page, 0, GET_ULL, REQUIRED_ARG,
- 0, 0, ULLONG_MAX, 0, 1, 0},
+ &start_page, &start_page, 0, GET_UINT, REQUIRED_ARG,
+ 0, 0, FIL_NULL, 0, 1, 0},
{"end_page", 'e', "End at this page number (0 based).",
- &end_page, &end_page, 0, GET_ULL, REQUIRED_ARG,
- 0, 0, ULLONG_MAX, 0, 1, 0},
+ &end_page, &end_page, 0, GET_UINT, REQUIRED_ARG,
+ 0, 0, FIL_NULL, 0, 1, 0},
{"page", 'p', "Check only this page (0 based).",
- &do_page, &do_page, 0, GET_ULL, REQUIRED_ARG,
- 0, 0, ULLONG_MAX, 0, 1, 0},
+ &do_page, &do_page, 0, GET_UINT, REQUIRED_ARG,
+ 0, 0, FIL_NULL, 0, 1, 0},
{"strict-check", 'C', "Specify the strict checksum algorithm by the user.",
&strict_check, &strict_check, &innochecksum_algorithms_typelib,
GET_ENUM, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -1437,14 +1437,14 @@ static bool check_encryption(const char* filename, const byte* page)
return false;
}
- uint min_key_version = mach_read_from_4
+ uint32_t min_key_version = mach_read_from_4
(page + offset + MAGIC_SZ + 2 + iv_length);
- uint key_id = mach_read_from_4
+ uint32_t key_id = mach_read_from_4
(page + offset + MAGIC_SZ + 2 + iv_length + 4);
if (type == CRYPT_SCHEME_1 && is_log_enabled) {
- fprintf(log_file,"Tablespace %s encrypted key_version %u key_id %u\n",
+ fprintf(log_file,"Tablespace %s encrypted key_version " UINT32PF " key_id " UINT32PF "\n",
filename, min_key_version, key_id);
}
@@ -1466,7 +1466,7 @@ static int verify_checksum(
{
int exit_status = 0;
if (is_page_corrupted(buf, is_encrypted, flags)) {
- fprintf(stderr, "Fail: page::%llu invalid\n",
+ fprintf(stderr, "Fail: page::" UINT32PF " invalid\n",
cur_page_num);
(*mismatch_count)++;
@@ -1542,7 +1542,7 @@ int main(
/* size of file (has to be 64 bits) */
unsigned long long int size = 0;
/* number of pages in file */
- ulint pages;
+ uint32_t pages;
off_t offset = 0;
/* count the no. of page corrupted. */
@@ -1743,36 +1743,38 @@ int main(
}
if (per_page_details) {
- printf("page %llu ", cur_page_num);
+ printf("page " UINT32PF " ", cur_page_num);
}
+ memcpy(xdes, buf, physical_page_size);
+
if (page_type_summary || page_type_dump) {
parse_page(buf, xdes, fil_page_type, is_encrypted);
}
- pages = (ulint) (size / physical_page_size);
+ pages = uint32_t(size / physical_page_size);
if (just_count) {
- if (read_from_stdin) {
- fprintf(stderr, "Number of pages:" ULINTPF "\n", pages);
- } else {
- printf("Number of pages:" ULINTPF "\n", pages);
- }
+ fprintf(read_from_stdin ? stderr : stdout,
+ "Number of pages:" UINT32PF "\n", pages);
continue;
} else if (verbose && !read_from_stdin) {
if (is_log_enabled) {
fprintf(log_file, "file %s = %llu bytes "
- "(" ULINTPF " pages)\n", filename, size, pages);
+ "(" UINT32PF " pages)\n",
+ filename, size, pages);
if (do_one_page) {
fprintf(log_file, "Innochecksum: "
- "checking page::%llu;\n",
+ "checking page::"
+ UINT32PF ";\n",
do_page);
}
}
} else {
if (is_log_enabled) {
fprintf(log_file, "Innochecksum: checking "
- "pages in range::%llu to %llu\n",
+ "pages in range::" UINT32PF
+ " to " UINT32PF "\n",
start_page, use_end_page ?
end_page : (pages - 1));
}
@@ -1816,8 +1818,8 @@ int main(
the desired page. */
partial_page_read = false;
- offset = (off_t) start_page
- * (off_t) physical_page_size;
+ offset = off_t(ulonglong(start_page)
+ * physical_page_size);
if (IF_WIN(_fseeki64,fseeko)(fil_in, offset,
SEEK_SET)) {
perror("Error: Unable to seek to "
@@ -1858,12 +1860,7 @@ int main(
count++;
if (!bytes || feof(fil_in)) {
- fprintf(stderr, "Error: Unable "
- "to seek to necessary "
- "offset");
-
- exit_status = 1;
- goto my_exit;
+ goto unexpected_eof;
}
}
}
@@ -1879,6 +1876,15 @@ int main(
partial_page_read = false;
if (!bytes && feof(fil_in)) {
+ if (cur_page_num == start_page) {
+unexpected_eof:
+ fputs("Error: Unable "
+ "to seek to necessary offset\n",
+ stderr);
+
+ exit_status = 1;
+ goto my_exit;
+ }
break;
}
@@ -1920,6 +1926,8 @@ first_non_zero:
checksum verification.*/
if (!no_check
&& !skip_page
+ && !is_page_free(xdes, physical_page_size,
+ cur_page_num)
&& (exit_status = verify_checksum(
buf, is_encrypted,
&mismatch_count, flags))) {
@@ -1938,7 +1946,11 @@ first_non_zero:
}
if (per_page_details) {
- printf("page %llu ", cur_page_num);
+ printf("page " UINT32PF " ", cur_page_num);
+ }
+
+ if (page_get_page_no(buf) % physical_page_size == 0) {
+ memcpy(xdes, buf, physical_page_size);
}
if (page_type_summary || page_type_dump) {
@@ -1954,10 +1966,10 @@ first_non_zero:
if (!lastt) {
lastt= now;
} else if (now - lastt >= 1 && is_log_enabled) {
- fprintf(log_file, "page::%llu "
+ fprintf(log_file, "page::" UINT32PF " "
"okay: %.3f%% done\n",
(cur_page_num - 1),
- (float) cur_page_num / pages * 100);
+ (double) cur_page_num / pages * 100);
lastt = now;
}
}
diff --git a/extra/mariabackup/CMakeLists.txt b/extra/mariabackup/CMakeLists.txt
index 796427107d4..75c942c8a7b 100644
--- a/extra/mariabackup/CMakeLists.txt
+++ b/extra/mariabackup/CMakeLists.txt
@@ -15,6 +15,7 @@
OPTION(WITH_MARIABACKUP "Include mariabackup" ON)
+ADD_FEATURE_INFO(MARIABACKUP WITH_MARIABACKUP "MariaDB Backup Utility")
IF(NOT WITH_MARIABACKUP)
RETURN()
ENDIF()
diff --git a/extra/mariabackup/innobackupex.cc b/extra/mariabackup/innobackupex.cc
index aadf406334e..5cc9ffb906d 100644
--- a/extra/mariabackup/innobackupex.cc
+++ b/extra/mariabackup/innobackupex.cc
@@ -309,7 +309,7 @@ static struct my_option ibx_long_options[] =
{"force-non-empty-directories", OPT_FORCE_NON_EMPTY_DIRS, "This "
"option, when specified, makes --copy-back or --move-back transfer "
"files to non-empty directories. Note that no existing files will be "
- "overwritten. If --copy-back or --nove-back has to copy a file from "
+ "overwritten. If --copy-back or --move-back has to copy a file from "
"the backup directory which already exists in the destination "
"directory, it will still fail with an error.",
(uchar *) &opt_ibx_force_non_empty_dirs,
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index db7f20d2fdd..198d39cdeb6 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -1284,7 +1284,7 @@ struct my_option xb_client_options[]= {
"This "
"option, when specified, makes --copy-back or --move-back transfer "
"files to non-empty directories. Note that no existing files will be "
- "overwritten. If --copy-back or --nove-back has to copy a file from "
+ "overwritten. If --copy-back or --move-back has to copy a file from "
"the backup directory which already exists in the destination "
"directory, it will still fail with an error.",
(uchar *) &opt_force_non_empty_dirs, (uchar *) &opt_force_non_empty_dirs,
diff --git a/include/my_sys.h b/include/my_sys.h
index d8101057f7c..29a9b426a5a 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2010, 2019, MariaDB Corporation.
+ Copyright (c) 2010, 2021, 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
@@ -282,7 +282,8 @@ extern int my_umask_dir,
extern my_bool my_use_symdir;
extern ulong my_default_record_cache_size;
-extern my_bool my_disable_locking, my_disable_async_io,
+extern MYSQL_PLUGIN_IMPORT my_bool my_disable_locking;
+extern my_bool my_disable_async_io,
my_disable_flush_key_blocks, my_disable_symlinks;
extern my_bool my_disable_sync, my_disable_copystat_in_redel;
extern char wild_many,wild_one,wild_prefix;
diff --git a/libmariadb b/libmariadb
-Subproject 802ce584a26fdc0ba67fcf35e277bf3c7440956
+Subproject 0cc16f18c1d87bbe6e360eaf578fcedeb947911
diff --git a/mysql-test/dgcov.pl b/mysql-test/dgcov.pl
index fbc5540e697..2c00c64d1ff 100755
--- a/mysql-test/dgcov.pl
+++ b/mysql-test/dgcov.pl
@@ -155,32 +155,34 @@ END
sub gcov_one_file {
return unless /\.gcda$/;
unless ($opt_skip_gcov) {
- $cmd= "gcov -i '$_' 2>/dev/null >/dev/null";
+ $cmd= "gcov -il '$_' 2>/dev/null >/dev/null";
print STDERR ++$file_no,"\r" if not $opt_verbose and -t STDERR;
logv "Running: $cmd";
system($cmd)==0 or die "system($cmd): $? $!";
}
# now, read the generated file
- open FH, '<', "$_.gcov" or die "open(<$_.gcov): $!";
- my $fname;
- while (<FH>) {
- chomp;
- if (/^function:/) {
- next;
- }
- if (/^file:/) {
- $fname=realpath($');
- next;
- }
- next if /^lcount:\d+,-\d+/; # whatever that means
- unless (/^lcount:(\d+),(\d+)/ and $fname) {
- warn "unknown line '$_' after running '$cmd'";
- next;
+ for my $gcov_file (<$_*.gcov>) {
+ open FH, '<', "$gcov_file" or die "open(<$gcov_file): $!";
+ my $fname;
+ while (<FH>) {
+ chomp;
+ if (/^function:/) {
+ next;
+ }
+ if (/^file:/) {
+ $fname=realpath(-f $' ? $' : $root.$');
+ next;
+ }
+ next if /^lcount:\d+,-\d+/; # whatever that means
+ unless (/^lcount:(\d+),(\d+)/ and $fname) {
+ warn "unknown line '$_' in $gcov_file";
+ next;
+ }
+ $cov{$fname}->{$1}+=$2;
}
- $cov{$fname}->{$1}+=$2;
+ close(FH);
}
- close(FH);
}
sub write_coverage {
diff --git a/mysql-test/include/wait_until_disconnected.inc b/mysql-test/include/wait_until_disconnected.inc
index 15bc6474995..93ada7f11ce 100644
--- a/mysql-test/include/wait_until_disconnected.inc
+++ b/mysql-test/include/wait_until_disconnected.inc
@@ -15,7 +15,7 @@ while (!$mysql_errno)
dec $counter;
if (!$counter)
{
- --die Server failed to dissapear
+ --die Server failed to disappear
}
--real_sleep 0.1
}
diff --git a/mysql-test/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm
index b5a7660ed3e..69033649b46 100644
--- a/mysql-test/lib/My/SafeProcess.pm
+++ b/mysql-test/lib/My/SafeProcess.pm
@@ -389,10 +389,10 @@ sub _collect {
# 1 Still running
#
sub wait_one {
- my ($self, $timeout)= @_;
- croak "usage: \$safe_proc->wait_one([timeout])" unless ref $self;
+ my ($self, $timeout, $keep)= @_;
+ croak "usage: \$safe_proc->wait_one([timeout] [, keep])" unless ref $self;
- _verbose("wait_one $self, $timeout");
+ _verbose("wait_one $self, $timeout, $keep");
if ( ! defined($self->{SAFE_PID}) ) {
# No pid => not running
@@ -466,16 +466,16 @@ sub wait_one {
return 1;
}
- if ( not $blocking and $retpid == -1 ) {
- # still running
- _verbose("still running");
- return 1;
- }
+ #if ( not $blocking and $retpid == -1 ) {
+ # # still running
+ # _verbose("still running");
+ # return 1;
+ #}
#warn "wait_one: expected pid $pid but got $retpid"
# unless( $retpid == $pid );
- $self->_collect($exit_code);
+ $self->_collect($exit_code) unless $keep;
return 0;
}
diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl
index cee9f2b6ed6..2ff78c0e10a 100644
--- a/mysql-test/lib/mtr_process.pl
+++ b/mysql-test/lib/mtr_process.pl
@@ -40,7 +40,7 @@ BEGIN
eval 'sub USE_NETPING { $use_netping }';
}
-sub sleep_until_file_created ($$$$);
+sub sleep_until_file_created ($$$$$);
sub mtr_ping_port ($);
sub mtr_ping_port ($) {
@@ -102,8 +102,9 @@ sub mtr_ping_port ($) {
# FIXME check that the pidfile contains the expected pid!
-sub sleep_until_file_created ($$$$) {
+sub sleep_until_file_created ($$$$$) {
my $pidfile= shift;
+ my $expectfile = shift;
my $timeout= shift;
my $proc= shift;
my $warn_seconds = shift;
@@ -120,8 +121,9 @@ sub sleep_until_file_created ($$$$) {
my $seconds= ($loop * $sleeptime) / 1000;
# Check if it died after the fork() was successful
- if ( defined $proc and ! $proc->wait_one(0) )
+ if ( defined $proc and ! $proc->wait_one(0, 1) )
{
+ return 1 if -r $expectfile;
mtr_warning("Process $proc died after mysql-test-run waited $seconds " .
"seconds for $pidfile to be created.");
return 0;
diff --git a/mysql-test/main/cte_nonrecursive.result b/mysql-test/main/cte_nonrecursive.result
index 4cd466ac350..11101d7d0f1 100644
--- a/mysql-test/main/cte_nonrecursive.result
+++ b/mysql-test/main/cte_nonrecursive.result
@@ -2019,6 +2019,73 @@ drop procedure sp1;
drop procedure sp2;
drop procedure sp3;
drop table t1;
+#
+# MDEV-26095: missing RECURSIVE for the recursive definition of CTE
+# embedded into another CTE definition
+#
+create table t1 (a int);
+insert into t1 values (5), (7);
+with cte_e as (
+with recursive cte_r as (
+select a from t1 union select a+1 as a from cte_r r where a < 10
+) select * from cte_r
+) select * from cte_e;
+a
+5
+7
+6
+8
+9
+10
+with cte_e as (
+with cte_r as (
+select a from t1 union select a+1 as a from cte_r r where a < 10
+) select * from cte_r
+) select * from cte_e;
+ERROR 42S02: Table 'test.cte_r' doesn't exist
+drop table t1;
+#
+# MDEV-26025: query with two usage of a CTE executing via PS /SP
+#
+create table t1 (a int, b int);
+insert into t1 value (1,3), (3,2), (1,3), (4,1);
+prepare stmt from "with
+cte1 as ( select a,b from t1 where a = 1 AND b = 3 ),
+cte2 as ( select a,b from cte1 ),
+cte3 as ( select a,b from cte2 )
+select * from cte3, cte2";
+execute stmt;
+a b a b
+1 3 1 3
+1 3 1 3
+1 3 1 3
+1 3 1 3
+execute stmt;
+a b a b
+1 3 1 3
+1 3 1 3
+1 3 1 3
+1 3 1 3
+deallocate prepare stmt;
+create procedure sp() with
+cte1 as ( select a,b from t1 where a = 1 AND b = 3 ),
+cte2 as ( select a,b from cte1 ),
+cte3 as ( select a,b from cte2 )
+select * from cte3, cte2;
+call sp();
+a b a b
+1 3 1 3
+1 3 1 3
+1 3 1 3
+1 3 1 3
+call sp();
+a b a b
+1 3 1 3
+1 3 1 3
+1 3 1 3
+1 3 1 3
+drop procedure sp;
+drop table t1;
# End of 10.2 tests
#
# MDEV-21673: several references to CTE that uses
diff --git a/mysql-test/main/cte_nonrecursive.test b/mysql-test/main/cte_nonrecursive.test
index 12949ecdaed..e1be68563d2 100644
--- a/mysql-test/main/cte_nonrecursive.test
+++ b/mysql-test/main/cte_nonrecursive.test
@@ -1492,6 +1492,56 @@ drop procedure sp3;
drop table t1;
+--echo #
+--echo # MDEV-26095: missing RECURSIVE for the recursive definition of CTE
+--echo # embedded into another CTE definition
+--echo #
+
+create table t1 (a int);
+insert into t1 values (5), (7);
+
+with cte_e as (
+ with recursive cte_r as (
+ select a from t1 union select a+1 as a from cte_r r where a < 10
+ ) select * from cte_r
+) select * from cte_e;
+
+--ERROR ER_NO_SUCH_TABLE
+with cte_e as (
+ with cte_r as (
+ select a from t1 union select a+1 as a from cte_r r where a < 10
+ ) select * from cte_r
+) select * from cte_e;
+
+drop table t1;
+
+--echo #
+--echo # MDEV-26025: query with two usage of a CTE executing via PS /SP
+--echo #
+
+create table t1 (a int, b int);
+insert into t1 value (1,3), (3,2), (1,3), (4,1);
+
+let $q=
+with
+ cte1 as ( select a,b from t1 where a = 1 AND b = 3 ),
+ cte2 as ( select a,b from cte1 ),
+ cte3 as ( select a,b from cte2 )
+select * from cte3, cte2;
+
+eval prepare stmt from "$q";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+eval create procedure sp() $q;
+
+call sp();
+call sp();
+
+drop procedure sp;
+drop table t1;
+
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/main/cte_recursive.result b/mysql-test/main/cte_recursive.result
index 74b450ff890..72d8d5cc00e 100644
--- a/mysql-test/main/cte_recursive.result
+++ b/mysql-test/main/cte_recursive.result
@@ -3733,7 +3733,7 @@ select * from t1 as t;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t ALL NULL NULL NULL NULL 4 100.00
Warnings:
-Note 1003 with recursive cte as (/* select#2 */ select `*` AS `*` from `test`.`t1` where `a` = 1 union /* select#3 */ select `a` + 1 AS `a+1` from `cte` where `a` < 3)/* select#1 */ select `test`.`t`.`a` AS `a` from `test`.`t1` `t`
+Note 1003 with recursive cte as (/* select#2 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1 union /* select#3 */ select `cte`.`a` + 1 AS `a+1` from `cte` where `cte`.`a` < 3)/* select#1 */ select `test`.`t`.`a` AS `a` from `test`.`t1` `t`
with recursive cte as
(select * from t1 where a=1 union select a+1 from cte where a<3)
select * from t1 as t;
@@ -3746,10 +3746,10 @@ create table t2 ( i1 int, i2 int);
insert into t2 values (1,1),(2,2);
explain
with recursive cte as
-( select * from t1 union select s1.* from t1 as s1, cte where s1.i1 = cte.i2 )
-select * from t1 as t;
+( select * from t2 union select s1.* from t2 as s1, cte where s1.i1 = cte.i2 )
+select * from t2 as t;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t ALL NULL NULL NULL NULL 4
+1 PRIMARY t ALL NULL NULL NULL NULL 2
drop table t1,t2;
#
# MDEV-22042: ANALYZE of query using stored function and recursive CTE
@@ -4500,6 +4500,93 @@ deallocate prepare stmt;
drop table folks;
set big_tables=@save_big_tables;
#
+# MDEV-26135: execution of PS for query with hanging recursive CTE
+#
+create table t1 (a int);
+insert into t1 values (5), (7);
+create table t2 (b int);
+insert into t2 values (3), (7), (1);
+with recursive r as (select a from t1 union select a+1 from r where a < 10)
+select * from t2;
+b
+3
+7
+1
+prepare stmt from "with recursive r as (select a from t1 union select a+1 from r where a < 10)
+select * from t2";
+execute stmt;
+b
+3
+7
+1
+execute stmt;
+b
+3
+7
+1
+deallocate prepare stmt;
+drop table t1,t2;
+#
+# MDEV-26189: Unknown column reference within hanging recursive CTE
+#
+create table t1 (a int);
+insert into t1 values (3), (7), (1);
+with recursive
+r as (select * from t1 union select s1.* from t1 as s1, r where s1.a = r.b)
+select * from t1 as t;
+ERROR 42S22: Unknown column 'r.b' in 'where clause'
+explain with recursive
+r as (select * from t1 union select s1.* from t1 as s1, r where s1.a = r.b)
+select * from t1 as t;
+ERROR 42S22: Unknown column 'r.b' in 'where clause'
+create procedure sp1() with recursive
+r as (select * from t1 union select s1.* from t1 as s1, r where s1.a = r.b)
+select * from t1 as t;
+call sp1();
+ERROR 42S22: Unknown column 'r.b' in 'where clause'
+call sp1();
+ERROR 42S22: Unknown column 'r.b' in 'where clause'
+with recursive
+r as (select * from t1 union select s1.* from t1 as s1, r where s1.b = r.a)
+select * from t1 as t;
+ERROR 42S22: Unknown column 's1.b' in 'where clause'
+explain with recursive
+r as (select * from t1 union select s1.* from t1 as s1, r where s1.b = r.a)
+select * from t1 as t;
+ERROR 42S22: Unknown column 's1.b' in 'where clause'
+create procedure sp2() with recursive
+r as (select * from t1 union select s1.* from t1 as s1, r where s1.b = r.a)
+select * from t1 as t;
+call sp2();
+ERROR 42S22: Unknown column 's1.b' in 'where clause'
+call sp2();
+ERROR 42S22: Unknown column 's1.b' in 'where clause'
+drop procedure sp1;
+drop procedure sp2;
+drop table t1;
+#
+# MDEV-26202: Recursive CTE used indirectly twice
+# (fixed by the patch forMDEV-26025)
+#
+with recursive
+rcte as ( SELECT 1 AS a
+UNION ALL
+SELECT cast(a + 1 as unsigned int) FROM rcte WHERE a < 3),
+cte1 AS (SELECT a FROM rcte),
+cte2 AS (SELECT a FROM cte1),
+cte3 AS ( SELECT a FROM cte2)
+SELECT * FROM cte2, cte3;
+a a
+1 1
+2 1
+3 1
+1 2
+2 2
+3 2
+1 3
+2 3
+3 3
+#
# End of 10.2 tests
#
#
diff --git a/mysql-test/main/cte_recursive.test b/mysql-test/main/cte_recursive.test
index 3b140b3cc6c..8ac6f841f6e 100644
--- a/mysql-test/main/cte_recursive.test
+++ b/mysql-test/main/cte_recursive.test
@@ -2590,8 +2590,8 @@ insert into t2 values (1,1),(2,2);
explain
with recursive cte as
- ( select * from t1 union select s1.* from t1 as s1, cte where s1.i1 = cte.i2 )
-select * from t1 as t;
+ ( select * from t2 union select s1.* from t2 as s1, cte where s1.i1 = cte.i2 )
+select * from t2 as t;
drop table t1,t2;
@@ -2855,6 +2855,85 @@ drop table folks;
set big_tables=@save_big_tables;
--echo #
+--echo # MDEV-26135: execution of PS for query with hanging recursive CTE
+--echo #
+
+create table t1 (a int);
+insert into t1 values (5), (7);
+create table t2 (b int);
+insert into t2 values (3), (7), (1);
+
+let $q=
+with recursive r as (select a from t1 union select a+1 from r where a < 10)
+select * from t2;
+
+eval $q;
+eval prepare stmt from "$q";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+drop table t1,t2;
+
+--echo #
+--echo # MDEV-26189: Unknown column reference within hanging recursive CTE
+--echo #
+
+create table t1 (a int);
+insert into t1 values (3), (7), (1);
+
+let $q1=
+with recursive
+ r as (select * from t1 union select s1.* from t1 as s1, r where s1.a = r.b)
+select * from t1 as t;
+
+--ERROR ER_BAD_FIELD_ERROR
+eval $q1;
+--ERROR ER_BAD_FIELD_ERROR
+eval explain $q1;
+
+eval create procedure sp1() $q1;
+--ERROR ER_BAD_FIELD_ERROR
+call sp1();
+--ERROR ER_BAD_FIELD_ERROR
+call sp1();
+
+let $q2=
+with recursive
+ r as (select * from t1 union select s1.* from t1 as s1, r where s1.b = r.a)
+select * from t1 as t;
+
+--ERROR ER_BAD_FIELD_ERROR
+eval $q2;
+--ERROR ER_BAD_FIELD_ERROR
+eval explain $q2;
+
+eval create procedure sp2() $q2;
+--ERROR ER_BAD_FIELD_ERROR
+call sp2();
+--ERROR ER_BAD_FIELD_ERROR
+call sp2();
+
+drop procedure sp1;
+drop procedure sp2;
+
+drop table t1;
+
+--echo #
+--echo # MDEV-26202: Recursive CTE used indirectly twice
+--echo # (fixed by the patch forMDEV-26025)
+--echo #
+
+with recursive
+ rcte as ( SELECT 1 AS a
+ UNION ALL
+ SELECT cast(a + 1 as unsigned int) FROM rcte WHERE a < 3),
+ cte1 AS (SELECT a FROM rcte),
+ cte2 AS (SELECT a FROM cte1),
+ cte3 AS ( SELECT a FROM cte2)
+SELECT * FROM cte2, cte3;
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/main/func_str.result b/mysql-test/main/func_str.result
index 7a6af68b1d8..a1522c473d3 100644
--- a/mysql-test/main/func_str.result
+++ b/mysql-test/main/func_str.result
@@ -5153,6 +5153,22 @@ c1
42
DROP TABLE t1, t2;
#
+# MDEV-25560 Creating table with certain generated column crashes server
+#
+CREATE TABLE t1 (i int, b int AS (RPAD(123,1)) stored);
+# Original case from the reporter
+CREATE TABLE crash_test_2 (
+DATA_VALUE CHAR(10) NULL,
+HAS_DATA BIT NOT NULL,
+TEST_COLUMN CHAR(10) AS (RPAD(CASE WHEN HAS_DATA = 1
+THEN DATA_VALUE ELSE NULL END, 10)) STORED);
+Warnings:
+Warning 1901 Function or expression 'rpad(case when `HAS_DATA` = 1 then `DATA_VALUE` else NULL end,10)' cannot be used in the GENERATED ALWAYS AS clause of `TEST_COLUMN`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+# Cleanup
+DROP TABLE t1;
+DROP TABLE crash_test_2;
+#
# End of 10.3 tests
#
#
diff --git a/mysql-test/main/func_str.test b/mysql-test/main/func_str.test
index ba5b671ca4f..efde77f21eb 100644
--- a/mysql-test/main/func_str.test
+++ b/mysql-test/main/func_str.test
@@ -2091,6 +2091,24 @@ DROP TABLE t1, t2;
--echo #
+--echo # MDEV-25560 Creating table with certain generated column crashes server
+--echo #
+
+CREATE TABLE t1 (i int, b int AS (RPAD(123,1)) stored);
+
+--echo # Original case from the reporter
+CREATE TABLE crash_test_2 (
+ DATA_VALUE CHAR(10) NULL,
+ HAS_DATA BIT NOT NULL,
+ TEST_COLUMN CHAR(10) AS (RPAD(CASE WHEN HAS_DATA = 1
+ THEN DATA_VALUE ELSE NULL END, 10)) STORED);
+
+--echo # Cleanup
+DROP TABLE t1;
+DROP TABLE crash_test_2;
+
+
+--echo #
--echo # End of 10.3 tests
--echo #
diff --git a/mysql-test/main/grant5.result b/mysql-test/main/grant5.result
index 9f6eb583e91..fa5a952a9c1 100644
--- a/mysql-test/main/grant5.result
+++ b/mysql-test/main/grant5.result
@@ -49,7 +49,7 @@ SHOW GRANTS FOR test_user;
Grants for test_user@%
GRANT `test_role` TO `test_user`@`%`
GRANT USAGE ON *.* TO `test_user`@`%`
-SET DEFAULT ROLE test_role FOR 'test_user'@'%'
+SET DEFAULT ROLE `test_role` FOR `test_user`@`%`
SET DEFAULT ROLE NONE for test_user;
SHOW GRANTS FOR test_user;
Grants for test_user@%
@@ -63,7 +63,7 @@ Grants for test_user@%
GRANT `test_role` TO `test_user`@`%`
GRANT USAGE ON *.* TO `test_user`@`%`
GRANT USAGE ON *.* TO `test_role`
-SET DEFAULT ROLE test_role FOR 'test_user'@'%'
+SET DEFAULT ROLE `test_role` FOR `test_user`@`%`
SET DEFAULT ROLE NONE;
SHOW GRANTS;
Grants for test_user@%
@@ -168,6 +168,23 @@ drop user 'user1'@'localhost';
drop user 'fetch'@'localhost';
drop user 'user-1'@'localhost';
drop user 'O\'Brien'@'localhost';
+#
+# MDEV-26080 SHOW GRANTS does not quote role names properly for DEFAULT ROLE
+#
+CREATE USER 'test-user';
+CREATE ROLE `r``o'l"e`;
+select user from mysql.user where is_role='Y';
+User
+r`o'l"e
+GRANT `r``o'l"e` TO 'test-user';
+SET DEFAULT ROLE `r``o'l"e` FOR 'test-user';
+SHOW GRANTS FOR 'test-user';
+Grants for test-user@%
+GRANT `r``o'l"e` TO `test-user`@`%`
+GRANT USAGE ON *.* TO `test-user`@`%`
+SET DEFAULT ROLE `r``o'l"e` FOR `test-user`@`%`
+DROP ROLE `r``o'l"e`;
+DROP USER 'test-user';
# End of 10.3 tests
create user u1@h identified with 'mysql_native_password' using 'pwd';
ERROR HY000: Password hash should be a 41-digit hexadecimal number
diff --git a/mysql-test/main/grant5.test b/mysql-test/main/grant5.test
index 9c3f20396c4..0b4a63ab075 100644
--- a/mysql-test/main/grant5.test
+++ b/mysql-test/main/grant5.test
@@ -124,6 +124,20 @@ drop user 'fetch'@'localhost';
drop user 'user-1'@'localhost';
drop user 'O\'Brien'@'localhost';
+--echo #
+--echo # MDEV-26080 SHOW GRANTS does not quote role names properly for DEFAULT ROLE
+--echo #
+
+CREATE USER 'test-user';
+CREATE ROLE `r``o'l"e`;
+select user from mysql.user where is_role='Y';
+GRANT `r``o'l"e` TO 'test-user';
+SET DEFAULT ROLE `r``o'l"e` FOR 'test-user';
+# it is expected that quotes won't be shown correctly
+SHOW GRANTS FOR 'test-user';
+DROP ROLE `r``o'l"e`;
+DROP USER 'test-user';
+
--echo # End of 10.3 tests
#
diff --git a/mysql-test/main/lock_multi_bug38499.test b/mysql-test/main/lock_multi_bug38499.test
index b812984e516..c489712e5d8 100644
--- a/mysql-test/main/lock_multi_bug38499.test
+++ b/mysql-test/main/lock_multi_bug38499.test
@@ -2,6 +2,9 @@
# MySQL >= 5.0
#
+# The test can take hours with valgrind
+--source include/not_valgrind.inc
+
# Save the initial number of concurrent sessions
--source include/count_sessions.inc
diff --git a/mysql-test/main/lock_multi_bug38691.test b/mysql-test/main/lock_multi_bug38691.test
index 881a0d8e502..9760c1a873a 100644
--- a/mysql-test/main/lock_multi_bug38691.test
+++ b/mysql-test/main/lock_multi_bug38691.test
@@ -4,6 +4,8 @@
# MySQL >= 5.0
#
+# The test can take hours with valgrind
+--source include/not_valgrind.inc
# Save the initial number of concurrent sessions
--source include/count_sessions.inc
diff --git a/mysql-test/main/mysql_client_test.result b/mysql-test/main/mysql_client_test.result
index 420e2fc8e3c..dbc1feaa23b 100644
--- a/mysql-test/main/mysql_client_test.result
+++ b/mysql-test/main/mysql_client_test.result
@@ -127,6 +127,11 @@ Data:
EOF
mysql_stmt_next_result(): 0; field_count: 0
# ------------------------------------
+# cat MYSQL_TMP_DIR/test_mdev26145.out.log
+# ------------------------------------
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def MAX(a) MAX(a) 3 11 0 Y 32768 0 63
+# ------------------------------------
# cat MYSQL_TMP_DIR/test_explain_meta.out.log
diff --git a/mysql-test/main/mysql_client_test.test b/mysql-test/main/mysql_client_test.test
index 7885dc5c0d7..9fb7bcd81c9 100644
--- a/mysql-test/main/mysql_client_test.test
+++ b/mysql-test/main/mysql_client_test.test
@@ -36,6 +36,10 @@ echo ok;
--echo # ------------------------------------
--cat_file $MYSQL_TMP_DIR/test_wl4435.out.log
--echo # ------------------------------------
+--echo # cat MYSQL_TMP_DIR/test_mdev26145.out.log
+--echo # ------------------------------------
+--cat_file $MYSQL_TMP_DIR/test_mdev26145.out.log
+--echo # ------------------------------------
--echo
--echo
diff --git a/mysql-test/main/mysql_upgrade.result b/mysql-test/main/mysql_upgrade.result
index 596b2673d82..af3688dca6b 100644
--- a/mysql-test/main/mysql_upgrade.result
+++ b/mysql-test/main/mysql_upgrade.result
@@ -758,7 +758,7 @@ GRANT `aRole` TO `root`@`localhost` WITH ADMIN OPTION
GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION
GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION
GRANT USAGE ON *.* TO `aRole`
-SET DEFAULT ROLE aRole FOR 'root'@'localhost'
+SET DEFAULT ROLE `aRole` FOR `root`@`localhost`
SET DEFAULT ROLE NONE;
SHOW GRANTS;
Grants for root@localhost
diff --git a/mysql-test/main/order_by_innodb.result b/mysql-test/main/order_by_innodb.result
index 9cdf9800cee..14b9b861a14 100644
--- a/mysql-test/main/order_by_innodb.result
+++ b/mysql-test/main/order_by_innodb.result
@@ -147,4 +147,56 @@ i n
656 eight
set optimizer_switch= @save_optimizer_switch;
DROP TABLE t1,t2,t3;
+#
+# MDEV-25858: Query results are incorrect when indexes are added
+#
+CREATE TABLE t1 (id int NOT NULL PRIMARY KEY) engine=innodb;
+insert into t1 values (1),(2),(3);
+CREATE TABLE t2 (
+id int NOT NULL PRIMARY KEY,
+id2 int NOT NULL,
+d1 datetime,
+d2 timestamp NOT NULL,
+KEY id2 (id2)
+) engine=innodb;
+insert into t2 values
+(1,2,'2019-03-05 00:00:00','2019-03-06 00:00:00'),
+(2,3,'2019-03-05 00:00:00','2019-03-06 00:00:00'),
+(3,3,'2019-03-06 00:00:00','2019-03-05 00:00:00');
+select
+t1.id,t2.id
+from
+t1 left join
+t2 on t2.id2 = t1.id and
+t2.id = (select dd.id
+from t2 dd
+where
+dd.id2 = t1.id and
+d1 > '2019-02-06 00:00:00'
+ order by
+dd.d1 desc, dd.d2 desc, dd.id desc limit 1
+);
+id id
+1 NULL
+2 1
+3 3
+create index for_latest_sort on t2 (d1 desc, d2 desc, id desc);
+select
+t1.id,t2.id
+from
+t1 left join
+t2 on t2.id2 = t1.id and
+t2.id = (select dd.id
+from t2 dd
+where
+dd.id2 = t1.id and
+d1 > '2019-02-06 00:00:00'
+ order by
+dd.d1 desc, dd.d2 desc, dd.id desc limit 1
+);
+id id
+1 NULL
+2 1
+3 3
+drop table t1,t2;
# End of 10.2 tests
diff --git a/mysql-test/main/order_by_innodb.test b/mysql-test/main/order_by_innodb.test
index f4c738263ae..97c043b8dbc 100644
--- a/mysql-test/main/order_by_innodb.test
+++ b/mysql-test/main/order_by_innodb.test
@@ -135,4 +135,55 @@ set optimizer_switch= @save_optimizer_switch;
DROP TABLE t1,t2,t3;
+--echo #
+--echo # MDEV-25858: Query results are incorrect when indexes are added
+--echo #
+
+CREATE TABLE t1 (id int NOT NULL PRIMARY KEY) engine=innodb;
+insert into t1 values (1),(2),(3);
+
+CREATE TABLE t2 (
+ id int NOT NULL PRIMARY KEY,
+ id2 int NOT NULL,
+ d1 datetime,
+ d2 timestamp NOT NULL,
+ KEY id2 (id2)
+) engine=innodb;
+
+insert into t2 values
+ (1,2,'2019-03-05 00:00:00','2019-03-06 00:00:00'),
+ (2,3,'2019-03-05 00:00:00','2019-03-06 00:00:00'),
+ (3,3,'2019-03-06 00:00:00','2019-03-05 00:00:00');
+
+select
+ t1.id,t2.id
+from
+ t1 left join
+ t2 on t2.id2 = t1.id and
+ t2.id = (select dd.id
+ from t2 dd
+ where
+ dd.id2 = t1.id and
+ d1 > '2019-02-06 00:00:00'
+ order by
+ dd.d1 desc, dd.d2 desc, dd.id desc limit 1
+ );
+
+create index for_latest_sort on t2 (d1 desc, d2 desc, id desc);
+
+select
+ t1.id,t2.id
+from
+ t1 left join
+ t2 on t2.id2 = t1.id and
+ t2.id = (select dd.id
+ from t2 dd
+ where
+ dd.id2 = t1.id and
+ d1 > '2019-02-06 00:00:00'
+ order by
+ dd.d1 desc, dd.d2 desc, dd.id desc limit 1
+ );
+drop table t1,t2;
+
--echo # End of 10.2 tests
diff --git a/mysql-test/main/prepare.result b/mysql-test/main/prepare.result
index c1a2969212b..cfe6603dbbe 100644
--- a/mysql-test/main/prepare.result
+++ b/mysql-test/main/prepare.result
@@ -50,3 +50,17 @@ t1_first
deallocate prepare stmt1;
deallocate prepare stmt2;
drop table t1;
+#
+# MDEV-25808 PREPARE/EXECUTE makes signed integer out of unsigned
+#
+prepare p1 from 'select concat(?)';
+execute p1 using 17864960750176564435;
+concat(?)
+17864960750176564435
+prepare p1 from 'select SQRT(?) is not null';
+execute p1 using 17864960750176564435;
+SQRT(?) is not null
+1
+#
+# End of 10.3 tests
+#
diff --git a/mysql-test/main/prepare.test b/mysql-test/main/prepare.test
index eaab376a5a2..4d1573eb0c8 100644
--- a/mysql-test/main/prepare.test
+++ b/mysql-test/main/prepare.test
@@ -40,3 +40,15 @@ execute stmt2;
deallocate prepare stmt1;
deallocate prepare stmt2;
drop table t1;
+
+--echo #
+--echo # MDEV-25808 PREPARE/EXECUTE makes signed integer out of unsigned
+--echo #
+prepare p1 from 'select concat(?)';
+execute p1 using 17864960750176564435;
+prepare p1 from 'select SQRT(?) is not null';
+execute p1 using 17864960750176564435;
+
+--echo #
+--echo # End of 10.3 tests
+--echo #
diff --git a/mysql-test/main/ps.result b/mysql-test/main/ps.result
index 3df72cf24f7..7ca8499ba76 100644
--- a/mysql-test/main/ps.result
+++ b/mysql-test/main/ps.result
@@ -5576,6 +5576,20 @@ DROP TABLE t1, t2, t3;
# End of 10.2 tests
#
#
+# MDEV-26147: The test main.sp-row fails in case it is run in PS mode
+#
+CREATE PROCEDURE p1(a ROW(a INT,b INT))
+BEGIN
+SELECT a.a, a.b;
+END;
+$$
+PREPARE stmt FROM 'CALL p1(ROW(10, 20))';
+EXECUTE stmt;
+a.a a.b
+10 20
+DEALLOCATE PREPARE stmt;
+DROP PROCEDURE p1;
+#
# MDEV-19263: Server crashes in mysql_handle_single_derived
# upon 2nd execution of PS
#
diff --git a/mysql-test/main/ps.test b/mysql-test/main/ps.test
index 837fa6f2b6e..a65c54c8788 100644
--- a/mysql-test/main/ps.test
+++ b/mysql-test/main/ps.test
@@ -4994,6 +4994,22 @@ DROP TABLE t1, t2, t3;
--echo #
--echo #
+--echo # MDEV-26147: The test main.sp-row fails in case it is run in PS mode
+--echo #
+DELIMITER $$;
+CREATE PROCEDURE p1(a ROW(a INT,b INT))
+BEGIN
+ SELECT a.a, a.b;
+END;
+$$
+DELIMITER ;$$
+PREPARE stmt FROM 'CALL p1(ROW(10, 20))';
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+DROP PROCEDURE p1;
+
+--echo #
--echo # MDEV-19263: Server crashes in mysql_handle_single_derived
--echo # upon 2nd execution of PS
--echo #
diff --git a/mysql-test/main/selectivity_innodb.result b/mysql-test/main/selectivity_innodb.result
index a87d0f53bfe..2159989597a 100644
--- a/mysql-test/main/selectivity_innodb.result
+++ b/mysql-test/main/selectivity_innodb.result
@@ -2098,6 +2098,57 @@ drop view v1;
#
# End of 10.1 tests
#
+#
+# MDEV-17783: AddressSanitizer: stack-buffer-overflow in table_cond_selectivity
+#
+set
+@tmp_jcl=@@join_cache_level,
+@tmp_sel=@@optimizer_use_condition_selectivity;
+set
+join_cache_level=3,
+optimizer_use_condition_selectivity=2;
+CREATE TABLE t1 (
+c1 int, c2 int, c3 int, c4 int, c5 int, c6 int, c7 int, c8 int, c9 int, c10 int,
+c11 int, c12 int, c13 int, c14 int, c15 int, c16 int, c17 int, c18 int, c19 int,
+c20 int, c21 int, c22 int, c23 int, c24 int, c25 int, c26 int, c27 int, c28 int,
+c29 int, c30 int, c31 int, c32 int, c33 int, c34 int
+) ENGINE=InnoDB;
+SELECT * FROM t1
+WHERE
+(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
+c11, c12, c13, c14, c15, c16, c17, c18, c19,
+c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,
+c30, c31, c32, c33, c34) IN (SELECT * FROM t1) ;
+c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34
+set
+join_cache_level=@tmp_jcl,
+optimizer_use_condition_selectivity=@tmp_sel;
+drop table t1;
+#
+# MDEV-25013: SIGSEGV in best_extension_by_limited_search | SIGSEGV in restore_prev_nj_state
+#
+SET join_cache_level=3;
+CREATE TABLE t1 (
+TEXT1 TEXT, TEXT2 TEXT, TEXT3 TEXT, TEXT4 TEXT, TEXT5 TEXT,
+TEXT6 TEXT, TEXT7 TEXT, TEXT8 TEXT, TEXT9 TEXT, TEXT10 TEXT,
+TEXT11 TEXT, TEXT12 TEXT,TEXT13 TEXT,TEXT14 TEXT,TEXT15 TEXT,
+TEXT16 TEXT,TEXT17 TEXT,TEXT18 TEXT,TEXT19 TEXT,TEXT20 TEXT,
+TEXT21 TEXT,TEXT22 TEXT,TEXT23 TEXT,TEXT24 TEXT,TEXT25 TEXT,
+TEXT26 TEXT,TEXT27 TEXT,TEXT28 TEXT,TEXT29 TEXT,TEXT30 TEXT,
+TEXT31 TEXT,TEXT32 TEXT,TEXT33 TEXT,TEXT34 TEXT,TEXT35 TEXT,
+TEXT36 TEXT,TEXT37 TEXT,TEXT38 TEXT,TEXT39 TEXT,TEXT40 TEXT,
+TEXT41 TEXT,TEXT42 TEXT,TEXT43 TEXT,TEXT44 TEXT,TEXT45 TEXT,
+TEXT46 TEXT,TEXT47 TEXT,TEXT48 TEXT,TEXT49 TEXT,TEXT50 TEXT
+) ENGINE=InnoDB;
+EXPLAIN SELECT 1 FROM t1 NATURAL JOIN t1 AS t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t2 hash_ALL NULL #hash#$hj 150 test.t1.TEXT1,test.t1.TEXT2,test.t1.TEXT3,test.t1.TEXT4,test.t1.TEXT5,test.t1.TEXT6,test.t1.TEXT7,test.t1.TEXT8,test.t1.TEXT9,test.t1.TEXT10,test.t1.TEXT11,test.t1.TEXT12,test.t1.TEXT13,test.t1.TEXT14,test.t1.TEXT15,test.t1.TEXT16,test.t1.TEXT17,test.t1.TEXT18,test.t1.TEXT19,test.t1.TEXT20,test.t1.TEXT21,test.t1.TEXT22,test.t1.TEXT23,test.t1.TEXT24,test.t1.TEXT25,test.t1.TEXT26,test.t1.TEXT27,test.t1.TEXT28,test.t1.TEXT29,test.t1.TEXT30,test.t1.TEXT31,test.t1.TEXT32,test.t1.TEXT33,test.t1.TEXT34,test.t1.TEXT35,test.t1.TEXT36,test.t1.TEXT37,test.t1.TEXT38,test.t1.TEXT39,test.t1.TEXT40,test.t1.TEXT41,test.t1.TEXT42,test.t1.TEXT43,test.t1.TEXT44,test.t1.TEXT45,test.t1.TEXT46,test.t1.TEXT47,test.t1.TEXT48,test.t1.TEXT49,test.t1.TEXT50 1 Using where; Using join buffer (flat, BNLH join)
+set join_cache_level=@tmp_jcl;
+drop table t1;
+#
+# End of 10.1 tests
+#
set use_stat_tables= @tmp_ust;
set optimizer_use_condition_selectivity= @tmp_oucs;
set @@global.histogram_size=@save_histogram_size;
diff --git a/mysql-test/main/selectivity_innodb.test b/mysql-test/main/selectivity_innodb.test
index 6c457e2848b..057a36fcf62 100644
--- a/mysql-test/main/selectivity_innodb.test
+++ b/mysql-test/main/selectivity_innodb.test
@@ -174,6 +174,61 @@ drop view v1;
--echo # End of 10.1 tests
--echo #
+--echo #
+--echo # MDEV-17783: AddressSanitizer: stack-buffer-overflow in table_cond_selectivity
+--echo #
+
+set
+ @tmp_jcl=@@join_cache_level,
+ @tmp_sel=@@optimizer_use_condition_selectivity;
+set
+ join_cache_level=3,
+ optimizer_use_condition_selectivity=2;
+
+CREATE TABLE t1 (
+ c1 int, c2 int, c3 int, c4 int, c5 int, c6 int, c7 int, c8 int, c9 int, c10 int,
+ c11 int, c12 int, c13 int, c14 int, c15 int, c16 int, c17 int, c18 int, c19 int,
+ c20 int, c21 int, c22 int, c23 int, c24 int, c25 int, c26 int, c27 int, c28 int,
+ c29 int, c30 int, c31 int, c32 int, c33 int, c34 int
+) ENGINE=InnoDB;
+
+SELECT * FROM t1
+WHERE
+ (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
+ c11, c12, c13, c14, c15, c16, c17, c18, c19,
+ c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,
+ c30, c31, c32, c33, c34) IN (SELECT * FROM t1) ;
+
+set
+ join_cache_level=@tmp_jcl,
+ optimizer_use_condition_selectivity=@tmp_sel;
+drop table t1;
+
+--echo #
+--echo # MDEV-25013: SIGSEGV in best_extension_by_limited_search | SIGSEGV in restore_prev_nj_state
+--echo #
+
+SET join_cache_level=3;
+CREATE TABLE t1 (
+ TEXT1 TEXT, TEXT2 TEXT, TEXT3 TEXT, TEXT4 TEXT, TEXT5 TEXT,
+ TEXT6 TEXT, TEXT7 TEXT, TEXT8 TEXT, TEXT9 TEXT, TEXT10 TEXT,
+ TEXT11 TEXT, TEXT12 TEXT,TEXT13 TEXT,TEXT14 TEXT,TEXT15 TEXT,
+ TEXT16 TEXT,TEXT17 TEXT,TEXT18 TEXT,TEXT19 TEXT,TEXT20 TEXT,
+ TEXT21 TEXT,TEXT22 TEXT,TEXT23 TEXT,TEXT24 TEXT,TEXT25 TEXT,
+ TEXT26 TEXT,TEXT27 TEXT,TEXT28 TEXT,TEXT29 TEXT,TEXT30 TEXT,
+ TEXT31 TEXT,TEXT32 TEXT,TEXT33 TEXT,TEXT34 TEXT,TEXT35 TEXT,
+ TEXT36 TEXT,TEXT37 TEXT,TEXT38 TEXT,TEXT39 TEXT,TEXT40 TEXT,
+ TEXT41 TEXT,TEXT42 TEXT,TEXT43 TEXT,TEXT44 TEXT,TEXT45 TEXT,
+ TEXT46 TEXT,TEXT47 TEXT,TEXT48 TEXT,TEXT49 TEXT,TEXT50 TEXT
+) ENGINE=InnoDB;
+EXPLAIN SELECT 1 FROM t1 NATURAL JOIN t1 AS t2;
+
+set join_cache_level=@tmp_jcl;
+drop table t1;
+--echo #
+--echo # End of 10.1 tests
+--echo #
+
set use_stat_tables= @tmp_ust;
set optimizer_use_condition_selectivity= @tmp_oucs;
set @@global.histogram_size=@save_histogram_size;
diff --git a/mysql-test/main/selectivity_no_engine.result b/mysql-test/main/selectivity_no_engine.result
index 743dcd04695..b6830e91f61 100644
--- a/mysql-test/main/selectivity_no_engine.result
+++ b/mysql-test/main/selectivity_no_engine.result
@@ -294,6 +294,26 @@ SELECT * FROM t1 WHERE t1.d = 0 AND t1.p = '1' AND t1.i != '-1' AND t1.n = 'some
i n d p
set optimizer_use_condition_selectivity= @tmp_mdev8779;
DROP TABLE t1;
+#
+# MDEV-23937: SIGSEGV in looped best_extension_by_limited_search from greedy_search
+# (Testcase only)
+#
+set
+@tmp_jcl= @@join_cache_level,
+@tmp_ucs= @@optimizer_use_condition_selectivity;
+set
+join_cache_level=3,
+optimizer_use_condition_selectivity=2;
+CREATE TABLE t1 AS SELECT * FROM mysql.user;
+CREATE TABLE t3 (b VARCHAR (1));
+CREATE TABLE t2 (c2 INT);
+INSERT INTO t2 VALUES (1);
+EXPLAIN
+SELECT * FROM t1 AS a NATURAL JOIN t1 AS b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE a ALL NULL NULL NULL NULL 5 Using where
+1 SIMPLE b hash_ALL NULL #hash#$hj 612 test.a.Host,test.a.User,test.a.Password,test.a.Select_priv,test.a.Insert_priv,test.a.Update_priv,test.a.Delete_priv,test.a.Create_priv,test.a.Drop_priv,test.a.Reload_priv,test.a.Shutdown_priv,test.a.Process_priv,test.a.File_priv,test.a.Grant_priv,test.a.References_priv,test.a.Index_priv,test.a.Alter_priv,test.a.Show_db_priv,test.a.Super_priv,test.a.Create_tmp_table_priv,test.a.Lock_tables_priv,test.a.Execute_priv,test.a.Repl_slave_priv,test.a.Repl_client_priv,test.a.Create_view_priv,test.a.Show_view_priv,test.a.Create_routine_priv,test.a.Alter_routine_priv,test.a.Create_user_priv,test.a.Event_priv,test.a.Trigger_priv,test.a.Create_tablespace_priv,test.a.Delete_history_priv,test.a.ssl_type,test.a.ssl_cipher,test.a.x509_issuer,test.a.x509_subject,test.a.max_questions,test.a.max_updates,test.a.max_connections,test.a.max_user_connections,test.a.plugin,test.a.authentication_string,test.a.password_expired,test.a.is_role,test.a.default_role,test.a.max_statement_time 5 Using where; Using join buffer (flat, BNLH join)
+DROP TABLE t1,t2,t3;
#
# End of the test file
#
diff --git a/mysql-test/main/selectivity_no_engine.test b/mysql-test/main/selectivity_no_engine.test
index c0f41ca7fb2..5bc78e03781 100644
--- a/mysql-test/main/selectivity_no_engine.test
+++ b/mysql-test/main/selectivity_no_engine.test
@@ -229,6 +229,27 @@ SELECT * FROM t1 WHERE t1.d = 0 AND t1.p = '1' AND t1.i != '-1' AND t1.n = 'some
set optimizer_use_condition_selectivity= @tmp_mdev8779;
DROP TABLE t1;
+--echo #
+--echo # MDEV-23937: SIGSEGV in looped best_extension_by_limited_search from greedy_search
+--echo # (Testcase only)
+--echo #
+set
+ @tmp_jcl= @@join_cache_level,
+ @tmp_ucs= @@optimizer_use_condition_selectivity;
+set
+ join_cache_level=3,
+ optimizer_use_condition_selectivity=2;
+
+CREATE TABLE t1 AS SELECT * FROM mysql.user;
+CREATE TABLE t3 (b VARCHAR (1));
+CREATE TABLE t2 (c2 INT);
+INSERT INTO t2 VALUES (1);
+
+EXPLAIN
+SELECT * FROM t1 AS a NATURAL JOIN t1 AS b;
+
+DROP TABLE t1,t2,t3;
+
--echo #
--echo # End of the test file
--echo #
diff --git a/mysql-test/main/skip_name_resolve.result b/mysql-test/main/skip_name_resolve.result
index 9a903ebf472..fe71b714cbc 100644
--- a/mysql-test/main/skip_name_resolve.result
+++ b/mysql-test/main/skip_name_resolve.result
@@ -39,4 +39,24 @@ SET @@LOCAL.skip_name_resolve=0;
ERROR HY000: Variable 'skip_name_resolve' is a read only variable
SET @@GLOBAL.skip_name_resolve=0;
ERROR HY000: Variable 'skip_name_resolve' is a read only variable
-End of 5.1 tests
+#
+# End of 5.1 tests
+#
+#
+# MDEV-26081 set role crashes when a hostname cannot be resolved
+#
+create user u1@`%`;
+create role r1;
+create role r2;
+grant r2 to r1;
+grant r1 to u1@`%`;
+connect u1,127.0.0.1,u1,,,$MASTER_MYPORT;
+set role r2;
+ERROR OP000: User `u1`@`%` has not been granted role `r2`
+disconnect u1;
+connection default;
+drop user u1@`%`;
+drop role r1, r2;
+#
+# End of 10.2 tests
+#
diff --git a/mysql-test/main/skip_name_resolve.test b/mysql-test/main/skip_name_resolve.test
index b0c5118f970..0ff19092b82 100644
--- a/mysql-test/main/skip_name_resolve.test
+++ b/mysql-test/main/skip_name_resolve.test
@@ -50,4 +50,28 @@ SET @@LOCAL.skip_name_resolve=0;
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
SET @@GLOBAL.skip_name_resolve=0;
---echo End of 5.1 tests
+--echo #
+--echo # End of 5.1 tests
+--echo #
+
+--echo #
+--echo # MDEV-26081 set role crashes when a hostname cannot be resolved
+--echo #
+
+create user u1@`%`;
+create role r1;
+create role r2;
+grant r2 to r1;
+grant r1 to u1@`%`;
+
+connect u1,127.0.0.1,u1,,,$MASTER_MYPORT;
+error ER_INVALID_ROLE;
+set role r2;
+disconnect u1;
+connection default;
+drop user u1@`%`;
+drop role r1, r2;
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
diff --git a/mysql-test/main/table_value_constr.result b/mysql-test/main/table_value_constr.result
index 0914645efbc..7cbec119a81 100644
--- a/mysql-test/main/table_value_constr.result
+++ b/mysql-test/main/table_value_constr.result
@@ -3062,6 +3062,44 @@ a
2
3
drop table t1;
+#
+# MDEV-25484: Derived table using TVC with LIMIT and ORDER BY
+#
+create table t1 (a int);
+insert into t1 values (3), (7), (1);
+select * from ( (select * from t1 limit 2) order by 1 desc) as dt;
+a
+3
+7
+(values (3), (7), (1) limit 2) order by 1 desc;
+3
+7
+3
+select * from ( (values (3), (7), (1) limit 2) order by 1 desc) as dt;
+3
+3
+7
+select * from ( select * from t1 order by 1 limit 2 ) as dt;
+a
+1
+3
+values (3),(7),(1) order by 1 limit 2;
+3
+1
+3
+select * from ( values (3),(7),(1) order by 1 limit 2 ) as dt;
+3
+1
+3
+values (3),(7),(1) union values (2),(4) order by 1 limit 2;
+3
+1
+2
+select * from (values (3),(7),(1) union values (2),(4) order by 1 limit 2) as dt;
+3
+1
+2
+drop table t1;
End of 10.3 tests
#
# MDEV-22610 Crash in INSERT INTO t1 (VALUES (DEFAULT) UNION VALUES (DEFAULT))
diff --git a/mysql-test/main/table_value_constr.test b/mysql-test/main/table_value_constr.test
index 49e1c7c18c6..d131022e2e0 100644
--- a/mysql-test/main/table_value_constr.test
+++ b/mysql-test/main/table_value_constr.test
@@ -1628,6 +1628,28 @@ select * from t1;
drop table t1;
+
+--echo #
+--echo # MDEV-25484: Derived table using TVC with LIMIT and ORDER BY
+--echo #
+
+create table t1 (a int);
+insert into t1 values (3), (7), (1);
+
+select * from ( (select * from t1 limit 2) order by 1 desc) as dt;
+(values (3), (7), (1) limit 2) order by 1 desc;
+select * from ( (values (3), (7), (1) limit 2) order by 1 desc) as dt;
+
+
+select * from ( select * from t1 order by 1 limit 2 ) as dt;
+values (3),(7),(1) order by 1 limit 2;
+select * from ( values (3),(7),(1) order by 1 limit 2 ) as dt;
+
+values (3),(7),(1) union values (2),(4) order by 1 limit 2;
+select * from (values (3),(7),(1) union values (2),(4) order by 1 limit 2) as dt;
+
+drop table t1;
+
--echo End of 10.3 tests
--echo #
diff --git a/mysql-test/main/union.result b/mysql-test/main/union.result
index 52bc3ccb0dc..fb1a2e35eb2 100644
--- a/mysql-test/main/union.result
+++ b/mysql-test/main/union.result
@@ -1612,7 +1612,7 @@ NULL binary(0) YES NULL
CREATE TABLE t5 SELECT NULL UNION SELECT NULL;
DESC t5;
Field Type Null Key Default Extra
-NULL null YES NULL
+NULL binary(0) YES NULL
CREATE TABLE t6
SELECT * FROM (SELECT * FROM (SELECT NULL)a) b UNION SELECT a FROM t1;
DESC t6;
@@ -2650,5 +2650,34 @@ CAST(1 AS UNSIGNED)
1
1
#
+# MDEV-24511 null field is created with CREATE..SELECT
+#
+set @save_default_storage_engine=@@default_storage_engine;
+SET @@default_storage_engine=MEMORY;
+CREATE TABLE t1 SELECT NULL UNION SELECT NULL;
+ALTER TABLE t1 ADD INDEX (`PRIMARY`);
+ERROR 42000: Key column 'PRIMARY' doesn't exist in table
+CREATE TABLE t2 SELECT NULL;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `NULL` binary(0) DEFAULT NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1
+CREATE TABLE t3 SELECT NULL UNION SELECT NULL;
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `NULL` binary(0) DEFAULT NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1
+CREATE OR REPLACE TABLE t4 SELECT NULL UNION SELECT NULL;
+SHOW CREATE TABLE t4;
+Table Create Table
+t4 CREATE TABLE `t4` (
+ `NULL` binary(0) DEFAULT NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1
+ALTER TABLE t4 ADD INDEX (`NULL`);
+DROP TABLE t1, t2, t3, t4;
+set @@default_storage_engine=@save_default_storage_engine;
+#
# End of 10.3 tests
#
diff --git a/mysql-test/main/union.test b/mysql-test/main/union.test
index 2e5a04a27f4..a7adc347a53 100644
--- a/mysql-test/main/union.test
+++ b/mysql-test/main/union.test
@@ -1884,5 +1884,30 @@ SELECT CAST(1 AS UNSIGNED) UNION ALL SELECT CAST(1 AS SIGNED);
--enable_ps_protocol
--echo #
+--echo # MDEV-24511 null field is created with CREATE..SELECT
+--echo #
+
+set @save_default_storage_engine=@@default_storage_engine;
+SET @@default_storage_engine=MEMORY;
+
+CREATE TABLE t1 SELECT NULL UNION SELECT NULL;
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+ALTER TABLE t1 ADD INDEX (`PRIMARY`);
+
+CREATE TABLE t2 SELECT NULL;
+SHOW CREATE TABLE t2;
+
+CREATE TABLE t3 SELECT NULL UNION SELECT NULL;
+SHOW CREATE TABLE t3;
+
+CREATE OR REPLACE TABLE t4 SELECT NULL UNION SELECT NULL;
+SHOW CREATE TABLE t4;
+ALTER TABLE t4 ADD INDEX (`NULL`);
+
+DROP TABLE t1, t2, t3, t4;
+
+set @@default_storage_engine=@save_default_storage_engine;
+
+--echo #
--echo # End of 10.3 tests
--echo #
diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result
index cf7fd5639ce..d4a5ac63216 100644
--- a/mysql-test/main/win.result
+++ b/mysql-test/main/win.result
@@ -3911,6 +3911,293 @@ sum(i) over () IN ( SELECT 1 FROM t1 a)
0
DROP TABLE t1;
#
+# MDEV-25565: 2-nd call of SP with SELECT from view / derived table / CTE
+# returning the result of calculation of 2 window
+# functions that use the same window specification
+#
+create table t1 (a int);
+insert into t1 values (3), (7), (1), (7), (1), (1), (3), (1), (5);
+create view v2 as select a from t1 group by a;
+create view v1 as select * from v2;
+create procedure sp1() select v1.a,
+sum(v1.a) over (partition by v1.a order by v1.a) as k,
+avg(v1.a) over (partition by v1.a order by v1.a) as m
+from v1;
+call sp1();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+call sp1();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+prepare stmt from "select v1.a,
+sum(v1.a) over (partition by v1.a order by v1.a) as k,
+avg(v1.a) over (partition by v1.a order by v1.a) as m
+from v1";
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+deallocate prepare stmt;
+create procedure sp2() select * from
+( select dt1.a,
+sum(dt1.a) over (partition by dt1.a order by dt1.a) as k,
+avg(dt1.a) over (partition by dt1.a order by dt1.a) as m
+from (select * from v2) as dt1
+) as dt;
+call sp2();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+call sp2();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+prepare stmt from "select * from
+( select dt1.a,
+sum(dt1.a) over (partition by dt1.a order by dt1.a) as k,
+avg(dt1.a) over (partition by dt1.a order by dt1.a) as m
+from (select * from v2) as dt1
+) as dt";
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+deallocate prepare stmt;
+create procedure sp3() select * from
+( select dt1.a,
+sum(dt1.a) over (partition by dt1.a order by dt1.a) as k,
+avg(dt1.a) over (partition by dt1.a order by dt1.a) as m
+from ( select * from (select * from t1 group by a) as dt2 ) as dt1
+) as dt;
+call sp3();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+call sp3();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+prepare stmt from "select * from
+( select dt1.a,
+sum(dt1.a) over (partition by dt1.a order by dt1.a) as k,
+avg(dt1.a) over (partition by dt1.a order by dt1.a) as m
+from ( select * from (select * from t1 group by a) as dt2 ) as dt1
+) as dt";
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+deallocate prepare stmt;
+create procedure sp4() with cte1 as (select * from (select * from t1 group by a) as dt2),
+cte as
+( select cte1.a,
+sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+from cte1 )
+select * from cte;
+call sp4();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+call sp4();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+prepare stmt from "with cte1 as (select * from (select * from t1 group by a) as dt2),
+cte as
+( select cte1.a,
+sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+from cte1 )
+select * from cte";
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+deallocate prepare stmt;
+create procedure sp5() with cte1 as (select * from v2),
+cte as
+( select cte1.a,
+sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+from cte1 )
+select * from cte;
+call sp5();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+call sp5();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+prepare stmt from "with cte1 as (select * from v2),
+cte as
+( select cte1.a,
+sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+from cte1 )
+select * from cte";
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+deallocate prepare stmt;
+create procedure sp6() with
+cte1 as (with cte2 as (select * from t1 group by a) select * from cte2),
+cte as
+( select cte1.a,
+sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+from cte1 )
+select * from cte;
+call sp6();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+call sp6();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+prepare stmt from "with
+cte1 as (with cte2 as (select * from t1 group by a) select * from cte2),
+cte as
+( select cte1.a,
+sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+from cte1 )
+select * from cte";
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+deallocate prepare stmt;
+create procedure sp7() with
+cte2 as (select * from v1),
+cte1 as (select * from cte2),
+cte as
+( select cte1.a,
+sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+from cte1 )
+select * from cte;
+call sp7();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+call sp7();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+prepare stmt from "with
+cte2 as (select * from v1),
+cte1 as (select * from cte2),
+cte as
+( select cte1.a,
+sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+from cte1 )
+select * from cte";
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+deallocate prepare stmt;
+drop procedure sp1;
+drop procedure sp2;
+drop procedure sp3;
+drop procedure sp4;
+drop procedure sp5;
+drop procedure sp6;
+drop procedure sp7;
+drop view v1,v2;
+drop table t1;
+#
# End of 10.2 tests
#
#
diff --git a/mysql-test/main/win.test b/mysql-test/main/win.test
index 356eac8f006..2b3ce469990 100644
--- a/mysql-test/main/win.test
+++ b/mysql-test/main/win.test
@@ -2557,6 +2557,153 @@ SELECT sum(i) over () IN ( SELECT 1 FROM t1 a) FROM t1;
DROP TABLE t1;
--echo #
+--echo # MDEV-25565: 2-nd call of SP with SELECT from view / derived table / CTE
+--echo # returning the result of calculation of 2 window
+--echo # functions that use the same window specification
+--echo #
+
+create table t1 (a int);
+insert into t1 values (3), (7), (1), (7), (1), (1), (3), (1), (5);
+
+create view v2 as select a from t1 group by a;
+create view v1 as select * from v2;
+
+let $q1=
+select v1.a,
+ sum(v1.a) over (partition by v1.a order by v1.a) as k,
+ avg(v1.a) over (partition by v1.a order by v1.a) as m
+from v1;
+
+eval create procedure sp1() $q1;
+call sp1();
+call sp1();
+
+eval prepare stmt from "$q1";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+let $q2=
+select * from
+ ( select dt1.a,
+ sum(dt1.a) over (partition by dt1.a order by dt1.a) as k,
+ avg(dt1.a) over (partition by dt1.a order by dt1.a) as m
+ from (select * from v2) as dt1
+ ) as dt;
+
+eval create procedure sp2() $q2;
+call sp2();
+call sp2();
+
+eval prepare stmt from "$q2";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+let $q3=
+select * from
+ ( select dt1.a,
+ sum(dt1.a) over (partition by dt1.a order by dt1.a) as k,
+ avg(dt1.a) over (partition by dt1.a order by dt1.a) as m
+ from ( select * from (select * from t1 group by a) as dt2 ) as dt1
+ ) as dt;
+
+eval create procedure sp3() $q3;
+call sp3();
+call sp3();
+
+eval prepare stmt from "$q3";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+let $q4=
+with cte1 as (select * from (select * from t1 group by a) as dt2),
+ cte as
+ ( select cte1.a,
+ sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+ avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+ from cte1 )
+select * from cte;
+
+eval create procedure sp4() $q4;
+call sp4();
+call sp4();
+
+eval prepare stmt from "$q4";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+let $q5=
+with cte1 as (select * from v2),
+ cte as
+ ( select cte1.a,
+ sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+ avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+ from cte1 )
+select * from cte;
+
+eval create procedure sp5() $q5;
+call sp5();
+call sp5();
+
+eval prepare stmt from "$q5";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+let $q6=
+with
+cte1 as (with cte2 as (select * from t1 group by a) select * from cte2),
+ cte as
+ ( select cte1.a,
+ sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+ avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+ from cte1 )
+select * from cte;
+
+eval create procedure sp6() $q6;
+call sp6();
+call sp6();
+
+eval prepare stmt from "$q6";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+let $q7=
+with
+ cte2 as (select * from v1),
+ cte1 as (select * from cte2),
+ cte as
+ ( select cte1.a,
+ sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+ avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+ from cte1 )
+select * from cte;
+
+eval create procedure sp7() $q7;
+call sp7();
+call sp7();
+
+eval prepare stmt from "$q7";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+
+drop procedure sp1;
+drop procedure sp2;
+drop procedure sp3;
+drop procedure sp4;
+drop procedure sp5;
+drop procedure sp6;
+drop procedure sp7;
+drop view v1,v2;
+drop table t1;
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index e4ecc910556..595fa2a2722 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -2687,7 +2687,9 @@ sub mysql_server_start($) {
if (!$opt_embedded_server)
{
- mysqld_start($mysqld,$extra_opts);
+ mysqld_start($mysqld, $extra_opts) or
+ mtr_error("Failed to start mysqld ".$mysqld->name()." with command "
+ . $ENV{MYSQLD_LAST_CMD});
# Save this test case information, so next can examine it
$mysqld->{'started_tinfo'}= $tinfo;
@@ -2710,10 +2712,10 @@ sub mysql_server_start($) {
sub mysql_server_wait {
my ($mysqld, $tinfo) = @_;
+ my $expect_file= "$opt_vardir/tmp/".$mysqld->name().".expect";
- if (!sleep_until_file_created($mysqld->value('pid-file'),
- $opt_start_timeout,
- $mysqld->{'proc'},
+ if (!sleep_until_file_created($mysqld->value('pid-file'), $expect_file,
+ $opt_start_timeout, $mysqld->{'proc'},
$warn_seconds))
{
$tinfo->{comment}= "Failed to start ".$mysqld->name() . "\n";
@@ -4027,9 +4029,12 @@ sub run_testcase ($$) {
# ----------------------------------------------------
# Check if it was an expected crash
# ----------------------------------------------------
- my $check_crash = check_expected_crash_and_restart($wait_for_proc);
+ my @mysqld = grep($wait_for_proc eq $_->{proc}, mysqlds());
+ goto SRVDIED unless @mysqld;
+ my $check_crash = check_expected_crash_and_restart($mysqld[0]);
if ($check_crash == 0) # unexpected exit/crash of $wait_for_proc
{
+ $proc= $mysqld[0]->{proc};
goto SRVDIED;
}
elsif ($check_crash == 1) # $wait_for_proc was started again by check_expected_crash_and_restart()
@@ -4595,61 +4600,52 @@ sub check_warnings_post_shutdown {
}
#
-# Loop through our list of processes and look for and entry
-# with the provided pid, if found check for the file indicating
-# expected crash and restart it.
+# Check for the file indicating expected crash and restart it.
#
sub check_expected_crash_and_restart {
- my ($proc)= @_;
+ my $mysqld = shift;
- foreach my $mysqld ( mysqlds() )
+ # Check if crash expected by looking at the .expect file
+ # in var/tmp
+ my $expect_file= "$opt_vardir/tmp/".$mysqld->name().".expect";
+ if ( -f $expect_file )
{
- next unless ( $mysqld->{proc} and $mysqld->{proc} eq $proc );
+ mtr_verbose("Crash was expected, file '$expect_file' exists");
- # Check if crash expected by looking at the .expect file
- # in var/tmp
- my $expect_file= "$opt_vardir/tmp/".$mysqld->name().".expect";
- if ( -f $expect_file )
+ for (my $waits = 0; $waits < 50; mtr_milli_sleep(100), $waits++)
{
- mtr_verbose("Crash was expected, file '$expect_file' exists");
-
- for (my $waits = 0; $waits < 50; mtr_milli_sleep(100), $waits++)
+ # Race condition seen on Windows: try again until file not empty
+ next if -z $expect_file;
+ # If last line in expect file starts with "wait"
+ # sleep a little and try again, thus allowing the
+ # test script to control when the server should start
+ # up again. Keep trying for up to 5s at a time.
+ my $last_line= mtr_lastlinesfromfile($expect_file, 1);
+ if ($last_line =~ /^wait/ )
{
- # Race condition seen on Windows: try again until file not empty
- next if -z $expect_file;
- # If last line in expect file starts with "wait"
- # sleep a little and try again, thus allowing the
- # test script to control when the server should start
- # up again. Keep trying for up to 5s at a time.
- my $last_line= mtr_lastlinesfromfile($expect_file, 1);
- if ($last_line =~ /^wait/ )
- {
- mtr_verbose("Test says wait before restart") if $waits == 0;
- next;
- }
-
- # Ignore any partial or unknown command
- next unless $last_line =~ /^restart/;
- # If last line begins "restart:", the rest of the line is read as
- # extra command line options to add to the restarted mysqld.
- # Anything other than 'wait' or 'restart:' (with a colon) will
- # result in a restart with original mysqld options.
- if ($last_line =~ /restart:(.+)/) {
- my @rest_opt= split(' ', $1);
- $mysqld->{'restart_opts'}= \@rest_opt;
- } else {
- delete $mysqld->{'restart_opts'};
- }
- unlink($expect_file);
-
- # Start server with same settings as last time
- mysqld_start($mysqld, $mysqld->{'started_opts'});
+ mtr_verbose("Test says wait before restart") if $waits == 0;
+ next;
+ }
- return 1;
+ # Ignore any partial or unknown command
+ next unless $last_line =~ /^restart/;
+ # If last line begins "restart:", the rest of the line is read as
+ # extra command line options to add to the restarted mysqld.
+ # Anything other than 'wait' or 'restart:' (with a colon) will
+ # result in a restart with original mysqld options.
+ if ($last_line =~ /restart:(.+)/) {
+ my @rest_opt= split(' ', $1);
+ $mysqld->{'restart_opts'}= \@rest_opt;
+ } else {
+ delete $mysqld->{'restart_opts'};
}
- # Loop ran through: we should keep waiting after a re-check
- return 2;
+ unlink($expect_file);
+
+ # Start server with same settings as last time
+ return mysqld_start($mysqld, $mysqld->{'started_opts'});
}
+ # Loop ran through: we should keep waiting after a re-check
+ return 2;
}
# Not an expected crash
@@ -5006,6 +5002,7 @@ sub mysqld_start ($$) {
if ( defined $exe )
{
+ mtr_tofile($output, "\$ $exe @$args\n");
pre_write_errorlog($output);
$mysqld->{'proc'}= My::SafeProcess->new
(
@@ -5024,17 +5021,11 @@ sub mysqld_start ($$) {
mtr_verbose("Started $mysqld->{proc}");
}
- if (!sleep_until_file_created($mysqld->value('pid-file'),
- $opt_start_timeout, $mysqld->{'proc'}, $warn_seconds))
- {
- my $mname= $mysqld->name();
- mtr_error("Failed to start mysqld $mname with command $exe");
- }
-
- # Remember options used when starting
$mysqld->{'started_opts'}= $extra_opts;
- return;
+ my $expect_file= "$opt_vardir/tmp/".$mysqld->name().".expect";
+ return sleep_until_file_created($mysqld->value('pid-file'), $expect_file,
+ $opt_start_timeout, $mysqld->{'proc'}, $warn_seconds);
}
diff --git a/mysql-test/suite/binlog/include/binlog.test b/mysql-test/suite/binlog/include/binlog.test
index e5d4efb183b..948f226b3f5 100644
--- a/mysql-test/suite/binlog/include/binlog.test
+++ b/mysql-test/suite/binlog/include/binlog.test
@@ -406,4 +406,22 @@ SHOW SESSION VARIABLES LIKE "unique_checks";
DROP TABLE t1;
disconnect fresh;
+connection default;
+--echo #
+--echo # MDEV-25595 DROP part of failed CREATE OR REPLACE is not written into binary log
+--echo #
+reset master;
+--error ER_DUP_FIELDNAME
+create table t as select 1 as b, 2 as b;
+create table t (old_table_field int);
+--error ER_DUP_FIELDNAME
+create or replace table t as select 1 as b, 2 as b;
+--error ER_DUP_FIELDNAME
+create or replace temporary table t as select 1 as b, 2 as b;
+create table t (new_table_field int);
+
+--source include/show_binlog_events.inc
+
+# cleanup
+drop table t;
diff --git a/mysql-test/suite/binlog/r/binlog_row_binlog.result b/mysql-test/suite/binlog/r/binlog_row_binlog.result
index 2d79de6960a..f15e2f9a0f1 100644
--- a/mysql-test/suite/binlog/r/binlog_row_binlog.result
+++ b/mysql-test/suite/binlog/r/binlog_row_binlog.result
@@ -1073,3 +1073,26 @@ Variable_name Value
unique_checks OFF
DROP TABLE t1;
disconnect fresh;
+connection default;
+#
+# MDEV-25595 DROP part of failed CREATE OR REPLACE is not written into binary log
+#
+reset master;
+create table t as select 1 as b, 2 as b;
+ERROR 42S21: Duplicate column name 'b'
+create table t (old_table_field int);
+create or replace table t as select 1 as b, 2 as b;
+ERROR 42S21: Duplicate column name 'b'
+create or replace temporary table t as select 1 as b, 2 as b;
+ERROR 42S21: Duplicate column name 'b'
+create table t (new_table_field int);
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; create table t (old_table_field int)
+master-bin.000001 # Gtid # # BEGIN GTID #-#-#
+master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t`/* Generated to handle failed CREATE OR REPLACE */
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; create table t (new_table_field int)
+drop table t;
diff --git a/mysql-test/suite/binlog/r/binlog_stm_binlog.result b/mysql-test/suite/binlog/r/binlog_stm_binlog.result
index ccc3db2ba7e..7ef943625de 100644
--- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result
+++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result
@@ -669,3 +669,27 @@ Variable_name Value
unique_checks OFF
DROP TABLE t1;
disconnect fresh;
+connection default;
+#
+# MDEV-25595 DROP part of failed CREATE OR REPLACE is not written into binary log
+#
+reset master;
+create table t as select 1 as b, 2 as b;
+ERROR 42S21: Duplicate column name 'b'
+create table t (old_table_field int);
+create or replace table t as select 1 as b, 2 as b;
+ERROR 42S21: Duplicate column name 'b'
+create or replace temporary table t as select 1 as b, 2 as b;
+ERROR 42S21: Duplicate column name 'b'
+create table t (new_table_field int);
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; create table t (old_table_field int)
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t`/* Generated to handle failed CREATE OR REPLACE */
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t`/* Generated to handle failed CREATE OR REPLACE */
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; create table t (new_table_field int)
+drop table t;
diff --git a/mysql-test/suite/binlog_encryption/encrypted_master.test b/mysql-test/suite/binlog_encryption/encrypted_master.test
index f67e93ce815..f6fc172c79e 100644
--- a/mysql-test/suite/binlog_encryption/encrypted_master.test
+++ b/mysql-test/suite/binlog_encryption/encrypted_master.test
@@ -18,6 +18,9 @@
# - with annotated events, default checksums and minimal binlog row image
#
+# The test can take very long time with valgrind
+--source include/not_valgrind.inc
+
--source include/have_partition.inc
--source encryption_algorithms.inc
--source include/have_innodb.inc
diff --git a/mysql-test/suite/encryption/r/tempfiles_encrypted.result b/mysql-test/suite/encryption/r/tempfiles_encrypted.result
index 0099eca9275..dea3e4f0968 100644
--- a/mysql-test/suite/encryption/r/tempfiles_encrypted.result
+++ b/mysql-test/suite/encryption/r/tempfiles_encrypted.result
@@ -3917,6 +3917,293 @@ sum(i) over () IN ( SELECT 1 FROM t1 a)
0
DROP TABLE t1;
#
+# MDEV-25565: 2-nd call of SP with SELECT from view / derived table / CTE
+# returning the result of calculation of 2 window
+# functions that use the same window specification
+#
+create table t1 (a int);
+insert into t1 values (3), (7), (1), (7), (1), (1), (3), (1), (5);
+create view v2 as select a from t1 group by a;
+create view v1 as select * from v2;
+create procedure sp1() select v1.a,
+sum(v1.a) over (partition by v1.a order by v1.a) as k,
+avg(v1.a) over (partition by v1.a order by v1.a) as m
+from v1;
+call sp1();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+call sp1();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+prepare stmt from "select v1.a,
+sum(v1.a) over (partition by v1.a order by v1.a) as k,
+avg(v1.a) over (partition by v1.a order by v1.a) as m
+from v1";
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+deallocate prepare stmt;
+create procedure sp2() select * from
+( select dt1.a,
+sum(dt1.a) over (partition by dt1.a order by dt1.a) as k,
+avg(dt1.a) over (partition by dt1.a order by dt1.a) as m
+from (select * from v2) as dt1
+) as dt;
+call sp2();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+call sp2();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+prepare stmt from "select * from
+( select dt1.a,
+sum(dt1.a) over (partition by dt1.a order by dt1.a) as k,
+avg(dt1.a) over (partition by dt1.a order by dt1.a) as m
+from (select * from v2) as dt1
+) as dt";
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+deallocate prepare stmt;
+create procedure sp3() select * from
+( select dt1.a,
+sum(dt1.a) over (partition by dt1.a order by dt1.a) as k,
+avg(dt1.a) over (partition by dt1.a order by dt1.a) as m
+from ( select * from (select * from t1 group by a) as dt2 ) as dt1
+) as dt;
+call sp3();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+call sp3();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+prepare stmt from "select * from
+( select dt1.a,
+sum(dt1.a) over (partition by dt1.a order by dt1.a) as k,
+avg(dt1.a) over (partition by dt1.a order by dt1.a) as m
+from ( select * from (select * from t1 group by a) as dt2 ) as dt1
+) as dt";
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+deallocate prepare stmt;
+create procedure sp4() with cte1 as (select * from (select * from t1 group by a) as dt2),
+cte as
+( select cte1.a,
+sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+from cte1 )
+select * from cte;
+call sp4();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+call sp4();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+prepare stmt from "with cte1 as (select * from (select * from t1 group by a) as dt2),
+cte as
+( select cte1.a,
+sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+from cte1 )
+select * from cte";
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+deallocate prepare stmt;
+create procedure sp5() with cte1 as (select * from v2),
+cte as
+( select cte1.a,
+sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+from cte1 )
+select * from cte;
+call sp5();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+call sp5();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+prepare stmt from "with cte1 as (select * from v2),
+cte as
+( select cte1.a,
+sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+from cte1 )
+select * from cte";
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+deallocate prepare stmt;
+create procedure sp6() with
+cte1 as (with cte2 as (select * from t1 group by a) select * from cte2),
+cte as
+( select cte1.a,
+sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+from cte1 )
+select * from cte;
+call sp6();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+call sp6();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+prepare stmt from "with
+cte1 as (with cte2 as (select * from t1 group by a) select * from cte2),
+cte as
+( select cte1.a,
+sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+from cte1 )
+select * from cte";
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+deallocate prepare stmt;
+create procedure sp7() with
+cte2 as (select * from v1),
+cte1 as (select * from cte2),
+cte as
+( select cte1.a,
+sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+from cte1 )
+select * from cte;
+call sp7();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+call sp7();
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+prepare stmt from "with
+cte2 as (select * from v1),
+cte1 as (select * from cte2),
+cte as
+( select cte1.a,
+sum(cte1.a) over (partition by cte1.a order by cte1.a) as k,
+avg(cte1.a) over (partition by cte1.a order by cte1.a) as m
+from cte1 )
+select * from cte";
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+execute stmt;
+a k m
+1 1 1.0000
+3 3 3.0000
+5 5 5.0000
+7 7 7.0000
+deallocate prepare stmt;
+drop procedure sp1;
+drop procedure sp2;
+drop procedure sp3;
+drop procedure sp4;
+drop procedure sp5;
+drop procedure sp6;
+drop procedure sp7;
+drop view v1,v2;
+drop table t1;
+#
# End of 10.2 tests
#
#
diff --git a/mysql-test/suite/encryption/t/innodb-page_encryption.test b/mysql-test/suite/encryption/t/innodb-page_encryption.test
index df2d1d52aaa..d756f07aea0 100644
--- a/mysql-test/suite/encryption/t/innodb-page_encryption.test
+++ b/mysql-test/suite/encryption/t/innodb-page_encryption.test
@@ -1,6 +1,9 @@
-- source include/have_innodb.inc
-- source include/have_file_key_management_plugin.inc
+# The test can take very long time with valgrind
+--source include/not_valgrind.inc
+
create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb;
show warnings;
create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1;
diff --git a/mysql-test/suite/galera/r/galera_fk_lock_wait.result b/mysql-test/suite/galera/r/galera_fk_lock_wait.result
new file mode 100644
index 00000000000..0d87aa2aa57
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_fk_lock_wait.result
@@ -0,0 +1,54 @@
+connection node_2;
+connection node_1;
+CREATE TABLE parent(parent_id int not null AUTO_INCREMENT PRIMARY KEY,
+parent_name varchar(80)) ENGINE=InnoDB;
+CREATE TABLE child(child_id int not null AUTO_INCREMENT PRIMARY KEY,
+child_name varchar(80),
+child_parent_id int not null,
+CONSTRAINT `fk_child_parent`
+ FOREIGN KEY (child_parent_id) REFERENCES parent (parent_id)
+ON DELETE CASCADE
+ON UPDATE CASCADE) ENGINE=InnoDB;
+INSERT INTO parent VALUES (1, 'first'),(2,'second'),(3,'foo'),(4,'tmp');
+INSERT INTO child VALUES (NULL,'first_child',1);
+INSERT INTO child VALUES (NULL,'second_child',1);
+INSERT INTO child VALUES (NULL,'first_child2',2);
+INSERT INTO child VALUES (NULL,'first_child3',2);
+INSERT INTO child VALUES (NULL,'first_child4',3);
+BEGIN;
+UPDATE parent SET parent_name = 'bar' WHERE parent_id = 2;
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+SET SESSION innodb_lock_wait_timeout=2;
+UPDATE child SET child_parent_id = 5 where child_parent_id = 2;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection node_1;
+COMMIT;
+SELECT * FROM parent;
+parent_id parent_name
+1 first
+2 bar
+3 foo
+4 tmp
+SELECT * FROM child;
+child_id child_name child_parent_id
+1 first_child 1
+3 second_child 1
+5 first_child2 2
+7 first_child3 2
+9 first_child4 3
+connection node_2;
+SELECT * FROM parent;
+parent_id parent_name
+1 first
+2 bar
+3 foo
+4 tmp
+SELECT * FROM child;
+child_id child_name child_parent_id
+1 first_child 1
+3 second_child 1
+5 first_child2 2
+7 first_child3 2
+9 first_child4 3
+DROP TABLE child, parent;
+disconnect node_1a;
diff --git a/mysql-test/suite/galera/t/galera_fk_lock_wait.test b/mysql-test/suite/galera/t/galera_fk_lock_wait.test
new file mode 100644
index 00000000000..150c7397f7e
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_fk_lock_wait.test
@@ -0,0 +1,40 @@
+--source include/galera_cluster.inc
+
+CREATE TABLE parent(parent_id int not null AUTO_INCREMENT PRIMARY KEY,
+parent_name varchar(80)) ENGINE=InnoDB;
+
+CREATE TABLE child(child_id int not null AUTO_INCREMENT PRIMARY KEY,
+child_name varchar(80),
+child_parent_id int not null,
+CONSTRAINT `fk_child_parent`
+ FOREIGN KEY (child_parent_id) REFERENCES parent (parent_id)
+ ON DELETE CASCADE
+ ON UPDATE CASCADE) ENGINE=InnoDB;
+
+INSERT INTO parent VALUES (1, 'first'),(2,'second'),(3,'foo'),(4,'tmp');
+INSERT INTO child VALUES (NULL,'first_child',1);
+INSERT INTO child VALUES (NULL,'second_child',1);
+INSERT INTO child VALUES (NULL,'first_child2',2);
+INSERT INTO child VALUES (NULL,'first_child3',2);
+INSERT INTO child VALUES (NULL,'first_child4',3);
+
+BEGIN;
+UPDATE parent SET parent_name = 'bar' WHERE parent_id = 2;
+
+--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
+SET SESSION innodb_lock_wait_timeout=2;
+--error ER_LOCK_WAIT_TIMEOUT
+UPDATE child SET child_parent_id = 5 where child_parent_id = 2;
+
+--connection node_1
+COMMIT;
+SELECT * FROM parent;
+SELECT * FROM child;
+
+--connection node_2
+
+SELECT * FROM parent;
+SELECT * FROM child;
+DROP TABLE child, parent;
+
+--disconnect node_1a
diff --git a/mysql-test/suite/gcol/inc/gcol_ins_upd.inc b/mysql-test/suite/gcol/inc/gcol_ins_upd.inc
index 7fde9c2e852..e745708c22a 100644
--- a/mysql-test/suite/gcol/inc/gcol_ins_upd.inc
+++ b/mysql-test/suite/gcol/inc/gcol_ins_upd.inc
@@ -607,4 +607,78 @@ DELETE FROM t1;
DROP TEMPORARY TABLE t1;
+--echo #
+--echo # Original test case from MDEV-17890
+--echo #
+
+CREATE TABLE t1 (
+ pk BIGINT AUTO_INCREMENT,
+ b BIT(15),
+ v BIT(10) AS (b) VIRTUAL,
+ PRIMARY KEY(pk),
+ UNIQUE(v)
+);
+
+INSERT IGNORE INTO t1 (b) VALUES (b'101110001110100'),(b'011101');
+SELECT pk, b INTO OUTFILE 'load.data' FROM t1;
+--error ER_DATA_TOO_LONG
+LOAD DATA INFILE 'load.data' REPLACE INTO TABLE t1 (pk, b);
+
+# Cleanup
+DROP TABLE t1;
+--let $datadir= `SELECT @@datadir`
+--remove_file $datadir/test/load.data
+
+
+--echo #
+--echo # MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols
+--echo #
+
+CREATE TABLE t1 (
+ id INT NOT NULL AUTO_INCREMENT,
+ f ENUM('a','b','c'),
+ v ENUM('a','b','c') AS (f),
+ KEY(v,id)
+) ENGINE=MyISAM;
+INSERT INTO t1 (f) VALUES ('a'),('b');
+INSERT IGNORE INTO t1 SELECT * FROM t1;
+
+# Cleanup
+DROP TABLE t1;
+
+
+CREATE TABLE t1 (
+ id INT NOT NULL AUTO_INCREMENT,
+ f ENUM('a','b','c'),
+ v ENUM('a','b','c') AS (f),
+ KEY(v,id)
+) ENGINE=MyISAM;
+INSERT INTO t1 (f) VALUES ('a'),('b');
+INSERT IGNORE INTO t1 SELECT * FROM t1;
+
+# Cleanup
+DROP TABLE t1;
+
}
+
+--echo #
+--echo # MDEV-23597 Assertion `marked_for_read()' failed while evaluating DEFAULT
+--echo #
+
+CREATE TABLE t1 (a INT UNIQUE, b INT DEFAULT (c+1), c int);
+INSERT INTO t1 VALUES (1,1,1);
+UPDATE t1 SET b=DEFAULT;
+SELECT * from t1;
+
+REPLACE t1 VALUES(1,1,1);
+INSERT INTO t1 VALUES (1,1,1) ON DUPLICATE KEY UPDATE b= DEFAULT;
+SELECT * from t1;
+
+REPLACE t1 VALUES(1,1,1);
+CREATE TABLE t2 (a INT, b INT DEFAULT (c+1), c int);
+INSERT INTO t2 VALUES (5,5,5);
+UPDATE t1 join t2 set t1.b= DEFAULT, t2.b= DEFAULT;
+SELECT * from t1, t2;
+
+DROP TABLE t1, t2;
+
diff --git a/mysql-test/suite/gcol/inc/gcol_keys.inc b/mysql-test/suite/gcol/inc/gcol_keys.inc
index e5f7f976120..cf0612b0d0c 100644
--- a/mysql-test/suite/gcol/inc/gcol_keys.inc
+++ b/mysql-test/suite/gcol/inc/gcol_keys.inc
@@ -812,7 +812,7 @@ DROP TABLE t1;
--echo # MDEV-19011 Assertion `file->s->base.reclength < file->s->vreclength'
--echo # failed in ha_myisam::setup_vcols_for_repair
-CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL) ENGINE=MyISAM;
+CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL);
ALTER TABLE t1 ADD KEY (a);
DROP TABLE t1;
diff --git a/mysql-test/suite/gcol/inc/gcol_partition.inc b/mysql-test/suite/gcol/inc/gcol_partition.inc
index df199e86c68..4e4af4f0023 100644
--- a/mysql-test/suite/gcol/inc/gcol_partition.inc
+++ b/mysql-test/suite/gcol/inc/gcol_partition.inc
@@ -153,3 +153,19 @@ CHECK TABLE t EXTENDED;
FLUSH TABLES;
CHECK TABLE t EXTENDED;
DROP TABLE t;
+
+--echo #
+--echo # MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols
+--echo #
+CREATE TABLE t1 (
+ a INT,
+ b INT,
+ c BIT(4) NOT NULL DEFAULT b'0',
+ pk INTEGER AUTO_INCREMENT,
+ d BIT(4) AS (c) VIRTUAL,
+ PRIMARY KEY(pk),
+ KEY (b,d)
+) PARTITION BY HASH(pk);
+INSERT INTO t1 () VALUES (),();
+UPDATE t1 SET a = 0 WHERE b IS NULL ORDER BY pk;
+DROP TABLE t1;
diff --git a/mysql-test/suite/gcol/inc/gcol_view.inc b/mysql-test/suite/gcol/inc/gcol_view.inc
index 51cb9b5d725..6f9ce673199 100644
--- a/mysql-test/suite/gcol/inc/gcol_view.inc
+++ b/mysql-test/suite/gcol/inc/gcol_view.inc
@@ -221,3 +221,58 @@ select * from t1;
drop view v1;
drop table t1;
+
+--echo #
+--echo # MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols
+--echo #
+
+CREATE TABLE t1 (d DATETIME(3), v DATETIME(2) AS (d));
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+INSERT INTO t1 (d) VALUES ('2004-04-19 15:37:39.123'),
+ ('1985-12-24 10:15:08.456');
+DELETE FROM v1 ORDER BY v LIMIT 4;
+
+# Cleanup
+DROP VIEW v1;
+DROP TABLE t1;
+
+--echo #
+--echo # [duplicate] MDEV-19306 Assertion `marked_for_read()' failed in
+--echo # Field_blob::val_str with virtual columns and views
+--echo #
+
+CREATE TABLE t1 (a BLOB, b TEXT AS (a) VIRTUAL);
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 (a) VALUES ('foo'),('bar');
+DELETE FROM v1 ORDER BY b LIMIT 2;
+
+# Cleanup
+DROP VIEW v1;
+DROP TABLE t1;
+CREATE TABLE t1 (d INT, v TINYINT AS (d));
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 (d) VALUES ('2004'),('1985') ;
+DELETE FROM v1 ORDER BY v LIMIT 4;
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+
+CREATE TABLE t1 (d VARCHAR(64), v VARCHAR(63) AS (d));
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 (d) VALUES ('2004-04-19 15:37:39.123'),('1985-12-24 10:15:08.456') ;
+DELETE FROM v1 ORDER BY v LIMIT 4;
+
+DROP TABLE t1;
+DROP VIEW v1;
+
+
+--echo #
+--echo # MDEV-18249 ASSERT_COLUMN_MARKED_FOR_READ failed in ANALYZE TABLE
+--echo #
+
+create table t1 (c varchar(3) not null, v varchar(4) as (c) virtual);
+insert into t1 (c) values ('a'),('b');
+analyze table t1 persistent for columns (v) indexes ();
+
diff --git a/mysql-test/suite/gcol/r/gcol_ins_upd_innodb.result b/mysql-test/suite/gcol/r/gcol_ins_upd_innodb.result
index 3024b58da54..ec5e8c0d70d 100644
--- a/mysql-test/suite/gcol/r/gcol_ins_upd_innodb.result
+++ b/mysql-test/suite/gcol/r/gcol_ins_upd_innodb.result
@@ -435,6 +435,26 @@ UPDATE t1 SET col1 = 2;
UPDATE t1 SET col7 = DEFAULT;
UPDATE t1 SET col8 = DEFAULT;
DROP TABLE t1;
+Bug#20797344: WL#8149: ALLOCATED SPACE FOR INDEXED BLOB VGC CAN BE
+OVERWRITTEN FOR UPDATE
+#
+CREATE TABLE t (a varchar(100), b blob,
+c blob GENERATED ALWAYS AS (concat(a,b)) VIRTUAL,
+d blob GENERATED ALWAYS AS (b) VIRTUAL,
+e int(11) GENERATED ALWAYS AS (10) VIRTUAL,
+h int(11) NOT NULL, PRIMARY KEY (h), key(c(20)));
+INSERT INTO t(a,b,h) VALUES('aaaaaaa','1111111', 11);
+INSERT INTO t(a,b,h) VALUES('bbbbbbb','2222222', 22);
+SELECT c FROM t;
+c
+aaaaaaa1111111
+bbbbbbb2222222
+UPDATE t SET a='ccccccc';
+SELECT c FROM t;
+c
+ccccccc1111111
+ccccccc2222222
+DROP TABLE t;
# Bug#21081742: ASSERTION !TABLE || (!TABLE->WRITE_SET ||
# BITMAP_IS_SET(TABLE->WRITE_SET
#
@@ -491,6 +511,21 @@ SELECT * FROM t;
x y gc
2 1 3
DROP TABLE t;
+CREATE TABLE t (
+x INT, y INT, gc INT GENERATED ALWAYS AS (x+1), KEY (x,gc)
+);
+INSERT INTO t VALUES ();
+UPDATE t t1, t t2 SET t1.x = 1, t2.y = 2;
+SELECT * FROM t;
+x y gc
+1 2 2
+SELECT gc FROM t;
+gc
+2
+CHECK TABLE t;
+Table Op Msg_type Msg_text
+test.t check status OK
+DROP TABLE t;
# stored
CREATE TABLE C (
col_varchar_nokey VARCHAR(1),
@@ -552,6 +587,104 @@ SELECT * from C;
col_varchar_nokey col_varchar_key
a aa
DROP TABLE C;
+# virtual, indexed
+CREATE TABLE C (
+col_varchar_nokey VARCHAR(1),
+col_varchar_key VARCHAR(2) GENERATED ALWAYS AS
+(CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL,
+KEY (col_varchar_key, col_varchar_nokey)
+);
+INSERT INTO C (col_varchar_nokey) VALUES ('c');
+EXPLAIN UPDATE C AS OUTR1, C AS OUTR2
+SET OUTR1.`col_varchar_nokey` = 'f',
+OUTR2.`col_varchar_nokey` = "a";
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE OUTR1 ALL NULL NULL NULL NULL 1
+1 SIMPLE OUTR2 ALL NULL NULL NULL NULL 1
+UPDATE C AS OUTR1, C AS OUTR2
+SET OUTR1.`col_varchar_nokey` = 'f',
+OUTR2.`col_varchar_nokey` = "a";
+SELECT * from C;
+col_varchar_nokey col_varchar_key
+a aa
+DROP TABLE C;
+#
+# Bug #21530366 CRASH/ASSERTION, CORRUPTION WITH INDEXES +
+# VIRTUAL COLUMNS, BLOB
+#
+CREATE TABLE t (
+a INTEGER,
+b BLOB GENERATED ALWAYS AS (a) VIRTUAL,
+INDEX (b(57))
+);
+INSERT INTO t (a) VALUES (9);
+UPDATE t SET a = 10;
+DELETE FROM t WHERE a = 10;
+DROP TABLE t;
+# Bug#21807818: Generated columns not updated with empty insert list
+CREATE TABLE t (
+a BLOB GENERATED ALWAYS AS ('') VIRTUAL,
+b TIMESTAMP(4) GENERATED ALWAYS AS ('') VIRTUAL,
+KEY (a(183),b)
+);
+Warnings:
+Warning 1901 Function or expression '''' cannot be used in the GENERATED ALWAYS AS clause of `b`
+Warning 1105 Expression depends on the @@sql_mode value TIME_ROUND_FRACTIONAL
+INSERT IGNORE INTO t VALUES(), (), ();
+Warnings:
+Warning 1901 Function or expression '''' cannot be used in the GENERATED ALWAYS AS clause of `b`
+Warning 1105 Expression depends on the @@sql_mode value TIME_ROUND_FRACTIONAL
+Warning 1265 Data truncated for column 'b' at row 1
+Warning 1265 Data truncated for column 'b' at row 2
+Warning 1265 Data truncated for column 'b' at row 3
+DELETE IGNORE FROM t;
+DROP TABLE t;
+#
+# Bug#22195458:GCOLS: ASSERTION 0 AND CORRUPTION...
+#
+CREATE TABLE t (
+a INT,
+b YEAR GENERATED ALWAYS AS ('a') VIRTUAL,
+c YEAR GENERATED ALWAYS AS ('aaaa') VIRTUAL,
+b1 YEAR GENERATED ALWAYS AS ('a') STORED,
+c1 YEAR GENERATED ALWAYS AS ('aaaa') STORED,
+UNIQUE(b),
+UNIQUE(b1)
+);
+INSERT IGNORE INTO t VALUES();
+SELECT b from t;
+b
+0000
+SELECT b1 from t;
+b1
+0000
+SELECT * from t;
+a b c b1 c1
+NULL 0000 0000 0000 0000
+DELETE FROM t;
+CHECK TABLE t EXTENDED;
+Table Op Msg_type Msg_text
+test.t check status OK
+DROP TABLE t;
+# Bug#22195364:GCOLS: FAILING ASSERTION:
+# DFIELD_IS_NULL(DFIELD2) || DFIELD2->DATA
+CREATE TABLE t (
+a INT,
+c BLOB GENERATED ALWAYS AS ('') VIRTUAL,
+UNIQUE KEY(c(1),a)
+);
+INSERT INTO t(a) VALUES(1) ON DUPLICATE KEY UPDATE a=2;
+SELECT * FROM t;
+a c
+1
+INSERT INTO t(a) VALUES(1) ON DUPLICATE KEY UPDATE a=2;
+SELECT * FROM t;
+a c
+2
+SELECT GROUP_CONCAT(c ORDER BY c) FROM t;
+GROUP_CONCAT(c ORDER BY c)
+
+DROP TABLE t;
#Bug#21929967:GCOLS:GCOL VALUE CHANGES WHEN SESSION CHANGES SQL_MODE
CREATE TABLE t(c1 INT GENERATED ALWAYS AS (1) VIRTUAL,
c2 INT GENERATED ALWAYS AS(2) STORED);
@@ -593,6 +726,98 @@ i1 i2
5 10
5 10
DROP TABLE t1,t2;
+#
+# Bug#22070021 GCOL:ASSERTION `!TABLE || (!TABLE->WRITE_SET ||
+# BITMAP_IS_SET(TABLE->WRITE_SET,
+#
+CREATE TABLE t1(
+c1 INT,
+c2 INT GENERATED ALWAYS AS (c1 + c1) VIRTUAL,
+KEY(c2)
+);
+INSERT INTO t1(c1) VALUES(0);
+DELETE O1.* FROM t1 AS O1, t1 AS O2;
+SELECT * FROM t1;
+c1 c2
+DROP TABLE t1;
+#
+# Bug#21944199 SIMPLE DELETE QUERY CAUSES INNODB: FAILING ASSERTION: 0
+# & DATA CORRUPTION
+#
+CREATE TEMPORARY TABLE t1 (
+a INTEGER NOT NULL,
+b INTEGER GENERATED ALWAYS AS (a+1) VIRTUAL
+);
+INSERT INTO t1 (a) VALUES (0), (0), (0);
+ALTER TABLE t1 ADD INDEX idx (b);
+DELETE FROM t1;
+DROP TEMPORARY TABLE t1;
+#
+# Original test case from MDEV-17890
+#
+CREATE TABLE t1 (
+pk BIGINT AUTO_INCREMENT,
+b BIT(15),
+v BIT(10) AS (b) VIRTUAL,
+PRIMARY KEY(pk),
+UNIQUE(v)
+);
+INSERT IGNORE INTO t1 (b) VALUES (b'101110001110100'),(b'011101');
+Warnings:
+Warning 1264 Out of range value for column 'v' at row 1
+SELECT pk, b INTO OUTFILE 'load.data' FROM t1;
+LOAD DATA INFILE 'load.data' REPLACE INTO TABLE t1 (pk, b);
+ERROR 22001: Data too long for column 'v' at row 1
+DROP TABLE t1;
+#
+# MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols
+#
+CREATE TABLE t1 (
+id INT NOT NULL AUTO_INCREMENT,
+f ENUM('a','b','c'),
+v ENUM('a','b','c') AS (f),
+KEY(v,id)
+) ENGINE=MyISAM;
+INSERT INTO t1 (f) VALUES ('a'),('b');
+INSERT IGNORE INTO t1 SELECT * FROM t1;
+Warnings:
+Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
+DROP TABLE t1;
+CREATE TABLE t1 (
+id INT NOT NULL AUTO_INCREMENT,
+f ENUM('a','b','c'),
+v ENUM('a','b','c') AS (f),
+KEY(v,id)
+) ENGINE=MyISAM;
+INSERT INTO t1 (f) VALUES ('a'),('b');
+INSERT IGNORE INTO t1 SELECT * FROM t1;
+Warnings:
+Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
+DROP TABLE t1;
+#
+# MDEV-23597 Assertion `marked_for_read()' failed while evaluating DEFAULT
+#
+CREATE TABLE t1 (a INT UNIQUE, b INT DEFAULT (c+1), c int);
+INSERT INTO t1 VALUES (1,1,1);
+UPDATE t1 SET b=DEFAULT;
+SELECT * from t1;
+a b c
+1 2 1
+REPLACE t1 VALUES(1,1,1);
+INSERT INTO t1 VALUES (1,1,1) ON DUPLICATE KEY UPDATE b= DEFAULT;
+SELECT * from t1;
+a b c
+1 2 1
+REPLACE t1 VALUES(1,1,1);
+CREATE TABLE t2 (a INT, b INT DEFAULT (c+1), c int);
+INSERT INTO t2 VALUES (5,5,5);
+UPDATE t1 join t2 set t1.b= DEFAULT, t2.b= DEFAULT;
+SELECT * from t1, t2;
+a b c a b c
+1 2 1 5 6 5
+DROP TABLE t1, t2;
DROP VIEW IF EXISTS v1,v2;
DROP TABLE IF EXISTS t1,t2,t3;
DROP PROCEDURE IF EXISTS p1;
diff --git a/mysql-test/suite/gcol/r/gcol_ins_upd_myisam.result b/mysql-test/suite/gcol/r/gcol_ins_upd_myisam.result
index 210c6450b70..a2ade8c324f 100644
--- a/mysql-test/suite/gcol/r/gcol_ins_upd_myisam.result
+++ b/mysql-test/suite/gcol/r/gcol_ins_upd_myisam.result
@@ -576,13 +576,13 @@ UNIQUE(b1)
INSERT IGNORE INTO t VALUES();
SELECT b from t;
b
-2000
+0000
SELECT b1 from t;
b1
0000
SELECT * from t;
a b c b1 c1
-NULL 2000 0000 0000 0000
+NULL 0000 0000 0000 0000
DELETE FROM t;
CHECK TABLE t EXTENDED;
Table Op Msg_type Msg_text
@@ -674,6 +674,72 @@ INSERT INTO t1 (a) VALUES (0), (0), (0);
ALTER TABLE t1 ADD INDEX idx (b);
DELETE FROM t1;
DROP TEMPORARY TABLE t1;
+#
+# Original test case from MDEV-17890
+#
+CREATE TABLE t1 (
+pk BIGINT AUTO_INCREMENT,
+b BIT(15),
+v BIT(10) AS (b) VIRTUAL,
+PRIMARY KEY(pk),
+UNIQUE(v)
+);
+INSERT IGNORE INTO t1 (b) VALUES (b'101110001110100'),(b'011101');
+Warnings:
+Warning 1264 Out of range value for column 'v' at row 1
+SELECT pk, b INTO OUTFILE 'load.data' FROM t1;
+LOAD DATA INFILE 'load.data' REPLACE INTO TABLE t1 (pk, b);
+ERROR 22001: Data too long for column 'v' at row 1
+DROP TABLE t1;
+#
+# MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols
+#
+CREATE TABLE t1 (
+id INT NOT NULL AUTO_INCREMENT,
+f ENUM('a','b','c'),
+v ENUM('a','b','c') AS (f),
+KEY(v,id)
+) ENGINE=MyISAM;
+INSERT INTO t1 (f) VALUES ('a'),('b');
+INSERT IGNORE INTO t1 SELECT * FROM t1;
+Warnings:
+Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
+DROP TABLE t1;
+CREATE TABLE t1 (
+id INT NOT NULL AUTO_INCREMENT,
+f ENUM('a','b','c'),
+v ENUM('a','b','c') AS (f),
+KEY(v,id)
+) ENGINE=MyISAM;
+INSERT INTO t1 (f) VALUES ('a'),('b');
+INSERT IGNORE INTO t1 SELECT * FROM t1;
+Warnings:
+Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
+DROP TABLE t1;
+#
+# MDEV-23597 Assertion `marked_for_read()' failed while evaluating DEFAULT
+#
+CREATE TABLE t1 (a INT UNIQUE, b INT DEFAULT (c+1), c int);
+INSERT INTO t1 VALUES (1,1,1);
+UPDATE t1 SET b=DEFAULT;
+SELECT * from t1;
+a b c
+1 2 1
+REPLACE t1 VALUES(1,1,1);
+INSERT INTO t1 VALUES (1,1,1) ON DUPLICATE KEY UPDATE b= DEFAULT;
+SELECT * from t1;
+a b c
+1 2 1
+REPLACE t1 VALUES(1,1,1);
+CREATE TABLE t2 (a INT, b INT DEFAULT (c+1), c int);
+INSERT INTO t2 VALUES (5,5,5);
+UPDATE t1 join t2 set t1.b= DEFAULT, t2.b= DEFAULT;
+SELECT * from t1, t2;
+a b c a b c
+1 2 1 5 6 5
+DROP TABLE t1, t2;
DROP VIEW IF EXISTS v1,v2;
DROP TABLE IF EXISTS t1,t2,t3;
DROP PROCEDURE IF EXISTS p1;
diff --git a/mysql-test/suite/gcol/r/gcol_keys_innodb.result b/mysql-test/suite/gcol/r/gcol_keys_innodb.result
index be9dfd92691..121ec59678b 100644
--- a/mysql-test/suite/gcol/r/gcol_keys_innodb.result
+++ b/mysql-test/suite/gcol/r/gcol_keys_innodb.result
@@ -885,7 +885,7 @@ ERROR 22003: Out of range value for column 'vi' at row 1
DROP TABLE t1;
# MDEV-19011 Assertion `file->s->base.reclength < file->s->vreclength'
# failed in ha_myisam::setup_vcols_for_repair
-CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL) ENGINE=MyISAM;
+CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL);
ALTER TABLE t1 ADD KEY (a);
DROP TABLE t1;
#
diff --git a/mysql-test/suite/gcol/r/gcol_keys_myisam.result b/mysql-test/suite/gcol/r/gcol_keys_myisam.result
index 48e11cbe222..c3cb35416ef 100644
--- a/mysql-test/suite/gcol/r/gcol_keys_myisam.result
+++ b/mysql-test/suite/gcol/r/gcol_keys_myisam.result
@@ -885,7 +885,7 @@ ERROR 22003: Out of range value for column 'vi' at row 1
DROP TABLE t1;
# MDEV-19011 Assertion `file->s->base.reclength < file->s->vreclength'
# failed in ha_myisam::setup_vcols_for_repair
-CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL) ENGINE=MyISAM;
+CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL);
ALTER TABLE t1 ADD KEY (a);
DROP TABLE t1;
DROP VIEW IF EXISTS v1,v2;
diff --git a/mysql-test/suite/gcol/r/gcol_partition_innodb.result b/mysql-test/suite/gcol/r/gcol_partition_innodb.result
index e5a68cdb177..d3f211c9b9a 100644
--- a/mysql-test/suite/gcol/r/gcol_partition_innodb.result
+++ b/mysql-test/suite/gcol/r/gcol_partition_innodb.result
@@ -89,6 +89,21 @@ Table Op Msg_type Msg_text
test.t check status OK
DROP TABLE t;
#
+# MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols
+#
+CREATE TABLE t1 (
+a INT,
+b INT,
+c BIT(4) NOT NULL DEFAULT b'0',
+pk INTEGER AUTO_INCREMENT,
+d BIT(4) AS (c) VIRTUAL,
+PRIMARY KEY(pk),
+KEY (b,d)
+) PARTITION BY HASH(pk);
+INSERT INTO t1 () VALUES (),();
+UPDATE t1 SET a = 0 WHERE b IS NULL ORDER BY pk;
+DROP TABLE t1;
+#
# MDEV-16980 Wrongly set tablename len while opening the
# table for purge thread
#
diff --git a/mysql-test/suite/gcol/r/gcol_partition_myisam.result b/mysql-test/suite/gcol/r/gcol_partition_myisam.result
index 81324da6fcd..75e216f903b 100644
--- a/mysql-test/suite/gcol/r/gcol_partition_myisam.result
+++ b/mysql-test/suite/gcol/r/gcol_partition_myisam.result
@@ -86,6 +86,21 @@ CHECK TABLE t EXTENDED;
Table Op Msg_type Msg_text
test.t check status OK
DROP TABLE t;
+#
+# MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols
+#
+CREATE TABLE t1 (
+a INT,
+b INT,
+c BIT(4) NOT NULL DEFAULT b'0',
+pk INTEGER AUTO_INCREMENT,
+d BIT(4) AS (c) VIRTUAL,
+PRIMARY KEY(pk),
+KEY (b,d)
+) PARTITION BY HASH(pk);
+INSERT INTO t1 () VALUES (),();
+UPDATE t1 SET a = 0 WHERE b IS NULL ORDER BY pk;
+DROP TABLE t1;
DROP VIEW IF EXISTS v1,v2;
DROP TABLE IF EXISTS t1,t2,t3;
DROP PROCEDURE IF EXISTS p1;
diff --git a/mysql-test/suite/gcol/r/gcol_view_innodb.result b/mysql-test/suite/gcol/r/gcol_view_innodb.result
index b23dbfc4bff..ac23d64bcee 100644
--- a/mysql-test/suite/gcol/r/gcol_view_innodb.result
+++ b/mysql-test/suite/gcol/r/gcol_view_innodb.result
@@ -272,6 +272,47 @@ a b c
1 -1 -1
drop view v1;
drop table t1;
+#
+# MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols
+#
+CREATE TABLE t1 (d DATETIME(3), v DATETIME(2) AS (d));
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 (d) VALUES ('2004-04-19 15:37:39.123'),
+('1985-12-24 10:15:08.456');
+DELETE FROM v1 ORDER BY v LIMIT 4;
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# [duplicate] MDEV-19306 Assertion `marked_for_read()' failed in
+# Field_blob::val_str with virtual columns and views
+#
+CREATE TABLE t1 (a BLOB, b TEXT AS (a) VIRTUAL);
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 (a) VALUES ('foo'),('bar');
+DELETE FROM v1 ORDER BY b LIMIT 2;
+DROP VIEW v1;
+DROP TABLE t1;
+CREATE TABLE t1 (d INT, v TINYINT AS (d));
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 (d) VALUES ('2004'),('1985') ;
+DELETE FROM v1 ORDER BY v LIMIT 4;
+DROP VIEW v1;
+DROP TABLE t1;
+CREATE TABLE t1 (d VARCHAR(64), v VARCHAR(63) AS (d));
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 (d) VALUES ('2004-04-19 15:37:39.123'),('1985-12-24 10:15:08.456') ;
+DELETE FROM v1 ORDER BY v LIMIT 4;
+DROP TABLE t1;
+DROP VIEW v1;
+#
+# MDEV-18249 ASSERT_COLUMN_MARKED_FOR_READ failed in ANALYZE TABLE
+#
+create table t1 (c varchar(3) not null, v varchar(4) as (c) virtual);
+insert into t1 (c) values ('a'),('b');
+analyze table t1 persistent for columns (v) indexes ();
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
DROP VIEW IF EXISTS v1,v2;
DROP TABLE IF EXISTS t1,t2,t3;
DROP PROCEDURE IF EXISTS p1;
diff --git a/mysql-test/suite/gcol/r/gcol_view_myisam.result b/mysql-test/suite/gcol/r/gcol_view_myisam.result
index 264bd904c30..ddbbf44222c 100644
--- a/mysql-test/suite/gcol/r/gcol_view_myisam.result
+++ b/mysql-test/suite/gcol/r/gcol_view_myisam.result
@@ -272,6 +272,47 @@ a b c
1 -1 -1
drop view v1;
drop table t1;
+#
+# MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols
+#
+CREATE TABLE t1 (d DATETIME(3), v DATETIME(2) AS (d));
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 (d) VALUES ('2004-04-19 15:37:39.123'),
+('1985-12-24 10:15:08.456');
+DELETE FROM v1 ORDER BY v LIMIT 4;
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# [duplicate] MDEV-19306 Assertion `marked_for_read()' failed in
+# Field_blob::val_str with virtual columns and views
+#
+CREATE TABLE t1 (a BLOB, b TEXT AS (a) VIRTUAL);
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 (a) VALUES ('foo'),('bar');
+DELETE FROM v1 ORDER BY b LIMIT 2;
+DROP VIEW v1;
+DROP TABLE t1;
+CREATE TABLE t1 (d INT, v TINYINT AS (d));
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 (d) VALUES ('2004'),('1985') ;
+DELETE FROM v1 ORDER BY v LIMIT 4;
+DROP VIEW v1;
+DROP TABLE t1;
+CREATE TABLE t1 (d VARCHAR(64), v VARCHAR(63) AS (d));
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 (d) VALUES ('2004-04-19 15:37:39.123'),('1985-12-24 10:15:08.456') ;
+DELETE FROM v1 ORDER BY v LIMIT 4;
+DROP TABLE t1;
+DROP VIEW v1;
+#
+# MDEV-18249 ASSERT_COLUMN_MARKED_FOR_READ failed in ANALYZE TABLE
+#
+create table t1 (c varchar(3) not null, v varchar(4) as (c) virtual);
+insert into t1 (c) values ('a'),('b');
+analyze table t1 persistent for columns (v) indexes ();
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
DROP VIEW IF EXISTS v1,v2;
DROP TABLE IF EXISTS t1,t2,t3;
DROP PROCEDURE IF EXISTS p1;
diff --git a/mysql-test/suite/gcol/r/innodb_virtual_fk.result b/mysql-test/suite/gcol/r/innodb_virtual_fk.result
index 252274f3e0a..367ed1223f7 100644
--- a/mysql-test/suite/gcol/r/innodb_virtual_fk.result
+++ b/mysql-test/suite/gcol/r/innodb_virtual_fk.result
@@ -809,15 +809,18 @@ generated_email_id int as (email_id),
PRIMARY KEY (id),
KEY mautic_generated_sent_date_email_id (generated_email_id),
FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE SET NULL
+ON UPDATE CASCADE
) ENGINE=InnoDB;
CREATE TABLE emails_metadata (
email_id int,
PRIMARY KEY (email_id),
CONSTRAINT FK FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE CASCADE
+ON UPDATE CASCADE
) ENGINE=InnoDB;
INSERT INTO emails VALUES (1);
INSERT INTO email_stats (id, email_id, date_sent) VALUES (1,1,'Jan');
INSERT INTO emails_metadata VALUES (1);
+UPDATE emails SET id=2;
DELETE FROM emails;
DROP TABLE email_stats;
DROP TABLE emails_metadata;
diff --git a/mysql-test/suite/gcol/t/gcol_ins_upd_innodb.test b/mysql-test/suite/gcol/t/gcol_ins_upd_innodb.test
index 23d97a797e0..15a0db29615 100644
--- a/mysql-test/suite/gcol/t/gcol_ins_upd_innodb.test
+++ b/mysql-test/suite/gcol/t/gcol_ins_upd_innodb.test
@@ -36,7 +36,7 @@ eval SET @@session.default_storage_engine = 'InnoDB';
#------------------------------------------------------------------------------#
# Execute the tests to be applied to all storage engines
-let $support_virtual_index= 0;
+let $support_virtual_index= 1;
--source suite/gcol/inc/gcol_ins_upd.inc
#------------------------------------------------------------------------------#
diff --git a/mysql-test/suite/gcol/t/innodb_virtual_fk.test b/mysql-test/suite/gcol/t/innodb_virtual_fk.test
index 24b6a4631e6..c99259531b3 100644
--- a/mysql-test/suite/gcol/t/innodb_virtual_fk.test
+++ b/mysql-test/suite/gcol/t/innodb_virtual_fk.test
@@ -670,6 +670,7 @@ CREATE TABLE email_stats (
PRIMARY KEY (id),
KEY mautic_generated_sent_date_email_id (generated_email_id),
FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE SET NULL
+ ON UPDATE CASCADE
) ENGINE=InnoDB;
@@ -677,6 +678,7 @@ CREATE TABLE emails_metadata (
email_id int,
PRIMARY KEY (email_id),
CONSTRAINT FK FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE CASCADE
+ ON UPDATE CASCADE
) ENGINE=InnoDB;
@@ -684,6 +686,7 @@ INSERT INTO emails VALUES (1);
INSERT INTO email_stats (id, email_id, date_sent) VALUES (1,1,'Jan');
INSERT INTO emails_metadata VALUES (1);
+UPDATE emails SET id=2;
DELETE FROM emails;
DROP TABLE email_stats;
diff --git a/mysql-test/suite/innodb/r/default_row_format_alter.result b/mysql-test/suite/innodb/r/default_row_format_alter.result
index fa5adb32fb0..42cbab8a5f2 100644
--- a/mysql-test/suite/innodb/r/default_row_format_alter.result
+++ b/mysql-test/suite/innodb/r/default_row_format_alter.result
@@ -23,6 +23,7 @@ INSERT INTO t1 VALUES (1, 'abc');
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
t1 InnoDB # Compact # # # # # # NULL # # NULL latin1_swedish_ci NULL 0 N
+CREATE TABLE t2 (b VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL) ENGINE=InnoDB;
SET GLOBAL innodb_default_row_format = DYNAMIC;
ALTER TABLE t1 DROP PRIMARY KEY, ADD COLUMN c INT PRIMARY KEY;
# Here we expect DYNAMIC because there is no explicit ROW_FORMAT and the
@@ -31,6 +32,10 @@ SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
t1 InnoDB # Dynamic # # # # # # NULL # # NULL latin1_swedish_ci NULL 0 N
DROP TABLE t1;
+ALTER TABLE t2 ADD INDEX(b);
+ERROR HY000: Index column size too large. The maximum column size is 767 bytes
+ALTER TABLE t2 FORCE, ADD INDEX(b);
+DROP TABLE t2;
####################################
# Check the row_format effect on ALTER, ALGORITHM=COPY
SET GLOBAL innodb_default_row_format = REDUNDANT;
@@ -39,6 +44,7 @@ INSERT INTO t1 VALUES (1, REPEAT('abc',1000));
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
t1 InnoDB # Redundant # # # # # # NULL # # NULL latin1_swedish_ci NULL 0 N
+CREATE TABLE t2 (b VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL) ENGINE=InnoDB;
SET GLOBAL innoDB_default_row_format = COMPACT;
ALTER TABLE t1 ADD COLUMN c2 BLOB, ALGORITHM=COPY;
# Because of ALGORITHM=COPY, there is TABLE REBUILD and the table isn't
@@ -47,9 +53,18 @@ SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
t1 InnoDB # Compact # # # # # # NULL # # NULL latin1_swedish_ci NULL 0 N
DROP TABLE t1;
+ALTER TABLE t2 ADD INDEX(b);
+ERROR HY000: Index column size too large. The maximum column size is 767 bytes
+ALTER TABLE t2 FORCE, ADD INDEX(b);
+ERROR HY000: Index column size too large. The maximum column size is 767 bytes
+SET GLOBAL innodb_default_row_format = DYNAMIC;
+ALTER TABLE t2 ADD INDEX(b);
+ERROR HY000: Index column size too large. The maximum column size is 767 bytes
+ALTER TABLE t2 FORCE, ADD INDEX(b);
+DROP TABLE t2;
###################################
-# Check the row_format effect on ALTER, ALGORITH=COPY on
+# Check the row_format effect on ALTER, ALGORITHM=COPY on
# create table with explicit row_format
CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ROW_FORMAT=REDUNDANT ENGINE=INNODB;
INSERT INTO t1 VALUES (1, REPEAT('abc',1000));
diff --git a/mysql-test/suite/innodb/t/default_row_format_alter.test b/mysql-test/suite/innodb/t/default_row_format_alter.test
index 7cd4d672858..f5dd246efb5 100644
--- a/mysql-test/suite/innodb/t/default_row_format_alter.test
+++ b/mysql-test/suite/innodb/t/default_row_format_alter.test
@@ -6,7 +6,7 @@ SET @row_format = @@GLOBAL.innodb_default_row_format;
--echo ####################################
--echo # Check if table rebuilding alter isn't affect if table is created
--echo # with explicit row_format
-eval CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ROW_FORMAT=COMPACT ENGINE=INNODB;
+CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ROW_FORMAT=COMPACT ENGINE=INNODB;
INSERT INTO t1 VALUES (1, 'abc');
--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 #
SHOW TABLE STATUS LIKE 't1';
@@ -23,12 +23,14 @@ DROP TABLE t1;
--echo # Check if table rebuilding alter is affected when there is no
--echo # row_format specified at CREATE TABLE.
SET GLOBAL innodb_default_row_format = COMPACT;
-eval CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ENGINE=INNODB;
+CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ENGINE=INNODB;
INSERT INTO t1 VALUES (1, 'abc');
--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 #
SHOW TABLE STATUS LIKE 't1';
+CREATE TABLE t2 (b VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL) ENGINE=InnoDB;
+
SET GLOBAL innodb_default_row_format = DYNAMIC;
ALTER TABLE t1 DROP PRIMARY KEY, ADD COLUMN c INT PRIMARY KEY;
@@ -38,15 +40,22 @@ ALTER TABLE t1 DROP PRIMARY KEY, ADD COLUMN c INT PRIMARY KEY;
SHOW TABLE STATUS LIKE 't1';
DROP TABLE t1;
+--error ER_INDEX_COLUMN_TOO_LONG
+ALTER TABLE t2 ADD INDEX(b);
+ALTER TABLE t2 FORCE, ADD INDEX(b);
+DROP TABLE t2;
+
--echo ####################################
--echo # Check the row_format effect on ALTER, ALGORITHM=COPY
SET GLOBAL innodb_default_row_format = REDUNDANT;
-eval CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ENGINE=INNODB;
+CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ENGINE=INNODB;
INSERT INTO t1 VALUES (1, REPEAT('abc',1000));
--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 #
SHOW TABLE STATUS LIKE 't1';
+CREATE TABLE t2 (b VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL) ENGINE=InnoDB;
+
SET GLOBAL innoDB_default_row_format = COMPACT;
ALTER TABLE t1 ADD COLUMN c2 BLOB, ALGORITHM=COPY;
@@ -56,11 +65,23 @@ ALTER TABLE t1 ADD COLUMN c2 BLOB, ALGORITHM=COPY;
SHOW TABLE STATUS LIKE 't1';
DROP TABLE t1;
+--error ER_INDEX_COLUMN_TOO_LONG
+ALTER TABLE t2 ADD INDEX(b);
+--error ER_INDEX_COLUMN_TOO_LONG
+ALTER TABLE t2 FORCE, ADD INDEX(b);
+
+SET GLOBAL innodb_default_row_format = DYNAMIC;
+--error ER_INDEX_COLUMN_TOO_LONG
+ALTER TABLE t2 ADD INDEX(b);
+ALTER TABLE t2 FORCE, ADD INDEX(b);
+
+DROP TABLE t2;
+
--echo
--echo ###################################
---echo # Check the row_format effect on ALTER, ALGORITH=COPY on
+--echo # Check the row_format effect on ALTER, ALGORITHM=COPY on
--echo # create table with explicit row_format
-eval CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ROW_FORMAT=REDUNDANT ENGINE=INNODB;
+CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ROW_FORMAT=REDUNDANT ENGINE=INNODB;
INSERT INTO t1 VALUES (1, REPEAT('abc',1000));
--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 #
@@ -81,7 +102,7 @@ DROP TABLE t1;
--echo # Check row_format on ALTER ALGORITHM=INPLACE
SET GLOBAL innodb_default_row_format=COMPACT;
-eval CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT, KEY k1(b(10))) ENGINE=INNODB;
+CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT, KEY k1(b(10))) ENGINE=INNODB;
INSERT INTO t1 VALUES (1, REPEAT('abc',1000));
--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 #
diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_lz4.test b/mysql-test/suite/innodb/t/innodb-page_compression_lz4.test
index 49255d3a1ac..ec9bc456e74 100644
--- a/mysql-test/suite/innodb/t/innodb-page_compression_lz4.test
+++ b/mysql-test/suite/innodb/t/innodb-page_compression_lz4.test
@@ -1,6 +1,8 @@
-- source include/have_innodb.inc
-- source include/have_innodb_lz4.inc
-- source include/not_embedded.inc
+# The test can take very long time with valgrind
+--source include/not_valgrind.inc
# lz4
set global innodb_compression_algorithm = 2;
diff --git a/mysql-test/suite/innodb/t/innodb_sys_semaphore_waits.test b/mysql-test/suite/innodb/t/innodb_sys_semaphore_waits.test
index ccd9e3d70f4..a0b9fc626f3 100644
--- a/mysql-test/suite/innodb/t/innodb_sys_semaphore_waits.test
+++ b/mysql-test/suite/innodb/t/innodb_sys_semaphore_waits.test
@@ -88,7 +88,7 @@ while (!$mysql_errno)
if (!$counter)
{
# This will fail this test.
- --die Server failed to dissapear
+ --die Server failed to disappear
}
--sleep 1
}
diff --git a/mysql-test/suite/innodb_zip/r/innochecksum_3.result b/mysql-test/suite/innodb_zip/r/innochecksum_3.result
index d17ea8dc9ce..7de90721d64 100644
--- a/mysql-test/suite/innodb_zip/r/innochecksum_3.result
+++ b/mysql-test/suite/innodb_zip/r/innochecksum_3.result
@@ -213,10 +213,10 @@ Filename::tab#.ibd
# allow-mismatches,page,start-page,end-page
[9]: check the both short and long options "page" and "start-page" when
# seek value is larger than file size.
-FOUND 1 /Error: Unable to seek to necessary offset: Invalid argument/ in my_restart.err
-FOUND 1 /Error: Unable to seek to necessary offset: Invalid argument/ in my_restart.err
-FOUND 1 /Error: Unable to seek to necessary offset: Invalid argument/ in my_restart.err
-FOUND 1 /Error: Unable to seek to necessary offset: Invalid argument/ in my_restart.err
+FOUND 1 /Error: Unable to seek to necessary offset/ in my_restart.err
+FOUND 1 /Error: Unable to seek to necessary offset/ in my_restart.err
+FOUND 1 /Error: Unable to seek to necessary offset/ in my_restart.err
+FOUND 1 /Error: Unable to seek to necessary offset/ in my_restart.err
[34]: check the invalid upper bound values for options, allow-mismatches, end-page, start-page and page.
# innochecksum will fail with error code: 1
NOT FOUND /Incorrect unsigned integer value: '18446744073709551616'/ in my_restart.err
diff --git a/mysql-test/suite/innodb_zip/t/innochecksum_3.test b/mysql-test/suite/innodb_zip/t/innochecksum_3.test
index dab10dcc997..6d14d4c334e 100644
--- a/mysql-test/suite/innodb_zip/t/innochecksum_3.test
+++ b/mysql-test/suite/innodb_zip/t/innochecksum_3.test
@@ -339,22 +339,19 @@ cat_file $MYSQLTEST_VARDIR/tmp/dump.txt;
--echo # seek value is larger than file size.
--error 1
--exec $INNOCHECKSUM --page=18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
-let SEARCH_PATTERN= Error: Unable to seek to necessary offset: Invalid argument;
+let SEARCH_PATTERN= Error: Unable to seek to necessary offset;
--source include/search_pattern_in_file.inc
--error 1
--exec $INNOCHECKSUM -p 18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
-let SEARCH_PATTERN= Error: Unable to seek to necessary offset: Invalid argument;
--source include/search_pattern_in_file.inc
--error 1
--exec $INNOCHECKSUM --start-page=18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
-let SEARCH_PATTERN= Error: Unable to seek to necessary offset: Invalid argument;
--source include/search_pattern_in_file.inc
--error 1
--exec $INNOCHECKSUM -s 18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
-let SEARCH_PATTERN= Error: Unable to seek to necessary offset: Invalid argument;
--source include/search_pattern_in_file.inc
--echo [34]: check the invalid upper bound values for options, allow-mismatches, end-page, start-page and page.
diff --git a/mysql-test/suite/roles/set_default_role_clear.result b/mysql-test/suite/roles/set_default_role_clear.result
index 281ed7e45ea..d8508f5d0d6 100644
--- a/mysql-test/suite/roles/set_default_role_clear.result
+++ b/mysql-test/suite/roles/set_default_role_clear.result
@@ -17,7 +17,7 @@ Grants for test_user@localhost
GRANT `test_role` TO `test_user`@`localhost`
GRANT USAGE ON *.* TO `test_user`@`localhost`
GRANT SELECT ON *.* TO `test_role`
-SET DEFAULT ROLE test_role FOR 'test_user'@'localhost'
+SET DEFAULT ROLE `test_role` FOR `test_user`@`localhost`
select user, host, default_role from mysql.user where user='test_user';
User Host default_role
test_user localhost test_role
diff --git a/mysql-test/suite/roles/set_default_role_for.result b/mysql-test/suite/roles/set_default_role_for.result
index fec43b8e763..3ddf48eb416 100644
--- a/mysql-test/suite/roles/set_default_role_for.result
+++ b/mysql-test/suite/roles/set_default_role_for.result
@@ -14,14 +14,14 @@ set default role role_a for user_a@localhost;
set default role invalid_role for user_a@localhost;
ERROR OP000: Invalid role specification `invalid_role`
set default role role_b for user_a@localhost;
-ERROR OP000: User `user_a@localhost` has not been granted role `role_b`
+ERROR OP000: User `root`@`localhost` has not been granted role `role_b`
set default role role_b for user_b@localhost;
show grants;
Grants for user_a@localhost
GRANT `role_a` TO `user_a`@`localhost`
GRANT USAGE ON *.* TO `user_a`@`localhost`
GRANT SELECT ON *.* TO `role_a`
-SET DEFAULT ROLE role_a FOR 'user_a'@'localhost'
+SET DEFAULT ROLE `role_a` FOR `user_a`@`localhost`
select user, host, default_role from mysql.user where user like 'user_%';
User Host default_role
user_a localhost role_a
@@ -37,13 +37,13 @@ User Host default_role
user_a localhost role_a
user_b localhost role_b
set default role role_b for current_user;
-ERROR OP000: User `user_a@localhost` has not been granted role `role_b`
+ERROR OP000: User `user_a`@`localhost` has not been granted role `role_b`
show grants;
Grants for user_b@localhost
GRANT `role_b` TO `user_b`@`localhost`
GRANT USAGE ON *.* TO `user_b`@`localhost`
GRANT INSERT, UPDATE ON *.* TO `role_b`
-SET DEFAULT ROLE role_b FOR 'user_b'@'localhost'
+SET DEFAULT ROLE `role_b` FOR `user_b`@`localhost`
select user, host, default_role from mysql.user where user like 'user_%';
ERROR 42000: SELECT command denied to user 'user_b'@'localhost' for table 'user'
set default role NONE for user_a@localhost;
diff --git a/mysql-test/suite/roles/set_default_role_invalid.result b/mysql-test/suite/roles/set_default_role_invalid.result
index 08087acc51f..eb3924dc617 100644
--- a/mysql-test/suite/roles/set_default_role_invalid.result
+++ b/mysql-test/suite/roles/set_default_role_invalid.result
@@ -24,7 +24,7 @@ Grants for test_user@localhost
GRANT `test_role` TO `test_user`@`localhost`
GRANT USAGE ON *.* TO `test_user`@`localhost`
GRANT SELECT ON *.* TO `test_role`
-SET DEFAULT ROLE test_role FOR 'test_user'@'localhost'
+SET DEFAULT ROLE `test_role` FOR `test_user`@`localhost`
select user, host, default_role from mysql.user where user='test_user';
User Host default_role
test_user localhost test_role
@@ -48,7 +48,7 @@ CREATE USER b;
CREATE ROLE r1;
CREATE ROLE r2;
SET DEFAULT ROLE r1 FOR a;
-ERROR OP000: User `a@%` has not been granted role `r1`
+ERROR OP000: User `root`@`localhost` has not been granted role `r1`
GRANT r1 TO b;
GRANT r2 TO b;
SET DEFAULT ROLE r1 FOR b;
@@ -72,7 +72,7 @@ GRANT `r1` TO `b`@`%`
GRANT `r2` TO `b`@`%`
GRANT USAGE ON *.* TO `b`@`%`
GRANT SELECT ON `mysql`.* TO `b`@`%`
-SET DEFAULT ROLE r2 FOR 'b'@'%'
+SET DEFAULT ROLE `r2` FOR `b`@`%`
SET DEFAULT ROLE r1 FOR a;
ERROR 42000: Access denied for user 'b'@'%' to database 'mysql'
SELECT CURRENT_ROLE;
@@ -98,9 +98,9 @@ GRANT `r1` TO `b`@`%`
GRANT `r2` TO `b`@`%`
GRANT USAGE ON *.* TO `b`@`%`
GRANT SELECT, UPDATE ON `mysql`.* TO `b`@`%`
-SET DEFAULT ROLE r2 FOR 'b'@'%'
+SET DEFAULT ROLE `r2` FOR `b`@`%`
SET DEFAULT ROLE r1 FOR a;
-ERROR OP000: User `a@%` has not been granted role `r1`
+ERROR OP000: User `b`@`%` has not been granted role `r1`
SET DEFAULT ROLE invalid_role;
ERROR OP000: Invalid role specification `invalid_role`
SET DEFAULT ROLE invalid_role FOR a;
@@ -117,7 +117,7 @@ SET DEFAULT ROLE None;
# Change user b (session 3: role granted to user a)
SET DEFAULT ROLE r1 FOR a;
SET DEFAULT ROLE r2 FOR a;
-ERROR OP000: User `a@%` has not been granted role `r2`
+ERROR OP000: User `b`@`%` has not been granted role `r2`
SET DEFAULT ROLE invalid_role;
ERROR OP000: Invalid role specification `invalid_role`
SET DEFAULT ROLE invalid_role FOR a;
diff --git a/mysql-test/suite/roles/set_default_role_new_connection.result b/mysql-test/suite/roles/set_default_role_new_connection.result
index 71035737f99..5c51b782ab7 100644
--- a/mysql-test/suite/roles/set_default_role_new_connection.result
+++ b/mysql-test/suite/roles/set_default_role_new_connection.result
@@ -23,7 +23,7 @@ Grants for test_user@localhost
GRANT `test_role` TO `test_user`@`localhost`
GRANT USAGE ON *.* TO `test_user`@`localhost`
GRANT SELECT ON *.* TO `test_role`
-SET DEFAULT ROLE test_role FOR 'test_user'@'localhost'
+SET DEFAULT ROLE `test_role` FOR `test_user`@`localhost`
select user, host, default_role from mysql.user where user = 'test_user';
User Host default_role
test_user localhost test_role
@@ -52,7 +52,7 @@ Grants for test_user@localhost
GRANT `test_role` TO `test_user`@`localhost`
GRANT USAGE ON *.* TO `test_user`@`localhost`
GRANT SELECT ON *.* TO `test_role`
-SET DEFAULT ROLE test_role FOR 'test_user'@'localhost'
+SET DEFAULT ROLE `test_role` FOR `test_user`@`localhost`
select user, host, default_role from mysql.user where user = 'test_user';
User Host default_role
test_user localhost test_role
diff --git a/mysql-test/suite/roles/set_role-recursive.result b/mysql-test/suite/roles/set_role-recursive.result
index be11728ad4e..102ee392581 100644
--- a/mysql-test/suite/roles/set_role-recursive.result
+++ b/mysql-test/suite/roles/set_role-recursive.result
@@ -67,7 +67,7 @@ Grants for test_user@localhost
GRANT USAGE ON *.* TO `test_user`@`localhost`
GRANT `test_role1` TO `test_user`@`localhost`
set role test_role2;
-ERROR OP000: User `test_user@localhost` has not been granted role `test_role2`
+ERROR OP000: User `test_user`@`localhost` has not been granted role `test_role2`
select current_user(), current_role();
current_user() current_role()
test_user@localhost NULL
diff --git a/mysql-test/suite/rpl/r/create_or_replace_mix.result b/mysql-test/suite/rpl/r/create_or_replace_mix.result
index 661278aa7ef..b44b2a5c10f 100644
--- a/mysql-test/suite/rpl/r/create_or_replace_mix.result
+++ b/mysql-test/suite/rpl/r/create_or_replace_mix.result
@@ -100,6 +100,9 @@ include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t1 (a int)
+master-bin.000001 # Gtid # # BEGIN GTID #-#-#
+master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t1`/* Generated to handle failed CREATE OR REPLACE */
+master-bin.000001 # Query # # ROLLBACK
drop table if exists t1,t2;
Warnings:
Note 1051 Unknown table 'test.t1'
diff --git a/mysql-test/suite/rpl/r/create_or_replace_row.result b/mysql-test/suite/rpl/r/create_or_replace_row.result
index c45daefd671..16f92b5e4b6 100644
--- a/mysql-test/suite/rpl/r/create_or_replace_row.result
+++ b/mysql-test/suite/rpl/r/create_or_replace_row.result
@@ -128,6 +128,9 @@ include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t1 (a int)
+master-bin.000001 # Gtid # # BEGIN GTID #-#-#
+master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t1`/* Generated to handle failed CREATE OR REPLACE */
+master-bin.000001 # Query # # ROLLBACK
drop table if exists t1,t2;
Warnings:
Note 1051 Unknown table 'test.t1'
diff --git a/mysql-test/suite/rpl/r/create_or_replace_statement.result b/mysql-test/suite/rpl/r/create_or_replace_statement.result
index f95b451e5ec..4d6409b1710 100644
--- a/mysql-test/suite/rpl/r/create_or_replace_statement.result
+++ b/mysql-test/suite/rpl/r/create_or_replace_statement.result
@@ -103,6 +103,8 @@ include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t1 (a int)
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t1`/* Generated to handle failed CREATE OR REPLACE */
drop table if exists t1,t2;
Warnings:
Note 1051 Unknown table 'test.t1'
diff --git a/mysql-test/suite/rpl/t/rpl_trunc_temp.test b/mysql-test/suite/rpl/t/rpl_trunc_temp.test
index 0e7d5483f62..1ef0fcedd1d 100644
--- a/mysql-test/suite/rpl/t/rpl_trunc_temp.test
+++ b/mysql-test/suite/rpl/t/rpl_trunc_temp.test
@@ -42,7 +42,7 @@ truncate t1;
sync_slave_with_master;
show status like 'Slave_open_temp_tables';
-# Disconnect the master, temp table on slave should dissapear
+# Disconnect the master, temp table on slave should disappear
disconnect master;
connection slave;
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 7a8984a3736..9e562426291 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
@@ -3349,7 +3349,7 @@ VARIABLE_COMMENT Default value for the FOR SYSTEM_TIME AS OF clause
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
-ENUM_VALUE_LIST DEFAULT
+ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT NULL
VARIABLE_NAME TABLE_DEFINITION_CACHE
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 79512aa9032..b9e4aac3288 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
@@ -4039,7 +4039,7 @@ VARIABLE_COMMENT Default value for the FOR SYSTEM_TIME AS OF clause
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
-ENUM_VALUE_LIST DEFAULT
+ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT NULL
VARIABLE_NAME TABLE_DEFINITION_CACHE
diff --git a/mysql-test/suite/sys_vars/t/innodb_fatal_semaphore_wait_threshold.test b/mysql-test/suite/sys_vars/t/innodb_fatal_semaphore_wait_threshold.test
index e9dd0c71936..4563e9b4469 100644
--- a/mysql-test/suite/sys_vars/t/innodb_fatal_semaphore_wait_threshold.test
+++ b/mysql-test/suite/sys_vars/t/innodb_fatal_semaphore_wait_threshold.test
@@ -89,7 +89,7 @@ while (!$mysql_errno)
if (!$counter)
{
# This will fail this test.
- --die Server failed to dissapear
+ --die Server failed to disappear
}
--sleep 1
}
diff --git a/mysql-test/suite/vcol/r/binlog.result b/mysql-test/suite/vcol/r/binlog.result
index d4893b7ed3c..463928b97b8 100644
--- a/mysql-test/suite/vcol/r/binlog.result
+++ b/mysql-test/suite/vcol/r/binlog.result
@@ -80,4 +80,18 @@ Warnings:
Warning 1265 Data truncated for column 'b' at row 1
Warning 1265 Data truncated for column 'b' at row 2
DROP TABLE t1;
+#
+# MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols
+#
+SET SESSION binlog_row_image= noblob;
+CREATE TEMPORARY TABLE t1 SELECT UUID();
+show create table t1;
+Table Create Table
+t1 CREATE TEMPORARY TABLE `t1` (
+ `UUID()` varchar(36) CHARACTER SET utf8 DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+CREATE TABLE t2 (a INT PRIMARY KEY, b TEXT, c INT GENERATED ALWAYS AS(b));
+INSERT INTO t2 (a,b) VALUES (1,1);
+SET SESSION binlog_row_image= default;
+DROP TABLE t2;
include/rpl_end.inc
diff --git a/mysql-test/suite/vcol/t/binlog.test b/mysql-test/suite/vcol/t/binlog.test
index aa939086f12..edf0a8957b9 100644
--- a/mysql-test/suite/vcol/t/binlog.test
+++ b/mysql-test/suite/vcol/t/binlog.test
@@ -66,4 +66,18 @@ UPDATE IGNORE t1 SET a = NULL;
DROP TABLE t1;
+--echo #
+--echo # MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols
+--echo #
+
+SET SESSION binlog_row_image= noblob;
+CREATE TEMPORARY TABLE t1 SELECT UUID();
+show create table t1;
+CREATE TABLE t2 (a INT PRIMARY KEY, b TEXT, c INT GENERATED ALWAYS AS(b));
+INSERT INTO t2 (a,b) VALUES (1,1);
+
+SET SESSION binlog_row_image= default;
+DROP TABLE t2;
+
+
--source include/rpl_end.inc
diff --git a/mysql-test/suite/versioning/r/create.result b/mysql-test/suite/versioning/r/create.result
index 001af7bfc6a..75f7b560f30 100644
--- a/mysql-test/suite/versioning/r/create.result
+++ b/mysql-test/suite/versioning/r/create.result
@@ -592,3 +592,22 @@ t2 CREATE TEMPORARY TABLE `t2` (
) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
drop temporary table t2;
drop table t1;
+#
+# MDEV-16857 system-invisible row_end is displayed in SHOW INDEX
+#
+create or replace table t1 (id int primary key, x int) with system versioning;
+select table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name
+from information_schema.statistics where table_name = 't1';
+table_schema table_name non_unique index_schema index_name seq_in_index column_name
+test t1 0 test PRIMARY 1 id
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+t1 0 PRIMARY 1 id # # # # # #
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `x` int(11) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+drop table t1;
diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result
index 9eeec045ef7..9ccc900cd12 100644
--- a/mysql-test/suite/versioning/r/partition.result
+++ b/mysql-test/suite/versioning/r/partition.result
@@ -734,6 +734,27 @@ create or replace table t1 (a int) with system versioning;
alter table t1 partition by system_time (partition pn current);
ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
drop table t1;
+#
+# MDEV-22247 History partition overflow leads to wrong SELECT result
+#
+set timestamp= unix_timestamp('2000-01-01 00:00:00');
+create or replace table t1 (x int) with system versioning
+partition by system_time interval 1 hour
+(partition p0 history, partition p1 history, partition pn current);
+insert into t1 values (0);
+update t1 set x= x + 1;
+set timestamp= unix_timestamp('2000-01-01 02:00:01');
+update t1 set x= x + 1;
+select *, row_start, row_end from t1 for system_time as of '2000-01-01 02:00:00';
+x row_start row_end
+1 2000-01-01 00:00:00.000000 2000-01-01 02:00:01.000000
+explain partitions select * from t1 for system_time as of '2000-01-01 02:00:00';
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1,pn ALL NULL NULL NULL NULL # Using where
+explain partitions select * from t1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 pn # NULL NULL NULL NULL # #
+drop table t1;
# End of 10.3 tests
#
# MDEV-22283 Server crashes in key_copy or unexpected error 156: The table already existed in the storage engine
diff --git a/mysql-test/suite/versioning/r/sysvars-notembedded.result b/mysql-test/suite/versioning/r/sysvars-notembedded.result
new file mode 100644
index 00000000000..8b1ad6cfc58
--- /dev/null
+++ b/mysql-test/suite/versioning/r/sysvars-notembedded.result
@@ -0,0 +1,30 @@
+create table t (a int) with system versioning;
+set @before= UNIX_TIMESTAMP(now(6));
+insert into t values (1);
+set @after= UNIX_TIMESTAMP(now(6));
+update t set a= 2;
+set global system_versioning_asof= FROM_UNIXTIME(@after);
+set system_versioning_asof= FROM_UNIXTIME(@after);
+select * from t as nonempty;
+a
+1
+connect subcon,127.0.0.1,root,,,$SERVER_MYPORT_1;
+connection subcon;
+select * from t as nonempty;
+a
+1
+disconnect subcon;
+connection default;
+set global system_versioning_asof= FROM_UNIXTIME(@before);
+select * from t as nonempty;
+a
+1
+connect subcon,127.0.0.1,root,,,$SERVER_MYPORT_1;
+connection subcon;
+select * from t as empty;
+a
+disconnect subcon;
+connection default;
+drop table t;
+set global system_versioning_asof= DEFAULT;
+set system_versioning_asof= DEFAULT;
diff --git a/mysql-test/suite/versioning/r/sysvars.result b/mysql-test/suite/versioning/r/sysvars.result
index 66513741631..a5a3f79990c 100644
--- a/mysql-test/suite/versioning/r/sysvars.result
+++ b/mysql-test/suite/versioning/r/sysvars.result
@@ -1,5 +1,7 @@
create table t (a int) with system versioning;
+set @before= UNIX_TIMESTAMP(now(6));
insert into t values (1);
+set @after= UNIX_TIMESTAMP(now(6));
update t set a= 2;
show global variables like 'system_versioning_asof';
Variable_name Value
@@ -56,65 +58,71 @@ ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of '201
set system_versioning_asof= '0000-00-00 00:00';
ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of '0000-00-00 00:00'
# GLOBAL @@system_versioning_asof
-set global system_versioning_asof= '1911-11-11 11:11:11.1111119';
+set global system_versioning_asof= '1991-11-11 11:11:11.1111119';
Warnings:
-Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
-Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
+Note 1292 Truncated incorrect datetime value: '1991-11-11 11:11:11.1111119'
show global variables like 'system_versioning_asof';
Variable_name Value
-system_versioning_asof 1911-11-11 11:11:11.111111
-set global system_versioning_asof= '1900-01-01 00:00:00';
+system_versioning_asof 1991-11-11 11:11:11.111111
+set global system_versioning_asof= '1990-01-01 00:00:00';
show global variables like 'system_versioning_asof';
Variable_name Value
-system_versioning_asof 1900-01-01 00:00:00.000000
-set global system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119';
+system_versioning_asof 1990-01-01 00:00:00.000000
+set global system_versioning_asof= timestamp'1991-11-11 11:11:11.1111119';
Warnings:
-Note 1292 Truncated incorrect DATETIME value: '1911-11-11 11:11:11.1111119'
+Note 1292 Truncated incorrect DATETIME value: '1991-11-11 11:11:11.1111119'
show global variables like 'system_versioning_asof';
Variable_name Value
-system_versioning_asof 1911-11-11 11:11:11.111111
-set @ts= timestamp'1900-01-01 00:00:00';
+system_versioning_asof 1991-11-11 11:11:11.111111
+set @ts= timestamp'1990-01-01 00:00:00';
set global system_versioning_asof= @ts;
show global variables like 'system_versioning_asof';
Variable_name Value
-system_versioning_asof 1900-01-01 00:00:00.000000
+system_versioning_asof 1990-01-01 00:00:00.000000
set global system_versioning_asof= default;
select @@global.system_versioning_asof;
@@global.system_versioning_asof
DEFAULT
# SESSION @@system_versioning_asof
-set system_versioning_asof= '1911-11-11 11:11:11.1111119';
+set system_versioning_asof= '1991-11-11 11:11:11.1111119';
Warnings:
-Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
-Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
+Note 1292 Truncated incorrect datetime value: '1991-11-11 11:11:11.1111119'
show variables like 'system_versioning_asof';
Variable_name Value
-system_versioning_asof 1911-11-11 11:11:11.111111
-set system_versioning_asof= '1900-01-01 00:00:00';
+system_versioning_asof 1991-11-11 11:11:11.111111
+set system_versioning_asof= '1990-01-01 00:00:00';
show variables like 'system_versioning_asof';
Variable_name Value
-system_versioning_asof 1900-01-01 00:00:00.000000
-set system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119';
+system_versioning_asof 1990-01-01 00:00:00.000000
+set system_versioning_asof= timestamp'1991-11-11 11:11:11.1111119';
Warnings:
-Note 1292 Truncated incorrect DATETIME value: '1911-11-11 11:11:11.1111119'
+Note 1292 Truncated incorrect DATETIME value: '1991-11-11 11:11:11.1111119'
show variables like 'system_versioning_asof';
Variable_name Value
-system_versioning_asof 1911-11-11 11:11:11.111111
-set @ts= timestamp'1900-01-01 00:00:00';
+system_versioning_asof 1991-11-11 11:11:11.111111
+set @ts= timestamp'1990-01-01 00:00:00';
set system_versioning_asof= @ts;
show variables like 'system_versioning_asof';
Variable_name Value
-system_versioning_asof 1900-01-01 00:00:00.000000
+system_versioning_asof 1990-01-01 00:00:00.000000
# DEFAULT: value is copied from GLOBAL to SESSION
-set global system_versioning_asof= timestamp'1911-11-11 11:11:11.111111';
-set system_versioning_asof= '1900-01-01 00:00:00';
+set global time_zone= "+03:00";
+set time_zone= "+10:00";
+set global system_versioning_asof= timestamp'1991-11-11 11:11:11.111111';
+set system_versioning_asof= '1990-01-01 00:00:00';
select @@global.system_versioning_asof != @@system_versioning_asof as different;
different
1
set system_versioning_asof= default;
+select @@global.system_versioning_asof != @@system_versioning_asof as different;
+different
+1
+set global system_versioning_asof= default;
select @@global.system_versioning_asof = @@system_versioning_asof as equal;
equal
1
+set global time_zone= DEFAULT;
+set time_zone= DEFAULT;
set global system_versioning_asof= DEFAULT;
set system_versioning_asof= DEFAULT;
select @@global.system_versioning_asof, @@system_versioning_asof;
@@ -142,6 +150,56 @@ select * from t for system_time between '1970-01-01 00:00' and current_timestamp
a
2
1
+# MDEV-16026: Global system_versioning_asof must not be used if client sessions can have non-default time zone
+# changing time zone should not abuse `system_versioning_asof`
+set session time_zone = '+10:00';
+set global system_versioning_asof = '1999-09-08 00:00:00.000000';
+show global variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1999-09-08 00:00:00.000000
+set session time_zone = '+03:00';
+show global variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1999-09-07 17:00:00.000000
+set session time_zone = '+03:00';
+set session system_versioning_asof = '2000-09-08 00:00:00.000000';
+show session variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 2000-09-08 00:00:00.000000
+set session time_zone = '+10:00';
+show session variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 2000-09-08 07:00:00.000000
+# global and local time zones should not interfere
+show global variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1999-09-08 00:00:00.000000
+set time_zone= "+10:00";
+set system_versioning_asof= FROM_UNIXTIME(@before);
+select * from t as empty;
+a
+set system_versioning_asof= FROM_UNIXTIME(@after);
+select * from t as nonempty;
+a
+1
+set time_zone= "+03:00";
+set system_versioning_asof= FROM_UNIXTIME(@before);
+select * from t as empty;
+a
+set system_versioning_asof= FROM_UNIXTIME(@after);
+select * from t as nonempty;
+a
+1
+# MDEV-16481: set global system_versioning_asof=sf() crashes in specific case
+# Using global variable inside a stored function should not crash
+create or replace function now_global() returns timestamp
+return CONVERT_TZ(now(), @@session.time_zone, @@global.time_zone);
+set global system_versioning_asof= now_global();
+drop function now_global;
+set global time_zone= "SYSTEM";
+set time_zone= "SYSTEM";
+set global system_versioning_asof= default;
+set system_versioning_asof= default;
show status like "Feature_system_versioning";
Variable_name Value
Feature_system_versioning 2
@@ -153,7 +211,7 @@ create or replace table t1 (x int) with system versioning;
create or replace table t2 (y int);
insert into t1 values (1);
insert into t2 values (1);
-set system_versioning_asof= '1970-01-01 00:00:00';
+set system_versioning_asof= '1970-01-02 00:00:00';
delete t1, t2 from t1 join t2 where t1.x = t2.y;
select * from t1 for system_time as of timestamp now(6);
x
diff --git a/mysql-test/suite/versioning/t/create.test b/mysql-test/suite/versioning/t/create.test
index 1f016fed871..6f8cff3ca2e 100644
--- a/mysql-test/suite/versioning/t/create.test
+++ b/mysql-test/suite/versioning/t/create.test
@@ -439,3 +439,15 @@ show create table t1;
show create table t2;
drop temporary table t2;
drop table t1;
+
+--echo #
+--echo # MDEV-16857 system-invisible row_end is displayed in SHOW INDEX
+--echo #
+create or replace table t1 (id int primary key, x int) with system versioning;
+select table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name
+from information_schema.statistics where table_name = 't1';
+--replace_column 6 # 7 # 8 # 9 # 10 # 11 #
+show index from t1;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t1;
+drop table t1;
diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test
index f50e6c07b64..c6279444a6a 100644
--- a/mysql-test/suite/versioning/t/partition.test
+++ b/mysql-test/suite/versioning/t/partition.test
@@ -697,6 +697,27 @@ alter table t1 partition by system_time (partition pn current);
# Cleanup
drop table t1;
+--echo #
+--echo # MDEV-22247 History partition overflow leads to wrong SELECT result
+--echo #
+set timestamp= unix_timestamp('2000-01-01 00:00:00');
+create or replace table t1 (x int) with system versioning
+partition by system_time interval 1 hour
+(partition p0 history, partition p1 history, partition pn current);
+
+insert into t1 values (0);
+update t1 set x= x + 1;
+
+set timestamp= unix_timestamp('2000-01-01 02:00:01');
+update t1 set x= x + 1;
+
+select *, row_start, row_end from t1 for system_time as of '2000-01-01 02:00:00';
+--replace_column 10 #
+explain partitions select * from t1 for system_time as of '2000-01-01 02:00:00';
+--replace_column 5 # 10 # 11 #
+explain partitions select * from t1;
+drop table t1;
+
--echo # End of 10.3 tests
--echo #
diff --git a/mysql-test/suite/versioning/t/sysvars-notembedded.test b/mysql-test/suite/versioning/t/sysvars-notembedded.test
new file mode 100644
index 00000000000..314972bc375
--- /dev/null
+++ b/mysql-test/suite/versioning/t/sysvars-notembedded.test
@@ -0,0 +1,31 @@
+source include/not_embedded.inc;
+
+create table t (a int) with system versioning;
+set @before= UNIX_TIMESTAMP(now(6));
+insert into t values (1);
+set @after= UNIX_TIMESTAMP(now(6));
+update t set a= 2;
+
+set global system_versioning_asof= FROM_UNIXTIME(@after);
+set system_versioning_asof= FROM_UNIXTIME(@after);
+select * from t as nonempty;
+
+--connect (subcon,127.0.0.1,root,,,$SERVER_MYPORT_1)
+--connection subcon
+select * from t as nonempty;
+--disconnect subcon
+--connection default
+
+set global system_versioning_asof= FROM_UNIXTIME(@before);
+select * from t as nonempty;
+
+--connect (subcon,127.0.0.1,root,,,$SERVER_MYPORT_1)
+--connection subcon
+select * from t as empty;
+--disconnect subcon
+--connection default
+
+drop table t;
+
+set global system_versioning_asof= DEFAULT;
+set system_versioning_asof= DEFAULT;
diff --git a/mysql-test/suite/versioning/t/sysvars.test b/mysql-test/suite/versioning/t/sysvars.test
index a1026418e98..ab1f612edf3 100644
--- a/mysql-test/suite/versioning/t/sysvars.test
+++ b/mysql-test/suite/versioning/t/sysvars.test
@@ -1,5 +1,7 @@
create table t (a int) with system versioning;
+set @before= UNIX_TIMESTAMP(now(6));
insert into t values (1);
+set @after= UNIX_TIMESTAMP(now(6));
update t set a= 2;
show global variables like 'system_versioning_asof';
@@ -51,16 +53,16 @@ set system_versioning_asof= '2011-00-28 00:00';
set system_versioning_asof= '0000-00-00 00:00';
--echo # GLOBAL @@system_versioning_asof
-set global system_versioning_asof= '1911-11-11 11:11:11.1111119';
+set global system_versioning_asof= '1991-11-11 11:11:11.1111119';
show global variables like 'system_versioning_asof';
-set global system_versioning_asof= '1900-01-01 00:00:00';
+set global system_versioning_asof= '1990-01-01 00:00:00';
show global variables like 'system_versioning_asof';
-set global system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119';
+set global system_versioning_asof= timestamp'1991-11-11 11:11:11.1111119';
show global variables like 'system_versioning_asof';
-set @ts= timestamp'1900-01-01 00:00:00';
+set @ts= timestamp'1990-01-01 00:00:00';
set global system_versioning_asof= @ts;
show global variables like 'system_versioning_asof';
@@ -68,26 +70,32 @@ set global system_versioning_asof= default;
select @@global.system_versioning_asof;
--echo # SESSION @@system_versioning_asof
-set system_versioning_asof= '1911-11-11 11:11:11.1111119';
+set system_versioning_asof= '1991-11-11 11:11:11.1111119';
show variables like 'system_versioning_asof';
-set system_versioning_asof= '1900-01-01 00:00:00';
+set system_versioning_asof= '1990-01-01 00:00:00';
show variables like 'system_versioning_asof';
-set system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119';
+set system_versioning_asof= timestamp'1991-11-11 11:11:11.1111119';
show variables like 'system_versioning_asof';
-set @ts= timestamp'1900-01-01 00:00:00';
+set @ts= timestamp'1990-01-01 00:00:00';
set system_versioning_asof= @ts;
show variables like 'system_versioning_asof';
--echo # DEFAULT: value is copied from GLOBAL to SESSION
-set global system_versioning_asof= timestamp'1911-11-11 11:11:11.111111';
-set system_versioning_asof= '1900-01-01 00:00:00';
+set global time_zone= "+03:00";
+set time_zone= "+10:00";
+set global system_versioning_asof= timestamp'1991-11-11 11:11:11.111111';
+set system_versioning_asof= '1990-01-01 00:00:00';
select @@global.system_versioning_asof != @@system_versioning_asof as different;
set system_versioning_asof= default;
+select @@global.system_versioning_asof != @@system_versioning_asof as different;
+set global system_versioning_asof= default;
select @@global.system_versioning_asof = @@system_versioning_asof as equal;
+set global time_zone= DEFAULT;
+set time_zone= DEFAULT;
set global system_versioning_asof= DEFAULT;
set system_versioning_asof= DEFAULT;
select @@global.system_versioning_asof, @@system_versioning_asof;
@@ -100,6 +108,47 @@ select * from t for system_time all;
select * from t for system_time from '1970-01-01 00:00' to current_timestamp(6);
select * from t for system_time between '1970-01-01 00:00' and current_timestamp(6);
+-- echo # MDEV-16026: Global system_versioning_asof must not be used if client sessions can have non-default time zone
+-- echo # changing time zone should not abuse `system_versioning_asof`
+
+set session time_zone = '+10:00';
+set global system_versioning_asof = '1999-09-08 00:00:00.000000';
+show global variables like 'system_versioning_asof';
+set session time_zone = '+03:00';
+show global variables like 'system_versioning_asof';
+
+set session time_zone = '+03:00';
+set session system_versioning_asof = '2000-09-08 00:00:00.000000';
+show session variables like 'system_versioning_asof';
+set session time_zone = '+10:00';
+show session variables like 'system_versioning_asof';
+-- echo # global and local time zones should not interfere
+show global variables like 'system_versioning_asof';
+
+set time_zone= "+10:00";
+set system_versioning_asof= FROM_UNIXTIME(@before);
+select * from t as empty;
+set system_versioning_asof= FROM_UNIXTIME(@after);
+select * from t as nonempty;
+
+set time_zone= "+03:00";
+set system_versioning_asof= FROM_UNIXTIME(@before);
+select * from t as empty;
+set system_versioning_asof= FROM_UNIXTIME(@after);
+select * from t as nonempty;
+
+--echo # MDEV-16481: set global system_versioning_asof=sf() crashes in specific case
+--echo # Using global variable inside a stored function should not crash
+create or replace function now_global() returns timestamp
+ return CONVERT_TZ(now(), @@session.time_zone, @@global.time_zone);
+set global system_versioning_asof= now_global();
+drop function now_global;
+
+set global time_zone= "SYSTEM";
+set time_zone= "SYSTEM";
+set global system_versioning_asof= default;
+set system_versioning_asof= default;
+
show status like "Feature_system_versioning";
drop table t;
@@ -111,7 +160,7 @@ create or replace table t1 (x int) with system versioning;
create or replace table t2 (y int);
insert into t1 values (1);
insert into t2 values (1);
-set system_versioning_asof= '1970-01-01 00:00:00';
+set system_versioning_asof= '1970-01-02 00:00:00';
delete t1, t2 from t1 join t2 where t1.x = t2.y;
select * from t1 for system_time as of timestamp now(6);
diff --git a/mysys/mf_qsort.c b/mysys/mf_qsort.c
index 3f91bb35354..b516639a341 100644
--- a/mysys/mf_qsort.c
+++ b/mysys/mf_qsort.c
@@ -114,7 +114,7 @@ qsort_t my_qsort(void *base_ptr, size_t count, size_t size, qsort_cmp cmp)
stack[0].low=stack[0].high=0;
#endif
pivot = (char *) my_alloca((int) size);
- ptr_cmp= size == sizeof(char*) && !((low - (char*) 0)& (sizeof(char*)-1));
+ ptr_cmp= size == sizeof(char*) && (intptr_t)low % sizeof(char*) == 0;
/* The following loop sorts elements between high and low */
do
diff --git a/pcre/AUTHORS b/pcre/AUTHORS
index bb8b32835bd..b3398bbc477 100644
--- a/pcre/AUTHORS
+++ b/pcre/AUTHORS
@@ -2,13 +2,13 @@ THE MAIN PCRE LIBRARY
---------------------
Written by: Philip Hazel
-Email local part: ph10
-Email domain: cam.ac.uk
+Email local part: Philip.Hazel
+Email domain: gmail.com
University of Cambridge Computing Service,
Cambridge, England.
-Copyright (c) 1997-2020 University of Cambridge
+Copyright (c) 1997-2021 University of Cambridge
All rights reserved
@@ -19,7 +19,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2010-2020 Zoltan Herczeg
+Copyright(c) 2010-2021 Zoltan Herczeg
All rights reserved.
@@ -30,7 +30,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2009-2020 Zoltan Herczeg
+Copyright(c) 2009-2021 Zoltan Herczeg
All rights reserved.
diff --git a/pcre/CMakeLists.txt b/pcre/CMakeLists.txt
index 857a96b9ef9..de8951d02fe 100644
--- a/pcre/CMakeLists.txt
+++ b/pcre/CMakeLists.txt
@@ -67,10 +67,17 @@
# 2013-11-05 PH added support for PARENS_NEST_LIMIT
# 2016-03-01 PH applied Chris Wilson's patch for MSVC static build
# 2016-06-24 PH applied Chris Wilson's revised patch (adds a separate option)
+# 2021-06-14 PH changed CMAKE_MODULE_PATH definition to add, not replace
+# 2021-06-14 PH applied Wolfgang Stöggl's patch for generating pcre-config and
+# libpcre*.pc files (Bugzilla #2583)
PROJECT(PCRE C CXX)
-SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) # for FindReadline.cmake
+# For FindReadline.cmake. This was changed to allow setting CMAKE_MODULE_PATH
+# on the command line.
+# SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) # for FindReadline.cmake
+
+LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
# Enable Unicode properties
OPTION(PCRE_SUPPORT_UNICODE_PROPERTIES "Unicode properties" ON)
@@ -83,6 +90,7 @@ INCLUDE(CheckIncludeFile)
INCLUDE(CheckIncludeFileCXX)
INCLUDE(CheckFunctionExists)
INCLUDE(CheckTypeSize)
+INCLUDE(GNUInstallDirs) # for CMAKE_INSTALL_LIBDIR
CHECK_INCLUDE_FILE(dirent.h HAVE_DIRENT_H)
CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT_H)
@@ -255,7 +263,7 @@ foreach(configure_line ${configure_lines})
foreach(_substitution_variable ${SEARCHED_VARIABLES})
string(TOUPPER ${_substitution_variable} _substitution_variable_upper)
if (NOT ${_substitution_variable_upper})
- string(REGEX MATCH "m4_define\\(${_substitution_variable}, \\[(.*)\\]" MACTHED_STRING ${configure_line})
+ string(REGEX MATCH "m4_define\\(${_substitution_variable}, \\[(.*)\\]" MATCHED_STRING ${configure_line})
if (CMAKE_MATCH_1)
set(${_substitution_variable_upper} ${CMAKE_MATCH_1})
endif()
@@ -442,7 +450,6 @@ MARK_AS_ADVANCED(PCRE_POSIX_MALLOC_THRESHOLD)
MARK_AS_ADVANCED(PCRE_SUPPORT_BSR_ANYCRLF)
MARK_AS_ADVANCED(PCRE_SUPPORT_UNICODE_PROPERTIES)
-
IF(PCRE_SHOW_REPORT)
STRING(TOUPPER "${CMAKE_BUILD_TYPE}" buildtype)
IF (CMAKE_C_FLAGS)
@@ -453,7 +460,7 @@ IF(PCRE_SHOW_REPORT)
ENDIF(CMAKE_CXX_FLAGS)
MESSAGE(STATUS "")
MESSAGE(STATUS "")
- MESSAGE(STATUS "PCRE configuration summary:")
+ MESSAGE(STATUS "PCRE-${PCRE_MAJOR}.${PCRE_MINOR} configuration summary:")
MESSAGE(STATUS "")
# MESSAGE(STATUS " Install prefix .................. : ${CMAKE_INSTALL_PREFIX}")
MESSAGE(STATUS " C compiler ...................... : ${CMAKE_C_COMPILER}")
diff --git a/pcre/ChangeLog b/pcre/ChangeLog
index 864ce2c3574..ed9d83207c3 100644
--- a/pcre/ChangeLog
+++ b/pcre/ChangeLog
@@ -1,8 +1,25 @@
ChangeLog for PCRE
------------------
-Note that the PCRE 8.xx series (PCRE1) is now in a bugfix-only state. All
-development is happening in the PCRE2 10.xx series.
+Note that the PCRE 8.xx series (PCRE1) is now at end of life. All development
+is happening in the PCRE2 10.xx series.
+
+
+Version 8.45 15-June-2021
+-------------------------
+
+This is the final release of PCRE1. A few minor tidies are included.
+
+1. CMakeLists.txt has two user-supplied patches applied, one to allow for the
+setting of MODULE_PATH, and the other to support the generation of pcre-config
+file and libpcre*.pc files.
+
+2. There was a memory leak if a compile error occurred when there were more
+than 20 named groups (Bugzilla #2613).
+
+3. Fixed some typos in code and documentation.
+
+4. Fixed a small (*MARK) bug in the interpreter (Bugzilla #2771).
Version 8.44 12 February-2020
diff --git a/pcre/LICENCE b/pcre/LICENCE
index 57a544814c8..803b4119e50 100644
--- a/pcre/LICENCE
+++ b/pcre/LICENCE
@@ -19,13 +19,13 @@ THE BASIC LIBRARY FUNCTIONS
---------------------------
Written by: Philip Hazel
-Email local part: ph10
-Email domain: cam.ac.uk
+Email local part: Philip.Hazel
+Email domain: gmail.com
University of Cambridge Computing Service,
Cambridge, England.
-Copyright (c) 1997-2020 University of Cambridge
+Copyright (c) 1997-2021 University of Cambridge
All rights reserved.
@@ -36,7 +36,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Email domain: freemail.hu
-Copyright(c) 2010-2020 Zoltan Herczeg
+Copyright(c) 2010-2021 Zoltan Herczeg
All rights reserved.
@@ -47,7 +47,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Email domain: freemail.hu
-Copyright(c) 2009-2020 Zoltan Herczeg
+Copyright(c) 2009-2021 Zoltan Herczeg
All rights reserved.
diff --git a/pcre/NEWS b/pcre/NEWS
index 3d91b67dfa9..bec4d4b3d39 100644
--- a/pcre/NEWS
+++ b/pcre/NEWS
@@ -1,8 +1,14 @@
News about PCRE releases
------------------------
-Note that this library (now called PCRE1) is now being maintained for bug fixes
-only. New projects are advised to use the new PCRE2 libraries.
+Note that this library (now called PCRE1) is no longer being maintained. New
+projects are advised to use the PCRE2 libraries.
+
+
+Release 8.45 15-June-2021
+-----------------------------
+
+This is the final PCRE1 release. A very few small issues have been fixed.
Release 8.44 12-February-2020
diff --git a/pcre/NON-AUTOTOOLS-BUILD b/pcre/NON-AUTOTOOLS-BUILD
index 37f6164475b..23c4e64f84a 100644
--- a/pcre/NON-AUTOTOOLS-BUILD
+++ b/pcre/NON-AUTOTOOLS-BUILD
@@ -5,8 +5,8 @@ NOTE: This document relates to PCRE releases that use the original API, with
library names libpcre, libpcre16, and libpcre32. January 2015 saw the first
release of a new API, known as PCRE2, with release numbers starting at 10.00
and library names libpcre2-8, libpcre2-16, and libpcre2-32. The old libraries
-(now called PCRE1) are still being maintained for bug fixes, but there will be
-no new development. New projects are advised to use the new PCRE2 libraries.
+(now called PCRE1) are now at end of life, and 8.45 is the final release. New
+projects are advised to use the new PCRE2 libraries.
This document contains the following sections:
@@ -768,6 +768,6 @@ Everything, source and executable, is in EBCDIC and native z/OS file formats.
However, this software is not maintained and will not be upgraded. If you are
new to PCRE you should be looking at PCRE2 (version 10.30 or later).
-===============================
-Last Updated: 13 September 2017
-===============================
+==========================
+Last Updated: 15 June 2021
+==========================
diff --git a/pcre/README b/pcre/README
index 334362b3e53..65f5e19ef69 100644
--- a/pcre/README
+++ b/pcre/README
@@ -5,9 +5,8 @@ NOTE: This set of files relates to PCRE releases that use the original API,
with library names libpcre, libpcre16, and libpcre32. January 2015 saw the
first release of a new API, known as PCRE2, with release numbers starting at
10.00 and library names libpcre2-8, libpcre2-16, and libpcre2-32. The old
-libraries (now called PCRE1) are still being maintained for bug fixes, but
-there will be no new development. New projects are advised to use the new PCRE2
-libraries.
+libraries (now called PCRE1) are now at end of life, and 8.45 is the final
+release. New projects are advised to use the new PCRE2 libraries.
The latest release of PCRE1 is always available in three alternative formats
@@ -998,6 +997,6 @@ pcre_xxx, one with the name pcre16_xx, and a third with the name pcre32_xxx.
RunTest.bat a script for running tests under Windows
Philip Hazel
-Email local part: ph10
-Email domain: cam.ac.uk
-Last updated: 12 February 2020
+Email local part: Philip.Hazel
+Email domain: gmail.com
+Last updated: 15 June 2021
diff --git a/pcre/configure.ac b/pcre/configure.ac
index 6a3e5f35d8e..4d2e2f37747 100644
--- a/pcre/configure.ac
+++ b/pcre/configure.ac
@@ -9,17 +9,17 @@ dnl The PCRE_PRERELEASE feature is for identifying release candidates. It might
dnl be defined as -RC2, for example. For real releases, it should be empty.
m4_define(pcre_major, [8])
-m4_define(pcre_minor, [44])
+m4_define(pcre_minor, [45])
m4_define(pcre_prerelease, [])
-m4_define(pcre_date, [2020-02-12])
+m4_define(pcre_date, [2021-06-15])
# NOTE: The CMakeLists.txt file searches for the above variables in the first
# 50 lines of this file. Please update that if the variables above are moved.
# Libtool shared library interface versions (current:revision:age)
-m4_define(libpcre_version, [3:12:2])
-m4_define(libpcre16_version, [2:12:2])
-m4_define(libpcre32_version, [0:12:0])
+m4_define(libpcre_version, [3:13:2])
+m4_define(libpcre16_version, [2:13:2])
+m4_define(libpcre32_version, [0:13:0])
m4_define(libpcreposix_version, [0:7:0])
m4_define(libpcrecpp_version, [0:2:0])
diff --git a/pcre/doc/html/NON-AUTOTOOLS-BUILD.txt b/pcre/doc/html/NON-AUTOTOOLS-BUILD.txt
index 37f6164475b..23c4e64f84a 100644
--- a/pcre/doc/html/NON-AUTOTOOLS-BUILD.txt
+++ b/pcre/doc/html/NON-AUTOTOOLS-BUILD.txt
@@ -5,8 +5,8 @@ NOTE: This document relates to PCRE releases that use the original API, with
library names libpcre, libpcre16, and libpcre32. January 2015 saw the first
release of a new API, known as PCRE2, with release numbers starting at 10.00
and library names libpcre2-8, libpcre2-16, and libpcre2-32. The old libraries
-(now called PCRE1) are still being maintained for bug fixes, but there will be
-no new development. New projects are advised to use the new PCRE2 libraries.
+(now called PCRE1) are now at end of life, and 8.45 is the final release. New
+projects are advised to use the new PCRE2 libraries.
This document contains the following sections:
@@ -768,6 +768,6 @@ Everything, source and executable, is in EBCDIC and native z/OS file formats.
However, this software is not maintained and will not be upgraded. If you are
new to PCRE you should be looking at PCRE2 (version 10.30 or later).
-===============================
-Last Updated: 13 September 2017
-===============================
+==========================
+Last Updated: 15 June 2021
+==========================
diff --git a/pcre/doc/html/README.txt b/pcre/doc/html/README.txt
index 334362b3e53..65f5e19ef69 100644
--- a/pcre/doc/html/README.txt
+++ b/pcre/doc/html/README.txt
@@ -5,9 +5,8 @@ NOTE: This set of files relates to PCRE releases that use the original API,
with library names libpcre, libpcre16, and libpcre32. January 2015 saw the
first release of a new API, known as PCRE2, with release numbers starting at
10.00 and library names libpcre2-8, libpcre2-16, and libpcre2-32. The old
-libraries (now called PCRE1) are still being maintained for bug fixes, but
-there will be no new development. New projects are advised to use the new PCRE2
-libraries.
+libraries (now called PCRE1) are now at end of life, and 8.45 is the final
+release. New projects are advised to use the new PCRE2 libraries.
The latest release of PCRE1 is always available in three alternative formats
@@ -998,6 +997,6 @@ pcre_xxx, one with the name pcre16_xx, and a third with the name pcre32_xxx.
RunTest.bat a script for running tests under Windows
Philip Hazel
-Email local part: ph10
-Email domain: cam.ac.uk
-Last updated: 12 February 2020
+Email local part: Philip.Hazel
+Email domain: gmail.com
+Last updated: 15 June 2021
diff --git a/pcre/doc/html/pcre.html b/pcre/doc/html/pcre.html
index 0db75e44892..31391f5c00a 100644
--- a/pcre/doc/html/pcre.html
+++ b/pcre/doc/html/pcre.html
@@ -22,13 +22,12 @@ man page, in case the conversion went wrong.
</ul>
<br><a name="SEC1" href="#TOC1">PLEASE TAKE NOTE</a><br>
<P>
-This document relates to PCRE releases that use the original API,
-with library names libpcre, libpcre16, and libpcre32. January 2015 saw the
-first release of a new API, known as PCRE2, with release numbers starting at
-10.00 and library names libpcre2-8, libpcre2-16, and libpcre2-32. The old
-libraries (now called PCRE1) are still being maintained for bug fixes, but
-there will be no new development. New projects are advised to use the new PCRE2
-libraries.
+This document relates to PCRE releases that use the original API, with library
+names libpcre, libpcre16, and libpcre32. January 2015 saw the first release of
+a new API, known as PCRE2, with release numbers starting at 10.00 and library
+names libpcre2-8, libpcre2-16, and libpcre2-32. The old libraries (now called
+PCRE1) are now at end of life, and 8.45 is the final release. New projects are
+advised to use the new PCRE2 libraries.
</P>
<br><a name="SEC2" href="#TOC1">INTRODUCTION</a><br>
<P>
@@ -215,9 +214,9 @@ two digits 10, at the domain cam.ac.uk.
</P>
<br><a name="SEC6" href="#TOC1">REVISION</a><br>
<P>
-Last updated: 10 February 2015
+Last updated: 14 June 2021
<br>
-Copyright &copy; 1997-2015 University of Cambridge.
+Copyright &copy; 1997-2021 University of Cambridge.
<br>
<p>
Return to the <a href="index.html">PCRE index page</a>.
diff --git a/pcre/doc/html/pcreapi.html b/pcre/doc/html/pcreapi.html
index 2fdfbff5ccf..2a0491f0f82 100644
--- a/pcre/doc/html/pcreapi.html
+++ b/pcre/doc/html/pcreapi.html
@@ -1718,7 +1718,7 @@ very long time, and so the <i>match_limit</i> value is also used in this case
<P>
The default value for the limit can be set when PCRE is built; the default
default is 10 million, which handles all but the most extreme cases. You can
-override the default by suppling <b>pcre_exec()</b> with a <b>pcre_extra</b>
+override the default by supplying <b>pcre_exec()</b> with a <b>pcre_extra</b>
block in which <i>match_limit</i> is set, and PCRE_EXTRA_MATCH_LIMIT is set in
the <i>flags</i> field. If the limit is exceeded, <b>pcre_exec()</b> returns
PCRE_ERROR_MATCHLIMIT.
@@ -1749,7 +1749,7 @@ and is ignored, when matching is done using JIT compiled code.
<P>
The default value for <i>match_limit_recursion</i> can be set when PCRE is
built; the default default is the same value as the default for
-<i>match_limit</i>. You can override the default by suppling <b>pcre_exec()</b>
+<i>match_limit</i>. You can override the default by supplying <b>pcre_exec()</b>
with a <b>pcre_extra</b> block in which <i>match_limit_recursion</i> is set, and
PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the <i>flags</i> field. If the limit
is exceeded, <b>pcre_exec()</b> returns PCRE_ERROR_RECURSIONLIMIT.
@@ -2063,10 +2063,10 @@ lookbehind. For example, consider the pattern
</pre>
which finds occurrences of "iss" in the middle of words. (\B matches only if
the current position in the subject is not a word boundary.) When applied to
-the string "Mississipi" the first call to <b>pcre_exec()</b> finds the first
+the string "Mississippi" the first call to <b>pcre_exec()</b> finds the first
occurrence. If <b>pcre_exec()</b> is called again with just the remainder of the
-subject, namely "issipi", it does not match, because \B is always false at the
-start of the subject, which is deemed to be a word boundary. However, if
+subject, namely "issippi", it does not match, because \B is always false at
+the start of the subject, which is deemed to be a word boundary. However, if
<b>pcre_exec()</b> is passed the entire string again, but with <i>startoffset</i>
set to 4, it finds the second occurrence of "iss" because it is able to look
behind the starting point to discover that it is preceded by a letter.
diff --git a/pcre/doc/html/pcrepattern.html b/pcre/doc/html/pcrepattern.html
index 96fc72986f6..2e3e6263e49 100644
--- a/pcre/doc/html/pcrepattern.html
+++ b/pcre/doc/html/pcrepattern.html
@@ -655,7 +655,7 @@ recognized.
<P>
It is possible to restrict \R to match only CR, LF, or CRLF (instead of the
complete set of Unicode line endings) by setting the option PCRE_BSR_ANYCRLF
-either at compile time or when the pattern is matched. (BSR is an abbrevation
+either at compile time or when the pattern is matched. (BSR is an abbreviation
for "backslash R".) This can be made the default when PCRE is built; if this is
the case, the other behaviour can be requested via the PCRE_BSR_UNICODE option.
It is also possible to specify these settings by starting a pattern string with
@@ -972,7 +972,7 @@ additional characters according to the following rules for ending a cluster:
3. Do not break Hangul (a Korean script) syllable sequences. Hangul characters
are of five types: L, V, T, LV, and LVT. An L character may be followed by an
L, V, LV, or LVT character; an LV or V character may be followed by a V or T
-character; an LVT or T character may be follwed only by a T character.
+character; an LVT or T character may be followed only by a T character.
</P>
<P>
4. Do not end before extending characters or spacing marks. Characters with
@@ -3080,7 +3080,7 @@ successful match. Consider:
</pre>
If the subject is "aaaac...", after the first match attempt fails (starting at
the first character in the string), the starting point skips on to start the
-next attempt at "c". Note that a possessive quantifer does not have the same
+next attempt at "c". Note that a possessive quantifier does not have the same
effect as this example; although it would suppress backtracking during the
first match attempt, the second attempt would start at the second character
instead of skipping on to "c".
diff --git a/pcre/doc/html/pcresyntax.html b/pcre/doc/html/pcresyntax.html
index 5896b9e0688..2946ab32872 100644
--- a/pcre/doc/html/pcresyntax.html
+++ b/pcre/doc/html/pcresyntax.html
@@ -157,7 +157,7 @@ is changed to use Unicode properties and they match many more characters.
Xan Alphanumeric: union of properties L and N
Xps POSIX space: property Z or tab, NL, VT, FF, CR
Xsp Perl space: property Z or tab, NL, VT, FF, CR
- Xuc Univerally-named character: one that can be
+ Xuc Universally-named character: one that can be
represented by a Universal Character Name
Xwd Perl word: property Xan or underscore
</pre>
diff --git a/pcre/doc/pcre.3 b/pcre/doc/pcre.3
index 716d58044c7..afd0830fab9 100644
--- a/pcre/doc/pcre.3
+++ b/pcre/doc/pcre.3
@@ -1,16 +1,15 @@
-.TH PCRE 3 "10 February 2015" "PCRE 8.37"
+.TH PCRE 3 "14 June 2021" "PCRE 8.45"
.SH NAME
PCRE - Perl-compatible regular expressions (original API)
.SH "PLEASE TAKE NOTE"
.rs
.sp
-This document relates to PCRE releases that use the original API,
-with library names libpcre, libpcre16, and libpcre32. January 2015 saw the
-first release of a new API, known as PCRE2, with release numbers starting at
-10.00 and library names libpcre2-8, libpcre2-16, and libpcre2-32. The old
-libraries (now called PCRE1) are still being maintained for bug fixes, but
-there will be no new development. New projects are advised to use the new PCRE2
-libraries.
+This document relates to PCRE releases that use the original API, with library
+names libpcre, libpcre16, and libpcre32. January 2015 saw the first release of
+a new API, known as PCRE2, with release numbers starting at 10.00 and library
+names libpcre2-8, libpcre2-16, and libpcre2-32. The old libraries (now called
+PCRE1) are now at end of life, and 8.45 is the final release. New projects are
+advised to use the new PCRE2 libraries.
.
.
.SH INTRODUCTION
@@ -225,6 +224,6 @@ two digits 10, at the domain cam.ac.uk.
.rs
.sp
.nf
-Last updated: 10 February 2015
-Copyright (c) 1997-2015 University of Cambridge.
+Last updated: 14 June 2021
+Copyright (c) 1997-2021 University of Cambridge.
.fi
diff --git a/pcre/doc/pcre.txt b/pcre/doc/pcre.txt
index 94f48b6aec1..f71526961f7 100644
--- a/pcre/doc/pcre.txt
+++ b/pcre/doc/pcre.txt
@@ -21,9 +21,9 @@ PLEASE TAKE NOTE
library names libpcre, libpcre16, and libpcre32. January 2015 saw the
first release of a new API, known as PCRE2, with release numbers start-
ing at 10.00 and library names libpcre2-8, libpcre2-16, and
- libpcre2-32. The old libraries (now called PCRE1) are still being main-
- tained for bug fixes, but there will be no new development. New
- projects are advised to use the new PCRE2 libraries.
+ libpcre2-32. The old libraries (now called PCRE1) are now at end of
+ life, and 8.45 is the final release. New projects are advised to use
+ the new PCRE2 libraries.
INTRODUCTION
@@ -190,8 +190,8 @@ AUTHOR
REVISION
- Last updated: 10 February 2015
- Copyright (c) 1997-2015 University of Cambridge.
+ Last updated: 14 June 2021
+ Copyright (c) 1997-2021 University of Cambridge.
------------------------------------------------------------------------------
@@ -3155,7 +3155,7 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
The default value for the limit can be set when PCRE is built; the de-
fault default is 10 million, which handles all but the most extreme
- cases. You can override the default by suppling pcre_exec() with a
+ cases. You can override the default by supplying pcre_exec() with a
pcre_extra block in which match_limit is set, and PCRE_EX-
TRA_MATCH_LIMIT is set in the flags field. If the limit is exceeded,
pcre_exec() returns PCRE_ERROR_MATCHLIMIT.
@@ -3183,7 +3183,7 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
The default value for match_limit_recursion can be set when PCRE is
built; the default default is the same value as the default for
- match_limit. You can override the default by suppling pcre_exec() with
+ match_limit. You can override the default by supplying pcre_exec() with
a pcre_extra block in which match_limit_recursion is set, and PCRE_EX-
TRA_MATCH_LIMIT_RECURSION is set in the flags field. If the limit is
exceeded, pcre_exec() returns PCRE_ERROR_RECURSIONLIMIT.
@@ -3475,9 +3475,9 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
which finds occurrences of "iss" in the middle of words. (\B matches
only if the current position in the subject is not a word boundary.)
- When applied to the string "Mississipi" the first call to pcre_exec()
+ When applied to the string "Mississippi" the first call to pcre_exec()
finds the first occurrence. If pcre_exec() is called again with just
- the remainder of the subject, namely "issipi", it does not match, be-
+ the remainder of the subject, namely "issippi", it does not match, be-
cause \B is always false at the start of the subject, which is deemed
to be a word boundary. However, if pcre_exec() is passed the entire
string again, but with startoffset set to 4, it finds the second occur-
@@ -5292,11 +5292,11 @@ BACKSLASH
It is possible to restrict \R to match only CR, LF, or CRLF (instead of
the complete set of Unicode line endings) by setting the option
PCRE_BSR_ANYCRLF either at compile time or when the pattern is matched.
- (BSR is an abbrevation for "backslash R".) This can be made the default
- when PCRE is built; if this is the case, the other behaviour can be re-
- quested via the PCRE_BSR_UNICODE option. It is also possible to spec-
- ify these settings by starting a pattern string with one of the follow-
- ing sequences:
+ (BSR is an abbreviation for "backslash R".) This can be made the de-
+ fault when PCRE is built; if this is the case, the other behaviour can
+ be requested via the PCRE_BSR_UNICODE option. It is also possible to
+ specify these settings by starting a pattern string with one of the
+ following sequences:
(*BSR_ANYCRLF) CR, LF, or CRLF only
(*BSR_UNICODE) any Unicode newline sequence
@@ -5488,8 +5488,8 @@ BACKSLASH
3. Do not break Hangul (a Korean script) syllable sequences. Hangul
characters are of five types: L, V, T, LV, and LVT. An L character may
be followed by an L, V, LV, or LVT character; an LV or V character may
- be followed by a V or T character; an LVT or T character may be follwed
- only by a T character.
+ be followed by a V or T character; an LVT or T character may be fol-
+ lowed only by a T character.
4. Do not end before extending characters or spacing marks. Characters
with the "mark" property always have the "extend" grapheme breaking
@@ -7494,7 +7494,7 @@ BACKTRACKING CONTROL
If the subject is "aaaac...", after the first match attempt fails
(starting at the first character in the string), the starting point
skips on to start the next attempt at "c". Note that a possessive quan-
- tifer does not have the same effect as this example; although it would
+ tifier does not have the same effect as this example; although it would
suppress backtracking during the first match attempt, the second at-
tempt would start at the second character instead of skipping on to
"c".
@@ -7793,7 +7793,7 @@ PCRE SPECIAL CATEGORY PROPERTIES FOR \p and \P
Xan Alphanumeric: union of properties L and N
Xps POSIX space: property Z or tab, NL, VT, FF, CR
Xsp Perl space: property Z or tab, NL, VT, FF, CR
- Xuc Univerally-named character: one that can be
+ Xuc Universally-named character: one that can be
represented by a Universal Character Name
Xwd Perl word: property Xan or underscore
diff --git a/pcre/doc/pcreapi.3 b/pcre/doc/pcreapi.3
index d79217818a6..685672a3cef 100644
--- a/pcre/doc/pcreapi.3
+++ b/pcre/doc/pcreapi.3
@@ -1699,7 +1699,7 @@ very long time, and so the \fImatch_limit\fP value is also used in this case
.P
The default value for the limit can be set when PCRE is built; the default
default is 10 million, which handles all but the most extreme cases. You can
-override the default by suppling \fBpcre_exec()\fP with a \fBpcre_extra\fP
+override the default by supplying \fBpcre_exec()\fP with a \fBpcre_extra\fP
block in which \fImatch_limit\fP is set, and PCRE_EXTRA_MATCH_LIMIT is set in
the \fIflags\fP field. If the limit is exceeded, \fBpcre_exec()\fP returns
PCRE_ERROR_MATCHLIMIT.
@@ -1726,7 +1726,7 @@ and is ignored, when matching is done using JIT compiled code.
.P
The default value for \fImatch_limit_recursion\fP can be set when PCRE is
built; the default default is the same value as the default for
-\fImatch_limit\fP. You can override the default by suppling \fBpcre_exec()\fP
+\fImatch_limit\fP. You can override the default by supplying \fBpcre_exec()\fP
with a \fBpcre_extra\fP block in which \fImatch_limit_recursion\fP is set, and
PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the \fIflags\fP field. If the limit
is exceeded, \fBpcre_exec()\fP returns PCRE_ERROR_RECURSIONLIMIT.
@@ -2044,10 +2044,10 @@ lookbehind. For example, consider the pattern
.sp
which finds occurrences of "iss" in the middle of words. (\eB matches only if
the current position in the subject is not a word boundary.) When applied to
-the string "Mississipi" the first call to \fBpcre_exec()\fP finds the first
+the string "Mississippi" the first call to \fBpcre_exec()\fP finds the first
occurrence. If \fBpcre_exec()\fP is called again with just the remainder of the
-subject, namely "issipi", it does not match, because \eB is always false at the
-start of the subject, which is deemed to be a word boundary. However, if
+subject, namely "issippi", it does not match, because \eB is always false at
+the start of the subject, which is deemed to be a word boundary. However, if
\fBpcre_exec()\fP is passed the entire string again, but with \fIstartoffset\fP
set to 4, it finds the second occurrence of "iss" because it is able to look
behind the starting point to discover that it is preceded by a letter.
diff --git a/pcre/doc/pcrepattern.3 b/pcre/doc/pcrepattern.3
index 97df217fdb2..2f501a6503b 100644
--- a/pcre/doc/pcrepattern.3
+++ b/pcre/doc/pcrepattern.3
@@ -656,7 +656,7 @@ recognized.
.P
It is possible to restrict \eR to match only CR, LF, or CRLF (instead of the
complete set of Unicode line endings) by setting the option PCRE_BSR_ANYCRLF
-either at compile time or when the pattern is matched. (BSR is an abbrevation
+either at compile time or when the pattern is matched. (BSR is an abbreviation
for "backslash R".) This can be made the default when PCRE is built; if this is
the case, the other behaviour can be requested via the PCRE_BSR_UNICODE option.
It is also possible to specify these settings by starting a pattern string with
@@ -968,7 +968,7 @@ additional characters according to the following rules for ending a cluster:
3. Do not break Hangul (a Korean script) syllable sequences. Hangul characters
are of five types: L, V, T, LV, and LVT. An L character may be followed by an
L, V, LV, or LVT character; an LV or V character may be followed by a V or T
-character; an LVT or T character may be follwed only by a T character.
+character; an LVT or T character may be followed only by a T character.
.P
4. Do not end before extending characters or spacing marks. Characters with
the "mark" property always have the "extend" grapheme breaking property.
@@ -3115,7 +3115,7 @@ successful match. Consider:
.sp
If the subject is "aaaac...", after the first match attempt fails (starting at
the first character in the string), the starting point skips on to start the
-next attempt at "c". Note that a possessive quantifer does not have the same
+next attempt at "c". Note that a possessive quantifier does not have the same
effect as this example; although it would suppress backtracking during the
first match attempt, the second attempt would start at the second character
instead of skipping on to "c".
diff --git a/pcre/doc/pcresyntax.3 b/pcre/doc/pcresyntax.3
index 0850369f7aa..b77a8664ed9 100644
--- a/pcre/doc/pcresyntax.3
+++ b/pcre/doc/pcresyntax.3
@@ -123,7 +123,7 @@ is changed to use Unicode properties and they match many more characters.
Xan Alphanumeric: union of properties L and N
Xps POSIX space: property Z or tab, NL, VT, FF, CR
Xsp Perl space: property Z or tab, NL, VT, FF, CR
- Xuc Univerally-named character: one that can be
+ Xuc Universally-named character: one that can be
represented by a Universal Character Name
Xwd Perl word: property Xan or underscore
.sp
diff --git a/pcre/pcre_compile.c b/pcre/pcre_compile.c
index 7441c404735..5a9a2d38ddc 100644
--- a/pcre/pcre_compile.c
+++ b/pcre/pcre_compile.c
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2020 University of Cambridge
+ Copyright (c) 1997-2021 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -9102,6 +9102,8 @@ pcre_uchar cworkspace[COMPILE_WORK_SIZE];
similar way to cworkspace, it can be expanded using malloc() if necessary. */
named_group named_groups[NAMED_GROUP_LIST_SIZE];
+cd->named_groups = named_groups;
+cd->named_group_list_size = NAMED_GROUP_LIST_SIZE;
/* Set this early so that early errors get offset 0. */
@@ -9375,8 +9377,6 @@ cd->hwm = cworkspace;
cd->iscondassert = FALSE;
cd->start_workspace = cworkspace;
cd->workspace_size = COMPILE_WORK_SIZE;
-cd->named_groups = named_groups;
-cd->named_group_list_size = NAMED_GROUP_LIST_SIZE;
cd->start_pattern = (const pcre_uchar *)pattern;
cd->end_pattern = (const pcre_uchar *)(pattern + STRLEN_UC((const pcre_uchar *)pattern));
cd->req_varyopt = 0;
@@ -9487,6 +9487,7 @@ if (cd->names_found > 0)
add_name(cd, ng->name, ng->length, ng->number);
if (cd->named_group_list_size > NAMED_GROUP_LIST_SIZE)
(PUBL(free))((void *)cd->named_groups);
+ cd->named_group_list_size = 0; /* So we don't free it twice */
}
/* Set up a starting, non-extracting bracket, then compile the expression. On
@@ -9637,6 +9638,8 @@ if (errorcode != 0)
{
(PUBL(free))(re);
PCRE_EARLY_ERROR_RETURN:
+ if (cd->named_group_list_size > NAMED_GROUP_LIST_SIZE)
+ (PUBL(free))((void *)cd->named_groups);
*erroroffset = (int)(ptr - (const pcre_uchar *)pattern);
PCRE_EARLY_ERROR_RETURN2:
*errorptr = find_error_text(errorcode);
diff --git a/pcre/pcre_exec.c b/pcre/pcre_exec.c
index 88a9a79e489..c30d90acfc7 100644
--- a/pcre/pcre_exec.c
+++ b/pcre/pcre_exec.c
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2018 University of Cambridge
+ Copyright (c) 1997-2021 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -764,7 +764,7 @@ for (;;)
md->mark = NULL; /* In case previously set by assertion */
RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
eptrb, RM55);
- if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
+ if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT || rrc == MATCH_KETRPOS) &&
md->mark == NULL) md->mark = ecode + 2;
/* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
diff --git a/pcre/testdata/testinput1 b/pcre/testdata/testinput1
index 02e4f4825fc..54bc79c6271 100644
--- a/pcre/testdata/testinput1
+++ b/pcre/testdata/testinput1
@@ -5757,4 +5757,7 @@ AbcdCBefgBhiBqz
/(?&word)* \. (?<word> \w+ )/xi
pokus.hokus
+/(?:A(*:X))*+/K
+ A
+
/-- End of testinput1 --/
diff --git a/pcre/testdata/testoutput1 b/pcre/testdata/testoutput1
index e6147e60b95..212dafaae58 100644
--- a/pcre/testdata/testoutput1
+++ b/pcre/testdata/testoutput1
@@ -9470,4 +9470,9 @@ No match
0: pokus.hokus
1: hokus
+/(?:A(*:X))*+/K
+ A
+ 0: A
+MK: X
+
/-- End of testinput1 --/
diff --git a/plugin/auth_gssapi/CMakeLists.txt b/plugin/auth_gssapi/CMakeLists.txt
index 3205a58ebbe..8af577b0188 100644
--- a/plugin/auth_gssapi/CMakeLists.txt
+++ b/plugin/auth_gssapi/CMakeLists.txt
@@ -11,6 +11,7 @@ IF(USE_SSPI)
ELSE()
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
FIND_PACKAGE(GSSAPI)
+ SET_PACKAGE_PROPERTIES(GSSAPI PROPERTIES TYPE OPTIONAL)
IF(GSSAPI_FOUND)
INCLUDE_DIRECTORIES(${GSSAPI_INCS})
ADD_DEFINITIONS(-DPLUGIN_GSSAPI)
diff --git a/plugin/aws_key_management/CMakeLists.txt b/plugin/aws_key_management/CMakeLists.txt
index 248d56e8d76..3c6ca018273 100644
--- a/plugin/aws_key_management/CMakeLists.txt
+++ b/plugin/aws_key_management/CMakeLists.txt
@@ -2,6 +2,7 @@ INCLUDE(aws_sdk)
CHECK_AWS_SDK(HAVE_AWS_SDK REASON)
IF(NOT HAVE_AWS_SDK)
MESSAGE_ONCE(AWS_KEY_MANAGEMENT_NO_AWS_SDK "Can't build aws_key_management - AWS SDK not available (${REASON})")
+ ADD_FEATURE_INFO(AWS_KEY_MANAGEMENT "OFF" "AWS Encryption Key Management Plugin")
RETURN()
ENDIF()
@@ -12,3 +13,5 @@ MYSQL_ADD_PLUGIN(aws_key_management
IF(TARGET aws_key_management)
USE_AWS_SDK_LIBS(aws_key_management kms)
ENDIF()
+
+ADD_FEATURE_INFO(AWS_KEY_MANAGEMENT "ON" "AWS Encryption Key Management Plugin")
diff --git a/plugin/win_auth_client/CMakeLists.txt b/plugin/win_auth_client/CMakeLists.txt
index 8c7696347aa..46f837e58d6 100644
--- a/plugin/win_auth_client/CMakeLists.txt
+++ b/plugin/win_auth_client/CMakeLists.txt
@@ -29,6 +29,6 @@ IF(WIN32)
MYSQL_ADD_PLUGIN(authentication_windows_client ${PLUGIN_SOURCES} ${HEADERS}
LINK_LIBRARIES Secur32
- MODULE_ONLY COMPONENT ClientPlugins)
+ MODULE_ONLY COMPONENT ClientPlugins CLIENT)
ENDIF(WIN32)
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index 1feb17ee1b6..b4cd06af87b 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -611,12 +611,8 @@ then
echo
echo
echo "PLEASE REMEMBER TO SET A PASSWORD FOR THE MariaDB root USER !"
- echo "To do so, start the server, then issue the following commands:"
+ echo "To do so, start the server, then issue the following command:"
echo
- echo "'$bindir/mysqladmin' -u root password 'new-password'"
- echo "'$bindir/mysqladmin' -u root -h $hostname password 'new-password'"
- echo
- echo "Alternatively you can run:"
echo "'$bindir/mysql_secure_installation'"
echo
echo "which will also give you the option of removing the test"
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
index 21ceebb1413..64209adbc85 100644
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -73,12 +73,14 @@ usage () {
cat <<EOF
Usage: $0 [OPTIONS]
--no-defaults Don't read the system defaults file
- --core-file-size=LIMIT Limit core files to the specified size
--defaults-file=FILE Use the specified defaults file
--defaults-extra-file=FILE Also use defaults from the specified file
+ --defaults-group-suffix=X Additionally read default groups with X appended
+ as a suffix
--ledir=DIRECTORY Look for mysqld in the specified directory
--open-files-limit=LIMIT Limit the number of open files
--crash-script=FILE Script to call when mysqld crashes
+ --core-file-size=LIMIT Limit core files to the specified size
--timezone=TZ Set the system timezone
--malloc-lib=LIB Preload shared library LIB if available
--mysqld=FILE Use the specified file as mysqld
diff --git a/sql/field.cc b/sql/field.cc
index cf4bb4ef4f2..b391234b866 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -6327,6 +6327,7 @@ bool Field_timef::val_native(Native *to)
int Field_year::store(const char *from, size_t len,CHARSET_INFO *cs)
{
DBUG_ASSERT(marked_for_write_or_computed());
+ THD *thd= get_thd();
char *end;
int error;
longlong nr= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error);
@@ -6338,7 +6339,14 @@ int Field_year::store(const char *from, size_t len,CHARSET_INFO *cs)
set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1);
return 1;
}
- if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION &&
+
+ if (thd->count_cuted_fields <= CHECK_FIELD_EXPRESSION && error == MY_ERRNO_EDOM)
+ {
+ *ptr= 0;
+ return 1;
+ }
+
+ if (thd->count_cuted_fields > CHECK_FIELD_EXPRESSION &&
(error= check_int(cs, from, len, end, error)))
{
if (unlikely(error == 1) /* empty or incorrect string */)
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index caefa83c443..50b9149ef0c 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -5443,8 +5443,7 @@ int ha_partition::index_init(uint inx, bool sorted)
do
{
for (i= 0; i < (*key_info)->user_defined_key_parts; i++)
- bitmap_set_bit(table->read_set,
- (*key_info)->key_part[i].field->field_index);
+ (*key_info)->key_part[i].field->register_field_in_read_map();
} while (*(++key_info));
}
for (i= bitmap_get_first_set(&m_part_info->read_partitions);
diff --git a/sql/item.cc b/sql/item.cc
index c2fe9933d02..895a3d31b64 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -4352,13 +4352,15 @@ bool Item_param::get_date(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate)
}
-double Item_param::PValue::val_real() const
+double Item_param::PValue::val_real(const Type_std_attributes *attr) const
{
switch (type_handler()->cmp_type()) {
case REAL_RESULT:
return real;
case INT_RESULT:
- return (double) integer;
+ return attr->unsigned_flag
+ ? (double) (ulonglong) integer
+ : (double) integer;
case DECIMAL_RESULT:
return m_decimal.to_double();
case STRING_RESULT:
@@ -4432,7 +4434,7 @@ String *Item_param::PValue::val_str(String *str,
str->set_real(real, NOT_FIXED_DEC, &my_charset_bin);
return str;
case INT_RESULT:
- str->set(integer, &my_charset_bin);
+ str->set_int(integer, attr->unsigned_flag, &my_charset_bin);
return str;
case DECIMAL_RESULT:
if (m_decimal.to_string_native(str, 0, 0, 0) <= 1)
diff --git a/sql/item.h b/sql/item.h
index 5a530f97192..2270b8d7623 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -3891,7 +3891,7 @@ class Item_param :public Item_basic_value,
m_string.swap(other.m_string);
m_string_ptr.swap(other.m_string_ptr);
}
- double val_real() const;
+ double val_real(const Type_std_attributes *attr) const;
longlong val_int(const Type_std_attributes *attr) const;
my_decimal *val_decimal(my_decimal *dec, const Type_std_attributes *attr);
String *val_str(String *str, const Type_std_attributes *attr);
@@ -3993,7 +3993,7 @@ public:
double val_real()
{
- return can_return_value() ? value.val_real() : 0e0;
+ return can_return_value() ? value.val_real(this) : 0e0;
}
longlong val_int()
{
@@ -6442,13 +6442,15 @@ public:
class Item_default_value : public Item_field
{
+ bool vcol_assignment_ok;
void calculate();
public:
Item *arg;
Field *cached_field;
- Item_default_value(THD *thd, Name_resolution_context *context_arg, Item *a)
+ Item_default_value(THD *thd, Name_resolution_context *context_arg, Item *a,
+ bool vcol_assignment_arg)
:Item_field(thd, context_arg, (const char *)NULL, (const char *)NULL,
- &null_clex_str),
+ &null_clex_str), vcol_assignment_ok(vcol_assignment_arg),
arg(a), cached_field(NULL) {}
enum Type type() const { return DEFAULT_VALUE_ITEM; }
bool eq(const Item *item, bool binary_cmp) const;
@@ -6487,6 +6489,7 @@ public:
if (field && field->default_value)
field->default_value->expr->update_used_tables();
}
+ bool vcol_assignment_allowed_value() const { return vcol_assignment_ok; }
Field *get_tmp_table_field() { return 0; }
Item *get_tmp_table_item(THD *thd) { return this; }
Item_field *field_for_view_update() { return 0; }
diff --git a/sql/item_func.cc b/sql/item_func.cc
index d50fb22a154..d73782dd94e 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -5726,7 +5726,7 @@ void Item_func_get_system_var::update_null_value()
bool Item_func_get_system_var::fix_length_and_dec()
{
- char *cptr;
+ const char *cptr;
maybe_null= TRUE;
max_length= 0;
@@ -5760,9 +5760,12 @@ bool Item_func_get_system_var::fix_length_and_dec()
case SHOW_CHAR:
case SHOW_CHAR_PTR:
mysql_mutex_lock(&LOCK_global_system_variables);
- cptr= var->show_type() == SHOW_CHAR ?
- (char*) var->value_ptr(current_thd, var_type, &component) :
- *(char**) var->value_ptr(current_thd, var_type, &component);
+ cptr= var->show_type() == SHOW_CHAR ?
+ reinterpret_cast<const char*>(var->value_ptr(current_thd, var_type,
+ &component)) :
+ *reinterpret_cast<const char* const*>(var->value_ptr(current_thd,
+ var_type,
+ &component));
if (cptr)
max_length= (uint32)system_charset_info->cset->numchars(system_charset_info,
cptr,
@@ -5775,7 +5778,10 @@ bool Item_func_get_system_var::fix_length_and_dec()
case SHOW_LEX_STRING:
{
mysql_mutex_lock(&LOCK_global_system_variables);
- LEX_STRING *ls= ((LEX_STRING*)var->value_ptr(current_thd, var_type, &component));
+ const LEX_STRING *ls=
+ reinterpret_cast<const LEX_STRING*>(var->value_ptr(current_thd,
+ var_type,
+ &component));
max_length= (uint32)system_charset_info->cset->numchars(system_charset_info,
ls->str,
ls->str + ls->length);
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 759b18c4657..4f62452aa5a 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -500,7 +500,7 @@ err:
const char *histogram_types[] =
{"SINGLE_PREC_HB", "DOUBLE_PREC_HB", 0};
-static TYPELIB hystorgam_types_typelib=
+static TYPELIB histogram_types_typelib=
{ array_elements(histogram_types),
"histogram_types",
histogram_types, NULL};
@@ -516,7 +516,7 @@ String *Item_func_decode_histogram::val_str(String *str)
tmp.length(0);
if (!(res= args[0]->val_str(&tmp)) ||
(type= find_type(res->c_ptr_safe(),
- &hystorgam_types_typelib, MYF(0))) <= 0)
+ &histogram_types_typelib, MYF(0))) <= 0)
{
null_value= 1;
return 0;
@@ -601,7 +601,7 @@ bool Item_func_concat::realloc_result(String *str, uint length) const
as str was initially set by args[0]->val_str(str).
So multiplication by 2 can overflow, if args[0] for some reasons
did not limit the result to max_alloced_packet. But it's not harmful,
- "str" will be realloced exactly to "length" bytes in case of overflow.
+ "str" will be reallocated exactly to "length" bytes in case of overflow.
*/
uint new_length= MY_MAX(str->alloced_length() * 2, length);
return str->realloc(new_length);
@@ -1528,7 +1528,7 @@ String *Item_func_insert::val_str(String *str)
start--;
/*
- There is one exception not handled (intentionaly) by the character set
+ There is one exception not handled (intentionally) by the character set
aggregation code. If one string is strong side and is binary, and
another one is weak side and is a multi-byte character string,
then we need to operate on the second string in terms on bytes when
@@ -3219,6 +3219,14 @@ err:
}
+static String *default_pad_str(String *pad_str, CHARSET_INFO *collation)
+{
+ pad_str->set_charset(collation);
+ pad_str->length(0);
+ pad_str->append(" ", 1);
+ return pad_str;
+}
+
bool Item_func_pad::fix_length_and_dec()
{
if (arg_count == 3)
@@ -3234,9 +3242,7 @@ bool Item_func_pad::fix_length_and_dec()
{
if (agg_arg_charsets_for_string_result(collation, &args[0], 1, 1))
return TRUE;
- pad_str.set_charset(collation.collation);
- pad_str.length(0);
- pad_str.append(" ", 1);
+ default_pad_str(&pad_str, collation.collation);
}
DBUG_ASSERT(collation.collation->mbmaxlen > 0);
@@ -3259,9 +3265,9 @@ bool Item_func_pad::fix_length_and_dec()
Sql_mode_dependency Item_func_rpad::value_depends_on_sql_mode() const
{
DBUG_ASSERT(fixed);
- DBUG_ASSERT(arg_count == 3);
+ DBUG_ASSERT(arg_count >= 2);
if (!args[1]->value_depends_on_sql_mode_const_item() ||
- !args[2]->value_depends_on_sql_mode_const_item())
+ (arg_count == 3 && !args[2]->value_depends_on_sql_mode_const_item()))
return Item_func::value_depends_on_sql_mode();
Longlong_hybrid len= args[1]->to_longlong_hybrid();
if (args[1]->null_value || len.neg())
@@ -3269,7 +3275,8 @@ Sql_mode_dependency Item_func_rpad::value_depends_on_sql_mode() const
if (len.abs() > 0 && len.abs() < args[0]->max_char_length())
return Item_func::value_depends_on_sql_mode();
StringBuffer<64> padstrbuf;
- String *padstr= args[2]->val_str(&padstrbuf);
+ String *padstr= arg_count == 3 ? args[2]->val_str(&padstrbuf) :
+ default_pad_str(&padstrbuf, collation.collation);
if (!padstr || !padstr->length())
return Sql_mode_dependency(); // will return NULL
if (padstr->lengthsp() != 0)
@@ -3309,7 +3316,7 @@ String *Item_func_rpad::val_str(String *str)
if ((ulonglong) count > INT_MAX32)
count= INT_MAX32;
/*
- There is one exception not handled (intentionaly) by the character set
+ There is one exception not handled (intentionally) by the character set
aggregation code. If one string is strong side and is binary, and
another one is weak side and is a multi-byte character string,
then we need to operate on the second string in terms on bytes when
@@ -3402,7 +3409,7 @@ String *Item_func_lpad::val_str(String *str)
count= INT_MAX32;
/*
- There is one exception not handled (intentionaly) by the character set
+ There is one exception not handled (intentionally) by the character set
aggregation code. If one string is strong side and is binary, and
another one is weak side and is a multi-byte character string,
then we need to operate on the second string in terms on bytes when
@@ -4210,7 +4217,7 @@ longlong Item_func_uncompressed_length::val_int()
5 bytes long.
res->c_ptr() is not used because:
- we do not need \0 terminated string to get first 4 bytes
- - c_ptr() tests simbol after string end (uninitialiozed memory) which
+ - c_ptr() tests simbol after string end (uninitialized memory) which
confuse valgrind
*/
return uint4korr(res->ptr()) & 0x3FFFFFFF;
diff --git a/sql/key.cc b/sql/key.cc
index 6f0a1112497..72f4e603023 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -467,7 +467,7 @@ void key_unpack(String *to, TABLE *table, KEY *key)
bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields)
{
- table->mark_columns_used_by_index(idx, &table->tmp_set);
+ table->mark_index_columns(idx, &table->tmp_set);
return bitmap_is_overlapping(&table->tmp_set, fields);
}
diff --git a/sql/mysqld.h b/sql/mysqld.h
index 37269125dc6..8e33d6488e4 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -194,7 +194,8 @@ enum vers_system_time_t
struct vers_asof_timestamp_t
{
ulong type;
- MYSQL_TIME ltime;
+ my_time_t unix_time;
+ ulong second_part;
};
enum vers_alter_history_enum
diff --git a/sql/set_var.cc b/sql/set_var.cc
index bebed453292..b97bf0677f3 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -233,12 +233,12 @@ bool sys_var::update(THD *thd, set_var *var)
}
}
-uchar *sys_var::session_value_ptr(THD *thd, const LEX_CSTRING *base)
+const uchar *sys_var::session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
return session_var_ptr(thd);
}
-uchar *sys_var::global_value_ptr(THD *thd, const LEX_CSTRING *base)
+const uchar *sys_var::global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
return global_var_ptr();
}
@@ -271,8 +271,8 @@ bool sys_var::check(THD *thd, set_var *var)
return false;
}
-uchar *sys_var::value_ptr(THD *thd, enum_var_type type,
- const LEX_CSTRING *base)
+const uchar *sys_var::value_ptr(THD *thd, enum_var_type type,
+ const LEX_CSTRING *base) const
{
DBUG_ASSERT(base);
if (type == OPT_GLOBAL || scope() == GLOBAL)
@@ -510,7 +510,7 @@ bool throw_bounds_warning(THD *thd, const char *name, bool fixed, double v)
return false;
}
-CHARSET_INFO *sys_var::charset(THD *thd)
+CHARSET_INFO *sys_var::charset(THD *thd) const
{
return is_os_charset ? thd->variables.character_set_filesystem :
system_charset_info;
@@ -1047,7 +1047,7 @@ int set_var_collation_client::update(THD *thd)
INFORMATION_SCHEMA.SYSTEM_VARIABLES
*****************************************************************************/
static void store_value_ptr(Field *field, sys_var *var, String *str,
- uchar *value_ptr)
+ const uchar *value_ptr)
{
field->set_notnull();
str= var->val_str_nolock(str, field->table->in_use, value_ptr);
@@ -1115,8 +1115,8 @@ int fill_sysvars(THD *thd, TABLE_LIST *tables, COND *cond)
fields[3]->store(origin->str, origin->length, scs);
// DEFAULT_VALUE
- uchar *def= var->is_readonly() && var->option.id < 0
- ? 0 : var->default_value_ptr(thd);
+ const uchar *def= var->is_readonly() && var->option.id < 0
+ ? 0 : var->default_value_ptr(thd);
if (def)
store_value_ptr(fields[4], var, &strbuf, def);
diff --git a/sql/set_var.h b/sql/set_var.h
index ca862b87fd4..56de00221d8 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -112,7 +112,7 @@ public:
virtual sys_var_pluginvar *cast_pluginvar() { return 0; }
bool check(THD *thd, set_var *var);
- uchar *value_ptr(THD *thd, enum_var_type type, const LEX_CSTRING *base);
+ const uchar *value_ptr(THD *thd, enum_var_type type, const LEX_CSTRING *base) const;
/**
Update the system variable with the default value from either
@@ -127,9 +127,9 @@ public:
String *val_str(String *str, THD *thd, enum_var_type type, const LEX_CSTRING *base);
double val_real(bool *is_null, THD *thd, enum_var_type type, const LEX_CSTRING *base);
- SHOW_TYPE show_type() { return show_val_type; }
+ SHOW_TYPE show_type() const { return show_val_type; }
int scope() const { return flags & SCOPE_MASK; }
- CHARSET_INFO *charset(THD *thd);
+ CHARSET_INFO *charset(THD *thd) const;
bool is_readonly() const { return flags & READONLY; }
/**
the following is only true for keycache variables,
@@ -208,7 +208,7 @@ public:
*/
virtual bool session_is_default(THD *thd) { return false; }
- virtual uchar *default_value_ptr(THD *thd)
+ virtual const uchar *default_value_ptr(THD *thd) const
{ return (uchar*)&option.def_value; }
private:
@@ -230,18 +230,18 @@ protected:
It must be of show_val_type type (my_bool for SHOW_MY_BOOL,
int for SHOW_INT, longlong for SHOW_LONGLONG, etc).
*/
- virtual uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base);
- virtual uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base);
+ virtual const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const;
+ virtual const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const;
/**
A pointer to a storage area of the variable, to the raw data.
Typically it's the same as session_value_ptr(), but it's different,
for example, for ENUM, that is printed as a string, but stored as a number.
*/
- uchar *session_var_ptr(THD *thd)
+ uchar *session_var_ptr(THD *thd) const
{ return ((uchar*)&(thd->variables)) + offset; }
- uchar *global_var_ptr()
+ uchar *global_var_ptr() const
{ return ((uchar*)&global_system_variables) + offset; }
void *max_var_ptr()
@@ -283,6 +283,16 @@ public:
/**
+ Structure for holding unix timestamp and high precision second part.
+ */
+typedef struct my_time_t_hires
+{
+ my_time_t unix_time;
+ ulong second_part;
+} my_time_t_hires;
+
+
+/**
set_var_base descendant for assignments to the system variables.
*/
class set_var :public set_var_base
@@ -300,6 +310,7 @@ public:
plugin_ref *plugins; ///< for Sys_var_pluginlist
Time_zone *time_zone; ///< for Sys_var_tz
LEX_STRING string_value; ///< for Sys_var_charptr and others
+ my_time_t_hires timestamp; ///< for Sys_var_vers_asof
const void *ptr; ///< for Sys_var_struct
} save_result;
LEX_CSTRING base; /**< for structured variables, like keycache_name.variable_name */
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index eed20b040c3..0e2c044e3a1 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -3121,7 +3121,6 @@ end:
my_error(ER_INVALID_ROLE, MYF(0), rolename);
break;
case 1:
- StringBuffer<1024> c_usr;
LEX_CSTRING role_lex;
/* First, check if current user can see mysql database. */
bool read_access= !check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 1);
@@ -3142,11 +3141,9 @@ end:
NULL) == -1))
{
/* Role is not granted but current user can see the role */
- c_usr.append(user, strlen(user));
- c_usr.append('@');
- c_usr.append(host, strlen(host));
- my_printf_error(ER_INVALID_ROLE, "User %`s has not been granted role %`s",
- MYF(0), c_usr.c_ptr(), rolename);
+ my_printf_error(ER_INVALID_ROLE, "User %`s@%`s has not been granted role %`s",
+ MYF(0), thd->security_ctx->priv_user,
+ thd->security_ctx->priv_host, rolename);
}
else
{
@@ -9261,14 +9258,13 @@ static bool show_default_role(THD *thd, ACL_USER *acl_entry,
String def_str(buff, buffsize, system_charset_info);
def_str.length(0);
def_str.append(STRING_WITH_LEN("SET DEFAULT ROLE "));
- def_str.append(&def_rolename);
- def_str.append(" FOR '");
- def_str.append(&acl_entry->user);
+ append_identifier(thd, &def_str, def_rolename.str, def_rolename.length);
+ def_str.append(" FOR ");
+ append_identifier(thd, &def_str, acl_entry->user.str, acl_entry->user.length);
DBUG_ASSERT(!(acl_entry->flags & IS_ROLE));
- def_str.append(STRING_WITH_LEN("'@'"));
- def_str.append(acl_entry->host.hostname, acl_entry->hostname_length,
- system_charset_info);
- def_str.append('\'');
+ def_str.append('@');
+ append_identifier(thd, &def_str, acl_entry->host.hostname,
+ acl_entry->hostname_length);
protocol->prepare_for_resend();
protocol->store(def_str.ptr(),def_str.length(),def_str.charset());
if (protocol->write())
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index 63a71ee4433..b626200d297 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -911,7 +911,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
enum enum_field_types type= (*field_ptr)->type();
if (type < MYSQL_TYPE_MEDIUM_BLOB ||
type > MYSQL_TYPE_BLOB)
- bitmap_set_bit(tab->read_set, fields);
+ tab->field[fields]->register_field_in_read_map();
else
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_NO_EIS_FOR_FIELD,
@@ -939,7 +939,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
enum enum_field_types type= tab->field[pos]->type();
if (type < MYSQL_TYPE_MEDIUM_BLOB ||
type > MYSQL_TYPE_BLOB)
- bitmap_set_bit(tab->read_set, pos);
+ tab->field[pos]->register_field_in_read_map();
else
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_NO_EIS_FOR_FIELD,
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index a7699db03b5..8408d8d31a4 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -6291,7 +6291,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
TABLE *table= field_to_set->table;
DBUG_ASSERT(table);
if (thd->column_usage == MARK_COLUMNS_READ)
- bitmap_set_bit(table->read_set, field_to_set->field_index);
+ field_to_set->register_field_in_read_map();
else
bitmap_set_bit(table->write_set, field_to_set->field_index);
}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 8aaa0ebbe71..3040aeba4ba 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -6805,8 +6805,8 @@ void THD::binlog_prepare_row_images(TABLE *table)
{
case BINLOG_ROW_IMAGE_MINIMAL:
/* MINIMAL: Mark only PK */
- table->mark_columns_used_by_index(table->s->primary_key,
- &table->tmp_set);
+ table->mark_index_columns(table->s->primary_key,
+ &table->tmp_set);
break;
case BINLOG_ROW_IMAGE_NOBLOB:
/**
diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc
index c5dcc15f018..bc6844b64cb 100644
--- a/sql/sql_cte.cc
+++ b/sql/sql_cte.cc
@@ -937,7 +937,8 @@ bool With_clause::prepare_unreferenced_elements(THD *thd)
with_elem;
with_elem= with_elem->next)
{
- if (!with_elem->is_referenced() && with_elem->prepare_unreferenced(thd))
+ if ((with_elem->is_hanging_recursive() || !with_elem->is_referenced()) &&
+ with_elem->prepare_unreferenced(thd))
return true;
}
@@ -1125,14 +1126,6 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex,
lex->unit.include_down(with_table->select_lex);
lex->unit.set_slave(with_select);
lex->unit.cloned_from= spec;
- last_clone_select= lex->all_selects_list;
- while (last_clone_select->next_select_in_list())
- last_clone_select= last_clone_select->next_select_in_list();
- old_lex->all_selects_list=
- (st_select_lex*) (lex->all_selects_list->
- insert_chain_before(
- (st_select_lex_node **) &(old_lex->all_selects_list),
- last_clone_select));
/*
Now all references to the CTE defined outside of the cloned specification
@@ -1148,6 +1141,15 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex,
goto err;
}
+ last_clone_select= lex->all_selects_list;
+ while (last_clone_select->next_select_in_list())
+ last_clone_select= last_clone_select->next_select_in_list();
+ old_lex->all_selects_list=
+ (st_select_lex*) (lex->all_selects_list->
+ insert_chain_before(
+ (st_select_lex_node **) &(old_lex->all_selects_list),
+ last_clone_select));
+
lex->sphead= NULL; // in order not to delete lex->sphead
lex_end(lex);
err:
@@ -1285,6 +1287,7 @@ bool With_element::is_anchor(st_select_lex *sel)
With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table)
{
With_element *found= NULL;
+ With_clause *containing_with_clause= NULL;
st_select_lex_unit *master_unit;
st_select_lex *outer_sl;
for (st_select_lex *sl= this; sl; sl= outer_sl)
@@ -1297,6 +1300,7 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table)
*/
With_clause *attached_with_clause= sl->get_with_clause();
if (attached_with_clause &&
+ attached_with_clause != containing_with_clause &&
(found= attached_with_clause->find_table_def(table, NULL)))
break;
master_unit= sl->master_unit();
@@ -1304,7 +1308,7 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table)
With_element *with_elem= sl->get_with_element();
if (with_elem)
{
- With_clause *containing_with_clause= with_elem->get_owner();
+ containing_with_clause= with_elem->get_owner();
With_element *barrier= containing_with_clause->with_recursive ?
NULL : with_elem;
if ((found= containing_with_clause->find_table_def(table, barrier)))
diff --git a/sql/sql_cte.h b/sql/sql_cte.h
index 4693599300b..c0624c5e9e1 100644
--- a/sql/sql_cte.h
+++ b/sql/sql_cte.h
@@ -261,6 +261,8 @@ public:
bool is_referenced() { return referenced; }
+ bool is_hanging_recursive() { return is_recursive && !rec_outer_references; }
+
void inc_references() { references++; }
bool rename_columns_of_derived_unit(THD *thd, st_select_lex_unit *unit);
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 820a305059f..e04062d66d5 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -4542,8 +4542,17 @@ select_create::prepare(List<Item> &_values, SELECT_LEX_UNIT *u)
}
if (!(table= create_table_from_items(thd, &values, &extra_lock, hook_ptr)))
+ {
+ if (create_info->or_replace())
+ {
+ /* Original table was deleted. We have to log it */
+ log_drop_table(thd, &create_table->db, &create_table->table_name,
+ thd->lex->tmp_table());
+ }
+
/* abort() deletes table */
DBUG_RETURN(-1);
+ }
if (create_info->tmp_table())
{
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 43264e3e508..0827a381b1c 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -3735,6 +3735,17 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
if (part_func_value >= part_end_val &&
(loc_part_id < max_partition || !part_info->defined_max_value))
loc_part_id++;
+ if (part_info->part_type == VERSIONING_PARTITION &&
+ part_func_value < INT_MAX32 &&
+ loc_part_id > part_info->vers_info->hist_part->id)
+ {
+ /*
+ Historical query with AS OF point after the last history partition must
+ include last history partition because it can be overflown (contain
+ history rows out of right endpoint).
+ */
+ loc_part_id= part_info->vers_info->hist_part->id;
+ }
}
else
{
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 981420f03ae..69702813f08 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -294,14 +294,14 @@ public:
sys_var_pluginvar(sys_var_chain *chain, const char *name_arg,
st_plugin_int *p, st_mysql_sys_var *plugin_var_arg);
sys_var_pluginvar *cast_pluginvar() { return this; }
- uchar* real_value_ptr(THD *thd, enum_var_type type);
- TYPELIB* plugin_var_typelib(void);
- uchar* do_value_ptr(THD *thd, enum_var_type type, const LEX_CSTRING *base);
- uchar* session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ uchar* real_value_ptr(THD *thd, enum_var_type type) const;
+ TYPELIB* plugin_var_typelib(void) const;
+ const uchar* do_value_ptr(THD *thd, enum_var_type type, const LEX_CSTRING *base) const;
+ const uchar* session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return do_value_ptr(thd, OPT_SESSION, base); }
- uchar* global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar* global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return do_value_ptr(thd, OPT_GLOBAL, base); }
- uchar *default_value_ptr(THD *thd)
+ const uchar *default_value_ptr(THD *thd) const
{ return do_value_ptr(thd, OPT_DEFAULT, 0); }
bool do_check(THD *thd, set_var *var);
virtual void session_save_default(THD *thd, set_var *var) {}
@@ -3388,7 +3388,7 @@ sys_var_pluginvar::sys_var_pluginvar(sys_var_chain *chain, const char *name_arg,
plugin_opt_set_limits(&option, pv);
}
-uchar* sys_var_pluginvar::real_value_ptr(THD *thd, enum_var_type type)
+uchar* sys_var_pluginvar::real_value_ptr(THD *thd, enum_var_type type) const
{
if (type == OPT_DEFAULT)
{
@@ -3462,7 +3462,7 @@ bool sys_var_pluginvar::session_is_default(THD *thd)
}
-TYPELIB* sys_var_pluginvar::plugin_var_typelib(void)
+TYPELIB* sys_var_pluginvar::plugin_var_typelib(void) const
{
switch (plugin_var->flags & (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_THDLOCAL)) {
case PLUGIN_VAR_ENUM:
@@ -3480,12 +3480,10 @@ TYPELIB* sys_var_pluginvar::plugin_var_typelib(void)
}
-uchar* sys_var_pluginvar::do_value_ptr(THD *thd, enum_var_type type,
- const LEX_CSTRING *base)
+const uchar* sys_var_pluginvar::do_value_ptr(THD *thd, enum_var_type type,
+ const LEX_CSTRING *base) const
{
- uchar* result;
-
- result= real_value_ptr(thd, type);
+ const uchar* result= real_value_ptr(thd, type);
if ((plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_ENUM)
result= (uchar*) get_type(plugin_var_typelib(), *(ulong*)result);
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 816990fc3b6..a3027ea52fd 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1623,7 +1623,12 @@ static int mysql_test_select(Prepared_statement *stmt,
if (!lex->describe && !thd->lex->analyze_stmt && !stmt->is_sql_prepare())
{
/* Make copy of item list, as change_columns may change it */
- List<Item> fields(lex->first_select_lex()->item_list);
+ SELECT_LEX_UNIT* master_unit= unit->first_select()->master_unit();
+ bool is_union_op=
+ master_unit->is_unit_op() || master_unit->fake_select_lex;
+
+ List<Item> fields(is_union_op ? unit->item_list :
+ lex->first_select_lex()->item_list);
/* Change columns if a procedure like analyse() */
if (unit->last_procedure && unit->last_procedure->change_columns(thd, fields))
@@ -1745,7 +1750,7 @@ static bool mysql_test_call_fields(Prepared_statement *stmt,
while ((item= it++))
{
- if (item->fix_fields_if_needed_for_scalar(thd, it.ref()))
+ if (item->fix_fields_if_needed(thd, it.ref()))
goto err;
}
DBUG_RETURN(FALSE);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 8a251ae339e..77832a657ff 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -760,7 +760,8 @@ bool vers_select_conds_t::init_from_sysvar(THD *thd)
if (type != SYSTEM_TIME_UNSPECIFIED && type != SYSTEM_TIME_ALL)
{
DBUG_ASSERT(type == SYSTEM_TIME_AS_OF);
- Datetime dt(&in.ltime);
+ Datetime dt(in.unix_time, in.second_part, thd->variables.time_zone);
+
start.item= new (thd->mem_root)
Item_datetime_literal(thd, &dt, TIME_SECOND_PART_DIGITS);
if (!start.item)
@@ -1813,7 +1814,7 @@ int JOIN::init_join_caches()
if (table->file->keyread_enabled())
{
if (!(table->file->index_flags(table->file->keyread, 0, 1) & HA_CLUSTERED_INDEX))
- table->mark_columns_used_by_index(table->file->keyread, table->read_set);
+ table->mark_index_columns(table->file->keyread, table->read_set);
}
else if ((tab->read_first_record == join_read_first ||
tab->read_first_record == join_read_last) &&
@@ -2093,7 +2094,7 @@ JOIN::optimize_inner()
sel->attach_to_conds.empty();
}
}
-
+
if (optimizer_flag(thd, OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_SUBQUERY))
{
TABLE_LIST *tbl;
@@ -2361,7 +2362,7 @@ int JOIN::optimize_stage2()
/* Generate an execution plan from the found optimal join order. */
if (get_best_combination())
DBUG_RETURN(1);
-
+
if (make_range_rowid_filters())
DBUG_RETURN(1);
@@ -7376,7 +7377,7 @@ best_access_path(JOIN *join,
Json_writer_object trace_wrapper(thd, "best_access_path");
Json_writer_array trace_paths(thd, "considered_access_paths");
-
+
bitmap_clear_all(eq_join_set);
loose_scan_opt.init(join, s, remaining_tables);
@@ -9165,7 +9166,9 @@ static
double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
table_map rem_tables)
{
- uint16 ref_keyuse_steps[MAX_REF_PARTS - 1];
+ uint16 ref_keyuse_steps_buf[MAX_REF_PARTS];
+ uint ref_keyuse_size= MAX_REF_PARTS;
+ uint16 *ref_keyuse_steps= ref_keyuse_steps_buf;
Field *field;
TABLE *table= s->table;
MY_BITMAP *read_set= table->read_set;
@@ -9312,6 +9315,29 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
}
if (keyparts > 1)
{
+ /*
+ Prepare to set ref_keyuse_steps[keyparts-2]: resize the array
+ if it is not large enough
+ */
+ if (keyparts - 2 >= ref_keyuse_size)
+ {
+ uint new_size= MY_MAX(ref_keyuse_size*2, keyparts);
+ void *new_buf;
+ if (!(new_buf= my_malloc(sizeof(*ref_keyuse_steps)*new_size,
+ MYF(0))))
+ {
+ sel= 1.0; // As if no selectivity was computed
+ goto exit;
+ }
+ memcpy(new_buf, ref_keyuse_steps,
+ sizeof(*ref_keyuse_steps)*ref_keyuse_size);
+ if (ref_keyuse_steps != ref_keyuse_steps_buf)
+ my_free(ref_keyuse_steps);
+
+ ref_keyuse_steps= (uint16*)new_buf;
+ ref_keyuse_size= new_size;
+ }
+
ref_keyuse_steps[keyparts-2]= (uint16)(keyuse - prev_ref_keyuse);
prev_ref_keyuse= keyuse;
}
@@ -9366,7 +9392,9 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
sel*= table_multi_eq_cond_selectivity(join, idx, s, rem_tables,
keyparts, ref_keyuse_steps);
-
+exit:
+ if (ref_keyuse_steps != ref_keyuse_steps_buf)
+ my_free(ref_keyuse_steps);
return sel;
}
@@ -23644,6 +23672,12 @@ check_reverse_order:
if (select->quick == save_quick)
save_quick= 0; // make_reverse() consumed it
select->set_quick(tmp);
+ /* Cancel "Range checked for each record" */
+ if (tab->use_quick == 2)
+ {
+ tab->use_quick= 1;
+ tab->read_first_record= join_init_read_record;
+ }
}
else if (tab->type != JT_NEXT && tab->type != JT_REF_OR_NULL &&
tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts)
@@ -23656,6 +23690,12 @@ check_reverse_order:
*/
tab->read_first_record= join_read_last_key;
tab->read_record.read_record_func= join_read_prev_same;
+ /* Cancel "Range checked for each record" */
+ if (tab->use_quick == 2)
+ {
+ tab->use_quick= 1;
+ tab->read_first_record= join_init_read_record;
+ }
/*
Cancel Pushed Index Condition, as it doesn't work for reverse scans.
*/
@@ -27065,9 +27105,11 @@ int JOIN::save_explain_data_intern(Explain_query *output,
if (!(tmp_unit->item && tmp_unit->item->eliminated) && // (1)
(!tmp_unit->derived ||
tmp_unit->derived->is_materialized_derived()) && // (2)
- !(tmp_unit->with_element &&
- (!tmp_unit->derived || !tmp_unit->derived->derived_result))) // (3)
- {
+ (!tmp_unit->with_element ||
+ (tmp_unit->derived &&
+ tmp_unit->derived->derived_result &&
+ !tmp_unit->with_element->is_hanging_recursive()))) // (3)
+ {
explain->add_child(tmp_unit->first_select()->select_number);
}
}
@@ -27141,8 +27183,10 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
*/
if (!(unit->item && unit->item->eliminated) && // (1)
!(unit->derived && unit->derived->merged_for_insert) && // (2)
- !(unit->with_element &&
- (!unit->derived || !unit->derived->derived_result))) // (3)
+ (!unit->with_element ||
+ (unit->derived &&
+ unit->derived->derived_result &&
+ !unit->with_element->is_hanging_recursive()))) // (3)
{
if (mysql_explain_union(thd, unit, result))
DBUG_VOID_RETURN;
@@ -28054,7 +28098,7 @@ void JOIN::cache_const_exprs()
static bool get_range_limit_read_cost(const JOIN_TAB *tab,
const TABLE *table,
ha_rows table_records,
- uint keynr,
+ uint keynr,
ha_rows rows_limit,
double *read_time)
{
@@ -28142,7 +28186,7 @@ static bool get_range_limit_read_cost(const JOIN_TAB *tab,
to discount it from the rows_limit:
*/
double rows_limit_for_quick= rows_limit * (best_rows / table_records);
-
+
if (best_rows > rows_limit_for_quick)
{
/*
@@ -28425,7 +28469,7 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table,
refkey_rows_estimate is E(#rows) produced by the table access
strategy that was picked without regard to ORDER BY ... LIMIT.
- It will be used as the source of selectivity data.
+ It will be used as the source of selectivity data.
Use table->cond_selectivity as a better estimate which includes
condition selectivity too.
*/
@@ -28434,7 +28478,7 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table,
// cond_selectivity=1 while refkey_rows_estimate has a better
// estimate.
refkey_rows_estimate= MY_MIN(refkey_rows_estimate,
- ha_rows(table_records *
+ ha_rows(table_records *
table->cond_selectivity));
}
@@ -28542,7 +28586,7 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table,
{
possible_key.add("usable", false);
possible_key.add("cause", "cost");
- }
+ }
}
else
{
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index af06acf4854..31fb2f6a654 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -3597,6 +3597,29 @@ void remove_status_vars(SHOW_VAR *list)
}
}
+/**
+ A union holding a pointer to a type that can be referred by a status variable.
+ */
+union Any_pointer {
+ const void *as_void;
+ const uchar *as_uchar;
+ const char *as_char;
+ const char ** as_charptr;
+ const double *as_double;
+ const int * as_int;
+ const uint * as_uint;
+ const long *as_long;
+ const longlong *as_longlong;
+ const bool *as_bool;
+ const my_bool *as_my_bool;
+ const sys_var *as_sys_var;
+ const system_status_var *as_system_status_var;
+ const ha_rows *as_ha_rows;
+ const LEX_STRING *as_lex_cstring;
+ const SHOW_COMP_OPTION *as_show_comp_options;
+ intptr as_intptr;
+ Atomic_counter<uint32_t>* as_atomic_counter;
+};
/**
@brief Returns the value of a system or a status variable.
@@ -3621,16 +3644,18 @@ const char* get_one_variable(THD *thd,
const CHARSET_INFO **charset, char *buff,
size_t *length)
{
- void *value= variable->value;
+ Any_pointer value, status_var_value;
+ value.as_void= variable->value;
+ status_var_value.as_system_status_var= status_var;
const char *pos= buff;
const char *end= buff;
if (show_type == SHOW_SYS)
{
- sys_var *var= (sys_var *) value;
+ const sys_var *var= value.as_sys_var;
show_type= var->show_type();
- value= var->value_ptr(thd, value_type, &null_clex_str);
+ value.as_uchar= var->value_ptr(thd, value_type, &null_clex_str);
*charset= var->charset(thd);
}
@@ -3640,66 +3665,65 @@ const char* get_one_variable(THD *thd,
*/
switch (show_type) {
case SHOW_DOUBLE_STATUS:
- value= ((char *) status_var + (intptr) value);
+ value.as_char= status_var_value.as_char + value.as_intptr;
/* fall through */
case SHOW_DOUBLE:
/* 6 is the default precision for '%f' in sprintf() */
- end= buff + my_fcvt(*(double *) value, 6, buff, NULL);
+ end= buff + my_fcvt(*value.as_double, 6, buff, NULL);
break;
case SHOW_LONG_STATUS:
- value= ((char *) status_var + (intptr) value);
+ value.as_char= status_var_value.as_char + value.as_intptr;
/* fall through */
case SHOW_ULONG:
case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
- end= int10_to_str(*(long*) value, buff, 10);
+ end= int10_to_str(*value.as_long, buff, 10);
break;
case SHOW_LONGLONG_STATUS:
- value= ((char *) status_var + (intptr) value);
+ value.as_char= status_var_value.as_char + value.as_intptr;
/* fall through */
case SHOW_ULONGLONG:
- end= longlong10_to_str(*(longlong*) value, buff, 10);
+ end= longlong10_to_str(*value.as_longlong, buff, 10);
break;
case SHOW_HA_ROWS:
- end= longlong10_to_str((longlong) *(ha_rows*) value, buff, 10);
+ end= longlong10_to_str((longlong) *value.as_ha_rows, buff, 10);
break;
case SHOW_BOOL:
- end= strmov(buff, *(bool*) value ? "ON" : "OFF");
+ end= strmov(buff, *value.as_bool ? "ON" : "OFF");
break;
case SHOW_MY_BOOL:
- end= strmov(buff, *(my_bool*) value ? "ON" : "OFF");
+ end= strmov(buff, *value.as_my_bool ? "ON" : "OFF");
break;
case SHOW_UINT32_STATUS:
- value= ((char *) status_var + (intptr) value);
+ value.as_char= status_var_value.as_char + value.as_intptr;
/* fall through */
case SHOW_UINT:
- end= int10_to_str((long) *(uint*) value, buff, 10);
+ end= int10_to_str((long) *value.as_uint, buff, 10);
break;
case SHOW_SINT:
- end= int10_to_str((long) *(int*) value, buff, -10);
+ end= int10_to_str((long) *value.as_int, buff, -10);
break;
case SHOW_SLONG:
- end= int10_to_str(*(long*) value, buff, -10);
+ end= int10_to_str(*value.as_long, buff, -10);
break;
case SHOW_SLONGLONG:
- end= longlong10_to_str(*(longlong*) value, buff, -10);
+ end= longlong10_to_str(*value.as_longlong, buff, -10);
break;
case SHOW_HAVE:
{
- SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
- pos= show_comp_option_name[(int) tmp];
+ pos= show_comp_option_name[(int) *value.as_show_comp_options];
end= strend(pos);
break;
}
case SHOW_CHAR:
{
- if (!(pos= (char*)value))
+ if (!(pos= value.as_char))
pos= "";
end= strend(pos);
break;
}
case SHOW_CHAR_PTR:
{
- if (!(pos= *(char**) value))
+ if (!(pos= *value.as_charptr))
pos= "";
end= strend(pos);
@@ -3707,17 +3731,14 @@ const char* get_one_variable(THD *thd,
}
case SHOW_LEX_STRING:
{
- LEX_STRING *ls=(LEX_STRING*)value;
- if (!(pos= ls->str))
+ if (!(pos= value.as_lex_cstring->str))
end= pos= "";
else
- end= pos + ls->length;
+ end= pos + value.as_lex_cstring->length;
break;
}
case SHOW_ATOMIC_COUNTER_UINT32_T:
- end= int10_to_str(
- static_cast<long>(*static_cast<Atomic_counter<uint32_t>*>(value)),
- buff, 10);
+ end= int10_to_str(static_cast<long>(*value.as_atomic_counter), buff, 10);
break;
case SHOW_UNDEF:
break; // Return empty string
@@ -6713,6 +6734,16 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables,
LEX_CSTRING unknown= {STRING_WITH_LEN("?unknown field?") };
for (uint j=0 ; j < key_info->user_defined_key_parts ; j++,key_part++)
{
+ if (key_part->field->invisible >= INVISIBLE_SYSTEM &&
+ DBUG_EVALUATE_IF("test_completely_invisible", 0, 1))
+ {
+ /*
+ NOTE: we will get SEQ_IN_INDEX gap inside the result if this key_part
+ is not last (currently not possible). Though nothing is wrong with
+ that probably.
+ */
+ continue;
+ }
restore_record(table, s->default_values);
table->field[0]->store(STRING_WITH_LEN("def"), cs);
table->field[1]->store(db_name->str, db_name->length, cs);
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index e92dc97771e..c349a433075 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -983,6 +983,13 @@ Datetime::Datetime(THD *thd, int *warn, const MYSQL_TIME *from,
DBUG_ASSERT(is_valid_value_slow());
}
+Datetime::Datetime(my_time_t unix_time, ulong second_part_arg,
+ const Time_zone* time_zone)
+{
+ time_zone->gmt_sec_to_TIME(this, unix_time);
+ second_part= second_part_arg;
+}
+
bool Temporal::datetime_add_nanoseconds_or_invalidate(THD *thd, int *warn, ulong nsec)
{
@@ -8321,7 +8328,7 @@ bool Type_handler_string_result::Item_eq_value(THD *thd,
/***************************************************************************/
-bool Type_handler_string_result::union_element_finalize(const Item * item) const
+bool Type_handler_string_result::union_element_finalize(Item_type_holder* item) const
{
if (item->collation.derivation == DERIVATION_NONE)
{
@@ -8617,6 +8624,12 @@ Type_handler_timestamp_common::Item_val_native_with_conversion(THD *thd,
TIME_to_native(thd, &ltime, to, item->datetime_precision(thd));
}
+bool Type_handler_null::union_element_finalize(Item_type_holder *item) const
+{
+ item->set_handler(&type_handler_string);
+ return false;
+}
+
bool
Type_handler_timestamp_common::Item_val_native_with_conversion_result(THD *thd,
diff --git a/sql/sql_type.h b/sql/sql_type.h
index 7a514643bf6..40e3541baf2 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -67,6 +67,7 @@ class Item_func_minus;
class Item_func_mul;
class Item_func_div;
class Item_func_mod;
+class Item_type_holder;
class cmp_item;
class in_vector;
class Type_handler_hybrid_field_type;
@@ -2309,6 +2310,8 @@ public:
*(static_cast<MYSQL_TIME*>(this))= *from;
DBUG_ASSERT(is_valid_datetime_slow());
}
+ Datetime(my_time_t unix_time, ulong second_part,
+ const Time_zone* time_zone);
bool is_valid_datetime() const
{
@@ -3617,7 +3620,7 @@ public:
Performs the final data type validation for a UNION element,
after the regular "aggregation for result" was done.
*/
- virtual bool union_element_finalize(const Item * item) const
+ virtual bool union_element_finalize(Item_type_holder* item) const
{
return false;
}
@@ -4886,7 +4889,7 @@ public:
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const;
- bool union_element_finalize(const Item * item) const;
+ bool union_element_finalize(Item_type_holder* item) const;
bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root,
@@ -6100,6 +6103,7 @@ public:
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool union_element_finalize(Item_type_holder* item) const;
bool Column_definition_fix_attributes(Column_definition *c) const;
bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root,
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index b295112b70d..ada09be071e 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -30,6 +30,7 @@
#include "filesort.h" // filesort_free_buffers
#include "sql_view.h"
#include "sql_cte.h"
+#include "item_windowfunc.h"
bool mysql_union(THD *thd, LEX *lex, select_result *result,
SELECT_LEX_UNIT *unit, ulong setup_tables_done_option)
@@ -1194,7 +1195,8 @@ cont:
Test if the aggregated data type is OK for a UNION element.
E.g. in case of string data, DERIVATION_NONE is not allowed.
*/
- if (type->type_handler()->union_element_finalize(type))
+ if (type->type() == Item::TYPE_HOLDER && type->type_handler()->
+ union_element_finalize(static_cast<Item_type_holder*>(type)))
goto err;
}
@@ -1916,7 +1918,8 @@ bool st_select_lex_unit::cleanup()
{
DBUG_RETURN(FALSE);
}
- if (with_element && with_element->is_recursive && union_result)
+ if (with_element && with_element->is_recursive && union_result &&
+ with_element->rec_outer_references)
{
select_union_recursive *result= with_element->rec_result;
if (++result->cleanup_count == with_element->rec_outer_references)
@@ -2085,6 +2088,29 @@ static void cleanup_order(ORDER *order)
}
+static void cleanup_window_funcs(List<Item_window_func> &win_funcs)
+{
+ List_iterator_fast<Item_window_func> it(win_funcs);
+ Item_window_func *win_func;
+ while ((win_func= it++))
+ {
+ Window_spec *win_spec= win_func->window_spec;
+ if (!win_spec)
+ continue;
+ if (win_spec->save_partition_list)
+ {
+ win_spec->partition_list= win_spec->save_partition_list;
+ win_spec->save_partition_list= NULL;
+ }
+ if (win_spec->save_order_list)
+ {
+ win_spec->order_list= win_spec->save_order_list;
+ win_spec->save_order_list= NULL;
+ }
+ }
+}
+
+
bool st_select_lex::cleanup()
{
bool error= FALSE;
@@ -2096,6 +2122,8 @@ bool st_select_lex::cleanup()
cleanup_order(group_list.first);
cleanup_ftfuncs(this);
+ cleanup_window_funcs(window_funcs);
+
if (join)
{
List_iterator<TABLE_LIST> ti(leaf_tables);
@@ -2122,7 +2150,8 @@ bool st_select_lex::cleanup()
for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
lex_unit= lex_unit->next_unit())
{
- if (lex_unit->with_element && lex_unit->with_element->is_recursive)
+ if (lex_unit->with_element && lex_unit->with_element->is_recursive &&
+ lex_unit->with_element->rec_outer_references)
continue;
error= (bool) ((uint) error | (uint) lex_unit->cleanup());
}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index bc4c124d7b1..691a6b7eaee 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -273,7 +273,7 @@ static void prepare_record_for_error_message(int error, TABLE *table)
/* Create unique_map with all fields used by that index. */
my_bitmap_init(&unique_map, unique_map_buf, table->s->fields, FALSE);
- table->mark_columns_used_by_index(keynr, &unique_map);
+ table->mark_index_columns(keynr, &unique_map);
/* Subtract read_set and write_set. */
bitmap_subtract(&unique_map, table->read_set);
diff --git a/sql/sql_window.cc b/sql/sql_window.cc
index abb3937096f..876ddef8f65 100644
--- a/sql/sql_window.cc
+++ b/sql/sql_window.cc
@@ -592,9 +592,15 @@ int compare_window_funcs_by_window_specs(Item_window_func *win_func1,
Let's use only one of the lists.
*/
if (!win_spec1->name() && win_spec2->name())
+ {
+ win_spec1->save_partition_list= win_spec1->partition_list;
win_spec1->partition_list= win_spec2->partition_list;
+ }
else
+ {
+ win_spec2->save_partition_list= win_spec2->partition_list;
win_spec2->partition_list= win_spec1->partition_list;
+ }
cmp= compare_order_lists(win_spec1->order_list,
win_spec2->order_list);
@@ -607,9 +613,15 @@ int compare_window_funcs_by_window_specs(Item_window_func *win_func1,
Let's use only one of the lists.
*/
if (!win_spec1->name() && win_spec2->name())
+ {
+ win_spec1->save_order_list= win_spec2->order_list;
win_spec1->order_list= win_spec2->order_list;
+ }
else
+ {
+ win_spec1->save_order_list= win_spec2->order_list;
win_spec2->order_list= win_spec1->order_list;
+ }
cmp= compare_window_frames(win_spec1->window_frame,
win_spec2->window_frame);
diff --git a/sql/sql_window.h b/sql/sql_window.h
index 373b367b211..5e76a33dcd0 100644
--- a/sql/sql_window.h
+++ b/sql/sql_window.h
@@ -111,8 +111,10 @@ class Window_spec : public Sql_alloc
LEX_CSTRING *window_ref;
SQL_I_List<ORDER> *partition_list;
+ SQL_I_List<ORDER> *save_partition_list;
SQL_I_List<ORDER> *order_list;
+ SQL_I_List<ORDER> *save_order_list;
Window_frame *window_frame;
@@ -123,7 +125,8 @@ class Window_spec : public Sql_alloc
SQL_I_List<ORDER> *ord_list,
Window_frame *win_frame)
: window_names_are_checked(false), window_ref(win_ref),
- partition_list(part_list), order_list(ord_list),
+ partition_list(part_list), save_partition_list(NULL),
+ order_list(ord_list), save_order_list(NULL),
window_frame(win_frame), referenced_win_spec(NULL) {}
virtual const char *name() { return NULL; }
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index dfe239c41bd..af7b29b3c3b 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1885,7 +1885,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
table_wild simple_expr column_default_non_parenthesized_expr udf_expr
primary_expr string_factor_expr mysql_concatenation_expr
select_sublist_qualified_asterisk
- expr_or_default set_expr_or_default
+ expr_or_ignore expr_or_ignore_or_default set_expr_or_default
geometry_function signed_literal expr_or_literal
sp_opt_default
simple_ident_nospvar
@@ -2388,12 +2388,12 @@ execute_using:
;
execute_params:
- expr_or_default
+ expr_or_ignore_or_default
{
if (unlikely(!($$= List<Item>::make(thd->mem_root, $1))))
MYSQL_YYABORT;
}
- | execute_params ',' expr_or_default
+ | execute_params ',' expr_or_ignore_or_default
{
if (($$= $1)->push_back($3, thd->mem_root))
MYSQL_YYABORT;
@@ -10586,7 +10586,7 @@ column_default_non_parenthesized_expr:
if (unlikely(il))
my_yyabort_error((ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str));
$$= new (thd->mem_root) Item_default_value(thd, Lex->current_context(),
- $3);
+ $3, 0);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
Lex->default_used= TRUE;
@@ -13715,7 +13715,7 @@ ident_eq_list:
;
ident_eq_value:
- simple_ident_nospvar equal expr_or_default
+ simple_ident_nospvar equal expr_or_ignore_or_default
{
LEX *lex=Lex;
if (unlikely(lex->field_list.push_back($1, thd->mem_root)) ||
@@ -13785,12 +13785,12 @@ opt_values_with_names:
;
values:
- values ',' expr_or_default
+ values ',' expr_or_ignore_or_default
{
if (unlikely(Lex->insert_list->push_back($3, thd->mem_root)))
MYSQL_YYABORT;
}
- | expr_or_default
+ | expr_or_ignore_or_default
{
if (unlikely(Lex->insert_list->push_back($1, thd->mem_root)))
MYSQL_YYABORT;
@@ -13798,7 +13798,7 @@ values:
;
values_with_names:
- values_with_names ',' remember_name expr_or_default remember_end
+ values_with_names ',' remember_name expr_or_ignore_or_default remember_end
{
if (unlikely(Lex->insert_list->push_back($4, thd->mem_root)))
MYSQL_YYABORT;
@@ -13806,7 +13806,7 @@ values_with_names:
if (!$4->name.str || $4->name.str == item_empty_name)
$4->set_name(thd, $3, (uint) ($5 - $3), thd->charset());
}
- | remember_name expr_or_default remember_end
+ | remember_name expr_or_ignore_or_default remember_end
{
if (unlikely(Lex->insert_list->push_back($2, thd->mem_root)))
MYSQL_YYABORT;
@@ -13816,17 +13816,21 @@ values_with_names:
}
;
-expr_or_default:
+expr_or_ignore:
expr { $$= $1;}
- | DEFAULT
+ | IGNORE_SYM
{
- $$= new (thd->mem_root) Item_default_specification(thd);
+ $$= new (thd->mem_root) Item_ignore_specification(thd);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | IGNORE_SYM
+ ;
+
+expr_or_ignore_or_default:
+ expr_or_ignore { $$= $1;}
+ | DEFAULT
{
- $$= new (thd->mem_root) Item_ignore_specification(thd);
+ $$= new (thd->mem_root) Item_default_specification(thd);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
@@ -13911,10 +13915,16 @@ update_list:
;
update_elem:
- simple_ident_nospvar equal expr_or_default
+ simple_ident_nospvar equal DEFAULT
+ {
+ Item *def= new (thd->mem_root) Item_default_value(thd,
+ Lex->current_context(), $1, 1);
+ if (!def || add_item_to_list(thd, $1) || add_value_to_list(thd, def))
+ MYSQL_YYABORT;
+ }
+ | simple_ident_nospvar equal expr_or_ignore
{
- if (unlikely(add_item_to_list(thd, $1)) ||
- unlikely(add_value_to_list(thd, $3)))
+ if (add_item_to_list(thd, $1) || add_value_to_list(thd, $3))
MYSQL_YYABORT;
}
;
@@ -13925,7 +13935,7 @@ insert_update_list:
;
insert_update_elem:
- simple_ident_nospvar equal expr_or_default
+ simple_ident_nospvar equal expr_or_ignore_or_default
{
LEX *lex= Lex;
if (unlikely(lex->update_list.push_back($1, thd->mem_root)) ||
@@ -15263,7 +15273,7 @@ load_data_set_list:
;
load_data_set_elem:
- simple_ident_nospvar equal remember_name expr_or_default remember_end
+ simple_ident_nospvar equal remember_name expr_or_ignore_or_default remember_end
{
LEX *lex= Lex;
if (unlikely(lex->update_list.push_back($1, thd->mem_root)) ||
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index 76eb21a88e8..ae8e5116cff 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -1368,7 +1368,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
table_wild simple_expr column_default_non_parenthesized_expr udf_expr
primary_expr string_factor_expr mysql_concatenation_expr
select_sublist_qualified_asterisk
- expr_or_default set_expr_or_default
+ expr_or_ignore expr_or_ignore_or_default set_expr_or_default
geometry_function signed_literal expr_or_literal
sp_opt_default
simple_ident_nospvar
@@ -1890,12 +1890,12 @@ execute_using:
;
execute_params:
- expr_or_default
+ expr_or_ignore_or_default
{
if (unlikely(!($$= List<Item>::make(thd->mem_root, $1))))
MYSQL_YYABORT;
}
- | execute_params ',' expr_or_default
+ | execute_params ',' expr_or_ignore_or_default
{
if (($$= $1)->push_back($3, thd->mem_root))
MYSQL_YYABORT;
@@ -10684,7 +10684,7 @@ column_default_non_parenthesized_expr:
if (unlikely(il))
my_yyabort_error((ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str));
$$= new (thd->mem_root) Item_default_value(thd, Lex->current_context(),
- $3);
+ $3, 0);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
Lex->default_used= TRUE;
@@ -13830,7 +13830,7 @@ ident_eq_list:
;
ident_eq_value:
- simple_ident_nospvar equal expr_or_default
+ simple_ident_nospvar equal expr_or_ignore_or_default
{
LEX *lex=Lex;
if (unlikely(lex->field_list.push_back($1, thd->mem_root)) ||
@@ -13900,12 +13900,12 @@ opt_values_with_names:
;
values:
- values ',' expr_or_default
+ values ',' expr_or_ignore_or_default
{
if (unlikely(Lex->insert_list->push_back($3, thd->mem_root)))
MYSQL_YYABORT;
}
- | expr_or_default
+ | expr_or_ignore_or_default
{
if (unlikely(Lex->insert_list->push_back($1, thd->mem_root)))
MYSQL_YYABORT;
@@ -13913,7 +13913,7 @@ values:
;
values_with_names:
- values_with_names ',' remember_name expr_or_default remember_end
+ values_with_names ',' remember_name expr_or_ignore_or_default remember_end
{
if (unlikely(Lex->insert_list->push_back($4, thd->mem_root)))
MYSQL_YYABORT;
@@ -13921,7 +13921,7 @@ values_with_names:
if (!$4->name.str || $4->name.str == item_empty_name)
$4->set_name(thd, $3, (uint) ($5 - $3), thd->charset());
}
- | remember_name expr_or_default remember_end
+ | remember_name expr_or_ignore_or_default remember_end
{
if (unlikely(Lex->insert_list->push_back($2, thd->mem_root)))
MYSQL_YYABORT;
@@ -13931,17 +13931,21 @@ values_with_names:
}
;
-expr_or_default:
+expr_or_ignore:
expr { $$= $1;}
- | DEFAULT
+ | IGNORE_SYM
{
- $$= new (thd->mem_root) Item_default_specification(thd);
+ $$= new (thd->mem_root) Item_ignore_specification(thd);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | IGNORE_SYM
+ ;
+
+expr_or_ignore_or_default:
+ expr_or_ignore { $$= $1;}
+ | DEFAULT
{
- $$= new (thd->mem_root) Item_ignore_specification(thd);
+ $$= new (thd->mem_root) Item_default_specification(thd);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
@@ -14026,10 +14030,16 @@ update_list:
;
update_elem:
- simple_ident_nospvar equal expr_or_default
+ simple_ident_nospvar equal DEFAULT
+ {
+ Item *def= new (thd->mem_root) Item_default_value(thd,
+ Lex->current_context(), $1, 1);
+ if (!def || add_item_to_list(thd, $1) || add_value_to_list(thd, def))
+ MYSQL_YYABORT;
+ }
+ | simple_ident_nospvar equal expr_or_ignore
{
- if (unlikely(add_item_to_list(thd, $1)) ||
- unlikely(add_value_to_list(thd, $3)))
+ if (add_item_to_list(thd, $1) || add_value_to_list(thd, $3))
MYSQL_YYABORT;
}
;
@@ -14040,7 +14050,7 @@ insert_update_list:
;
insert_update_elem:
- simple_ident_nospvar equal expr_or_default
+ simple_ident_nospvar equal expr_or_ignore_or_default
{
LEX *lex= Lex;
if (unlikely(lex->update_list.push_back($1, thd->mem_root)) ||
@@ -15380,7 +15390,7 @@ load_data_set_list:
;
load_data_set_elem:
- simple_ident_nospvar equal remember_name expr_or_default remember_end
+ simple_ident_nospvar equal remember_name expr_or_ignore_or_default remember_end
{
LEX *lex= Lex;
if (unlikely(lex->update_list.push_back($1, thd->mem_root)) ||
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index c52a8f742a8..14d45d951eb 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -448,11 +448,10 @@ static Sys_var_charptr Sys_my_bind_addr(
READ_ONLY GLOBAL_VAR(my_bind_addr_str), CMD_LINE(REQUIRED_ARG),
IN_FS_CHARSET, DEFAULT(0));
-const char *Sys_var_vers_asof::asof_keywords[]= {"DEFAULT", NULL};
static Sys_var_vers_asof Sys_vers_asof_timestamp(
"system_versioning_asof", "Default value for the FOR SYSTEM_TIME AS OF clause",
SESSION_VAR(vers_asof_timestamp.type), NO_CMD_LINE,
- Sys_var_vers_asof::asof_keywords, DEFAULT(SYSTEM_TIME_UNSPECIFIED));
+ DEFAULT(SYSTEM_TIME_UNSPECIFIED));
static const char *vers_alter_history_keywords[]= {"ERROR", "KEEP", NullS};
static Sys_var_enum Sys_vers_alter_history(
@@ -1739,8 +1738,9 @@ static Sys_var_gtid_binlog_pos Sys_gtid_binlog_pos(
READ_ONLY GLOBAL_VAR(opt_gtid_binlog_pos_dummy), NO_CMD_LINE);
-uchar *
-Sys_var_gtid_binlog_pos::global_value_ptr(THD *thd, const LEX_CSTRING *base)
+const uchar *
+Sys_var_gtid_binlog_pos::global_value_ptr(THD *thd,
+ const LEX_CSTRING *base) const
{
char buf[128];
String str(buf, sizeof(buf), system_charset_info);
@@ -1767,8 +1767,9 @@ static Sys_var_gtid_current_pos Sys_gtid_current_pos(
READ_ONLY GLOBAL_VAR(opt_gtid_current_pos_dummy), NO_CMD_LINE);
-uchar *
-Sys_var_gtid_current_pos::global_value_ptr(THD *thd, const LEX_CSTRING *base)
+const uchar *
+Sys_var_gtid_current_pos::global_value_ptr(THD *thd,
+ const LEX_CSTRING *base) const
{
String str;
char *p;
@@ -1848,8 +1849,9 @@ Sys_var_gtid_slave_pos::global_update(THD *thd, set_var *var)
}
-uchar *
-Sys_var_gtid_slave_pos::global_value_ptr(THD *thd, const LEX_CSTRING *base)
+const uchar *
+Sys_var_gtid_slave_pos::global_value_ptr(THD *thd,
+ const LEX_CSTRING *base) const
{
String str;
char *p;
@@ -1969,8 +1971,9 @@ Sys_var_gtid_binlog_state::global_update(THD *thd, set_var *var)
}
-uchar *
-Sys_var_gtid_binlog_state::global_value_ptr(THD *thd, const LEX_CSTRING *base)
+const uchar *
+Sys_var_gtid_binlog_state::global_value_ptr(THD *thd,
+ const LEX_CSTRING *base) const
{
char buf[512];
String str(buf, sizeof(buf), system_charset_info);
@@ -2004,8 +2007,8 @@ static Sys_var_last_gtid Sys_last_gtid(
export sys_var *Sys_last_gtid_ptr= &Sys_last_gtid; // for check changing
-uchar *
-Sys_var_last_gtid::session_value_ptr(THD *thd, const LEX_CSTRING *base)
+const uchar *
+Sys_var_last_gtid::session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
char buf[10+1+10+1+20+1];
String str(buf, sizeof(buf), system_charset_info);
@@ -2169,9 +2172,10 @@ Sys_var_slave_parallel_mode::global_update(THD *thd, set_var *var)
}
-uchar *
+const uchar *
Sys_var_slave_parallel_mode::global_value_ptr(THD *thd,
- const LEX_CSTRING *base_name)
+ const
+ LEX_CSTRING *base_name) const
{
Master_info *mi;
enum_slave_parallel_mode val=
@@ -5062,8 +5066,9 @@ bool Sys_var_rpl_filter::set_filter_value(const char *value, Master_info *mi)
return status;
}
-uchar *Sys_var_rpl_filter::global_value_ptr(THD *thd,
- const LEX_CSTRING *base_name)
+const uchar *
+Sys_var_rpl_filter::global_value_ptr(THD *thd,
+ const LEX_CSTRING *base_name) const
{
char buf[256];
String tmp(buf, sizeof(buf), &my_charset_bin);
@@ -5175,7 +5180,7 @@ static Sys_var_uint Sys_slave_net_timeout(
*/
ulonglong Sys_var_multi_source_ulonglong::
-get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset)
+get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset) const
{
Master_info *mi;
ulonglong res= 0; // Default value
diff --git a/sql/sys_vars.ic b/sql/sys_vars.ic
index 50e2ec46222..84d1cd6b331 100644
--- a/sql/sys_vars.ic
+++ b/sql/sys_vars.ic
@@ -223,7 +223,7 @@ public:
{ var->save_result.ulonglong_value= option.def_value; }
private:
T get_max_var() { return *((T*) max_var_ptr()); }
- uchar *default_value_ptr(THD *thd) { return (uchar*) &option.def_value; }
+ const uchar *default_value_ptr(THD *thd) const { return (uchar*) &option.def_value; }
};
typedef Sys_var_integer<int, GET_INT, SHOW_SINT> Sys_var_int;
@@ -234,25 +234,25 @@ typedef Sys_var_integer<ulonglong, GET_ULL, SHOW_ULONGLONG> Sys_var_ulonglong;
typedef Sys_var_integer<long, GET_LONG, SHOW_SLONG> Sys_var_long;
-template<> uchar *Sys_var_int::default_value_ptr(THD *thd)
+template<> const uchar *Sys_var_int::default_value_ptr(THD *thd) const
{
thd->sys_var_tmp.int_value= (int)option.def_value;
return (uchar*) &thd->sys_var_tmp.int_value;
}
-template<> uchar *Sys_var_uint::default_value_ptr(THD *thd)
+template<> const uchar *Sys_var_uint::default_value_ptr(THD *thd) const
{
thd->sys_var_tmp.uint_value= (uint)option.def_value;
return (uchar*) &thd->sys_var_tmp.uint_value;
}
-template<> uchar *Sys_var_long::default_value_ptr(THD *thd)
+template<> const uchar *Sys_var_long::default_value_ptr(THD *thd) const
{
thd->sys_var_tmp.long_value= (long)option.def_value;
return (uchar*) &thd->sys_var_tmp.long_value;
}
-template<> uchar *Sys_var_ulong::default_value_ptr(THD *thd)
+template<> const uchar *Sys_var_ulong::default_value_ptr(THD *thd) const
{
thd->sys_var_tmp.ulong_value= (ulong)option.def_value;
return (uchar*) &thd->sys_var_tmp.ulong_value;
@@ -382,13 +382,13 @@ public:
{ var->save_result.ulonglong_value= global_var(ulong); }
void global_save_default(THD *thd, set_var *var)
{ var->save_result.ulonglong_value= option.def_value; }
- uchar *valptr(THD *thd, ulong val)
- { return (uchar*)typelib.type_names[val]; }
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *valptr(THD *thd, ulong val) const
+ { return reinterpret_cast<const uchar*>(typelib.type_names[val]); }
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return valptr(thd, session_var(thd, ulong)); }
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return valptr(thd, global_var(ulong)); }
- uchar *default_value_ptr(THD *thd)
+ const uchar *default_value_ptr(THD *thd) const
{ return valptr(thd, (ulong)option.def_value); }
ulong get_max_var() { return *((ulong *) max_var_ptr()); }
@@ -436,7 +436,7 @@ public:
{ var->save_result.ulonglong_value= (ulonglong)*(my_bool *)global_value_ptr(thd, 0); }
void global_save_default(THD *thd, set_var *var)
{ var->save_result.ulonglong_value= option.def_value; }
- uchar *default_value_ptr(THD *thd)
+ const uchar *default_value_ptr(THD *thd) const
{
thd->sys_var_tmp.my_bool_value=(my_bool) option.def_value;
return (uchar*) &thd->sys_var_tmp.my_bool_value;
@@ -681,7 +681,7 @@ public:
void global_save_default(THD *thd, set_var *var)
{ DBUG_ASSERT(FALSE); }
protected:
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
return thd->security_ctx->proxy_user[0] ?
(uchar *) &(thd->security_ctx->proxy_user[0]) : NULL;
@@ -697,7 +697,7 @@ public:
{}
protected:
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
return (uchar*)thd->security_ctx->external_user;
}
@@ -741,7 +741,7 @@ public:
bool global_update(THD *thd, set_var *var);
protected:
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base);
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const;
bool set_filter_value(const char *value, Master_info *mi);
};
@@ -859,7 +859,7 @@ public:
{
DBUG_ASSERT(FALSE);
}
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
DBUG_ASSERT(FALSE);
return NULL;
@@ -937,19 +937,19 @@ public:
var->save_result.string_value.str= ptr;
var->save_result.string_value.length= safe_strlen(ptr);
}
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
char buf[256];
DBUG_EXPLAIN(buf, sizeof(buf));
return (uchar*) thd->strdup(buf);
}
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
char buf[256];
DBUG_EXPLAIN_INITIAL(buf, sizeof(buf));
return (uchar*) thd->strdup(buf);
}
- uchar *default_value_ptr(THD *thd)
+ const uchar *default_value_ptr(THD *thd) const
{ return (uchar*)""; }
};
#endif
@@ -1025,7 +1025,7 @@ public:
return keycache_update(thd, key_cache, offset, new_value);
}
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
KEY_CACHE *key_cache= get_key_cache(base);
if (!key_cache)
@@ -1210,7 +1210,7 @@ public:
lock, binlog_status_arg, on_check_func, on_update_func,
substitute)
{ }
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
if (thd->user_connect && thd->user_connect->user_resources.user_conn)
return (uchar*) &(thd->user_connect->user_resources.user_conn);
@@ -1322,13 +1322,13 @@ public:
{ var->save_result.ulonglong_value= global_var(ulonglong); }
void global_save_default(THD *thd, set_var *var)
{ var->save_result.ulonglong_value= option.def_value; }
- uchar *valptr(THD *thd, ulonglong val)
+ const uchar *valptr(THD *thd, ulonglong val) const
{ return (uchar*)flagset_to_string(thd, 0, val, typelib.type_names); }
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return valptr(thd, session_var(thd, ulonglong)); }
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return valptr(thd, global_var(ulonglong)); }
- uchar *default_value_ptr(THD *thd)
+ const uchar *default_value_ptr(THD *thd) const
{ return valptr(thd, option.def_value); }
};
@@ -1436,13 +1436,13 @@ public:
{ var->save_result.ulonglong_value= global_var(ulonglong); }
void global_save_default(THD *thd, set_var *var)
{ var->save_result.ulonglong_value= option.def_value; }
- uchar *valptr(THD *thd, ulonglong val)
- { return (uchar*)set_to_string(thd, 0, val, typelib.type_names); }
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *valptr(THD *thd, ulonglong val) const
+ { return reinterpret_cast<const uchar*>(set_to_string(thd, 0, val, typelib.type_names)); }
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return valptr(thd, session_var(thd, ulonglong)); }
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return valptr(thd, global_var(ulonglong)); }
- uchar *default_value_ptr(THD *thd)
+ const uchar *default_value_ptr(THD *thd) const
{ return valptr(thd, option.def_value); }
ulonglong get_max_var() { return *((ulonglong*) max_var_ptr()); }
@@ -1539,7 +1539,7 @@ public:
plugin_ref plugin= global_var(plugin_ref);
var->save_result.plugin= plugin ? my_plugin_lock(thd, plugin) : 0;
}
- plugin_ref get_default(THD *thd)
+ plugin_ref get_default(THD *thd) const
{
char *default_value= *reinterpret_cast<char**>(option.def_value);
if (!default_value)
@@ -1561,16 +1561,16 @@ public:
var->save_result.plugin= get_default(thd);
}
- uchar *valptr(THD *thd, plugin_ref plugin)
+ uchar *valptr(THD *thd, plugin_ref plugin) const
{
return (uchar*)(plugin ? thd->strmake(plugin_name(plugin)->str,
plugin_name(plugin)->length) : 0);
}
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return valptr(thd, session_var(thd, plugin_ref)); }
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return valptr(thd, global_var(plugin_ref)); }
- uchar *default_value_ptr(THD *thd)
+ const uchar *default_value_ptr(THD *thd) const
{ return valptr(thd, get_default(thd)); }
};
@@ -1657,7 +1657,7 @@ public:
plugin_ref* plugins= global_var(plugin_ref *);
var->save_result.plugins= plugins ? temp_copy_engine_list(thd, plugins) : 0;
}
- plugin_ref *get_default(THD *thd)
+ plugin_ref *get_default(THD *thd) const
{
char *default_value= *reinterpret_cast<char**>(option.def_value);
if (!default_value)
@@ -1671,15 +1671,15 @@ public:
var->save_result.plugins= get_default(thd);
}
- uchar *valptr(THD *thd, plugin_ref *plugins)
+ uchar *valptr(THD *thd, plugin_ref *plugins) const
{
- return (uchar*)pretty_print_engine_list(thd, plugins);
+ return reinterpret_cast<uchar*>(pretty_print_engine_list(thd, plugins));
}
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return valptr(thd, session_var(thd, plugin_ref*)); }
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return valptr(thd, global_var(plugin_ref*)); }
- uchar *default_value_ptr(THD *thd)
+ const uchar *default_value_ptr(THD *thd) const
{ return valptr(thd, get_default(thd)); }
};
@@ -1743,16 +1743,16 @@ public:
{
DBUG_ASSERT(FALSE);
}
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
return debug_sync_value_ptr(thd);
}
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
DBUG_ASSERT(FALSE);
return 0;
}
- uchar *default_value_ptr(THD *thd)
+ const uchar *default_value_ptr(THD *thd) const
{ return (uchar*)""; }
};
#endif /* defined(ENABLED_DEBUG_SYNC) */
@@ -1828,16 +1828,16 @@ public:
void global_save_default(THD *thd, set_var *var)
{ var->save_result.ulonglong_value= option.def_value; }
- uchar *valptr(THD *thd, ulonglong val)
+ uchar *valptr(THD *thd, ulonglong val) const
{
thd->sys_var_tmp.my_bool_value= (reverse_semantics == !(val & bitmask));
return (uchar*) &thd->sys_var_tmp.my_bool_value;
}
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return valptr(thd, session_var(thd, ulonglong)); }
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return valptr(thd, global_var(ulonglong)); }
- uchar *default_value_ptr(THD *thd)
+ const uchar *default_value_ptr(THD *thd) const
{
thd->sys_var_tmp.my_bool_value= option.def_value != 0;
return (uchar*) &thd->sys_var_tmp.my_bool_value;
@@ -1896,17 +1896,17 @@ public:
{ var->value= 0; }
void global_save_default(THD *thd, set_var *var)
{ DBUG_ASSERT(FALSE); }
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
thd->sys_var_tmp.ulonglong_value= read_func(thd);
return (uchar*) &thd->sys_var_tmp.ulonglong_value;
}
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
DBUG_ASSERT(FALSE);
return 0;
}
- uchar *default_value_ptr(THD *thd)
+ const uchar *default_value_ptr(THD *thd) const
{
thd->sys_var_tmp.ulonglong_value= 0;
return (uchar*) &thd->sys_var_tmp.ulonglong_value;
@@ -1962,18 +1962,18 @@ public:
{ var->value= 0; }
void global_save_default(THD *thd, set_var *var)
{ DBUG_ASSERT(FALSE); }
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
thd->sys_var_tmp.double_value= thd->start_time +
thd->start_time_sec_part/(double)TIME_SECOND_PART_FACTOR;
return (uchar*) &thd->sys_var_tmp.double_value;
}
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
DBUG_ASSERT(FALSE);
return 0;
}
- uchar *default_value_ptr(THD *thd)
+ const uchar *default_value_ptr(THD *thd) const
{
thd->sys_var_tmp.double_value= 0;
return (uchar*) &thd->sys_var_tmp.double_value;
@@ -2032,12 +2032,12 @@ public:
}
void session_save_default(THD *thd, set_var *var) { }
void global_save_default(THD *thd, set_var *var) { }
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
DBUG_ASSERT(FALSE);
return 0;
}
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
return (uchar*)show_comp_option_name[global_var(enum SHOW_COMP_OPTION)];
}
@@ -2107,13 +2107,13 @@ public:
void **default_value= reinterpret_cast<void**>(option.def_value);
var->save_result.ptr= *default_value;
}
- uchar *valptr(THD *thd, uchar *val)
+ uchar *valptr(THD *thd, uchar *val) const
{ return val ? *(uchar**)(val+name_offset) : 0; }
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return valptr(thd, session_var(thd, uchar*)); }
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return valptr(thd, global_var(uchar*)); }
- uchar *default_value_ptr(THD *thd)
+ const uchar *default_value_ptr(THD *thd) const
{ return valptr(thd, *(uchar**)option.def_value); }
};
@@ -2183,9 +2183,9 @@ public:
var->save_result.time_zone=
*(Time_zone**)(intptr)option.def_value;
}
- uchar *valptr(THD *thd, Time_zone *val)
- { return (uchar *)(val->get_name()->ptr()); }
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *valptr(THD *thd, Time_zone *val) const
+ { return reinterpret_cast<const uchar*>(val->get_name()->ptr()); }
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
/*
This is an ugly fix for replication: we don't replicate properly queries
@@ -2198,9 +2198,9 @@ public:
thd->time_zone_used= 1;
return valptr(thd, session_var(thd, Time_zone *));
}
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return valptr(thd, global_var(Time_zone*)); }
- uchar *default_value_ptr(THD *thd)
+ const uchar *default_value_ptr(THD *thd) const
{ return valptr(thd, *(Time_zone**)option.def_value); }
};
@@ -2359,7 +2359,7 @@ public:
/* Use value given in variable declaration */
global_save_default(thd, var);
}
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
ulonglong *tmp, res;
tmp= (ulonglong*) (((uchar*)&(thd->variables)) + offset);
@@ -2367,11 +2367,11 @@ public:
*tmp= res;
return (uchar*) tmp;
}
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
return session_value_ptr(thd, base);
}
- ulonglong get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset);
+ ulonglong get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset) const;
bool update_variable(THD *thd, Master_info *mi)
{
return update_multi_source_variable_func(this, thd, mi);
@@ -2419,12 +2419,12 @@ public:
{
DBUG_ASSERT(false);
}
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
DBUG_ASSERT(false);
return NULL;
}
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base);
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const;
};
@@ -2468,12 +2468,12 @@ public:
{
DBUG_ASSERT(false);
}
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
DBUG_ASSERT(false);
return NULL;
}
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base);
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const;
};
@@ -2508,13 +2508,13 @@ public:
/* Record the attempt to use default so we can error. */
var->value= 0;
}
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
DBUG_ASSERT(false);
return NULL;
}
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base);
- uchar *default_value_ptr(THD *thd)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const;
+ const uchar *default_value_ptr(THD *thd) const
{ return 0; }
};
@@ -2550,13 +2550,13 @@ public:
/* Record the attempt to use default so we can error. */
var->value= 0;
}
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
DBUG_ASSERT(false);
return NULL;
}
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base);
- uchar *default_value_ptr(THD *thd)
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const;
+ const uchar *default_value_ptr(THD *thd) const
{ return 0; }
};
@@ -2600,8 +2600,8 @@ public:
{
DBUG_ASSERT(false);
}
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base);
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const;
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
DBUG_ASSERT(false);
return NULL;
@@ -2627,30 +2627,32 @@ public:
SYSVAR_ASSERT(scope() == GLOBAL);
}
bool global_update(THD *thd, set_var *var);
- uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base);
+ const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const;
};
-class Sys_var_vers_asof: public Sys_var_enum
+class Sys_var_vers_asof: public sys_var
{
public:
- static const char *asof_keywords[];
-
-public:
Sys_var_vers_asof(const char *name_arg,
const char *comment, int flag_args, ptrdiff_t off, size_t size,
- CMD_LINE getopt, const char *values[],
- uint def_val)
- : Sys_var_enum(name_arg, comment, flag_args, off, size,
- getopt, values, def_val)
+ CMD_LINE getopt, uint def_val,
+ PolyLock *lock= NO_MUTEX_GUARD,
+ binlog_status_enum binlog_status_arg= VARIABLE_NOT_IN_BINLOG,
+ on_check_function on_check_func= NULL,
+ on_update_function on_update_func= NULL,
+ const char *substitute= NULL)
+ : sys_var(&all_sys_vars, name_arg, comment, flag_args, off,
+ getopt.id, getopt.arg_type, SHOW_CHAR, def_val, lock,
+ binlog_status_arg, on_check_func, on_update_func, substitute)
{
- // setval() accepts string rather enum
option.var_type= GET_STR;
}
virtual bool do_check(THD *thd, set_var *var)
{
- if (!Sys_var_enum::do_check(thd, var))
+ if (!var->value)
return false;
+
MYSQL_TIME ltime;
Datetime::Options opt(TIME_CONV_NONE |
TIME_NO_ZERO_IN_DATE |
@@ -2658,78 +2660,92 @@ public:
bool res= var->value->get_date(thd, &ltime, opt);
if (!res)
{
- var->save_result.ulonglong_value= SYSTEM_TIME_AS_OF;
+ uint error;
+ var->save_result.timestamp.unix_time=
+ thd->variables.time_zone->TIME_to_gmt_sec(&ltime, &error);
+ var->save_result.timestamp.second_part= ltime.second_part;
+ res= error != 0;
}
return res;
}
private:
- bool update(set_var *var, vers_asof_timestamp_t &out)
+ static bool update(THD *thd, set_var *var, vers_asof_timestamp_t *out)
{
- bool res= false;
- out.type= static_cast<enum_var_type>(var->save_result.ulonglong_value);
- if (out.type == SYSTEM_TIME_AS_OF)
+ if (var->value)
{
- if (var->value)
- {
- THD *thd= current_thd;
- Datetime::Options opt(TIME_CONV_NONE |
- TIME_NO_ZERO_IN_DATE |
- TIME_NO_ZERO_DATE, thd);
- /*
- var->value is allowed to return DATETIME and DATE
- Make sure to convert DATE to DATETIME.
- */
- res= Datetime(thd, var->value, opt).copy_to_mysql_time(&out.ltime);
- }
- else // set DEFAULT from global var
- {
- out= global_var(vers_asof_timestamp_t);
- res= false;
- }
+ out->type = SYSTEM_TIME_AS_OF;
+ out->unix_time = var->save_result.timestamp.unix_time;
+ out->second_part= var->save_result.timestamp.second_part;
}
- return res;
+ return 0;
+ }
+
+ static void save_default(set_var *var, vers_asof_timestamp_t *out)
+ {
+ out->type= SYSTEM_TIME_UNSPECIFIED;
}
public:
virtual bool global_update(THD *thd, set_var *var)
{
- return update(var, global_var(vers_asof_timestamp_t));
+ return update(thd, var, &global_var(vers_asof_timestamp_t));
}
virtual bool session_update(THD *thd, set_var *var)
{
- return update(var, session_var(thd, vers_asof_timestamp_t));
+ return update(thd, var, &session_var(thd, vers_asof_timestamp_t));
+ }
+
+ virtual bool session_is_default(THD *thd)
+ {
+ const vers_asof_timestamp_t &var= session_var(thd, vers_asof_timestamp_t);
+ return var.type == SYSTEM_TIME_UNSPECIFIED;
+ }
+
+ virtual void session_save_default(THD *thd, set_var *var)
+ {
+ save_default(var, &session_var(thd, vers_asof_timestamp_t));
+ }
+ virtual void global_save_default(THD *thd, set_var *var)
+ {
+ save_default(var, &global_var(vers_asof_timestamp_t));
}
private:
- uchar *value_ptr(THD *thd, vers_asof_timestamp_t &val)
+ const uchar *value_ptr(THD *thd, vers_asof_timestamp_t &val) const
{
+ const char *value;
switch (val.type)
{
case SYSTEM_TIME_UNSPECIFIED:
- case SYSTEM_TIME_ALL:
- return (uchar*) thd->strdup(asof_keywords[val.type]);
+ return (uchar*)"DEFAULT";
+ break;
case SYSTEM_TIME_AS_OF:
{
- uchar *buf= (uchar*) thd->alloc(MAX_DATE_STRING_REP_LENGTH);
- if (buf &&!my_datetime_to_str(&val.ltime, (char*) buf, 6))
+ char *buf= (char*) thd->alloc(MAX_DATE_STRING_REP_LENGTH);
+ MYSQL_TIME ltime;
+
+ thd->variables.time_zone->gmt_sec_to_TIME(&ltime, val.unix_time);
+ ltime.second_part= val.second_part;
+
+ value= buf;
+ if (buf && !my_datetime_to_str(&ltime, buf, 6))
{
- // TODO: figure out variable name
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "system_versioning_asof_timestamp", "NULL (wrong datetime)");
- return (uchar*) thd->strdup("Error: wrong datetime");
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, "NULL (wrong datetime)");
+ value= thd->strdup("Error: wrong datetime");
}
- return buf;
+ break;
}
default:
- break;
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, "NULL (wrong range type)");
+ value= thd->strdup("Error: wrong range type");
}
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "system_versioning_asof_timestamp", "NULL (wrong range type)");
- return (uchar*) thd->strdup("Error: wrong range type");
+ return reinterpret_cast<const uchar *>(value);
}
public:
- virtual uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ virtual const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return value_ptr(thd, session_var(thd, vers_asof_timestamp_t)); }
- virtual uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ virtual const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{ return value_ptr(thd, global_var(vers_asof_timestamp_t)); }
};
diff --git a/sql/table.cc b/sql/table.cc
index 12299271ab3..d5dfc414792 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -6870,7 +6870,7 @@ void TABLE::prepare_for_position()
if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
s->primary_key < MAX_KEY)
{
- mark_columns_used_by_index_no_reset(s->primary_key, read_set);
+ mark_index_columns_for_read(s->primary_key);
/* signal change */
file->column_bitmaps_signal();
}
@@ -6886,7 +6886,7 @@ MY_BITMAP *TABLE::prepare_for_keyread(uint index, MY_BITMAP *map)
file->ha_start_keyread(index);
if (map != read_set || !(file->index_flags(index, 0, 1) & HA_CLUSTERED_INDEX))
{
- mark_columns_used_by_index(index, map);
+ mark_index_columns(index, map);
column_bitmaps_set(map);
}
DBUG_RETURN(backup);
@@ -6897,12 +6897,12 @@ MY_BITMAP *TABLE::prepare_for_keyread(uint index, MY_BITMAP *map)
Mark that only fields from one key is used. Useful before keyread.
*/
-void TABLE::mark_columns_used_by_index(uint index, MY_BITMAP *bitmap)
+void TABLE::mark_index_columns(uint index, MY_BITMAP *bitmap)
{
- DBUG_ENTER("TABLE::mark_columns_used_by_index");
+ DBUG_ENTER("TABLE::mark_index_columns");
bitmap_clear_all(bitmap);
- mark_columns_used_by_index_no_reset(index, bitmap);
+ mark_index_columns_no_reset(index, bitmap);
DBUG_VOID_RETURN;
}
@@ -6926,23 +6926,36 @@ void TABLE::restore_column_maps_after_keyread(MY_BITMAP *backup)
DBUG_VOID_RETURN;
}
+static void do_mark_index_columns(TABLE *table, uint index,
+ MY_BITMAP *bitmap, bool read)
+{
+ KEY_PART_INFO *key_part= table->key_info[index].key_part;
+ uint key_parts= table->key_info[index].user_defined_key_parts;
+ for (uint k= 0; k < key_parts; k++)
+ if (read)
+ key_part[k].field->register_field_in_read_map();
+ else
+ bitmap_set_bit(bitmap, key_part[k].fieldnr-1);
+ if (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX &&
+ table->s->primary_key != MAX_KEY && table->s->primary_key != index)
+ do_mark_index_columns(table, table->s->primary_key, bitmap, read);
+}
/*
mark columns used by key, but don't reset other fields
*/
-void TABLE::mark_columns_used_by_index_no_reset(uint index, MY_BITMAP *bitmap)
+inline void TABLE::mark_index_columns_no_reset(uint index, MY_BITMAP *bitmap)
{
- KEY_PART_INFO *key_part= key_info[index].key_part;
- KEY_PART_INFO *key_part_end= (key_part + key_info[index].user_defined_key_parts);
- for (;key_part != key_part_end; key_part++)
- bitmap_set_bit(bitmap, key_part->fieldnr-1);
- if (file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX &&
- s->primary_key != MAX_KEY && s->primary_key != index)
- mark_columns_used_by_index_no_reset(s->primary_key, bitmap);
+ do_mark_index_columns(this, index, bitmap, false);
}
+inline void TABLE::mark_index_columns_for_read(uint index)
+{
+ do_mark_index_columns(this, index, read_set, true);
+}
+
/*
Mark auto-increment fields as used fields in both read and write maps
@@ -6961,7 +6974,7 @@ void TABLE::mark_auto_increment_column()
bitmap_set_bit(read_set, found_next_number_field->field_index);
bitmap_set_bit(write_set, found_next_number_field->field_index);
if (s->next_number_keypart)
- mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
+ mark_index_columns_for_read(s->next_number_index);
file->column_bitmaps_signal();
}
@@ -7012,7 +7025,7 @@ void TABLE::mark_columns_needed_for_delete()
file->use_hidden_primary_key();
else
{
- mark_columns_used_by_index_no_reset(s->primary_key, read_set);
+ mark_index_columns_for_read(s->primary_key);
need_signal= true;
}
}
@@ -7098,7 +7111,7 @@ void TABLE::mark_columns_needed_for_update()
file->use_hidden_primary_key();
else
{
- mark_columns_used_by_index_no_reset(s->primary_key, read_set);
+ mark_index_columns_for_read(s->primary_key);
need_signal= true;
}
}
@@ -7259,7 +7272,7 @@ void TABLE::mark_columns_per_binlog_row_image()
if ((my_field->flags & PRI_KEY_FLAG) ||
(my_field->type() != MYSQL_TYPE_BLOB))
{
- bitmap_set_bit(read_set, my_field->field_index);
+ my_field->register_field_in_read_map();
bitmap_set_bit(rpl_write_set, my_field->field_index);
}
}
@@ -7271,7 +7284,7 @@ void TABLE::mark_columns_per_binlog_row_image()
We don't need to mark the primary key in the rpl_write_set as the
binary log will include all columns read anyway.
*/
- mark_columns_used_by_index_no_reset(s->primary_key, read_set);
+ mark_index_columns_for_read(s->primary_key);
if (versioned())
{
// TODO: After MDEV-18432 we don't pass history rows, so remove this:
diff --git a/sql/table.h b/sql/table.h
index 273c2159c5e..05add349fb0 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1510,8 +1510,9 @@ public:
MY_BITMAP *prepare_for_keyread(uint index, MY_BITMAP *map);
MY_BITMAP *prepare_for_keyread(uint index)
{ return prepare_for_keyread(index, &tmp_set); }
- void mark_columns_used_by_index(uint index, MY_BITMAP *map);
- void mark_columns_used_by_index_no_reset(uint index, MY_BITMAP *map);
+ void mark_index_columns(uint index, MY_BITMAP *bitmap);
+ void mark_index_columns_no_reset(uint index, MY_BITMAP *bitmap);
+ void mark_index_columns_for_read(uint index);
void restore_column_maps_after_keyread(MY_BITMAP *backup);
void mark_auto_increment_column(void);
void mark_columns_needed_for_update(void);
diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt
index f83bb1b57ce..0100f80415d 100644
--- a/storage/connect/CMakeLists.txt
+++ b/storage/connect/CMakeLists.txt
@@ -108,6 +108,7 @@ 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)
+ADD_FEATURE_INFO(CONNECT_VCT CONNECT_WITH_VCT "Support for VCT in the CONNECT storage engine")
#
@@ -133,6 +134,7 @@ IF(CONNECT_WITH_LIBXML2)
D:/libxml/lib)
ENDIF(WIN32)
FIND_PACKAGE(LibXml2)
+ SET_PACKAGE_PROPERTIES(LibXml2 PROPERTIES TYPE OPTIONAL)
IF (LIBXML2_FOUND)
INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR})
SET(XML_LIBRARY ${LIBXML2_LIBRARIES})
@@ -140,6 +142,8 @@ IF(CONNECT_WITH_LIBXML2)
add_definitions(-DLIBXML2_SUPPORT)
ENDIF(LIBXML2_FOUND)
ENDIF(CONNECT_WITH_LIBXML2)
+ADD_FEATURE_INFO(CONNECT_LIBXML2 CONNECT_WITH_LIBXML2
+ "Support for LIBXML2 in the CONNECT storage engine")
IF(WIN32)
@@ -153,6 +157,8 @@ IF(WIN32)
SET(MSXML_FOUND 1)
SET(CONNECT_SOURCES ${CONNECT_SOURCES} domdoc.cpp domdoc.h)
ENDIF(CONNECT_WITH_MSXML)
+ ADD_FEATURE_INFO(CONNECT_MSXML CONNECT_WITH_MSXML
+ "Support for MSXML in the CONNECT storage engine")
ENDIF(WIN32)
IF(LIBXML2_FOUND OR MSXML_FOUND)
@@ -253,6 +259,7 @@ int main() {
tabodbc.cpp tabodbc.h odbccat.h odbconn.cpp odbconn.h)
ENDIF(UNIX)
ENDIF(CONNECT_WITH_ODBC)
+ADD_FEATURE_INFO(CONNECT_ODBC ODBC_LIBRARY "Support for ODBC in the CONNECT storage engine")
#
# JDBC with MongoDB Java Driver included but disabled if without MONGO
@@ -262,7 +269,9 @@ OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON)
IF(CONNECT_WITH_JDBC)
FIND_PACKAGE(Java 1.6)
+ SET_PACKAGE_PROPERTIES(Java PROPERTIES TYPE OPTIONAL)
FIND_PACKAGE(JNI)
+ SET_PACKAGE_PROPERTIES(JNI PROPERTIES TYPE OPTIONAL)
IF (JAVA_FOUND AND JNI_FOUND)
INCLUDE(UseJava)
INCLUDE_DIRECTORIES(${JAVA_INCLUDE_PATH})
@@ -278,6 +287,7 @@ IF(CONNECT_WITH_JDBC)
Mongo2Interface.java Mongo3Interface.java
mysql-test/connect/std_data/JavaWrappers.jar)
add_definitions(-DJAVA_SUPPORT)
+ ADD_FEATURE_INFO(CONNECT_JDBC "ON" "Support for JDBC in the CONNECT storage engine")
IF(CONNECT_WITH_MONGO)
SET(CONNECT_SOURCES ${CONNECT_SOURCES}
mysql-test/connect/std_data/Mongo2.jar
@@ -286,7 +296,10 @@ IF(CONNECT_WITH_JDBC)
ENDIF()
ELSE()
SET(JDBC_LIBRARY "")
+ ADD_FEATURE_INFO(CONNECT_JDBC "OFF" "Support for JDBC in the CONNECT storage engine")
ENDIF()
+ELSE(CONNECT_WITH_JDBC)
+ ADD_FEATURE_INFO(CONNECT_JDBC "OFF" "Support for JDBC in the CONNECT storage engine")
ENDIF(CONNECT_WITH_JDBC)
#
@@ -300,6 +313,7 @@ IF(CONNECT_WITH_ZIP)
filamzip.h tabzip.h ioapi.h unzip.h zip.h)
add_definitions(-DZIP_SUPPORT -DNOCRYPT)
ENDIF(CONNECT_WITH_ZIP)
+ADD_FEATURE_INFO(CONNECT_ZIP CONNECT_WITH_ZIP "Support for ZIP in the CONNECT storage engine")
#
# MONGO C Driver
@@ -316,6 +330,7 @@ IF(CONNECT_WITH_MONGO)
D:/mongo-c-driver/lib)
ENDIF(WIN32)
FIND_PACKAGE(libmongoc-1.0 1.7 QUIET)
+ SET_PACKAGE_PROPERTIES(libmongoc PROPERTIES TYPE OPTIONAL)
IF (libmongoc-1.0_FOUND)
INCLUDE_DIRECTORIES(${MONGOC_INCLUDE_DIRS})
SET(MONGOC_LIBRARY ${MONGOC_LIBRARIES})
@@ -323,14 +338,18 @@ IF(CONNECT_WITH_MONGO)
cmgoconn.cpp cmgfam.cpp tabcmg.cpp
cmgoconn.h cmgfam.h tabcmg.h)
add_definitions(-DCMGO_SUPPORT)
+ ADD_FEATURE_INFO(CONNECT_MONGODB "ON" "Support for MongoDB in the CONNECT storage engine")
IF (NOT JAVA_FOUND AND JNI_FOUND)
SET(CONNECT_SOURCES ${CONNECT_SOURCES} mongo.cpp mongo.h)
add_definitions(-DMONGO_SUPPORT)
ENDIF (NOT JAVA_FOUND AND JNI_FOUND)
+ ELSE(libmongoc-1.0_FOUND)
+ ADD_FEATURE_INFO(CONNECT_MONGODB "OFF" "Support for MongoDB in the CONNECT storage engine")
ENDIF(libmongoc-1.0_FOUND)
+ELSE(CONNECT_WITH_MONGO)
+ ADD_FEATURE_INFO(CONNECT_MONGODB "OFF" "Support for MongoDB in the CONNECT storage engine")
ENDIF(CONNECT_WITH_MONGO)
-
#
# REST
#
@@ -362,6 +381,7 @@ IF(CONNECT_WITH_REST)
## MESSAGE(STATUS "=====> cpprestsdk package not found")
# ENDIF (cpprestsdk_FOUND)
ENDIF(CONNECT_WITH_REST)
+ADD_FEATURE_INFO(CONNECT_REST CONNECT_WITH_REST "Support for REST API in the CONNECT storage engine")
#
# XMAP
@@ -372,6 +392,7 @@ OPTION(CONNECT_WITH_XMAP "Compile CONNECT storage engine with index file mapping
IF(CONNECT_WITH_XMAP)
add_definitions(-DXMAP)
ENDIF(CONNECT_WITH_XMAP)
+ADD_FEATURE_INFO(CONNECT_XMAP CONNECT_WITH_XMAP "Support for index file mapping in the CONNECT storage engine")
#
# Plugin definition
diff --git a/storage/connect/Client2.java b/storage/connect/Client2.java
new file mode 100644
index 00000000000..6dbf4188032
--- /dev/null
+++ b/storage/connect/Client2.java
@@ -0,0 +1,130 @@
+package wrappers;
+
+import java.io.BufferedReader;
+import java.io.Console;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Set;
+
+public class Client2 {
+ static boolean DEBUG = true;
+ static final Console c = System.console();
+ static Mongo2Interface jdi = null;
+
+ public static void main(String[] args) {
+ int rc, m, i = 0;
+ boolean brc;
+ Set<String> columns;
+ String[] parms = new String[4];
+
+ jdi = new Mongo2Interface(DEBUG);
+
+ parms[0] = getLine("URI: ", false);
+ parms[1] = getLine("DB: ", false);
+ parms[2] = null;
+ parms[3] = null;
+
+ if (parms[0] == null)
+ parms[0] = "mongodb://localhost:27017";
+
+ if (parms[1] == null)
+ parms[1] = "test";
+
+ rc = jdi.MongoConnect(parms);
+
+ if (rc == 0) {
+ String name, pipeline, query, fields;
+ System.out.println("Successfully connected to " + parms[1]);
+
+ while ((name = getLine("Collection: ", false)) != null) {
+ if (jdi.GetCollection(name))
+ System.out.println("GetCollection failed");
+ else
+ System.out.println("Collection size: " + jdi.GetCollSize());
+
+ pipeline = getLine("Pipeline: ", false);
+
+ if (pipeline == null) {
+ query = getLine("Filter: ", false);
+ fields = getLine("Proj: ", false);
+ brc = jdi.FindColl(query, fields);
+ } else
+ brc = jdi.AggregateColl(pipeline);
+
+ System.out.println("Returned brc = " + brc);
+
+ if (!brc) {
+ for (i = 0; i < 10; i++) {
+ m = jdi.ReadNext();
+
+ if (m > 0) {
+ columns = jdi.GetColumns();
+
+ for (String col : columns)
+ System.out.println(col + "=" + jdi.GetField(col));
+
+ if (pipeline == null) {
+ if (name.equalsIgnoreCase("gtst"))
+ System.out.println("gtst=" + jdi.GetField("*"));
+
+ if (name.equalsIgnoreCase("inventory")) {
+ System.out.println("warehouse=" + jdi.GetField("instock.0.warehouse"));
+ System.out.println("quantity=" + jdi.GetField("instock.1.qty"));
+ } // endif inventory
+
+ if (name.equalsIgnoreCase("restaurants")) {
+ System.out.println("score=" + jdi.GetField("grades.0.score"));
+ System.out.println("date=" + jdi.GetField("grades.0.date"));
+ } // endif restaurants
+
+ } // endif pipeline
+
+ } else if (m < 0) {
+ System.out.println("ReadNext: " + jdi.GetErrmsg());
+ break;
+ } else
+ break;
+
+ } // endfor i
+
+ } // endif brc
+
+ } // endwhile name
+
+ rc = jdi.MongoDisconnect();
+ System.out.println("Disconnect returned " + rc);
+ } else
+ System.out.println(jdi.GetErrmsg() + " rc=" + rc);
+
+ } // end of main
+
+ // ==================================================================
+ private static String getLine(String p, boolean b) {
+ String response;
+
+ if (c != null) {
+ // Standard console mode
+ if (b) {
+ response = new String(c.readPassword(p));
+ } else
+ response = c.readLine(p);
+
+ } else {
+ // For instance when testing from Eclipse
+ BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+
+ System.out.print(p);
+
+ try {
+ // Cannot suppress echo for password entry
+ response = in.readLine();
+ } catch (IOException e) {
+ response = "";
+ } // end of try/catch
+
+ } // endif c
+
+ return (response.isEmpty()) ? null : response;
+ } // end of getLine
+
+} // end of class Client
diff --git a/storage/connect/Client3.java b/storage/connect/Client3.java
new file mode 100644
index 00000000000..0d3914cdd0d
--- /dev/null
+++ b/storage/connect/Client3.java
@@ -0,0 +1,154 @@
+package wrappers;
+
+import java.io.BufferedReader;
+import java.io.Console;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Set;
+
+public class Client3 {
+ static boolean DEBUG = true;
+ static final Console c = System.console();
+ static Mongo3Interface jdi = null;
+
+ public static void main(String[] args) {
+ int rc, level = 0;
+ boolean brc, desc = false;
+ Set<String> columns;
+ String[] parms = new String[4];
+
+ jdi = new Mongo3Interface(DEBUG);
+
+ parms[0] = getLine("URI: ", false);
+ parms[1] = getLine("Database: ", false);
+ parms[2] = null;
+ parms[3] = null;
+
+ if (parms[0] == null)
+ parms[0] = "mongodb://localhost:27017";
+
+ if (parms[1] == null)
+ parms[1] = "test";
+
+ rc = jdi.MongoConnect(parms);
+
+ if (rc == 0) {
+ String name, pipeline, query, fields;
+ System.out.println("Successfully connected to " + parms[0]);
+
+ while ((name = getLine("Collection: ", false)) != null) {
+ if (jdi.GetCollection(name))
+ System.out.println("GetCollection failed");
+ else
+ System.out.println("Collection size: " + jdi.GetCollSize());
+
+ pipeline = getLine("Pipeline: ", false);
+
+ if (pipeline == null || (desc = pipeline.equals("*"))) {
+ query = getLine("Filter: ", false);
+ fields = getLine("Proj: ", false);
+
+ if (desc)
+ level = Integer.parseInt(getLine("Level: ", false));
+
+ brc = jdi.FindColl(query, fields);
+ } else
+ brc = jdi.AggregateColl(pipeline);
+
+ System.out.println("Returned brc = " + brc);
+
+ if (!brc && !desc) {
+ for (int i = 0; jdi.ReadNext() > 0 && i < 10; i++) {
+ columns = jdi.GetColumns();
+
+ for (String col : columns)
+ System.out.println(col + "=" + jdi.GetField(col));
+
+ if (name.equalsIgnoreCase("gtst"))
+ System.out.println("gtst=" + jdi.GetField("*"));
+
+ if (name.equalsIgnoreCase("inventory")) {
+ System.out.println("warehouse=" + jdi.GetField("instock.0.warehouse"));
+ System.out.println("quantity=" + jdi.GetField("instock.1.qty"));
+ } // endif inventory
+
+ if (name.equalsIgnoreCase("restaurants")) {
+ System.out.println("score=" + jdi.GetField("grades.0.score"));
+ System.out.println("date=" + jdi.GetField("grades.0.date"));
+ } // endif inventory
+
+ } // endfor i
+
+ } else if (desc) {
+ int ncol;
+
+ for (int i = 0; (ncol = jdi.ReadNext()) > 0 && i < 2; i++) {
+ if (discovery(null, "", ncol, level))
+ break;
+
+ System.out.println("--------------");
+ } // endfor i
+
+ } // endif desc
+
+ } // endwhile query
+
+ rc = jdi.MongoDisconnect();
+ System.out.println("Disconnect returned " + rc);
+ } else
+ System.out.println(jdi.GetErrmsg() + " rc=" + rc);
+
+ } // end of main
+
+ private static boolean discovery(Object obj, String name, int ncol, int level) {
+ int[] val = new int[5];
+ Object ret = null;
+ String bvn = null;
+
+ for (int k = 0; k < ncol; k++) {
+ ret = jdi.ColumnDesc(obj, k, val, level);
+ bvn = jdi.ColDescName();
+
+ if (ret != null)
+ discovery(ret, name.concat(bvn).concat("."), val[4], level - 1);
+ else if (val[0] > 0)
+ System.out.println(
+ name + bvn + ": type=" + val[0] + " length=" + val[1] + " prec=" + val[2] + " nullable=" + val[3]);
+ else if (val[0] < 0)
+ System.out.println(jdi.GetErrmsg());
+
+ } // endfor k
+
+ return false;
+ } // end of discovery
+
+ // ==================================================================
+ private static String getLine(String p, boolean b) {
+ String response;
+
+ if (c != null) {
+ // Standard console mode
+ if (b) {
+ response = new String(c.readPassword(p));
+ } else
+ response = c.readLine(p);
+
+ } else {
+ // For instance when testing from Eclipse
+ BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+
+ System.out.print(p);
+
+ try {
+ // Cannot suppress echo for password entry
+ response = in.readLine();
+ } catch (IOException e) {
+ response = "";
+ } // end of try/catch
+
+ } // endif c
+
+ return (response.isEmpty()) ? null : response;
+ } // end of getLine
+
+} // end of class Client
diff --git a/storage/connect/Mongo2Interface.java b/storage/connect/Mongo2Interface.java
index 106dd4a4d63..5d27fe467d6 100644
--- a/storage/connect/Mongo2Interface.java
+++ b/storage/connect/Mongo2Interface.java
@@ -21,6 +21,7 @@ import com.mongodb.util.JSON;
public class Mongo2Interface {
boolean DEBUG = false;
String Errmsg = "No error";
+ String ovalName = null;
Set<String> Colnames = null;
Cursor cursor = null;
MongoClient client = null;
@@ -220,7 +221,7 @@ public class Mongo2Interface {
System.out.println("Class doc = " + doc.getClass());
Colnames = doc.keySet();
- return 1;
+ return Colnames.size();
} else
return 0;
@@ -253,30 +254,106 @@ public class Mongo2Interface {
} // end of GetColumns
- public String ColumnDesc(int n, int[] val) {
- // if (rsmd == null) {
- // System.out.println("No result metadata");
- // return null;
- // } else try {
- // val[0] = rsmd.getColumnType(n);
- // val[1] = rsmd.getPrecision(n);
- // val[2] = rsmd.getScale(n);
- // val[3] = rsmd.isNullable(n);
- // return rsmd.getColumnLabel(n);
- // } catch (SQLException se) {
- // SetErrmsg(se);
- // } //end try/catch
+ public Object ColumnDesc(Object obj, int n, int[] val, int lvl) {
+ Object ret = null;
+ Object oval = ((obj != null) ? obj : doc);
+ BasicDBObject dob = (oval instanceof BasicDBObject) ? (BasicDBObject) oval : null;
+ BasicDBList ary = (oval instanceof BasicDBList) ? (BasicDBList) oval : null;
+ try {
+ if (ary != null) {
+ oval = ary.get(n);
+ ovalName = Integer.toString(n);
+ } else if (dob != null) {
+ // String[] k = dob.keySet().toArray(new String[0]);
+ Object[] k = dob.keySet().toArray();
+ oval = dob.get(k[n]);
+ ovalName = (String) k[n];
+ } else
+ ovalName = "x" + Integer.toString(n);
+
+ if (DEBUG)
+ System.out.println("Class of " + ovalName + " = " + oval.getClass());
+
+ val[0] = 0; // ColumnType
+ val[1] = 0; // Precision
+ val[2] = 0; // Scale
+ val[3] = 0; // Nullable
+ val[4] = 0; // ncol
+
+ if (oval == null) {
+ val[3] = 1;
+ } else if (oval instanceof String) {
+ val[0] = 1;
+ val[1] = ((String) oval).length();
+ } else if (oval instanceof org.bson.types.ObjectId) {
+ val[0] = 1;
+ val[1] = ((org.bson.types.ObjectId) oval).toString().length();
+ } else if (oval instanceof Integer) {
+ val[0] = 7;
+ val[1] = Integer.toString(((Integer) oval).intValue()).length();
+ } else if (oval instanceof Long) {
+ val[0] = 5;
+ val[1] = Long.toString(((Long) oval).longValue()).length();
+ } else if (oval instanceof Date) {
+ Long TS = (((Date) oval).getTime() / 1000);
+ val[0] = 8;
+ val[1] = TS.toString().length();
+ } else if (oval instanceof Double) {
+ String d = Double.toString(((Double) oval).doubleValue());
+ int i = d.indexOf('.') + 1;
+
+ val[0] = 2;
+ val[1] = d.length();
+ val[2] = (i > 0) ? val[1] - i : 0;
+ } else if (oval instanceof Boolean) {
+ val[0] = 4;
+ val[1] = 1;
+ } else if (oval instanceof BasicDBObject) {
+ if (lvl > 0) {
+ ret = oval;
+ val[0] = 1;
+ val[4] = ((BasicDBObject) oval).size();
+ } else if (lvl == 0) {
+ val[0] = 1;
+ val[1] = oval.toString().length();
+ } // endif lvl
+
+ } else if (oval instanceof BasicDBList) {
+ if (lvl > 0) {
+ ret = oval;
+ val[0] = 2;
+ val[4] = ((BasicDBList) oval).size();
+ } else if (lvl == 0) {
+ val[0] = 1;
+ val[1] = oval.toString().length();
+ } // endif lvl
+
+ } else {
+ SetErrmsg("Type " + " of " + ovalName + " not supported");
+ val[0] = -1;
+ } // endif's
+
+ return ret;
+ } catch (Exception ex) {
+ SetErrmsg(ex);
+ } // end try/catch
+
+ val[0] = -1;
return null;
} // end of ColumnDesc
+ public String ColDescName() {
+ return ovalName;
+ } // end of ColDescName
+
protected Object GetFieldObject(String path) {
Object o = null;
BasicDBObject dob = null;
BasicDBList lst = null;
String[] names = null;
- if (path == null || path.equals("*"))
+ if (path == null || path.equals("") || path.equals("*"))
return doc;
else if (doc instanceof BasicDBObject)
dob = doc;
@@ -325,9 +402,10 @@ public class Mongo2Interface {
if (o != null) {
if (o instanceof Date) {
- Integer TS = (int) (((Date) o).getTime() / 1000);
+ Long TS = (((Date) o).getTime() / 1000);
return TS.toString();
- } // endif Date
+ } else if (o instanceof Boolean)
+ return (Boolean) o ? "1" : "0";
return o.toString();
} else
@@ -335,13 +413,25 @@ public class Mongo2Interface {
} // end of GetField
+ public Object MakeBson(String s, int json) {
+ if (json == 1 || json == 2) {
+ return com.mongodb.util.JSON.parse(s);
+ } else
+ return null;
+
+ } // end of MakeBson
+
public Object MakeDocument() {
return new BasicDBObject();
} // end of MakeDocument
- public boolean DocAdd(Object bdc, String key, Object val) {
+ public boolean DocAdd(Object bdc, String key, Object val, int json) {
try {
- ((BasicDBObject) bdc).append(key, val);
+ if (json != 0 && val instanceof String)
+ ((BasicDBObject) bdc).append(key, JSON.parse((String) val));
+ else
+ ((BasicDBObject) bdc).append(key, val);
+
} catch (MongoException me) {
SetErrmsg(me);
return true;
@@ -354,9 +444,13 @@ public class Mongo2Interface {
return new BasicDBList();
} // end of MakeArray
- public boolean ArrayAdd(Object bar, int n, Object val) {
+ public boolean ArrayAdd(Object bar, int n, Object val, int json) {
try {
- ((BasicDBList) bar).put(n, val);
+ if (json != 0 && val instanceof String)
+ ((BasicDBList) bar).put(n, JSON.parse((String) val));
+ else
+ ((BasicDBList) bar).put(n, val);
+
} catch (MongoException me) {
SetErrmsg(me);
return true;
diff --git a/storage/connect/Mongo3Interface.java b/storage/connect/Mongo3Interface.java
index f587c01b391..73175e13aa3 100644
--- a/storage/connect/Mongo3Interface.java
+++ b/storage/connect/Mongo3Interface.java
@@ -1,5 +1,6 @@
package wrappers;
+//import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
@@ -9,6 +10,7 @@ import java.util.Set;
import org.bson.BsonArray;
import org.bson.BsonBoolean;
import org.bson.BsonDateTime;
+//import org.bson.BsonDecimal128;
import org.bson.BsonDocument;
import org.bson.BsonDouble;
import org.bson.BsonInt32;
@@ -18,6 +20,7 @@ import org.bson.BsonString;
import org.bson.BsonValue;
import org.bson.Document;
import org.bson.conversions.Bson;
+//import org.bson.types.Decimal128;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
@@ -34,6 +37,7 @@ import com.mongodb.client.result.UpdateResult;
public class Mongo3Interface {
boolean DEBUG = false;
String Errmsg = "No error";
+ String bvalName = null;
Set<String> Colnames = null;
MongoClient client = null;
MongoDatabase db = null;
@@ -167,7 +171,7 @@ public class Mongo3Interface {
try {
if (query != null) {
- Bson dbq = Document.parse((query != null) ? query : "{}");
+ Bson dbq = Document.parse(query);
finditer = coll.find(dbq);
} else
finditer = coll.find();
@@ -218,17 +222,23 @@ public class Mongo3Interface {
} // end of Rewind
public int ReadNext() {
- if (cursor.hasNext()) {
- doc = cursor.next();
+ try {
+ if (cursor.hasNext()) {
+ doc = cursor.next();
- if (DEBUG)
- System.out.println("Class doc = " + doc.getClass());
+ if (DEBUG)
+ System.out.println("Class doc = " + doc.getClass());
- Colnames = doc.keySet();
- return 1;
- } else
- return 0;
+ Colnames = doc.keySet();
+ return Colnames.size();
+ } else
+ return 0;
+ } catch (MongoException mx) {
+ SetErrmsg(mx);
+ } // end try/catch
+
+ return -1;
} // end of ReadNext
public boolean Fetch(int row) {
@@ -254,13 +264,11 @@ public class Mongo3Interface {
} // end of GetColumns
public String ColumnName(int n) {
- int i = 1;
-
- for (String name : Colnames)
- if (i++ == n)
- return name;
+ if (n < Colnames.size())
+ return (String) Colnames.toArray()[n];
+ else
+ return null;
- return null;
} // end of ColumnName
public int ColumnType(int n, String name) {
@@ -278,30 +286,111 @@ public class Mongo3Interface {
return 666; // Not a type
} // end of ColumnType
- public String ColumnDesc(int n, int[] val) {
- // if (rsmd == null) {
- // System.out.println("No result metadata");
- // return null;
- // } else try {
- // val[0] = rsmd.getColumnType(n);
- // val[1] = rsmd.getPrecision(n);
- // val[2] = rsmd.getScale(n);
- // val[3] = rsmd.isNullable(n);
- // return rsmd.getColumnLabel(n);
- // } catch (SQLException se) {
- // SetErrmsg(se);
- // } //end try/catch
+ public Object ColumnDesc(Object obj, int n, int[] val, int lvl) {
+ Object ret = null;
+ BsonValue bval = (BsonValue) ((obj != null) ? obj : doc);
+ BsonDocument dob = (bval instanceof BsonDocument) ? (BsonDocument) bval : null;
+ BsonArray ary = (bval instanceof BsonArray) ? (BsonArray) bval : null;
+
+ try {
+ if (ary != null) {
+ bval = ary.get(n);
+ bvalName = Integer.toString(n);
+ } else if (dob != null) {
+ // String[] k = dob.keySet().toArray(new String[0]);
+ Object[] k = dob.keySet().toArray();
+ bval = dob.get(k[n]);
+ bvalName = (String) k[n];
+ } else
+ bvalName = "x" + Integer.toString(n);
+
+ val[0] = 0; // ColumnType
+ val[1] = 0; // Precision
+ val[2] = 0; // Scale
+ val[3] = 0; // Nullable
+ val[4] = 0; // ncol
+
+ if (bval.isString()) {
+ val[0] = 1;
+ val[1] = bval.asString().getValue().length();
+ } else if (bval.isInt32()) {
+ val[0] = 7;
+ val[1] = Integer.toString(bval.asInt32().getValue()).length();
+ } else if (bval.isInt64()) {
+ val[0] = 5;
+ val[1] = Long.toString(bval.asInt64().getValue()).length();
+ } else if (bval.isObjectId()) {
+ val[0] = 1;
+ val[1] = bval.asObjectId().getValue().toString().length();
+ } else if (bval.isDateTime()) {
+ Long TS = (bval.asDateTime().getValue() / 1000);
+ val[0] = 8;
+ val[1] = TS.toString().length();
+ } else if (bval.isDouble()) {
+ String d = Double.toString(bval.asDouble().getValue());
+ int i = d.indexOf('.') + 1;
+
+ val[0] = 2;
+ val[1] = d.length();
+ val[2] = (i > 0) ? val[1] - i : 0;
+ } else if (bval.isBoolean()) {
+ val[0] = 4;
+ val[1] = 1;
+ } else if (bval.isDocument()) {
+ if (lvl > 0) {
+ ret = bval;
+ val[0] = 1;
+ val[4] = bval.asDocument().keySet().size();
+ } else if (lvl == 0) {
+ val[0] = 1;
+ val[1] = bval.asDocument().toJson().length();
+ } // endif lvl
+
+ } else if (bval.isArray()) {
+ if (lvl > 0) {
+ ret = bval;
+ val[0] = 2;
+ val[4] = bval.asArray().size();
+ } else if (lvl == 0) {
+ val[0] = 1;
+ util = new BsonDocument("arr", bval.asArray());
+ String s = util.toJson();
+ int i1 = s.indexOf('[');
+ int i2 = s.lastIndexOf(']');
+ val[1] = i2 - i1 + 1;
+ } // endif lvl
+
+ } else if (bval.isDecimal128()) {
+ val[0] = 9;
+ val[1] = bval.asDecimal128().toString().length();
+ } else if (bval.isNull()) {
+ val[0] = 0;
+ val[3] = 1;
+ } else {
+ SetErrmsg("Type " + bval.getBsonType() + " of " + bvalName + " not supported");
+ val[0] = -1;
+ } // endif's
+
+ return ret;
+ } catch (Exception ex) {
+ SetErrmsg(ex);
+ } // end try/catch
+ val[0] = -1;
return null;
} // end of ColumnDesc
+ public String ColDescName() {
+ return bvalName;
+ } // end of ColDescName
+
protected BsonValue GetFieldObject(String path) {
BsonValue o = doc;
BsonDocument dob = null;
BsonArray ary = null;
String[] names = null;
- if (path == null || path.equals("*"))
+ if (path == null || path.equals("") || path.equals("*"))
return doc;
else if (o instanceof BsonDocument)
dob = doc;
@@ -362,6 +451,8 @@ public class Mongo3Interface {
return TS.toString();
} else if (o.isDouble()) {
return Double.toString(o.asDouble().getValue());
+ } else if (o.isBoolean()) {
+ return o.asBoolean().getValue() ? "1" : "0";
} else if (o.isDocument()) {
return o.asDocument().toJson();
} else if (o.isArray()) {
@@ -370,6 +461,8 @@ public class Mongo3Interface {
int i1 = s.indexOf('[');
int i2 = s.lastIndexOf(']');
return s.substring(i1, i2 + 1);
+ } else if (o.isDecimal128()) {
+ return o.asDecimal128().toString();
} else if (o.isNull()) {
return null;
} else
@@ -380,14 +473,33 @@ public class Mongo3Interface {
} // end of GetField
- protected BsonValue ObjToBson(Object val) {
+ public Object MakeBson(String s, int json) {
+ BsonValue bval;
+
+ if (json == 1)
+ bval = BsonDocument.parse(s);
+ else if (json == 2)
+ bval = BsonArray.parse(s);
+ else
+ bval = null;
+
+ return bval;
+ } // end of MakeBson
+
+ protected BsonValue ObjToBson(Object val, int json) {
BsonValue bval = null;
if (val == null)
bval = bsonull;
- else if (val.getClass() == String.class)
- bval = new BsonString((String) val);
- else if (val.getClass() == Integer.class)
+ else if (val.getClass() == String.class) {
+ if (json == 1)
+ bval = BsonDocument.parse((String) val);
+ else if (json == 2)
+ bval = BsonArray.parse((String) val);
+ else
+ bval = new BsonString((String) val);
+
+ } else if (val.getClass() == Integer.class)
bval = new BsonInt32((int) val);
else if (val.getClass() == Double.class)
bval = new BsonDouble((double) val);
@@ -401,6 +513,8 @@ public class Mongo3Interface {
bval = (BsonDocument) val;
else if (val.getClass() == BsonArray.class)
bval = (BsonArray) val;
+ // else if (val.getClass() == BigDecimal.class)
+ // bval = new BsonDecimal128((BigDecimal) val);
return bval;
} // end of ObjToBson
@@ -409,9 +523,9 @@ public class Mongo3Interface {
return new BsonDocument();
} // end of MakeDocument
- public boolean DocAdd(Object bdc, String key, Object val) {
+ public boolean DocAdd(Object bdc, String key, Object val, int json) {
try {
- ((BsonDocument) bdc).append(key, ObjToBson(val));
+ ((BsonDocument) bdc).append(key, ObjToBson(val, json));
} catch (MongoException me) {
SetErrmsg(me);
return true;
@@ -424,12 +538,12 @@ public class Mongo3Interface {
return new BsonArray();
} // end of MakeArray
- public boolean ArrayAdd(Object bar, int n, Object val) {
+ public boolean ArrayAdd(Object bar, int n, Object val, int json) {
try {
for (int i = ((BsonArray) bar).size(); i < n; i++)
((BsonArray) bar).add(bsonull);
- ((BsonArray) bar).add(ObjToBson(val));
+ ((BsonArray) bar).add(ObjToBson(val, json));
} catch (MongoException me) {
SetErrmsg(me);
return true;
@@ -501,4 +615,4 @@ public class Mongo3Interface {
return n;
} // end of CollDelete
-} // end of class MongoInterface
+} // end of class Mongo3Interface
diff --git a/storage/connect/TestInsert2.java b/storage/connect/TestInsert2.java
new file mode 100644
index 00000000000..e1a7cb4f98b
--- /dev/null
+++ b/storage/connect/TestInsert2.java
@@ -0,0 +1,131 @@
+package wrappers;
+
+import java.io.BufferedReader;
+import java.io.Console;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Date;
+
+public class TestInsert2 {
+ static boolean DEBUG = true;
+ static final Console c = System.console();
+ static Mongo2Interface jdi = null;
+
+ public static void main(String[] args) {
+ int rc;
+ String[] parms = new String[4];
+
+ jdi = new Mongo2Interface(DEBUG);
+
+ parms[0] = getLine("URI: ", false);
+ parms[1] = getLine("Database: ", false);
+ parms[2] = null;
+ parms[3] = null;
+
+ if (parms[0] == null)
+ parms[0] = "mongodb://localhost:27017";
+
+ if (parms[1] == null)
+ parms[1] = "test";
+
+ rc = jdi.MongoConnect(parms);
+
+ if (rc == 0) {
+ Object bdoc = jdi.MakeDocument();
+
+ if (jdi.DocAdd(bdoc, "_id", (Object) 1, 0))
+ System.out.println(jdi.GetErrmsg());
+
+ if (jdi.DocAdd(bdoc, "Name", (Object) "Smith", 0))
+ System.out.println(jdi.GetErrmsg());
+
+ if (jdi.DocAdd(bdoc, "Age", (Object) 39, 0))
+ System.out.println(jdi.GetErrmsg());
+
+ if (jdi.DocAdd(bdoc, "Pi", (Object) 3.14, 0))
+ System.out.println(jdi.GetErrmsg());
+
+ if (jdi.DocAdd(bdoc, "Phone", (Object) "{\"ext\":[4,5,7]}", 1))
+ System.out.println(jdi.GetErrmsg());
+
+ if (jdi.DocAdd(bdoc, "Scores", (Object) "[24,2,13]", 2))
+ System.out.println(jdi.GetErrmsg());
+
+ Object bar = jdi.MakeArray();
+
+ for (int i = 1; i < 3; i++)
+ if (jdi.ArrayAdd(bar, i, (Object) (Math.random() * 10.0), 0))
+ System.out.println(jdi.GetErrmsg());
+
+ if (jdi.DocAdd(bdoc, "Prices", bar, 0))
+ System.out.println(jdi.GetErrmsg());
+
+ Object dat = new Date();
+
+ if (jdi.DocAdd(bdoc, "Date", dat, 0))
+ System.out.println(jdi.GetErrmsg());
+
+ System.out.println(bdoc);
+
+ // Try to update
+ if (!jdi.GetCollection("updtest") && !jdi.FindColl(null, null)) {
+ if (jdi.CollDelete(true) < 0)
+ System.out.println(jdi.GetErrmsg());
+
+ if (jdi.CollInsert(bdoc))
+ System.out.println(jdi.GetErrmsg());
+
+ Object updlist = jdi.MakeDocument();
+
+ if (jdi.DocAdd(updlist, "Age", (Object) 45, 0))
+ System.out.println(jdi.GetErrmsg());
+
+ Object upd = jdi.MakeDocument();
+
+ if (jdi.DocAdd(upd, "$set", updlist, 0))
+ System.out.println(jdi.GetErrmsg());
+
+ if (jdi.ReadNext() > 0 && jdi.CollUpdate(upd) < 0)
+ System.out.println(jdi.GetErrmsg());
+
+ if (!jdi.Rewind() && jdi.ReadNext() > 0)
+ System.out.println(jdi.GetDoc());
+ else
+ System.out.println("Failed Rewind");
+
+ } // endif n
+
+ } // endif rc
+
+ } // end of main
+
+ // ==================================================================
+ private static String getLine(String p, boolean b) {
+ String response;
+
+ if (c != null) {
+ // Standard console mode
+ if (b) {
+ response = new String(c.readPassword(p));
+ } else
+ response = c.readLine(p);
+
+ } else {
+ // For instance when testing from Eclipse
+ BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+
+ System.out.print(p);
+
+ try {
+ // Cannot suppress echo for password entry
+ response = in.readLine();
+ } catch (IOException e) {
+ response = "";
+ } // end of try/catch
+
+ } // endif c
+
+ return (response.isEmpty()) ? null : response;
+ } // end of getLine
+
+}
diff --git a/storage/connect/TestInsert3.java b/storage/connect/TestInsert3.java
new file mode 100644
index 00000000000..a56a361e7aa
--- /dev/null
+++ b/storage/connect/TestInsert3.java
@@ -0,0 +1,131 @@
+package wrappers;
+
+import java.io.BufferedReader;
+import java.io.Console;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Date;
+
+public class TestInsert3 {
+ static boolean DEBUG = true;
+ static final Console c = System.console();
+ static Mongo3Interface jdi = null;
+
+ public static void main(String[] args) {
+ int rc;
+ String[] parms = new String[4];
+
+ jdi = new Mongo3Interface(DEBUG);
+
+ parms[0] = getLine("URI: ", false);
+ parms[1] = getLine("Database: ", false);
+ parms[2] = null;
+ parms[3] = null;
+
+ if (parms[0] == null)
+ parms[0] = "mongodb://localhost:27017";
+
+ if (parms[1] == null)
+ parms[1] = "test";
+
+ rc = jdi.MongoConnect(parms);
+
+ if (rc == 0) {
+ Object bdoc = jdi.MakeDocument();
+
+ if (jdi.DocAdd(bdoc, "_id", (Object) 1, 0))
+ System.out.println(jdi.GetErrmsg());
+
+ if (jdi.DocAdd(bdoc, "Name", (Object) "Smith", 0))
+ System.out.println(jdi.GetErrmsg());
+
+ if (jdi.DocAdd(bdoc, "Age", (Object) 39, 0))
+ System.out.println(jdi.GetErrmsg());
+
+ if (jdi.DocAdd(bdoc, "Pi", (Object) 3.14, 0))
+ System.out.println(jdi.GetErrmsg());
+
+ if (jdi.DocAdd(bdoc, "Phone", (Object) "{\"ext\":[4,5,7]}", 1))
+ System.out.println(jdi.GetErrmsg());
+
+ if (jdi.DocAdd(bdoc, "Scores", (Object) "[24,2,13]", 2))
+ System.out.println(jdi.GetErrmsg());
+
+ Object bar = jdi.MakeArray();
+
+ for (int i = 0; i < 2; i++)
+ if (jdi.ArrayAdd(bar, i, (Object) (Math.random() * 10.0), 0))
+ System.out.println(jdi.GetErrmsg());
+
+ if (jdi.DocAdd(bdoc, "Prices", bar, 0))
+ System.out.println(jdi.GetErrmsg());
+
+ Object dat = new Date();
+
+ if (jdi.DocAdd(bdoc, "Date", dat, 0))
+ System.out.println(jdi.GetErrmsg());
+
+ System.out.println(bdoc);
+
+ // Try to update
+ if (!jdi.GetCollection("updtest") && !jdi.FindColl(null, null)) {
+ if (jdi.CollDelete(true) < 0)
+ System.out.println(jdi.GetErrmsg());
+
+ if (jdi.CollInsert(bdoc))
+ System.out.println(jdi.GetErrmsg());
+
+ Object updlist = jdi.MakeDocument();
+
+ if (jdi.DocAdd(updlist, "Age", (Object) 40, 0))
+ System.out.println(jdi.GetErrmsg());
+
+ Object upd = jdi.MakeDocument();
+
+ if (jdi.DocAdd(upd, "$set", updlist, 0))
+ System.out.println(jdi.GetErrmsg());
+
+ if (jdi.ReadNext() > 0 && jdi.CollUpdate(upd) < 0)
+ System.out.println(jdi.GetErrmsg());
+
+ if (!jdi.Rewind() && jdi.ReadNext() > 0)
+ System.out.println(jdi.GetDoc());
+ else
+ System.out.println("Failed Rewind");
+
+ } // endif n
+
+ } // endif rc
+
+ } // end of main
+
+ // ==================================================================
+ private static String getLine(String p, boolean b) {
+ String response;
+
+ if (c != null) {
+ // Standard console mode
+ if (b) {
+ response = new String(c.readPassword(p));
+ } else
+ response = c.readLine(p);
+
+ } else {
+ // For instance when testing from Eclipse
+ BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+
+ System.out.print(p);
+
+ try {
+ // Cannot suppress echo for password entry
+ response = in.readLine();
+ } catch (IOException e) {
+ response = "";
+ } // end of try/catch
+
+ } // endif c
+
+ return (response.isEmpty()) ? null : response;
+ } // end of getLine
+
+}
diff --git a/storage/connect/array.cpp b/storage/connect/array.cpp
index 3c736941b6f..6d105c12a59 100644
--- a/storage/connect/array.cpp
+++ b/storage/connect/array.cpp
@@ -19,14 +19,14 @@
#include "sql_class.h"
//#include "sql_time.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h> // for uintprt_h
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Include required application header files */
diff --git a/storage/connect/blkfil.cpp b/storage/connect/blkfil.cpp
index 76c9d09ac93..93ae5a5ef0c 100644
--- a/storage/connect/blkfil.cpp
+++ b/storage/connect/blkfil.cpp
@@ -20,13 +20,13 @@
#include "sql_class.h"
//#include "sql_time.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Include application header files: */
diff --git a/storage/connect/block.h b/storage/connect/block.h
index c10fc4761ac..e8871277d48 100644
--- a/storage/connect/block.h
+++ b/storage/connect/block.h
@@ -24,11 +24,11 @@
#if !defined(BLOCK_DEFINED)
#define BLOCK_DEFINED
-#if defined(__WIN__) && !defined(NOEX)
+#if defined(_WIN32) && !defined(NOEX)
#define DllExport __declspec( dllexport )
-#else // !__WIN__
+#else // !_WIN32
#define DllExport
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Definition of class BLOCK with its method function new. */
diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp
index a0a421657bd..bf03f47a10d 100644
--- a/storage/connect/bson.cpp
+++ b/storage/connect/bson.cpp
@@ -30,7 +30,7 @@
#define CheckType(X,Y)
#endif
-#if defined(__WIN__)
+#if defined(_WIN32)
#define EL "\r\n"
#else
#define EL "\n"
@@ -1205,15 +1205,14 @@ void BJSON::SetArrayValue(PBVAL bap, PBVAL nvp, int n)
int i = 0;
PBVAL bvp = NULL;
- if (bap->To_Val)
- for (bvp = GetArray(bap); bvp; i++, bvp = GetNext(bvp))
- if (i == n) {
- SetValueVal(bvp, nvp);
- return;
- }
+ for (bvp = GetArray(bap); i < n; i++, bvp = bvp ? GetNext(bvp) : NULL)
+ if (!bvp)
+ AddArrayValue(bap, NewVal());
if (!bvp)
AddArrayValue(bap, MOF(nvp));
+ else
+ SetValueVal(bvp, nvp);
} // end of SetValue
diff --git a/storage/connect/bsonudf.cpp b/storage/connect/bsonudf.cpp
index a56db4d731b..0c7112ee15f 100644
--- a/storage/connect/bsonudf.cpp
+++ b/storage/connect/bsonudf.cpp
@@ -1889,24 +1889,31 @@ static int *GetIntArgPtr(PGLOBAL g, UDF_ARGS *args, uint& n)
/*********************************************************************************/
int IsArgJson(UDF_ARGS *args, uint i)
{
- int n = 0;
+ const char *pat = args->attributes[i];
+ int n = 0;
+
+ if (*pat == '@') {
+ pat++;
+
+ if (*pat == '\'' || *pat == '"')
+ pat++;
+
+ } // endif pat
if (i >= args->arg_count || args->arg_type[i] != STRING_RESULT) {
- } else if (!strnicmp(args->attributes[i], "Bson_", 5) ||
- !strnicmp(args->attributes[i], "Json_", 5)) {
+ } else if (!strnicmp(pat, "Bson_", 5) || !strnicmp(pat, "Json_", 5)) {
if (!args->args[i] || strchr("[{ \t\r\n", *args->args[i]))
n = 1; // arg should be is a json item
// else
// n = 2; // A file name may have been returned
- } else if (!strnicmp(args->attributes[i], "Bbin_", 5)) {
+ } else if (!strnicmp(pat, "Bbin_", 5)) {
if (args->lengths[i] == sizeof(BSON))
n = 3; // arg is a binary json item
// else
// n = 2; // A file name may have been returned
- } else if (!strnicmp(args->attributes[i], "Bfile_", 6) ||
- !strnicmp(args->attributes[i], "Jfile_", 6)) {
+ } else if (!strnicmp(pat, "Bfile_", 6) || !strnicmp(pat, "Jfile_", 6)) {
n = 2; // arg is a json file name
#if 0
} else if (args->lengths[i]) {
@@ -4682,7 +4689,7 @@ char *bfile_convert(UDF_INIT* initid, UDF_ARGS* args, char* result,
str = (char*)g->Xchk;
if (!str) {
- PUSH_WARNING(g->Message ? g->Message : "Unexpected error");
+ PUSH_WARNING(*g->Message ? g->Message : "Unexpected error");
*is_null = 1;
*error = 1;
*res_length = 0;
@@ -4742,7 +4749,7 @@ char *bfile_bjson(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!g->Xchk) {
int msgid = MSGID_OPEN_MODE_STRERROR;
- FILE *fout;
+ FILE *fout = NULL;
FILE *fin;
if (!(fin = global_fopen(g, msgid, fn, "rt")))
@@ -4805,7 +4812,7 @@ char *bfile_bjson(UDF_INIT *initid, UDF_ARGS *args, char *result,
str = (char*)g->Xchk;
if (!str) {
- if (g->Message)
+ if (*g->Message)
str = strcpy(result, g->Message);
else
str = strcpy(result, "Unexpected error");
diff --git a/storage/connect/cmgfam.cpp b/storage/connect/cmgfam.cpp
index 690c087c2bb..a3afc154224 100644
--- a/storage/connect/cmgfam.cpp
+++ b/storage/connect/cmgfam.cpp
@@ -56,6 +56,7 @@ CMGFAM::CMGFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL)
Pcg.Coll_name = tdp->Collname;
Pcg.Options = tdp->Options;
Pcg.Filter = tdp->Filter;
+ Pcg.Line = NULL;
Pcg.Pipe = tdp->Pipe && tdp->Options != NULL;
Lrecl = tdp->Lrecl + tdp->Ending;
} else {
@@ -64,6 +65,7 @@ CMGFAM::CMGFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL)
Pcg.Coll_name = NULL;
Pcg.Options = NULL;
Pcg.Filter = NULL;
+ Pcg.Line = NULL;
Pcg.Pipe = false;
Lrecl = 0;
} // endif tdp
@@ -88,6 +90,7 @@ CMGFAM::CMGFAM(PBDEF tdp) : DOSFAM((PDOSDEF)NULL)
Pcg.Coll_name = tdp->Collname;
Pcg.Options = tdp->Options;
Pcg.Filter = tdp->Filter;
+ Pcg.Line = NULL;
Pcg.Pipe = tdp->Pipe && tdp->Options != NULL;
Lrecl = tdp->Lrecl + tdp->Ending;
} else {
@@ -96,6 +99,7 @@ CMGFAM::CMGFAM(PBDEF tdp) : DOSFAM((PDOSDEF)NULL)
Pcg.Coll_name = NULL;
Pcg.Options = NULL;
Pcg.Filter = NULL;
+ Pcg.Line = NULL;
Pcg.Pipe = false;
Lrecl = 0;
} // endif tdp
@@ -280,6 +284,7 @@ int CMGFAM::ReadBuffer(PGLOBAL g)
/***********************************************************************/
int CMGFAM::WriteBuffer(PGLOBAL g)
{
+ Pcg.Line = Tdbp->GetLine();
return Cmgp->Write(g);
} // end of WriteBuffer
diff --git a/storage/connect/cmgoconn.cpp b/storage/connect/cmgoconn.cpp
index 474f940a8cf..f3fc30fa9e2 100644
--- a/storage/connect/cmgoconn.cpp
+++ b/storage/connect/cmgoconn.cpp
@@ -1,7 +1,7 @@
/************ CMgoConn C++ Functions Source Code File (.CPP) ***********/
-/* Name: CMgoConn.CPP Version 1.0 */
+/* Name: CMgoConn.CPP Version 1.1 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2017 - 2021 */
/* */
/* This file contains the MongoDB C connection classes functions. */
/***********************************************************************/
@@ -24,8 +24,9 @@
bool CMgoConn::IsInit = false;
-bool IsNum(PSZ s);
+bool IsArray(PSZ s);
bool MakeSelector(PGLOBAL g, PFIL fp, PSTRG s);
+int GetDefaultPrec(void);
/* --------------------------- Class INCOL --------------------------- */
@@ -47,12 +48,13 @@ void INCOL::AddCol(PGLOBAL g, PCOL colp, char *jp)
break;
if (!kp) {
- icp = new(g) INCOL(IsNum(p));
+ icp = new(g) INCOL();
kcp = (PKC)PlugSubAlloc(g, NULL, sizeof(KEYCOL));
kcp->Next = NULL;
kcp->Incolp = icp;
kcp->Colp = NULL;
kcp->Key = PlugDup(g, jp);
+ kcp->Array = IsArray(p);
if (Klist) {
for (kp = Klist; kp->Next; kp = kp->Next);
@@ -73,6 +75,7 @@ void INCOL::AddCol(PGLOBAL g, PCOL colp, char *jp)
kcp->Incolp = NULL;
kcp->Colp = colp;
kcp->Key = jp;
+ kcp->Array = IsArray(jp);
if (Klist) {
for (kp = Klist; kp->Next; kp = kp->Next);
@@ -120,11 +123,12 @@ CMgoConn::CMgoConn(PGLOBAL g, PCPARM pcg)
{
Pcg = pcg;
Uri = NULL;
- Pool = NULL;
+//Pool = NULL;
Client = NULL;
Database = NULL;
Collection = NULL;
Cursor = NULL;
+ Document = NULL;
Query = NULL;
Opts = NULL;
Fpc = NULL;
@@ -157,24 +161,26 @@ bool CMgoConn::Connect(PGLOBAL g)
} // endif name
if (!IsInit)
-#if defined(__WIN__)
+#if defined(_WIN32)
__try {
mongo_init(true);
} __except (EXCEPTION_EXECUTE_HANDLER) {
strcpy(g->Message, "Cannot load MongoDB C driver");
return true;
} // end try/except
-#else // !__WIN__
+#else // !_WIN32
mongo_init(true);
-#endif // !__WIN__
+#endif // !_WIN32
- Uri = mongoc_uri_new(Pcg->Uristr);
+ Uri = mongoc_uri_new_with_error(Pcg->Uristr, &Error);
if (!Uri) {
- sprintf(g->Message, "Failed to parse URI: \"%s\"", Pcg->Uristr);
+ sprintf(g->Message, "Failed to parse URI: \"%s\" Msg: %s",
+ Pcg->Uristr, Error.message);
return true;
} // endif Uri
+#if 0
// Create a new client pool instance
Pool = mongoc_client_pool_new(Uri);
mongoc_client_pool_set_error_api(Pool, 2);
@@ -185,13 +191,24 @@ bool CMgoConn::Connect(PGLOBAL g)
// Create a new client instance
Client = mongoc_client_pool_pop(Pool);
+#else
+ // Create a new client instance
+ Client = mongoc_client_new_from_uri (Uri);
if (!Client) {
sprintf(g->Message, "Failed to get Client");
return true;
} // endif Client
- // Get a handle on the collection Coll_name
+ // Register the application name so we can track it in the profile logs
+ // on the server. This can also be done from the URI (see other examples).
+ mongoc_client_set_appname (Client, "Connect");
+
+ // Get a handle on the database
+ // Database = mongoc_client_get_database (Client, Pcg->Db_name);
+#endif // 0
+
+ // Get a handle on the collection
Collection = mongoc_client_get_collection(Client, Pcg->Db_name, Pcg->Coll_name);
if (!Collection) {
@@ -228,8 +245,8 @@ bool CMgoConn::Connect(PGLOBAL g)
int CMgoConn::CollSize(PGLOBAL g)
{
int cnt;
- bson_t *query;
- const char *jf = NULL;
+ bson_t* query;
+ const char* jf = NULL;
if (Pcg->Pipe)
return 10;
@@ -237,7 +254,7 @@ int CMgoConn::CollSize(PGLOBAL g)
jf = Pcg->Filter;
if (jf) {
- query = bson_new_from_json((const uint8_t *)jf, -1, &Error);
+ query = bson_new_from_json((const uint8_t*)jf, -1, &Error);
if (!query) {
htrc("Wrong filter: %s", Error.message);
@@ -247,8 +264,17 @@ int CMgoConn::CollSize(PGLOBAL g)
} else
query = bson_new();
+#if defined(DEVELOPMENT)
+ if (jf)
+ cnt = (int)mongoc_collection_count_documents(Collection,
+ query, NULL, NULL, NULL, &Error);
+ else
+ cnt = (int)mongoc_collection_estimated_document_count(
+ Collection, NULL, NULL, NULL, &Error);
+#else
cnt = (int)mongoc_collection_count(Collection,
- MONGOC_QUERY_NONE, query, 0, 0, NULL, &Error);
+ MONGOC_QUERY_NONE, query, 0, 0, NULL, &Error);
+#endif
if (cnt < 0) {
htrc("Collection count: %s", Error.message);
@@ -260,30 +286,91 @@ int CMgoConn::CollSize(PGLOBAL g)
} // end of CollSize
/***********************************************************************/
-/* OpenDB: Data Base open routine for MONGO access method. */
+/* Project: make the projection avoid path collision. */
+/***********************************************************************/
+void CMgoConn::Project(PGLOBAL g, PSTRG s)
+{
+ bool m, b = false;
+ size_t n;
+ PSZ path;
+ PCOL cp;
+ PTDB tp = Pcg->Tdbp;
+ PTHP hp, php = NULL, * nphp = &php;
+
+ for (cp = tp->GetColumns(); cp; cp = cp->GetNext()) {
+ path = cp->GetJpath(g, true);
+
+ // Resolve path collision
+ for (hp = php; hp; hp = hp->Next) {
+ if (strlen(path) < strlen(hp->Path)) {
+ n = strlen(path);
+ m = true;
+ } else {
+ n = strlen(hp->Path);
+ m = false;
+ } // endif path
+
+ if (!strncmp(path, hp->Path, n))
+ break;
+
+ } // endfor hp
+
+ if (!hp) {
+ // New path
+ hp = (PTHP)PlugSubAlloc(g, NULL, sizeof(PTH));
+ hp->Path = path;
+ hp->Name = cp->GetName();
+ hp->Next = NULL;
+ *nphp = hp;
+ nphp = &hp->Next;
+ } else if (m) // Smaller path must replace longer one
+ hp->Path = path;
+
+ } // endfor cp
+
+ for (hp = php; hp; hp = hp->Next) {
+ if (b)
+ s->Append(",\"");
+ else
+ b = true;
+
+ if (*hp->Path == '{') {
+ // This is a Mongo defined column
+ s->Append(hp->Name);
+ s->Append("\":");
+ s->Append(hp->Path);
+ } else {
+ s->Append(hp->Path);
+ s->Append("\":1");
+ } // endif Path
+
+ } // endfor hp
+
+} // end of Project
+
+/***********************************************************************/
+/* MakeCursor: make the cursor used to retrieve documents. */
/***********************************************************************/
bool CMgoConn::MakeCursor(PGLOBAL g)
{
const char *p;
- bool id, b = false, all = false;
+ bool id, all = false;
PCSZ options = Pcg->Options;
PTDB tp = Pcg->Tdbp;
PCOL cp;
PSTRG s = NULL;
PFIL filp = tp->GetFilter();
- id = (tp->GetMode() != MODE_READ);
+ id = (tp->GetMode() == MODE_UPDATE || tp->GetMode() == MODE_DELETE);
if (options && !stricmp(options, "all")) {
options = NULL;
all = true;
- } // endif Options
-
- for (cp = tp->GetColumns(); cp; cp = cp->GetNext())
- if (!strcmp(cp->GetName(), "_id"))
- id = true;
- else if (cp->GetFmt() && !strcmp(cp->GetFmt(), "*") && !options)
+ } else for (cp = tp->GetColumns(); cp && !all; cp = cp->GetNext())
+ if (cp->GetFmt() && !strcmp(cp->GetFmt(), "*") && !options)
all = true;
+ else if (!id)
+ id = !strcmp(cp->GetFmt() ? cp->GetFmt() : cp->GetName(), "_id");
if (Pcg->Pipe) {
if (trace(1))
@@ -311,23 +398,14 @@ bool CMgoConn::MakeCursor(PGLOBAL g)
tp->SetFilter(NULL); // Not needed anymore
} // endif To_Filter
- if (!all && tp->GetColumns()) {
+ if (tp->GetColumns() && !strstr(s->GetStr(), "$project")) {
// Project list
s->Append(",{\"$project\":{\"");
if (!id)
s->Append("_id\":0,\"");
- for (cp = tp->GetColumns(); cp; cp = cp->GetNext()) {
- if (b)
- s->Append(",\"");
- else
- b = true;
-
- s->Append(cp->GetJpath(g, true));
- s->Append("\":1");
- } // endfor cp
-
+ Project(g, s);
s->Append("}}");
} // endif all
@@ -377,7 +455,7 @@ bool CMgoConn::MakeCursor(PGLOBAL g)
if (MakeSelector(g, filp, s)) {
strcpy(g->Message, "Failed making selector");
- return NULL;
+ return true;
} // endif Selector
tp->SetFilter(NULL); // Not needed anymore
@@ -391,7 +469,7 @@ bool CMgoConn::MakeCursor(PGLOBAL g)
if (!Query) {
sprintf(g->Message, "Wrong filter: %s", Error.message);
- return NULL;
+ return true;
} // endif Query
} else
@@ -413,16 +491,7 @@ bool CMgoConn::MakeCursor(PGLOBAL g)
if (!id)
s->Append("_id\":0,\"");
- for (cp = tp->GetColumns(); cp; cp = cp->GetNext()) {
- if (b)
- s->Append(",\"");
- else
- b = true;
-
- s->Append(cp->GetJpath(g, true));
- s->Append("\":1");
- } // endfor cp
-
+ Project(g, s);
s->Append("}}");
s->Resize(s->GetLength() + 1);
p = s->GetStr();
@@ -435,7 +504,7 @@ bool CMgoConn::MakeCursor(PGLOBAL g)
if (!Opts) {
sprintf(g->Message, "Wrong options: %s", Error.message);
- return NULL;
+ return true;
} // endif Opts
} // endif all
@@ -495,44 +564,54 @@ void CMgoConn::ShowDocument(bson_iter_t *iter, const bson_t *doc, const char *k)
key = bson_iter_key(iter);
htrc("Found element key: \"%s\"\n", key);
- if (BSON_ITER_HOLDS_UTF8(iter))
- htrc("%s.%s=\"%s\"\n", k, key, bson_iter_utf8(iter, NULL));
- else if (BSON_ITER_HOLDS_INT32(iter))
- htrc("%s.%s=%d\n", k, key, bson_iter_int32(iter));
- else if (BSON_ITER_HOLDS_INT64(iter))
- htrc("%s.%s=%lld\n", k, key, bson_iter_int64(iter));
- else if (BSON_ITER_HOLDS_DOUBLE(iter))
- htrc("%s.%s=%g\n", k, key, bson_iter_double(iter));
- else if (BSON_ITER_HOLDS_DATE_TIME(iter))
- htrc("%s.%s=date(%lld)\n", k, key, bson_iter_date_time(iter));
- else if (BSON_ITER_HOLDS_OID(iter)) {
- char str[25];
-
- bson_oid_to_string(bson_iter_oid(iter), str);
- htrc("%s.%s=%s\n", k, key, str);
- } else if (BSON_ITER_HOLDS_DECIMAL128(iter)) {
- char *str = NULL;
- bson_decimal128_t dec;
-
- bson_iter_decimal128(iter, &dec);
- bson_decimal128_to_string(&dec, str);
- htrc("%s.%s=%s\n", k, key, str);
- } else if (BSON_ITER_HOLDS_DOCUMENT(iter)) {
- bson_iter_t child;
-
- if (bson_iter_recurse(iter, &child))
- ShowDocument(&child, NULL, key);
-
- } else if (BSON_ITER_HOLDS_ARRAY(iter)) {
- bson_t *arr;
- bson_iter_t itar;
- const uint8_t *data = NULL;
- uint32_t len = 0;
-
- bson_iter_array(iter, &len, &data);
- arr = bson_new_from_data(data, len);
- ShowDocument(&itar, arr, key);
- } // endif's
+ switch (bson_iter_type(iter)) {
+ case BSON_TYPE_UTF8:
+ htrc("%s.%s=\"%s\"\n", k, key, bson_iter_utf8(iter, NULL));
+ break;
+ case BSON_TYPE_INT32:
+ htrc("%s.%s=%d\n", k, key, bson_iter_int32(iter));
+ break;
+ case BSON_TYPE_INT64:
+ htrc("%s.%s=%lld\n", k, key, bson_iter_int64(iter));
+ break;
+ case BSON_TYPE_DOUBLE:
+ htrc("%s.%s=%g\n", k, key, bson_iter_double(iter));
+ break;
+ case BSON_TYPE_DATE_TIME:
+ htrc("%s.%s=date(%lld)\n", k, key, bson_iter_date_time(iter));
+ break;
+ case BSON_TYPE_OID: {
+ char str[25];
+
+ bson_oid_to_string(bson_iter_oid(iter), str);
+ htrc("%s.%s=%s\n", k, key, str);
+ } break;
+ case BSON_TYPE_DECIMAL128: {
+ char str[BSON_DECIMAL128_STRING];
+ bson_decimal128_t dec;
+
+ bson_iter_decimal128(iter, &dec);
+ bson_decimal128_to_string(&dec, str);
+ htrc("%s.%s=%s\n", k, key, str);
+ } break;
+ case BSON_TYPE_DOCUMENT: {
+ bson_iter_t child;
+
+ if (bson_iter_recurse(iter, &child))
+ ShowDocument(&child, NULL, key);
+
+ } break;
+ case BSON_TYPE_ARRAY: {
+ bson_t* arr;
+ bson_iter_t itar;
+ const uint8_t* data = NULL;
+ uint32_t len = 0;
+
+ bson_iter_array(iter, &len, &data);
+ arr = bson_new_from_data(data, len);
+ ShowDocument(&itar, arr, key);
+ } break;
+ } // endswitch iter
} // endwhile bson_iter_next
@@ -545,7 +624,7 @@ void CMgoConn::ShowDocument(bson_iter_t *iter, const bson_t *doc, const char *k)
/***********************************************************************/
void CMgoConn::MakeColumnGroups(PGLOBAL g)
{
- Fpc = new(g) INCOL(false);
+ Fpc = new(g) INCOL();
for (PCOL colp = Pcg->Tdbp->GetColumns(); colp; colp = colp->GetNext())
if (!colp->IsSpecial())
@@ -560,7 +639,7 @@ bool CMgoConn::DocWrite(PGLOBAL g, PINCOL icp)
{
for (PKC kp = icp->Klist; kp; kp = kp->Next)
if (kp->Incolp) {
- bool isdoc = !kp->Incolp->Array;
+ bool isdoc = !kp->Array;
if (isdoc)
BSON_APPEND_DOCUMENT_BEGIN(icp->Child, kp->Key, kp->Incolp->Child);
@@ -582,7 +661,7 @@ bool CMgoConn::DocWrite(PGLOBAL g, PINCOL icp)
} // end of DocWrite
/***********************************************************************/
-/* WriteDB: Data Base write routine for DOS access method. */
+/* WriteDB: Data Base write routine for CMGO access method. */
/***********************************************************************/
int CMgoConn::Write(PGLOBAL g)
{
@@ -590,22 +669,45 @@ int CMgoConn::Write(PGLOBAL g)
PTDB tp = Pcg->Tdbp;
if (tp->GetMode() == MODE_INSERT) {
- Fpc->Init();
+ if (!Pcg->Line) {
+ Fpc->Init();
- if (DocWrite(g, Fpc))
- return RC_FX;
+ if (DocWrite(g, Fpc))
+ return RC_FX;
- if (trace(2)) {
- char *str = bson_as_json(Fpc->Child, NULL);
- htrc("Inserting: %s\n", str);
- bson_free(str);
- } // endif trace
+ if (trace(2)) {
+ char* str = bson_as_json(Fpc->Child, NULL);
+ htrc("Inserting: %s\n", str);
+ bson_free(str);
+ } // endif trace
- if (!mongoc_collection_insert(Collection, MONGOC_INSERT_NONE,
- Fpc->Child, NULL, &Error)) {
- sprintf(g->Message, "Mongo insert: %s", Error.message);
- rc = RC_FX;
- } // endif insert
+ if (!mongoc_collection_insert(Collection, MONGOC_INSERT_NONE,
+ Fpc->Child, NULL, &Error)) {
+ sprintf(g->Message, "Mongo insert: %s", Error.message);
+ rc = RC_FX;
+ } // endif insert
+
+ } else {
+ const uint8_t* val = (const uint8_t*)Pcg->Line;
+ bson_t* doc = bson_new_from_json(val, -1, &Error);
+
+ if (doc && trace(2)) {
+ char* str = bson_as_json(doc, NULL);
+ htrc("Inserting: %s\n", str);
+ bson_free(str);
+ } // endif trace
+
+ if (!doc) {
+ sprintf(g->Message, "bson_new_from_json: %s", Error.message);
+ rc = RC_FX;
+ } else if (!mongoc_collection_insert(Collection,
+ MONGOC_INSERT_NONE, doc, NULL, &Error)) {
+ sprintf(g->Message, "Mongo insert: %s", Error.message);
+ bson_destroy(doc);
+ rc = RC_FX;
+ } // endif insert
+
+ } // endif Line
} else {
bool b = false;
@@ -614,19 +716,26 @@ int CMgoConn::Write(PGLOBAL g)
bson_iter_init(&iter, Document);
- if (bson_iter_find(&iter, "_id")) {
- if (BSON_ITER_HOLDS_OID(&iter))
- b = BSON_APPEND_OID(query, "_id", bson_iter_oid(&iter));
- else if (BSON_ITER_HOLDS_INT32(&iter))
- b = BSON_APPEND_INT32(query, "_id", bson_iter_int32(&iter));
- else if (BSON_ITER_HOLDS_INT64(&iter))
- b = BSON_APPEND_INT64(query, "_id", bson_iter_int64(&iter));
- else if (BSON_ITER_HOLDS_DOUBLE(&iter))
- b = BSON_APPEND_DOUBLE(query, "_id", bson_iter_double(&iter));
- else if (BSON_ITER_HOLDS_UTF8(&iter))
- b = BSON_APPEND_UTF8(query, "_id", bson_iter_utf8(&iter, NULL));
-
- } // endif iter
+ if (bson_iter_find(&iter, "_id"))
+ switch (bson_iter_type(&iter)) {
+ case BSON_TYPE_OID:
+ b = BSON_APPEND_OID(query, "_id", bson_iter_oid(&iter));
+ break;
+ case BSON_TYPE_UTF8:
+ b = BSON_APPEND_UTF8(query, "_id", bson_iter_utf8(&iter, NULL));
+ break;
+ case BSON_TYPE_INT32:
+ b = BSON_APPEND_INT32(query, "_id", bson_iter_int32(&iter));
+ break;
+ case BSON_TYPE_INT64:
+ b = BSON_APPEND_INT64(query, "_id", bson_iter_int64(&iter));
+ break;
+ case BSON_TYPE_DOUBLE:
+ b = BSON_APPEND_DOUBLE(query, "_id", bson_iter_double(&iter));
+ break;
+ default:
+ break;
+ } // endswitch iter
if (b) {
if (trace(2)) {
@@ -708,8 +817,9 @@ void CMgoConn::Close(void)
if (Opts) bson_destroy(Opts);
if (Cursor) mongoc_cursor_destroy(Cursor);
if (Collection) mongoc_collection_destroy(Collection);
- if (Client) mongoc_client_pool_push(Pool, Client);
- if (Pool) mongoc_client_pool_destroy(Pool);
+//if (Client) mongoc_client_pool_push(Pool, Client);
+//if (Pool) mongoc_client_pool_destroy(Pool);
+ if (Client) mongoc_client_destroy(Client);
if (Uri) mongoc_uri_destroy(Uri);
if (Fpc) Fpc->Destroy();
if (fp) fp->Count = 0;
@@ -720,23 +830,51 @@ void CMgoConn::Close(void)
/***********************************************************************/
char *CMgoConn::Mini(PGLOBAL g, PCOL colp, const bson_t *bson, bool b)
{
- char *s, *str = NULL;
- char *Mbuf = (char*)PlugSubAlloc(g, NULL, colp->GetLength() + 1);
- int i, k = 0;
- bool ok = true;
+ char *s, *str = NULL;
+ char *Mbuf = (char*)PlugSubAlloc(g, NULL, (size_t)colp->GetLength() + 1);
+ int i, j = 0, k = 0, n = 0, m = GetDefaultPrec();
+ bool ok = true, dbl = false;
+ double d;
+ size_t len;
if (b)
- s = str = bson_array_as_json(bson, NULL);
+ s = str = bson_array_as_json(bson, &len);
else
- s = str = bson_as_json(bson, NULL);
+ s = str = bson_as_json(bson, &len);
+
+ if (len > (size_t)colp->GetLength()) {
+ sprintf(g->Message, "Value too long for column %s", colp->GetName());
+ bson_free(str);
+ throw (int)TYPE_AM_MGO;
+ } // endif len
for (i = 0; i < colp->GetLength() && s[i]; i++) {
switch (s[i]) {
case ' ':
if (ok) continue;
+ break;
case '"':
ok = !ok;
+ break;
+ case '.':
+ if (j) dbl = true;
+ break;
default:
+ if (ok) {
+ if (isdigit(s[i])) {
+ if (!j) j = k;
+ if (dbl) n++;
+ } else if (dbl && n > m) {
+ Mbuf[k] = 0;
+ d = atof(Mbuf + j);
+ n = sprintf(Mbuf + j, "%.*f", m, d);
+ k = j + n;
+ j = n = 0;
+ } else if (j)
+ j = n = 0;
+
+ } // endif ok
+
break;
} // endswitch s[i]
@@ -745,11 +883,6 @@ char *CMgoConn::Mini(PGLOBAL g, PCOL colp, const bson_t *bson, bool b)
bson_free(str);
- if (i >= colp->GetLength()) {
- sprintf(g->Message, "Value too long for column %s", colp->GetName());
- throw (int)TYPE_AM_MGO;
- } // endif i
-
Mbuf[k] = 0;
return Mbuf;
} // end of Mini
@@ -759,97 +892,103 @@ char *CMgoConn::Mini(PGLOBAL g, PCOL colp, const bson_t *bson, bool b)
/***********************************************************************/
void CMgoConn::GetColumnValue(PGLOBAL g, PCOL colp)
{
- char *jpath = colp->GetJpath(g, false);
- PVAL value = colp->GetValue();
-
- if (!strcmp(jpath, "*")) {
+ char *jpath = colp->GetJpath(g, false);
+ bool b = false;
+ PVAL value = colp->GetValue();
+ bson_iter_t Iter; // Used to retrieve column value
+ bson_iter_t Desc; // Descendant iter
+
+ if (*jpath == '{')
+ jpath = colp->GetName(); // This is a Mongo defined column
+
+ if (!*jpath || !strcmp(jpath, "*")) {
value->SetValue_psz(Mini(g, colp, Document, false));
} else if (bson_iter_init(&Iter, Document) &&
bson_iter_find_descendant(&Iter, jpath, &Desc)) {
- if (BSON_ITER_HOLDS_UTF8(&Desc))
- value->SetValue_psz((PSZ)bson_iter_utf8(&Desc, NULL));
- else if (BSON_ITER_HOLDS_INT32(&Desc))
- value->SetValue(bson_iter_int32(&Desc));
- else if (BSON_ITER_HOLDS_INT64(&Desc))
- value->SetValue(bson_iter_int64(&Desc));
- else if (BSON_ITER_HOLDS_DOUBLE(&Desc))
- value->SetValue(bson_iter_double(&Desc));
- else if (BSON_ITER_HOLDS_DATE_TIME(&Desc))
- value->SetValue(bson_iter_date_time(&Desc) / 1000);
- else if (BSON_ITER_HOLDS_BOOL(&Desc)) {
- bool b = bson_iter_bool(&Desc);
-
- if (value->IsTypeNum())
- value->SetValue(b ? 1 : 0);
- else
- value->SetValue_psz(b ? "true" : "false");
-
- } else if (BSON_ITER_HOLDS_OID(&Desc)) {
- char str[25];
-
- bson_oid_to_string(bson_iter_oid(&Desc), str);
- value->SetValue_psz(str);
- } else if (BSON_ITER_HOLDS_NULL(&Iter)) {
- // Apparently this does not work...
- value->Reset();
- value->SetNull(true);
- } else if (BSON_ITER_HOLDS_DECIMAL128(&Desc)) {
- char *str = NULL;
- bson_decimal128_t dec;
-
- bson_iter_decimal128(&Desc, &dec);
- bson_decimal128_to_string(&dec, str);
- value->SetValue_psz(str);
- bson_free(str);
- } else if (BSON_ITER_HOLDS_DOCUMENT(&Iter)) {
- bson_t *doc;
- const uint8_t *data = NULL;
- uint32_t len = 0;
-
- bson_iter_document(&Desc, &len, &data);
-
- if (data) {
- doc = bson_new_from_data(data, len);
- value->SetValue_psz(Mini(g, colp, doc, false));
- bson_destroy(doc);
- } else {
- // ... but we can come here in case of NULL!
- value->Reset();
- value->SetNull(true);
- } // endif data
+ switch (bson_iter_type(&Desc)) {
+ case BSON_TYPE_UTF8:
+ value->SetValue_psz((PSZ)bson_iter_utf8(&Desc, NULL));
+ break;
+ case BSON_TYPE_INT32:
+ value->SetValue(bson_iter_int32(&Desc));
+ break;
+ case BSON_TYPE_INT64:
+ value->SetValue(bson_iter_int64(&Desc));
+ break;
+ case BSON_TYPE_DOUBLE:
+ value->SetValue(bson_iter_double(&Desc));
+ break;
+ case BSON_TYPE_DATE_TIME:
+ value->SetValue(bson_iter_date_time(&Desc) / 1000);
+ break;
+ case BSON_TYPE_BOOL:
+ b = bson_iter_bool(&Desc);
- } else if (BSON_ITER_HOLDS_ARRAY(&Iter)) {
- bson_t *arr;
- const uint8_t *data = NULL;
- uint32_t len = 0;
+ if (value->IsTypeNum())
+ value->SetValue(b ? 1 : 0);
+ else
+ value->SetValue_psz(b ? "true" : "false");
- bson_iter_array(&Desc, &len, &data);
+ break;
+ case BSON_TYPE_OID: {
+ char str[25];
- if (data) {
- arr = bson_new_from_data(data, len);
- value->SetValue_psz(Mini(g, colp, arr, true));
- bson_destroy(arr);
- } else {
- // This is a bug in returning the wrong type
- // This fix is only for document items
- bson_t *doc;
+ bson_oid_to_string(bson_iter_oid(&Desc), str);
+ value->SetValue_psz(str);
+ } break;
+ case BSON_TYPE_ARRAY:
+ b = true;
+ // passthru
+ case BSON_TYPE_DOCUMENT:
+ { // All this because MongoDB can return the wrong type
+ int i = 0;
+ const uint8_t *data = NULL;
+ uint32_t len = 0;
- bson_iter_document(&Desc, &len, &data);
+ for (; i < 2; i++) {
+ if (b) // Try array first
+ bson_iter_array(&Desc, &len, &data);
+ else
+ bson_iter_document(&Desc, &len, &data);
+
+ if (!data) {
+ len = 0;
+ b = !b;
+ } else
+ break;
+
+ } // endfor i
if (data) {
- doc = bson_new_from_data(data, len);
- value->SetValue_psz(Mini(g, colp, doc, false));
+ bson_t *doc = bson_new_from_data(data, len);
+
+ value->SetValue_psz(Mini(g, colp, doc, b));
bson_destroy(doc);
} else {
// ... or we can also come here in case of NULL!
value->Reset();
value->SetNull(true);
- } // endif data
+ } // endif data
- } // endif data
+ } break;
+ case BSON_TYPE_NULL:
+ // Apparently this does not work...
+ value->Reset();
+ value->SetNull(true);
+ break;
+ case BSON_TYPE_DECIMAL128: {
+ char str[BSON_DECIMAL128_STRING];
+ bson_decimal128_t dec;
- } else
- value->Reset();
+ bson_iter_decimal128(&Desc, &dec);
+ bson_decimal128_to_string(&dec, str);
+ value->SetValue_psz(str);
+// bson_free(str);
+ } break;
+ default:
+ value->Reset();
+ break;
+ } // endswitch Desc
} else {
// Field does not exist
@@ -868,14 +1007,35 @@ bool CMgoConn::AddValue(PGLOBAL g, PCOL colp, bson_t *doc, char *key, bool upd)
PVAL value = colp->GetValue();
if (value->IsNull()) {
- if (upd)
+// if (upd)
rc = BSON_APPEND_NULL(doc, key);
- else
- return false;
+// else
+// return false;
} else switch (colp->GetResultType()) {
case TYPE_STRING:
- rc = BSON_APPEND_UTF8(doc, key, value->GetCharValue());
+ if (colp->Stringify()) {
+ const uint8_t *val = (const uint8_t*)value->GetCharValue();
+ bson_t *bsn = bson_new_from_json(val, -1, &Error);
+
+ if (!bsn) {
+ sprintf (g->Message, "AddValue: %s", Error.message);
+ return true;
+ } else if (*key) {
+ if (*val == '[')
+ rc = BSON_APPEND_ARRAY(doc, key, bsn);
+ else
+ rc = BSON_APPEND_DOCUMENT(doc, key, bsn);
+
+ } else {
+ bson_copy_to (bsn, doc);
+ rc = true;
+ } // endif's
+
+ bson_free(bsn);
+ } else
+ rc = BSON_APPEND_UTF8(doc, key, value->GetCharValue());
+
break;
case TYPE_INT:
case TYPE_SHORT:
diff --git a/storage/connect/cmgoconn.h b/storage/connect/cmgoconn.h
index b1216ac576c..f37a96cb7b9 100644
--- a/storage/connect/cmgoconn.h
+++ b/storage/connect/cmgoconn.h
@@ -28,11 +28,8 @@ typedef struct mongo_parms {
PCSZ Coll_name;
PCSZ Options;
PCSZ Filter;
+ PCSZ Line;
bool Pipe;
-//PCSZ User; // User connect info
-//PCSZ Pwd; // Password connect info
-//int Fsize; // Fetch size
-//bool Scrollable; // Scrollable cursor
} CMGOPARM, *PCPARM;
typedef struct KEYCOL {
@@ -40,15 +37,24 @@ typedef struct KEYCOL {
PINCOL Incolp;
PCOL Colp;
char *Key;
+ bool Array;
} *PKC;
+typedef struct _path_list *PTHP;
+
+typedef struct _path_list {
+ PSZ Path;
+ PSZ Name;
+ PTHP Next;
+} PTH;
+
/***********************************************************************/
/* Used when inserting values in a MongoDB collection. */
/***********************************************************************/
class INCOL : public BLOCK {
public:
// Constructor
- INCOL(bool ar) { Child = bson_new(); Klist = NULL; Array = ar; }
+ INCOL(void) { Child = bson_new(); Klist = NULL; }
// Methods
void AddCol(PGLOBAL g, PCOL colp, char *jp);
@@ -58,7 +64,6 @@ public:
//Members
bson_t *Child;
PKC Klist;
- bool Array;
}; // end of INCOL;
/***********************************************************************/
@@ -80,6 +85,7 @@ public:
bool IsConnected(void) { return m_Connected; }
bool Connect(PGLOBAL g);
int CollSize(PGLOBAL g);
+ void CMgoConn::Project(PGLOBAL g, PSTRG s);
bool MakeCursor(PGLOBAL g);
int ReadNext(PGLOBAL g);
PSZ GetDocument(PGLOBAL g);
@@ -99,7 +105,7 @@ protected:
// Members
PCPARM Pcg;
mongoc_uri_t *Uri;
- mongoc_client_pool_t *Pool; // Thread safe client pool
+//mongoc_client_pool_t *Pool; // Thread safe client pool
mongoc_client_t *Client; // The MongoDB client
mongoc_database_t *Database; // The MongoDB database
mongoc_collection_t *Collection; // The MongoDB collection
@@ -108,8 +114,6 @@ protected:
bson_t *Query; // MongoDB cursor filter
bson_t *Opts; // MongoDB cursor options
bson_error_t Error;
- bson_iter_t Iter; // Used to retrieve column value
- bson_iter_t Desc; // Descendant iter
PINCOL Fpc; // To insert INCOL classes
PFBLOCK fp;
bool m_Connected;
diff --git a/storage/connect/colblk.cpp b/storage/connect/colblk.cpp
index e42d9703ad7..19e98537d27 100644
--- a/storage/connect/colblk.cpp
+++ b/storage/connect/colblk.cpp
@@ -298,9 +298,9 @@ FIDBLK::FIDBLK(PCOLUMN cp, OPVAL op) : SPCBLK(cp), Op(op)
Buf_Type = TYPE_STRING;
*Format.Type = 'C';
Format.Length = Long;
-#if defined(__WIN__)
+#if defined(_WIN32)
Format.Prec = 1; // Case insensitive
-#endif // __WIN__
+#endif // _WIN32
Constant = (!To_Tdb->GetDef()->GetMultiple() &&
To_Tdb->GetAmType() != TYPE_AM_PLG &&
To_Tdb->GetAmType() != TYPE_AM_PLM);
diff --git a/storage/connect/colblk.h b/storage/connect/colblk.h
index 51ab32cfae2..7f1af8b8368 100644
--- a/storage/connect/colblk.h
+++ b/storage/connect/colblk.h
@@ -38,7 +38,8 @@ class DllExport COLBLK : public XOBJECT {
virtual PTDB GetTo_Tdb(void) {return To_Tdb;}
virtual int GetClustered(void) {return 0;}
virtual int IsClustered(void) {return FALSE;}
- virtual PSZ GetJpath(PGLOBAL g, bool proj) {return NULL;}
+ virtual bool Stringify(void) {return FALSE;}
+ virtual PSZ GetJpath(PGLOBAL g, bool proj) {return NULL;}
PCOL GetNext(void) {return Next;}
PSZ GetName(void) {return Name;}
int GetIndex(void) {return Index;}
diff --git a/storage/connect/domdoc.cpp b/storage/connect/domdoc.cpp
index 4502530cf82..482f0b347d2 100644
--- a/storage/connect/domdoc.cpp
+++ b/storage/connect/domdoc.cpp
@@ -4,7 +4,7 @@
/******************************************************************/
#include "my_global.h"
#include <stdio.h>
-#if defined(__WIN__)
+#if defined(_WIN32)
//#include <windows.h>
#if defined(MSX2)
#import "msxml2.dll" //Does not exist on Vista
diff --git a/storage/connect/filamap.cpp b/storage/connect/filamap.cpp
index f50290119ae..4930e3944af 100644
--- a/storage/connect/filamap.cpp
+++ b/storage/connect/filamap.cpp
@@ -17,12 +17,12 @@
/* Include relevant sections of the System header files. */
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#if defined(__BORLANDC__)
#define __MFC_COMPAT__ // To define min/max as macro
#endif // __BORLANDC__
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
#if defined(UNIX)
#include <errno.h>
#include <unistd.h>
@@ -30,7 +30,7 @@
#include <io.h>
#endif // !UNIX
#include <fcntl.h>
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Include application header files: */
@@ -197,11 +197,11 @@ bool MAPFAM::OpenTableFile(PGLOBAL g)
return true;
} // endif Memory
-#if defined(__WIN__)
+#if defined(_WIN32)
if (mode != MODE_DELETE) {
-#else // !__WIN__
+#else // !_WIN32
if (mode == MODE_READ) {
-#endif // !__WIN__
+#endif // !_WIN32
CloseFileHandle(hFile); // Not used anymore
hFile = INVALID_HANDLE_VALUE; // For Fblock
} // endif Mode
@@ -469,7 +469,7 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
/*****************************************************************/
n = (int)(Tpos - Memory);
-#if defined(__WIN__)
+#if defined(_WIN32)
DWORD drc = SetFilePointer(fp->Handle, n, NULL, FILE_BEGIN);
if (drc == 0xFFFFFFFF) {
@@ -499,7 +499,7 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
#endif // UNIX
} // endif Abort
-#if defined(__WIN__)
+#if defined(_WIN32)
CloseHandle(fp->Handle);
#else // UNIX
close(fp->Handle);
diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp
index 1ac4161e478..71bf626c08c 100644
--- a/storage/connect/filamdbf.cpp
+++ b/storage/connect/filamdbf.cpp
@@ -22,12 +22,12 @@
/* Include relevant sections of the System header files. */
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <io.h>
#include <fcntl.h>
//#include <errno.h>
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
#if defined(UNIX)
#include <errno.h>
#include <unistd.h>
@@ -35,7 +35,7 @@
//#include <io.h>
#endif // !UNIX
//#include <fcntl.h>
-#endif // !__WIN__
+#endif // !_WIN32
#include <ctype.h>
#include <stdio.h>
#include <string.h>
@@ -649,7 +649,7 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);
if (mode == MODE_INSERT) {
-#if defined(__WIN__)
+#if defined(_WIN32)
/************************************************************************/
/* Now we can revert to binary mode in particular because the eventual */
/* writing of a new header must be done in binary mode to avoid */
@@ -659,7 +659,7 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
sprintf(g->Message, MSG(BIN_MODE_FAIL), strerror(errno));
return true;
} // endif setmode
-#endif // __WIN__
+#endif // _WIN32
/************************************************************************/
/* If this is a new file, the header must be generated. */
diff --git a/storage/connect/filamfix.cpp b/storage/connect/filamfix.cpp
index 433dd71cd0c..1b1cb7ca3f1 100644
--- a/storage/connect/filamfix.cpp
+++ b/storage/connect/filamfix.cpp
@@ -17,7 +17,7 @@
/* Include relevant sections of the System header files. */
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <io.h>
#include <fcntl.h>
#include <errno.h>
@@ -25,7 +25,7 @@
#define __MFC_COMPAT__ // To define min/max as macro
#endif // __BORLANDC__
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
#if defined(UNIX)
#include <errno.h>
#include <unistd.h>
@@ -34,7 +34,7 @@
#endif // !UNIX
#include <sys/stat.h>
#include <fcntl.h>
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Include application header files: */
@@ -338,7 +338,7 @@ int FIXFAM::ReadBuffer(PGLOBAL g)
} else if (feof(Stream)) {
rc = RC_EF;
} else {
-#if defined(__WIN__)
+#if defined(_WIN32)
sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL));
#else
sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno));
@@ -678,7 +678,7 @@ BGXFAM::BGXFAM(PBGXFAM txfp) : FIXFAM(txfp)
/***********************************************************************/
bool BGXFAM::BigSeek(PGLOBAL g, HANDLE h, BIGINT pos, int org)
{
-#if defined(__WIN__)
+#if defined(_WIN32)
char buf[256];
DWORD drc;
LARGE_INTEGER of;
@@ -694,14 +694,14 @@ bool BGXFAM::BigSeek(PGLOBAL g, HANDLE h, BIGINT pos, int org)
sprintf(g->Message, MSG(SFP_ERROR), buf);
return true;
} // endif
-#else // !__WIN__
+#else // !_WIN32
if (lseek64(h, pos, org) < 0) {
// sprintf(g->Message, MSG(ERROR_IN_LSK), errno);
sprintf(g->Message, "lseek64: %s", strerror(errno));
printf("%s\n", g->Message);
return true;
} // endif
-#endif // !__WIN__
+#endif // !_WIN32
return false;
} // end of BigSeek
@@ -714,7 +714,7 @@ int BGXFAM::BigRead(PGLOBAL g __attribute__((unused)),
{
int rc;
-#if defined(__WIN__)
+#if defined(_WIN32)
DWORD nbr, drc, len = (DWORD)req;
bool brc = ReadFile(h, inbuf, len, &nbr, NULL);
@@ -736,12 +736,12 @@ int BGXFAM::BigRead(PGLOBAL g __attribute__((unused)),
rc = -1;
} else
rc = (int)nbr;
-#else // !__WIN__
+#else // !_WIN32
size_t len = (size_t)req;
ssize_t nbr = read(h, inbuf, len);
rc = (int)nbr;
-#endif // !__WIN__
+#endif // !_WIN32
return rc;
} // end of BigRead
@@ -753,7 +753,7 @@ bool BGXFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req)
{
bool rc = false;
-#if defined(__WIN__)
+#if defined(_WIN32)
DWORD nbw, drc, len = (DWORD)req;
bool brc = WriteFile(h, inbuf, len, &nbw, NULL);
@@ -781,7 +781,7 @@ bool BGXFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req)
rc = true;
} // endif brc || nbw
-#else // !__WIN__
+#else // !_WIN32
size_t len = (size_t)req;
ssize_t nbw = write(h, inbuf, len);
@@ -796,7 +796,7 @@ bool BGXFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req)
rc = true;
} // endif nbr
-#endif // !__WIN__
+#endif // !_WIN32
return rc;
} // end of BigWrite
@@ -831,7 +831,7 @@ bool BGXFAM::OpenTableFile(PGLOBAL g)
if (trace(1))
htrc("OpenTableFile: filename=%s mode=%d\n", filename, mode);
-#if defined(__WIN__)
+#if defined(_WIN32)
DWORD rc, access, creation, share = 0;
/*********************************************************************/
@@ -989,7 +989,7 @@ int BGXFAM::Cardinality(PGLOBAL g)
PlugSetPath(filename, To_File, Tdbp->GetPath());
-#if defined(__WIN__) // OB
+#if defined(_WIN32) // OB
LARGE_INTEGER len;
DWORD rc = 0;
@@ -1348,7 +1348,7 @@ int BGXFAM::DeleteRecords(PGLOBAL g, int irc)
/*****************************************************************/
/* Remove extra records. */
/*****************************************************************/
-#if defined(__WIN__)
+#if defined(_WIN32)
if (BigSeek(g, Hfile, (BIGINT)Tpos * (BIGINT)Lrecl))
return RC_FX;
@@ -1358,12 +1358,12 @@ int BGXFAM::DeleteRecords(PGLOBAL g, int irc)
sprintf(g->Message, MSG(SETEOF_ERROR), drc);
return RC_FX;
} // endif error
-#else // !__WIN__
+#else // !_WIN32
if (ftruncate64(Hfile, (BIGINT)(Tpos * Lrecl))) {
sprintf(g->Message, MSG(TRUNCATE_ERROR), strerror(errno));
return RC_FX;
} // endif
-#endif // !__WIN__
+#endif // !_WIN32
} // endif UseTemp
@@ -1388,7 +1388,7 @@ bool BGXFAM::OpenTempFile(PGLOBAL g)
strcat(PlugRemoveType(tempname, tempname), ".t");
remove(tempname); // Be sure it does not exist yet
-#if defined(__WIN__)
+#if defined(_WIN32)
Tfile = CreateFile(tempname, GENERIC_WRITE, 0, NULL,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
@@ -1528,7 +1528,7 @@ void BGXFAM::CloseTableFile(PGLOBAL g, bool abort)
void BGXFAM::Rewind(void)
{
#if 0 // This is probably unuseful because file is accessed directly
-#if defined(__WIN__) //OB
+#if defined(_WIN32) //OB
SetFilePointer(Hfile, 0, NULL, FILE_BEGIN);
#else // UNIX
lseek64(Hfile, 0, SEEK_SET);
diff --git a/storage/connect/filamgz.cpp b/storage/connect/filamgz.cpp
index 6c960ab86de..1fe632b0bcf 100644
--- a/storage/connect/filamgz.cpp
+++ b/storage/connect/filamgz.cpp
@@ -17,21 +17,21 @@
/* Include relevant MariaDB header file. */
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <io.h>
#include <fcntl.h>
#if defined(__BORLANDC__)
#define __MFC_COMPAT__ // To define min/max as macro
#endif
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
#if defined(UNIX)
#include <errno.h>
#else // !UNIX
#include <io.h>
#endif
#include <fcntl.h>
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Include application header files: */
@@ -89,11 +89,11 @@ int GZFAM::Zerror(PGLOBAL g)
strcpy(g->Message, gzerror(Zfile, &errnum));
if (errnum == Z_ERRNO)
-#if defined(__WIN__)
+#if defined(_WIN32)
sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(NULL));
-#else // !__WIN__
+#else // !_WIN32
sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno));
-#endif // !__WIN__
+#endif // !_WIN32
return (errnum == Z_STREAM_END) ? RC_EF : RC_FX;
} // end of Zerror
@@ -764,9 +764,9 @@ bool GZXFAM::AllocateBuffer(PGLOBAL g)
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__)
+#if defined(_WIN32)
To_Buf[len - 2] = '\r';
-#endif // __WIN__
+#endif // _WIN32
To_Buf[len - 1] = '\n';
} // endfor len
diff --git a/storage/connect/filamtxt.cpp b/storage/connect/filamtxt.cpp
index 84eab272cc5..393ca360df9 100644
--- a/storage/connect/filamtxt.cpp
+++ b/storage/connect/filamtxt.cpp
@@ -17,7 +17,7 @@
/* Include relevant sections of the System header files. */
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <io.h>
#include <fcntl.h>
#include <errno.h>
@@ -25,7 +25,7 @@
#define __MFC_COMPAT__ // To define min/max as macro
#endif // __BORLANDC__
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
#if defined(UNIX) || defined(UNIV_LINUX)
#include <errno.h>
#include <unistd.h>
@@ -36,7 +36,7 @@
#include <io.h>
#endif // !UNIX
#include <fcntl.h>
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Include application header files: */
@@ -82,7 +82,7 @@ TXTFAM::TXTFAM(PDOSDEF tdp)
To_File = NULL;
Lrecl = 0;
Eof = false;
-#if defined(__WIN__)
+#if defined(_WIN32)
Ending = 2;
#else
Ending = 1;
@@ -731,7 +731,7 @@ int DOSFAM::SkipRecord(PGLOBAL g, bool header)
if (feof(Stream))
return RC_EF;
-#if defined(__WIN__)
+#if defined(_WIN32)
sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL));
#else
sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(0));
@@ -814,7 +814,7 @@ int DOSFAM::ReadBuffer(PGLOBAL g)
if (trace(2))
htrc(" Read: To_Buf=%p p=%c\n", To_Buf, p);
-#if defined(__WIN__)
+#if defined(_WIN32)
if (Bin) {
// Data file is read in binary so CRLF remains
#else
@@ -848,7 +848,7 @@ int DOSFAM::ReadBuffer(PGLOBAL g)
} else if (feof(Stream)) {
rc = RC_EF;
} else {
-#if defined(__WIN__)
+#if defined(_WIN32)
sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL));
#else
sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(0));
@@ -1043,7 +1043,7 @@ int DOSFAM::DeleteRecords(PGLOBAL g, int irc)
/*****************************************************************/
/* Remove extra records. */
/*****************************************************************/
-#if defined(__WIN__)
+#if defined(_WIN32)
if (chsize(h, Tpos)) {
sprintf(g->Message, MSG(CHSIZE_ERROR), strerror(errno));
close(h);
@@ -1482,7 +1482,7 @@ int BLKFAM::ReadBuffer(PGLOBAL g)
} else if (feof(Stream)) {
rc = RC_EF;
} else {
-#if defined(__WIN__)
+#if defined(_WIN32)
sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL));
#else
sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno));
@@ -1568,11 +1568,11 @@ int BLKFAM::WriteBuffer(PGLOBAL g)
Spos = GetNextPos(); // New start position
// Prepare the output buffer
-#if defined(__WIN__)
+#if defined(_WIN32)
crlf = "\r\n";
#else
crlf = "\n";
-#endif // __WIN__
+#endif // _WIN32
strcat(strcpy(OutBuf, Tdbp->GetLine()), crlf);
len = strlen(OutBuf);
} else {
@@ -1872,7 +1872,7 @@ int BINFAM::ReadBuffer(PGLOBAL g)
} else if (feof(Stream)) {
rc = RC_EF;
} else {
-#if defined(__WIN__)
+#if defined(_WIN32)
sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL));
#else
sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(0));
@@ -2066,7 +2066,7 @@ int DOSFAM::DeleteRecords(PGLOBAL g, int irc)
/*****************************************************************/
/* Remove extra records. */
/*****************************************************************/
-#if defined(__WIN__)
+#if defined(_WIN32)
if (chsize(h, Tpos)) {
sprintf(g->Message, MSG(CHSIZE_ERROR), strerror(errno));
close(h);
diff --git a/storage/connect/filamvct.cpp b/storage/connect/filamvct.cpp
index 97f29dddc7e..fd3ce79c762 100644
--- a/storage/connect/filamvct.cpp
+++ b/storage/connect/filamvct.cpp
@@ -21,7 +21,7 @@
/* Include relevant MariaDB header file. */
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <io.h>
#include <fcntl.h>
#if defined(__BORLANDC__)
@@ -29,7 +29,7 @@
#endif // __BORLAND__
//#include <windows.h>
#include <sys/stat.h>
-#else // !__WIN__
+#else // !_WIN32
#if defined(UNIX)
#include <sys/types.h>
#include <sys/stat.h>
@@ -40,7 +40,7 @@
#include <io.h>
#endif // !UNIX
#include <fcntl.h>
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Include application header files: */
@@ -372,11 +372,11 @@ bool VCTFAM::MakeEmptyFile(PGLOBAL g, PCSZ fn)
int h, n;
PlugSetPath(filename, fn, Tdbp->GetPath());
-#if defined(__WIN__)
+#if defined(_WIN32)
h= global_open(g, MSGID_OPEN_EMPTY_FILE, filename, _O_CREAT | _O_WRONLY, S_IREAD | S_IWRITE);
-#else // !__WIN__
+#else // !_WIN32
h= global_open(g, MSGID_OPEN_EMPTY_FILE, filename, O_CREAT | O_WRONLY, S_IREAD | S_IWRITE);
-#endif // !__WIN__
+#endif // !_WIN32
if (h == -1)
return true;
@@ -1673,7 +1673,7 @@ int VCMFAM::DeleteRecords(PGLOBAL g, int irc)
// Remove extra blocks
n = Block * Blksize;
-#if defined(__WIN__)
+#if defined(_WIN32)
DWORD drc = SetFilePointer(fp->Handle, n, NULL, FILE_BEGIN);
if (drc == 0xFFFFFFFF) {
@@ -2580,11 +2580,11 @@ bool VECFAM::ReadBlock(PGLOBAL g, PVCTCOL colp)
char fn[_MAX_PATH];
sprintf(fn, Colfn, colp->Index);
-#if defined(__WIN__)
+#if defined(_WIN32)
if (feof(Streams[i]))
-#else // !__WIN__
+#else // !_WIN32
if (errno == NO_ERROR)
-#endif // !__WIN__
+#endif // !_WIN32
sprintf(g->Message, MSG(BAD_READ_NUMBER), (int) n, fn);
else
sprintf(g->Message, MSG(READ_ERROR),
@@ -2980,7 +2980,7 @@ int VMPFAM::DeleteRecords(PGLOBAL g, int irc)
/*****************************************************************/
n = Tpos * Clens[i];
-#if defined(__WIN__)
+#if defined(_WIN32)
DWORD drc = SetFilePointer(fp->Handle, n, NULL, FILE_BEGIN);
if (drc == 0xFFFFFFFF) {
@@ -3060,7 +3060,7 @@ BGVFAM::BGVFAM(PBGVFAM txfp) : VCTFAM(txfp)
/***********************************************************************/
bool BGVFAM::BigSeek(PGLOBAL g, HANDLE h, BIGINT pos, bool b)
{
-#if defined(__WIN__)
+#if defined(_WIN32)
char buf[256];
DWORD drc, m = (b) ? FILE_END : FILE_BEGIN;
LARGE_INTEGER of;
@@ -3076,12 +3076,12 @@ bool BGVFAM::BigSeek(PGLOBAL g, HANDLE h, BIGINT pos, bool b)
sprintf(g->Message, MSG(SFP_ERROR), buf);
return true;
} // endif
-#else // !__WIN__
+#else // !_WIN32
if (lseek64(h, pos, (b) ? SEEK_END : SEEK_SET) < 0) {
sprintf(g->Message, MSG(ERROR_IN_LSK), errno);
return true;
} // endif
-#endif // !__WIN__
+#endif // !_WIN32
return false;
} // end of BigSeek
@@ -3093,7 +3093,7 @@ bool BGVFAM::BigRead(PGLOBAL g, HANDLE h, void *inbuf, int req)
{
bool rc = false;
-#if defined(__WIN__)
+#if defined(_WIN32)
DWORD nbr, drc, len = (DWORD)req;
bool brc = ReadFile(h, inbuf, len, &nbr, NULL);
@@ -3119,7 +3119,7 @@ bool BGVFAM::BigRead(PGLOBAL g, HANDLE h, void *inbuf, int req)
rc = true;
} // endif brc || nbr
-#else // !__WIN__
+#else // !_WIN32
size_t len = (size_t)req;
ssize_t nbr = read(h, inbuf, len);
@@ -3134,7 +3134,7 @@ bool BGVFAM::BigRead(PGLOBAL g, HANDLE h, void *inbuf, int req)
rc = true;
} // endif nbr
-#endif // !__WIN__
+#endif // !_WIN32
return rc;
} // end of BigRead
@@ -3146,7 +3146,7 @@ bool BGVFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req)
{
bool rc = false;
-#if defined(__WIN__)
+#if defined(_WIN32)
DWORD nbw, drc, len = (DWORD)req;
bool brc = WriteFile(h, inbuf, len, &nbw, NULL);
@@ -3174,7 +3174,7 @@ bool BGVFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req)
rc = true;
} // endif brc || nbw
-#else // !__WIN__
+#else // !_WIN32
size_t len = (size_t)req;
ssize_t nbw = write(h, inbuf, len);
@@ -3189,7 +3189,7 @@ bool BGVFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req)
rc = true;
} // endif nbr
-#endif // !__WIN__
+#endif // !_WIN32
return rc;
} // end of BigWrite
@@ -3215,7 +3215,7 @@ int BGVFAM::GetBlockInfo(PGLOBAL g)
if (Header == 2)
strcat(PlugRemoveType(filename, filename), ".blk");
-#if defined(__WIN__)
+#if defined(_WIN32)
LARGE_INTEGER len;
h = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
@@ -3227,11 +3227,11 @@ int BGVFAM::GetBlockInfo(PGLOBAL g)
} // endif h
if (h == INVALID_HANDLE_VALUE || !len.QuadPart) {
-#else // !__WIN__
+#else // !_WIN32
h = open64(filename, O_RDONLY, 0);
if (h == INVALID_HANDLE_VALUE || !_filelength(h)) {
-#endif // !__WIN__
+#endif // !_WIN32
// Consider this is a void table
if (trace(1))
htrc("Void table h=%d\n", h);
@@ -3292,17 +3292,17 @@ bool BGVFAM::SetBlockInfo(PGLOBAL g)
strcat(PlugRemoveType(filename, filename), ".blk");
if (h == INVALID_HANDLE_VALUE) {
-#if defined(__WIN__)
+#if defined(_WIN32)
DWORD creation = (b) ? OPEN_EXISTING : TRUNCATE_EXISTING;
h = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, 0,
NULL, creation, FILE_ATTRIBUTE_NORMAL, NULL);
-#else // !__WIN__
+#else // !_WIN32
int oflag = (b) ? O_RDWR : O_RDWR | O_TRUNC;
h = open64(filename, oflag, 0);
-#endif // !__WIN__
+#endif // !_WIN32
if (h == INVALID_HANDLE_VALUE) {
sprintf(g->Message, "Error opening header file %s", filename);
@@ -3340,7 +3340,7 @@ bool BGVFAM::MakeEmptyFile(PGLOBAL g, PCSZ fn)
PlugSetPath(filename, fn, Tdbp->GetPath());
-#if defined(__WIN__)
+#if defined(_WIN32)
PCSZ p;
DWORD rc;
bool brc;
@@ -3392,7 +3392,7 @@ bool BGVFAM::MakeEmptyFile(PGLOBAL g, PCSZ fn)
CloseHandle(h);
return true;
-#else // !__WIN__
+#else // !_WIN32
int h;
BIGINT pos;
@@ -3421,7 +3421,7 @@ bool BGVFAM::MakeEmptyFile(PGLOBAL g, PCSZ fn)
sprintf(g->Message, MSG(MAKE_EMPTY_FILE), To_File, strerror(errno));
close(h);
return true;
-#endif // !__WIN__
+#endif // !_WIN32
} // end of MakeEmptyFile
/***********************************************************************/
@@ -3452,7 +3452,7 @@ bool BGVFAM::OpenTableFile(PGLOBAL g)
htrc("OpenTableFile: filename=%s mode=%d Last=%d\n",
filename, mode, Last);
-#if defined(__WIN__)
+#if defined(_WIN32)
DWORD access, creation, share = 0, rc = 0;
/*********************************************************************/
@@ -3780,7 +3780,7 @@ int BGVFAM::WriteBuffer(PGLOBAL g)
if (!Closing && !MaxBlk) {
// Close the VCT file and reopen it in mode Insert
-//#if defined(__WIN__) //OB
+//#if defined(_WIN32) //OB
// CloseHandle(Hfile);
//#else // UNIX
// close(Hfile);
@@ -3907,7 +3907,7 @@ int BGVFAM::DeleteRecords(PGLOBAL g, int irc)
/***************************************************************/
/* Remove extra records. */
/***************************************************************/
-#if defined(__WIN__)
+#if defined(_WIN32)
BIGINT pos = (BIGINT)Block * (BIGINT)Blksize;
if (BigSeek(g, Hfile, pos))
@@ -3919,12 +3919,12 @@ int BGVFAM::DeleteRecords(PGLOBAL g, int irc)
sprintf(g->Message, MSG(SETEOF_ERROR), drc);
return RC_FX;
} // endif error
-#else // !__WIN__
+#else // !_WIN32
if (ftruncate64(Hfile, (BIGINT)(Tpos * Lrecl))) {
sprintf(g->Message, MSG(TRUNCATE_ERROR), strerror(errno));
return RC_FX;
} // endif
-#endif // !__WIN__
+#endif // !_WIN32
} else // MaxBlk
// Clean the unused space in the file, this is required when
// inserting again with a partial column list.
@@ -3961,7 +3961,7 @@ bool BGVFAM::OpenTempFile(PGLOBAL g)
else if (MakeEmptyFile(g, tempname))
return true;
-#if defined(__WIN__)
+#if defined(_WIN32)
DWORD access = (MaxBlk) ? OPEN_EXISTING : CREATE_NEW;
Tfile = CreateFile(tempname, GENERIC_WRITE, 0, NULL,
@@ -4233,7 +4233,7 @@ void BGVFAM::Rewind(void)
CurNum = Nrec - 1;
#if 0 // This is probably unuseful as the file is directly accessed
-#if defined(__WIN__) //OB
+#if defined(_WIN32) //OB
SetFilePointer(Hfile, 0, NULL, FILE_BEGIN);
#else // UNIX
lseek64(Hfile, 0, SEEK_SET);
diff --git a/storage/connect/filamzip.cpp b/storage/connect/filamzip.cpp
index 79599382693..4e9d008b455 100644
--- a/storage/connect/filamzip.cpp
+++ b/storage/connect/filamzip.cpp
@@ -17,7 +17,7 @@
/* Include relevant sections of the System header files. */
/***********************************************************************/
#include "my_global.h"
-#if !defined(__WIN__)
+#if !defined(_WIN32)
#if defined(UNIX)
#include <fnmatch.h>
#include <errno.h>
@@ -27,7 +27,7 @@
#include <io.h>
#endif // !UNIX
#include <fcntl.h>
-#endif // !__WIN__
+#endif // !_WIN32
#include <time.h>
/***********************************************************************/
@@ -153,7 +153,7 @@ static bool ZipFiles(PGLOBAL g, ZIPUTIL *zutp, PCSZ pat, char *buf)
/*********************************************************************/
strcpy(filename, pat);
-#if defined(__WIN__)
+#if defined(_WIN32)
int rc;
char drive[_MAX_DRIVE], direc[_MAX_DIR];
WIN32_FIND_DATA FileData;
@@ -210,7 +210,7 @@ static bool ZipFiles(PGLOBAL g, ZIPUTIL *zutp, PCSZ pat, char *buf)
return true;
} // endif FindClose
-#else // !__WIN__
+#else // !_WIN32
struct stat fileinfo;
char fn[FN_REFLEN], direc[FN_REFLEN], pattern[FN_HEADLEN], ftype[FN_EXTLEN];
DIR *dir;
@@ -251,7 +251,7 @@ static bool ZipFiles(PGLOBAL g, ZIPUTIL *zutp, PCSZ pat, char *buf)
// Close the dir handle.
closedir(dir);
-#endif // !__WIN__
+#endif // !_WIN32
return false;
} // end of ZipFiles
@@ -275,9 +275,9 @@ bool ZipLoadFile(PGLOBAL g, PCSZ zfn, PCSZ fn, PCSZ entry, bool append, bool mul
if (!entry) { // entry defaults to the file name
char* p = strrchr((char*)fn, '/');
-#if defined(__WIN__)
+#if defined(_WIN32)
if (!p) p = strrchr((char*)fn, '\\');
-#endif // __WIN__
+#endif // _WIN32
entp = (p) ? p + 1 : entry;
} else
entp = entry;
@@ -467,7 +467,7 @@ UNZIPUTL::UNZIPUTL(PCSZ tgt, PCSZ pw, bool mul)
memset(fn, 0, sizeof(fn));
// Init the case mapping table.
-#if defined(__WIN__)
+#if defined(_WIN32)
for (int i = 0; i < 256; ++i) mapCaseTable[i] = toupper(i);
#else
for (int i = 0; i < 256; ++i) mapCaseTable[i] = i;
@@ -487,7 +487,7 @@ UNZIPUTL::UNZIPUTL(PDOSDEF tdp)
memset(fn, 0, sizeof(fn));
// Init the case mapping table.
-#if defined(__WIN__)
+#if defined(_WIN32)
for (int i = 0; i < 256; ++i) mapCaseTable[i] = toupper(i);
#else
for (int i = 0; i < 256; ++i) mapCaseTable[i] = i;
diff --git a/storage/connect/filter.cpp b/storage/connect/filter.cpp
index d776b403917..fd6a6a68de0 100644
--- a/storage/connect/filter.cpp
+++ b/storage/connect/filter.cpp
@@ -13,13 +13,13 @@
//#include "sql_class.h"
//#include "sql_time.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
diff --git a/storage/connect/filter.h b/storage/connect/filter.h
index c6ab8fddd35..12ac3a169c1 100644
--- a/storage/connect/filter.h
+++ b/storage/connect/filter.h
@@ -106,7 +106,7 @@ class FILTERX : public FILTER {
// Fake operator new used to change a filter into a derived filter
void * operator new(size_t, PFIL filp) {return filp;}
-#if defined(__WIN__)
+#if defined(_WIN32)
// Avoid warning C4291 by defining a matching dummy delete operator
void operator delete(void *, PFIL) {}
#else
diff --git a/storage/connect/fmdlex.c b/storage/connect/fmdlex.c
index 28b71b95e4d..1bca2d4ec18 100644
--- a/storage/connect/fmdlex.c
+++ b/storage/connect/fmdlex.c
@@ -22,12 +22,12 @@
*/
#define FLEX_SCANNER
-#ifdef __WIN__
+#ifdef _WIN32
#define __STDC__ 1
#define isatty _isatty
#endif
#include <stdio.h>
-#ifndef __WIN__
+#ifndef _WIN32
#include <unistd.h>
#endif
diff --git a/storage/connect/global.h b/storage/connect/global.h
index 8774285e54b..eb3d4106477 100644
--- a/storage/connect/global.h
+++ b/storage/connect/global.h
@@ -14,11 +14,11 @@
#include <time.h> /* time_t type declaration */
#include <setjmp.h> /* Long jump declarations */
-#if defined(__WIN__) && !defined(NOEX)
+#if defined(_WIN32) && !defined(NOEX)
#define DllExport __declspec( dllexport )
-#else // !__WIN__
+#else // !_WIN32
#define DllExport
-#endif // !__WIN__
+#endif // !_WIN32
#if defined(DOMDOC_SUPPORT) || defined(LIBXML2_SUPPORT)
#define XML_SUPPORT 1
@@ -43,11 +43,11 @@
#define STEP(I) MSG_##I
#endif // !XMSG and !NEWMSG
-#if defined(__WIN__)
+#if defined(_WIN32)
#define CRLF 2
-#else // !__WIN__
+#else // !_WIN32
#define CRLF 1
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Define access to the thread based trace value. */
@@ -204,9 +204,9 @@ DllExport char *PlugReadMessage(PGLOBAL, int, char *);
#elif defined(NEWMSG)
DllExport char *PlugGetMessage(PGLOBAL, int);
#endif // XMSG || NEWMSG
-#if defined(__WIN__)
+#if defined(_WIN32)
DllExport short GetLineLength(PGLOBAL); // Console line length
-#endif // __WIN__
+#endif // _WIN32
DllExport PGLOBAL PlugInit(LPCSTR, size_t); // Plug global initialization
DllExport PGLOBAL PlugExit(PGLOBAL); // Plug global termination
DllExport LPSTR PlugRemoveType(LPSTR, LPCSTR);
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 7d9c7517159..c1262b9630a 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -139,10 +139,10 @@
//#include "reldef.h"
#include "tabcol.h"
#include "xindex.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <io.h>
#include "tabwmi.h"
-#endif // __WIN__
+#endif // _WIN32
#include "connect.h"
#include "user_connect.h"
#include "ha_connect.h"
@@ -167,16 +167,16 @@
#define SZCONV 1024 // Default converted text size
#define SZWORK 67108864 // Default work area size 64M
#define SZWMIN 4194304 // Minimum work area size 4M
-#define JSONMAX 10 // JSON Default max grp size
+#define JSONMAX 50 // JSON Default max grp size
extern "C" {
- char version[]= "Version 1.07.0002 March 22, 2021";
-#if defined(__WIN__)
- char compver[]= "Version 1.07.0002 " __DATE__ " " __TIME__;
+ char version[]= "Version 1.07.0003 June 06, 2021";
+#if defined(_WIN32)
+ char compver[]= "Version 1.07.0003 " __DATE__ " " __TIME__;
char slash= '\\';
-#else // !__WIN__
+#else // !_WIN32
char slash= '/';
-#endif // !__WIN__
+#endif // !_WIN32
} // extern "C"
#if MYSQL_VERSION_ID > 100200
@@ -288,15 +288,14 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
/****************************************************************************/
static char *strz(PGLOBAL g, LEX_CSTRING &ls)
{
- char *str= (char*)PlugSubAlloc(g, NULL, ls.length + 1);
-
- /*
- ls.str can be NULL, for example when called with
- create_info->connect_string
- */
- if (ls.str)
+ char* str= NULL;
+
+ if (ls.str) {
+ str= (char*)PlugSubAlloc(g, NULL, ls.length + 1);
memcpy(str, ls.str, ls.length);
- str[ls.length]= 0;
+ str[ls.length] = 0;
+ } // endif str
+
return str;
} // end of strz
@@ -511,7 +510,7 @@ char *GetJsonNull(void)
int GetDefaultDepth(void) {return THDVAR(current_thd, default_depth);}
int GetDefaultPrec(void) {return THDVAR(current_thd, default_prec);}
uint GetJsonGrpSize(void)
- {return connect_hton ? THDVAR(current_thd, json_grp_size) : 10;}
+ {return connect_hton ? THDVAR(current_thd, json_grp_size) : 50;}
size_t GetWorkSize(void) {return (size_t)THDVAR(current_thd, work_size);}
void SetWorkSize(size_t)
{
@@ -805,11 +804,11 @@ static int connect_init_func(void *p)
}
#endif // 0 (LINUX)
-#if defined(__WIN__)
+#if defined(_WIN32)
sql_print_information("CONNECT: %s", compver);
-#else // !__WIN__
+#else // !_WIN32
sql_print_information("CONNECT: %s", version);
-#endif // !__WIN__
+#endif // !_WIN32
pthread_mutex_init(&parmut, NULL);
pthread_mutex_init(&usrmut, NULL);
pthread_mutex_init(&tblmut, NULL);
@@ -868,9 +867,9 @@ int connect_done_func(void *)
JAVAConn::ResetJVM();
#endif // JAVA_SUPPORT
-#if !defined(__WIN__)
+#if !defined(_WIN32)
PROFILE_End();
-#endif // !__WIN__
+#endif // !_WIN32
pthread_mutex_lock(&usrmut);
for (pc= user_connect::to_users; pc; pc= pn) {
@@ -944,11 +943,11 @@ ha_connect::ha_connect(handlerton *hton, TABLE_SHARE *table_arg)
xp= (table) ? GetUser(ha_thd(), NULL) : NULL;
if (xp)
xp->SetHandler(this);
-#if defined(__WIN__)
+#if defined(_WIN32)
datapath= ".\\";
-#else // !__WIN__
+#else // !_WIN32
datapath= "./";
-#endif // !__WIN__
+#endif // !_WIN32
tdbp= NULL;
sdvalin1= sdvalin2= sdvalin3= sdvalin4= NULL;
sdvalout= NULL;
@@ -4550,11 +4549,11 @@ static bool checkPrivileges(THD *thd, TABTYPE type, PTOS options,
strcpy(dbpath, mysql_real_data_home);
if (db)
-#if defined(__WIN__)
+#if defined(_WIN32)
strcat(strcat(dbpath, db), "\\");
-#else // !__WIN__
+#else // !_WIN32
strcat(strcat(dbpath, db), "/");
-#endif // !__WIN__
+#endif // !_WIN32
(void)fn_format(path, options->filename, dbpath, "",
MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
@@ -5475,14 +5474,13 @@ static bool add_field(String* sql, TABTYPE ttp, const char* field_name, int typ,
} // endif rem
if (fmt && *fmt) {
- switch (ttp) {
- case TAB_JSON: error |= sql->append(" JPATH='"); break;
-#if defined(BSON_SUPPORT)
- case TAB_BSON: error |= sql->append(" JPATH='"); break;
-#endif // BSON_SUPPORT
- case TAB_XML: error |= sql->append(" XPATH='"); break;
- default: error |= sql->append(" FIELD_FORMAT='");
- } // endswitch ttp
+ switch (ttp) {
+ case TAB_MONGO:
+ case TAB_BSON:
+ case TAB_JSON: error |= sql->append(" JPATH='"); break;
+ case TAB_XML: error |= sql->append(" XPATH='"); break;
+ default: error |= sql->append(" FIELD_FORMAT='");
+ } // endswitch ttp
error |= sql->append_for_single_quote(fmt, strlen(fmt));
error |= sql->append("'");
@@ -5613,9 +5611,9 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
PCSZ user, fn, db, host, pwd, sep, tbl, src;
PCSZ col, ocl, rnk, pic, fcl, skc, zfn;
char *tab, *dsn, *shm, *dpath, *url;
-#if defined(__WIN__)
+#if defined(_WIN32)
PCSZ nsp= NULL, cls= NULL;
-#endif // __WIN__
+#endif // _WIN32
//int hdr, mxe;
int port= 0, mxr __attribute__((unused)) = 0, rc= 0, mul= 0;
//PCSZ tabtyp= NULL;
@@ -5631,7 +5629,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#endif // JAVA_SUPPORT
uint tm, fnc= FNC_NO, supfnc= (FNC_NO | FNC_COL);
bool bif, ok= false, dbf= false;
- TABTYPE ttp= TAB_UNDEF;
+ TABTYPE ttp= TAB_UNDEF, ttr=TAB_UNDEF;
PQRYRES qrp= NULL;
PCOLRES crp;
PCONNECT xp= NULL;
@@ -5674,10 +5672,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
skc= GetListOption(g, "skipcol", topt->oplist, NULL);
rnk= GetListOption(g, "rankcol", topt->oplist, NULL);
pwd= GetListOption(g, "password", topt->oplist);
-#if defined(__WIN__)
+#if defined(_WIN32)
nsp= GetListOption(g, "namespace", topt->oplist);
cls= GetListOption(g, "class", topt->oplist);
-#endif // __WIN__
+#endif // _WIN32
port= atoi(GetListOption(g, "port", topt->oplist, "0"));
#if defined(ODBC_SUPPORT)
// tabtyp= GetListOption(g, "Tabtype", topt->oplist, NULL);
@@ -5711,7 +5709,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
topt->type= (src) ? "MYSQL" : (tab) ? "PROXY" : "DOS";
ttp= GetTypeID(topt->type);
sprintf(g->Message, "No table_type. Was set to %s", topt->type);
- push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
+ push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, 0, g->Message);
} else if (ttp == TAB_NIY) {
sprintf(g->Message, "Unsupported table type %s", topt->type);
rc= HA_ERR_INTERNAL_ERROR;
@@ -5719,13 +5717,13 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#if defined(REST_SUPPORT)
} else if (topt->http) {
if (ttp == TAB_UNDEF) {
- topt->type = "JSON";
- ttp= GetTypeID(topt->type);
- sprintf(g->Message, "No table_type. Was set to %s", topt->type);
- push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
- } // endif ttp
+ ttr= TAB_JSON;
+ strcpy(g->Message, "No table_type. Was set to JSON");
+ push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, 0, g->Message);
+ } else
+ ttr= ttp;
- switch (ttp) {
+ switch (ttr) {
case TAB_JSON:
#if defined(BSON_SUPPORT)
case TAB_BSON:
@@ -5908,11 +5906,11 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
ok= false;
break;
-#if defined(__WIN__)
+#if defined(_WIN32)
case TAB_WMI:
ok= true;
break;
-#endif // __WIN__
+#endif // _WIN32
case TAB_PIVOT:
supfnc= FNC_NO;
// fall through
@@ -5945,9 +5943,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
if (!fn && !zfn && !mul && !dsn)
sprintf(g->Message, "Missing %s file name", topt->type);
- else
- ok= true;
+ else if (dsn && !topt->tabname)
+ topt->tabname= tab;
+ ok= true;
break;
#if defined(JAVA_SUPPORT)
case TAB_MONGO:
@@ -5960,7 +5959,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#if defined(REST_SUPPORT)
case TAB_REST:
if (!topt->http)
- sprintf(g->Message, "Missing %s HTTP address", topt->type);
+ strcpy(g->Message, "Missing REST HTTP option");
else
ok = true;
@@ -6076,11 +6075,11 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
case TAB_CSV:
qrp= CSVColumns(g, dpath, topt, fnc == FNC_COL);
break;
-#if defined(__WIN__)
+#if defined(_WIN32)
case TAB_WMI:
qrp= WMIColumns(g, nsp, cls, fnc == FNC_COL);
break;
-#endif // __WIN__
+#endif // _WIN32
case TAB_PRX:
case TAB_TBL:
case TAB_XCL:
@@ -6180,7 +6179,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
// Restore language type
if (ttp == TAB_REST)
- ttp = GetTypeID(topt->type);
+ ttp = ttr;
for (i= 0; !rc && i < qrp->Nblin; i++) {
typ= len= prec= dec= flg= 0;
@@ -6610,11 +6609,11 @@ int ha_connect::create(const char *name, TABLE *table_arg,
// on Windows and libxml2 otherwise
switch (toupper(*xsup)) {
case '*':
-#if defined(__WIN__)
+#if defined(_WIN32)
dom= true;
-#else // !__WIN__
+#else // !_WIN32
dom= false;
-#endif // !__WIN__
+#endif // !_WIN32
break;
case 'M':
case 'D':
@@ -6997,11 +6996,11 @@ bool ha_connect::FileExists(const char *fn, bool bf)
int n;
struct stat info;
-#if defined(__WIN__)
+#if defined(_WIN32)
s= "\\";
-#else // !__WIN__
+#else // !_WIN32
s= "/";
-#endif // !__WIN__
+#endif // !_WIN32
if (IsPartitioned()) {
sprintf(tfn, fn, GetPartName());
@@ -7518,7 +7517,7 @@ maria_declare_plugin(connect)
0x0107, /* version number (1.07) */
NULL, /* status variables */
connect_system_variables, /* system variables */
- "1.07.0002", /* string version */
+ "1.07.0003", /* string version */
MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
}
maria_declare_plugin_end;
diff --git a/storage/connect/javaconn.cpp b/storage/connect/javaconn.cpp
index af5986dad81..364d49f8e7c 100644
--- a/storage/connect/javaconn.cpp
+++ b/storage/connect/javaconn.cpp
@@ -6,24 +6,24 @@
/* This file contains the JAVA connection classes functions. */
/***********************************************************************/
-#if defined(__WIN__)
+#if defined(_WIN32)
// This is needed for RegGetValue
#define _WINVER 0x0601
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0601
-#endif // __WIN__
+#endif // _WIN32
/***********************************************************************/
/* Include relevant MariaDB header file. */
/***********************************************************************/
#include <my_global.h>
//#include <m_string.h>
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <direct.h> // for getcwd
#if defined(__BORLANDC__)
#define __MFC_COMPAT__ // To define min/max as macro
#endif // __BORLANDC__
-#else // !__WIN__
+#else // !_WIN32
#if defined(UNIX)
#include <errno.h>
#else // !UNIX
@@ -31,7 +31,7 @@
#include <stdio.h>
#include <stdlib.h> // for getenv
#define NODW
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Required objects includes. */
@@ -47,9 +47,9 @@
#include "valblk.h"
#include "osutil.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
extern "C" HINSTANCE s_hModule; // Saved module handle
-#endif // __WIN__
+#endif // _WIN32
#define nullptr 0
//TYPCONV GetTypeConv();
@@ -57,6 +57,8 @@ extern "C" HINSTANCE s_hModule; // Saved module handle
extern char *JvmPath; // The connect_jvm_path global variable value
extern char *ClassPath; // The connect_class_path global variable value
+char *GetPluginDir(void);
+char *GetMessageDir(void);
char *GetJavaWrapper(void); // The connect_java_wrapper variable value
extern MYSQL_PLUGIN_IMPORT char lc_messages_dir[FN_REFLEN];
@@ -199,11 +201,11 @@ int JAVAConn::GetMaxValue(int n)
void JAVAConn::ResetJVM(void)
{
if (LibJvm) {
-#if defined(__WIN__)
+#if defined(_WIN32)
FreeLibrary((HMODULE)LibJvm);
-#else // !__WIN__
+#else // !_WIN32
dlclose(LibJvm);
-#endif // !__WIN__
+#endif // !_WIN32
LibJvm = NULL;
CreateJavaVM = NULL;
GetCreatedJavaVMs = NULL;
@@ -226,7 +228,7 @@ bool JAVAConn::GetJVM(PGLOBAL g)
if (!LibJvm) {
char soname[512];
-#if defined(__WIN__)
+#if defined(_WIN32)
for (ntry = 0; !LibJvm && ntry < 3; ntry++) {
if (!ntry && JvmPath) {
strcat(strcpy(soname, JvmPath), "\\jvm.dll");
@@ -294,7 +296,7 @@ bool JAVAConn::GetJVM(PGLOBAL g)
LibJvm = NULL;
#endif // _DEBUG
} // endif LibJvm
-#else // !__WIN__
+#else // !_WIN32
const char *error = NULL;
for (ntry = 0; !LibJvm && ntry < 2; ntry++) {
@@ -335,7 +337,7 @@ bool JAVAConn::GetJVM(PGLOBAL g)
LibJvm = NULL;
#endif // _DEBUG
} // endif LibJvm
-#endif // !__WIN__
+#endif // !_WIN32
} // endif LibJvm
@@ -377,7 +379,7 @@ bool JAVAConn::Open(PGLOBAL g)
char *cp = NULL;
char sep;
-#if defined(__WIN__)
+#if defined(_WIN32)
sep = ';';
#define N 1
//#define N 2
@@ -400,24 +402,17 @@ bool JAVAConn::Open(PGLOBAL g)
jpop->Append(ClassPath);
} // endif ClassPath
-#if 0
- // Java source will be compiled as a jar file installed in the mysql share dir
- jpop->Append(sep);
- jpop->Append(lc_messages_dir);
- jpop->Append("JdbcInterface.jar");
-#endif // 0
-
- // All wrappers are pre-compiled in JavaWrappers.jar in the mysql share dir
+ // All wrappers are pre-compiled in JavaWrappers.jar in the share dir
jpop->Append(sep);
- jpop->Append(lc_messages_dir);
+ jpop->Append(GetMessageDir());
jpop->Append("JavaWrappers.jar");
#if defined(MONGO_SUPPORT)
jpop->Append(sep);
- jpop->Append(lc_messages_dir);
+ jpop->Append(GetMessageDir());
jpop->Append("Mongo3.jar");
jpop->Append(sep);
- jpop->Append(lc_messages_dir);
+ jpop->Append(GetMessageDir());
jpop->Append("Mongo2.jar");
#endif // MONGO_SUPPORT
diff --git a/storage/connect/javaconn.h b/storage/connect/javaconn.h
index 73812f6ab3b..963b8c1a6ac 100644
--- a/storage/connect/javaconn.h
+++ b/storage/connect/javaconn.h
@@ -27,9 +27,9 @@
//efine MAX_CURSOR_NAME 18 // Max size of a cursor name
//efine DEFAULT_FIELD_TYPE 0 // TYPE_NULL
-#if !defined(__WIN__)
+#if !defined(_WIN32)
typedef unsigned char *PUCHAR;
-#endif // !__WIN__
+#endif // !_WIN32
enum JCATINFO {
JCAT_TAB = 1, // JDBC Tables
@@ -104,11 +104,11 @@ public:
protected:
// Members
-#if defined(__WIN__)
+#if defined(_WIN32)
static HANDLE LibJvm; // Handle to the jvm DLL
-#else // !__WIN__
+#else // !_WIN32
static void *LibJvm; // Handle for the jvm shared library
-#endif // !__WIN__
+#endif // !_WIN32
static CRTJVM CreateJavaVM;
static GETJVM GetCreatedJavaVMs;
#if defined(_DEBUG)
diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp
index 2cb75e0adc1..20918745316 100644
--- a/storage/connect/jdbconn.cpp
+++ b/storage/connect/jdbconn.cpp
@@ -6,19 +6,19 @@
/* This file contains the JDBC connection classes functions. */
/***********************************************************************/
-#if defined(__WIN__)
+#if defined(_WIN32)
// This is needed for RegGetValue
#define _WINVER 0x0601
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0601
-#endif // __WIN__
+#endif // _WIN32
/***********************************************************************/
/* Include relevant MariaDB header file. */
/***********************************************************************/
#include <my_global.h>
#include <m_string.h>
-#if defined(__WIN__)
+#if defined(_WIN32)
//nclude <io.h>
//nclude <fcntl.h>
#include <direct.h> // for getcwd
@@ -26,7 +26,7 @@
#define __MFC_COMPAT__ // To define min/max as macro
#endif // __BORLANDC__
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
#if defined(UNIX)
#include <errno.h>
#else // !UNIX
@@ -36,7 +36,7 @@
#include <stdlib.h> // for getenv
//nclude <fcntl.h>
#define NODW
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Required objects includes. */
@@ -53,9 +53,9 @@
#include "osutil.h"
-//#if defined(__WIN__)
+//#if defined(_WIN32)
//extern "C" HINSTANCE s_hModule; // Saved module handle
-//#endif // __WIN__
+//#endif // _WIN32
#define nullptr 0
TYPCONV GetTypeConv();
diff --git a/storage/connect/jmgfam.cpp b/storage/connect/jmgfam.cpp
index 2d45753ec63..670781da6f5 100644
--- a/storage/connect/jmgfam.cpp
+++ b/storage/connect/jmgfam.cpp
@@ -1,11 +1,11 @@
/************ JMONGO FAM C++ Program Source Code File (.CPP) ***********/
/* PROGRAM NAME: jmgfam.cpp */
/* ------------- */
-/* Version 1.1 */
+/* Version 1.2 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 20017 - 2020 */
+/* (C) Copyright to the author Olivier BERTRAND 20017 - 2021 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -17,7 +17,7 @@
/* Include relevant sections of the System header files. */
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
//#include <io.h>
//#include <fcntl.h>
//#include <errno.h>
@@ -25,7 +25,7 @@
#define __MFC_COMPAT__ // To define min/max as macro
#endif // __BORLANDC__
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
#if defined(UNIX) || defined(UNIV_LINUX)
//#include <errno.h>
#include <unistd.h>
@@ -36,7 +36,7 @@
//#include <io.h>
#endif // !UNIX
//#include <fcntl.h>
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Include application header files: */
@@ -241,8 +241,8 @@ bool JMGFAM::OpenTableFile(PGLOBAL g)
return true;
} // endif Mode
- if (Mode == MODE_INSERT)
- Jcp->MakeColumnGroups(g, Tdbp);
+//if (Mode == MODE_INSERT)
+// Jcp->MakeColumnGroups(g, Tdbp);
if (Mode != MODE_UPDATE)
return Jcp->MakeCursor(g, Tdbp, Options, Filter, Pipe);
@@ -346,14 +346,14 @@ int JMGFAM::ReadBuffer(PGLOBAL g)
} // end of ReadBuffer
/***********************************************************************/
-/* WriteBuffer: File write routine for MGO access method. */
+/* WriteBuffer: File write routine for JMG access method. */
/***********************************************************************/
int JMGFAM::WriteBuffer(PGLOBAL g)
{
int rc = RC_OK;
if (Mode == MODE_INSERT) {
- rc = Jcp->DocWrite(g);
+ rc = Jcp->DocWrite(g, Tdbp->GetLine());
} else if (Mode == MODE_DELETE) {
rc = Jcp->DocDelete(g, false);
} else if (Mode == MODE_UPDATE) {
diff --git a/storage/connect/jmgoconn.cpp b/storage/connect/jmgoconn.cpp
index 0af91bc78cd..a4091e88bbf 100644
--- a/storage/connect/jmgoconn.cpp
+++ b/storage/connect/jmgoconn.cpp
@@ -1,7 +1,7 @@
/************ JMgoConn C++ Functions Source Code File (.CPP) ***********/
-/* Name: JMgoConn.CPP Version 1.1 */
+/* Name: JMgoConn.CPP Version 1.2 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2017 - 2021 */
/* */
/* This file contains the MongoDB Java connection classes functions. */
/***********************************************************************/
@@ -24,7 +24,7 @@
#define nullptr 0
-bool IsNum(PSZ s);
+bool IsArray(PSZ s);
bool MakeSelector(PGLOBAL g, PFIL fp, PSTRG s);
/* --------------------------- Class JNCOL --------------------------- */
@@ -43,19 +43,21 @@ void JNCOL::AddCol(PGLOBAL g, PCOL colp, PSZ jp)
*p++ = 0;
for (kp = Klist; kp; kp = kp->Next)
- if (kp->Jncolp && !strcmp(jp, kp->Key))
+ if (kp->Jncolp && ((kp->Key && !strcmp(jp, kp->Key))
+ || (!kp->Key && IsArray(jp) && kp->N == atoi(jp))))
break;
if (!kp) {
- icp = new(g) JNCOL(IsNum(p));
+ icp = new(g) JNCOL();
kcp = (PJKC)PlugSubAlloc(g, NULL, sizeof(JKCOL));
kcp->Next = NULL;
kcp->Jncolp = icp;
kcp->Colp = NULL;
+ kcp->Array = IsArray(jp);
- if (Array) {
+ if (kcp->Array) {
kcp->Key = NULL;
- kcp->N = atoi(p);
+ kcp->N = atoi(jp);
} else {
kcp->Key = PlugDup(g, jp);
kcp->N = 0;
@@ -75,12 +77,12 @@ void JNCOL::AddCol(PGLOBAL g, PCOL colp, PSZ jp)
icp->AddCol(g, colp, p);
} else {
kcp = (PJKC)PlugSubAlloc(g, NULL, sizeof(JKCOL));
-
kcp->Next = NULL;
kcp->Jncolp = NULL;
kcp->Colp = colp;
+ kcp->Array = IsArray(jp);
- if (Array) {
+ if (kcp->Array) {
kcp->Key = NULL;
kcp->N = atoi(jp);
} else {
@@ -108,7 +110,7 @@ JMgoConn::JMgoConn(PGLOBAL g, PCSZ collname, PCSZ wrapper)
CollName = collname;
readid = fetchid = getdocid = objfldid = fcollid = acollid =
mkdocid = docaddid = mkarid = araddid = insertid = updateid =
- deleteid = gcollid = countid = rewindid = nullptr;
+ deleteid = gcollid = countid = rewindid = mkbsonid = nullptr;
DiscFunc = "MongoDisconnect";
Fpc = NULL;
m_Fetch = 0;
@@ -235,7 +237,7 @@ bool JMgoConn::MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options,
PCSZ filter, bool pipe)
{
const char *p;
- bool b = false, id = (tdbp->GetMode() != MODE_READ), all = false;
+ bool id, b = false, all = false;
uint len;
PCOL cp;
PSZ jp;
@@ -246,13 +248,14 @@ bool JMgoConn::MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options,
if (Options && !stricmp(Options, "all")) {
Options = NULL;
all = true;
- } // endif Options
+ } else
+ id = (tdbp->GetMode() == MODE_UPDATE || tdbp->GetMode() == MODE_DELETE);
- for (cp = tdbp->GetColumns(); cp; cp = cp->GetNext())
- if (!strcmp(cp->GetName(), "_id"))
- id = true;
- else if (cp->GetFmt() && !strcmp(cp->GetFmt(), "*") && (!Options || pipe))
+ for (cp = tdbp->GetColumns(); cp && !all; cp = cp->GetNext())
+ if (cp->GetFmt() && !strcmp(cp->GetFmt(), "*") && (!Options || pipe))
all = true;
+ else if (!id)
+ id = !strcmp(cp->GetJpath(g, false), "_id");
if (pipe && Options) {
if (trace(1))
@@ -535,7 +538,7 @@ PSZ JMgoConn::GetDocument(void)
/***********************************************************************/
void JMgoConn::MakeColumnGroups(PGLOBAL g, PTDB tdbp)
{
- Fpc = new(g) JNCOL(false);
+ Fpc = new(g) JNCOL();
for (PCOL colp = tdbp->GetColumns(); colp; colp = colp->GetNext())
if (!colp->IsSpecial())
@@ -553,7 +556,7 @@ bool JMgoConn::GetMethodId(PGLOBAL g, MODE mode)
return true;
if (gmID(g, docaddid, "DocAdd",
- "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z"))
+ "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;I)Z"))
return true;
if (gmID(g, updateid, "CollUpdate", "(Ljava/lang/Object;)J"))
@@ -563,14 +566,19 @@ bool JMgoConn::GetMethodId(PGLOBAL g, MODE mode)
if (gmID(g, mkdocid, "MakeDocument", "()Ljava/lang/Object;"))
return true;
+ if (gmID(g, mkbsonid, "MakeBson",
+ "(Ljava/lang/String;I)Ljava/lang/Object;"))
+ return true;
+
if (gmID(g, docaddid, "DocAdd",
- "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z"))
+ "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;I)Z"))
return true;
if (gmID(g, mkarid, "MakeArray", "()Ljava/lang/Object;"))
return true;
- if (gmID(g, araddid, "ArrayAdd", "(Ljava/lang/Object;ILjava/lang/Object;)Z"))
+ if (gmID(g, araddid, "ArrayAdd",
+ "(Ljava/lang/Object;ILjava/lang/Object;I)Z"))
return true;
if (gmID(g, insertid, "CollInsert", "(Ljava/lang/Object;)Z"))
@@ -639,48 +647,81 @@ jobject JMgoConn::MakeObject(PGLOBAL g, PCOL colp, bool&error )
} // end of MakeObject
/***********************************************************************/
+/* Stringify. */
+/***********************************************************************/
+bool JMgoConn::Stringify(PCOL colp)
+{
+ bool b = false;
+
+ if (colp)
+ b = (colp->Stringify() && colp->GetResultType() == TYPE_STRING);
+
+ return b;
+} // end of Stringify
+
+/***********************************************************************/
/* MakeDoc. */
/***********************************************************************/
jobject JMgoConn::MakeDoc(PGLOBAL g, PJNCOL jcp)
{
- bool error = false;
+ int j;
+ bool b, error = false;
jobject parent, child, val;
jstring jkey;
-
- if (jcp->Array)
+ PJKC kp = jcp->Klist;
+
+ if (kp->Array)
parent = env->CallObjectMethod(job, mkarid);
else
parent = env->CallObjectMethod(job, mkdocid);
- for (PJKC kp = jcp->Klist; kp; kp = kp->Next)
+ for (j = 0; kp; j = 0, kp = kp->Next) {
+ if (Stringify(kp->Colp)) {
+ switch (*kp->Colp->GetCharValue()) {
+ case '{': j = 1; break;
+ case '[': j = 2; break;
+ default: break;
+ } // endswitch
+
+ b = (!kp->Key || !*kp->Key || *kp->Key == '*');
+ } else
+ b = false;
+
if (kp->Jncolp) {
if (!(child = MakeDoc(g, kp->Jncolp)))
return NULL;
- if (!jcp->Array) {
+ if (!kp->Array) {
jkey = env->NewStringUTF(kp->Key);
- if (env->CallBooleanMethod(job, docaddid, parent, jkey, child))
+ if (env->CallBooleanMethod(job, docaddid, parent, jkey, child, j))
return NULL;
env->DeleteLocalRef(jkey);
} else
- if (env->CallBooleanMethod(job, araddid, parent, kp->N, child))
+ if (env->CallBooleanMethod(job, araddid, parent, kp->N, child, j))
return NULL;
+ env->DeleteLocalRef(child);
} else {
if (!(val = MakeObject(g, kp->Colp, error))) {
if (error)
return NULL;
- } else if (!jcp->Array) {
- jkey = env->NewStringUTF(kp->Key);
+ } else if (!kp->Array) {
+ if (!b) {
+ jkey = env->NewStringUTF(kp->Key);
- if (env->CallBooleanMethod(job, docaddid, parent, jkey, val))
- return NULL;
+ if (env->CallBooleanMethod(job, docaddid, parent, jkey, val, j))
+ return NULL;
- env->DeleteLocalRef(jkey);
- } else if (env->CallBooleanMethod(job, araddid, parent, kp->N, val)) {
+ env->DeleteLocalRef(jkey);
+ } else {
+ env->DeleteLocalRef(parent);
+ parent = env->CallObjectMethod(job, mkbsonid, val, j);
+ } // endif b
+
+ } else if (env->CallBooleanMethod(job, araddid, parent, kp->N, val, j)) {
if (Check(-1))
sprintf(g->Message, "ArrayAdd: %s", Msg);
else
@@ -689,19 +730,38 @@ jobject JMgoConn::MakeDoc(PGLOBAL g, PJNCOL jcp)
return NULL;
} // endif ArrayAdd
+ env->DeleteLocalRef(val);
} // endif Jncolp
+ } // endfor kp
+
return parent;
} // end of MakeDoc
/***********************************************************************/
/* Insert a new document in the collation. */
/***********************************************************************/
-int JMgoConn::DocWrite(PGLOBAL g)
+int JMgoConn::DocWrite(PGLOBAL g, PCSZ line)
{
- jobject doc;
+ int rc = RC_OK;
+ jobject doc = nullptr;
+
+ if (line) {
+ int j;
+ jobject val = env->NewStringUTF(line);
- if (!Fpc || !(doc = MakeDoc(g, Fpc)))
+ switch (*line) {
+ case '{': j = 1; break;
+ case '[': j = 2; break;
+ default: j = 0; break;
+ } // endswitch line
+
+ doc = env->CallObjectMethod(job, mkbsonid, val, j);
+ env->DeleteLocalRef(val);
+ } else if (Fpc)
+ doc = MakeDoc(g, Fpc);
+
+ if (!doc)
return RC_FX;
if (env->CallBooleanMethod(job, insertid, doc)) {
@@ -710,10 +770,11 @@ int JMgoConn::DocWrite(PGLOBAL g)
else
sprintf(g->Message, "CollInsert: unknown error");
- return RC_FX;
+ rc = RC_FX;
} // endif Insert
- return RC_OK;
+ env->DeleteLocalRef(doc);
+ return rc;
} // end of DocWrite
/***********************************************************************/
@@ -721,7 +782,7 @@ int JMgoConn::DocWrite(PGLOBAL g)
/***********************************************************************/
int JMgoConn::DocUpdate(PGLOBAL g, PTDB tdbp)
{
- int rc = RC_OK;
+ int j = 0, rc = RC_OK;
bool error;
PCOL colp;
jstring jkey;
@@ -734,8 +795,14 @@ int JMgoConn::DocUpdate(PGLOBAL g, PTDB tdbp)
if (error)
return RC_FX;
-
- if (env->CallBooleanMethod(job, docaddid, updlist, jkey, val))
+ else if (Stringify(colp))
+ switch (*colp->GetCharValue()) {
+ case '{': j = 1; break;
+ case '[': j = 2; break;
+ default: break;
+ } // endswitch
+
+ if (env->CallBooleanMethod(job, docaddid, updlist, jkey, val, j))
return RC_OK;
env->DeleteLocalRef(jkey);
@@ -745,7 +812,7 @@ int JMgoConn::DocUpdate(PGLOBAL g, PTDB tdbp)
upd = env->CallObjectMethod(job, mkdocid);
jkey = env->NewStringUTF("$set");
- if (env->CallBooleanMethod(job, docaddid, upd, jkey, updlist))
+ if (env->CallBooleanMethod(job, docaddid, upd, jkey, updlist, 0))
return RC_OK;
env->DeleteLocalRef(jkey);
diff --git a/storage/connect/jmgoconn.h b/storage/connect/jmgoconn.h
index 8ee7985d760..9fed1907abc 100644
--- a/storage/connect/jmgoconn.h
+++ b/storage/connect/jmgoconn.h
@@ -25,6 +25,7 @@ typedef struct JKCOL {
PCOL Colp;
char *Key;
int N;
+ bool Array;
} *PJKC;
/***********************************************************************/
@@ -33,18 +34,18 @@ typedef struct JKCOL {
class JNCOL : public BLOCK {
public:
// Constructor
- JNCOL(bool ar) { Klist = NULL; Array = ar; }
+//JNCOL(bool ar) { Klist = NULL; Array = ar; }
+ JNCOL(void) { Klist = NULL; }
// Methods
void AddCol(PGLOBAL g, PCOL colp, PSZ jp);
//Members
PJKC Klist;
- bool Array;
}; // end of JNCOL;
/***********************************************************************/
-/* JMgoConn class. */
+/* JMgoConn class. */
/***********************************************************************/
class JMgoConn : public JAVAConn {
friend class TDBJMG;
@@ -81,11 +82,12 @@ public:
bool GetMethodId(PGLOBAL g, MODE mode);
jobject MakeObject(PGLOBAL g, PCOL colp, bool& error);
jobject MakeDoc(PGLOBAL g, PJNCOL jcp);
- int DocWrite(PGLOBAL g);
+ int DocWrite(PGLOBAL g, PCSZ line);
int DocUpdate(PGLOBAL g, PTDB tdbp);
int DocDelete(PGLOBAL g, bool all);
bool Rewind(void);
PSZ GetDocument(void);
+ bool Stringify(PCOL colp);
protected:
// Members
@@ -100,6 +102,7 @@ protected:
jmethodID getdocid; // The GetDoc method ID
jmethodID objfldid; // The ObjectField method ID
jmethodID mkdocid; // The MakeDocument method ID
+ jmethodID mkbsonid; // The MakeBson method ID
jmethodID docaddid; // The DocAdd method ID
jmethodID mkarid; // The MakeArray method ID
jmethodID araddid; // The ArrayAdd method ID
diff --git a/storage/connect/json.cpp b/storage/connect/json.cpp
index e9925ee959a..b9f9492320b 100644
--- a/storage/connect/json.cpp
+++ b/storage/connect/json.cpp
@@ -1,7 +1,7 @@
/*************** json CPP Declares Source Code File (.H) ***************/
-/* Name: json.cpp Version 1.5 */
+/* Name: json.cpp Version 1.6 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2014 - 2020 */
+/* (C) Copyright to the author Olivier BERTRAND 2014 - 2021 */
/* */
/* This file contains the JSON classes functions. */
/***********************************************************************/
@@ -23,7 +23,7 @@
#define ARGS MY_MIN(24,(int)len-i),s+MY_MAX(i-3,0)
-#if defined(__WIN__)
+#if defined(_WIN32)
#define EL "\r\n"
#else
#define EL "\n"
@@ -55,6 +55,7 @@ char *GetExceptionDesc(PGLOBAL g, unsigned int e);
char *GetJsonNull(void);
int GetDefaultPrec(void);
+int PrepareColist(char*);
/***********************************************************************/
/* IsNum: check whether this string is all digits. */
@@ -78,6 +79,24 @@ bool IsNum(PSZ s)
} // end of IsNum
/***********************************************************************/
+/* IsArray: check whether this is a Mongo array path. */
+/***********************************************************************/
+bool IsArray(PSZ s)
+{
+ char* p = s;
+
+ if (!p || !*p)
+ return false;
+ else for (; *p; p++)
+ if (*p == '.')
+ break;
+ else if (!isdigit(*p))
+ return false;
+
+ return true;
+} // end of IsArray
+
+/***********************************************************************/
/* NextChr: return the first found '[' or Sep pointer. */
/***********************************************************************/
char* NextChr(PSZ s, char sep)
@@ -93,6 +112,27 @@ char* NextChr(PSZ s, char sep)
return p2;
} // end of NextChr
+/***********************************************************************/
+/* Stringified: check that this column is in the stringified list. */
+/***********************************************************************/
+bool Stringified(PCSZ strfy, char *colname)
+{
+ if (strfy) {
+ char *p, colist[512];
+ int n;
+
+ strncpy(colist, strfy, sizeof(colist) - 1);
+ n = PrepareColist(colist);
+
+ for (p = colist; n && p; p += (strlen(p) + 1), n--)
+ if (!stricmp(p, colname))
+ return true;
+
+ } // endif strfy
+
+ return false;
+} // end of Stringified
+
#if 0
/***********************************************************************/
/* Allocate a VAL structure, make sure common field and Nd are zeroed. */
@@ -227,6 +267,7 @@ PSZ Serialize(PGLOBAL g, PJSON jsp, char* fn, int pretty) {
try {
jdp = new(g) JDOC; // MUST BE ALLOCATED BEFORE jp !!!!!
+ jdp->dfp = GetDefaultPrec();
if (!jsp) {
strcpy(g->Message, "Null json tree");
@@ -987,8 +1028,8 @@ bool JDOC::SerializeValue(PJVAL jvp)
case TYPE_BINT:
sprintf(buf, "%lld", jvp->LLn);
return js->WriteStr(buf);
- case TYPE_DBL:
- sprintf(buf, "%.*lf", jvp->Nd, jvp->F);
+ case TYPE_DBL: // dfp to limit to the default number of decimals
+ sprintf(buf, "%.*f", MY_MIN(jvp->Nd, dfp), jvp->F);
return js->WriteStr(buf);
case TYPE_NULL:
return js->WriteStr("null");
@@ -1326,9 +1367,9 @@ bool JARRAY::Merge(PGLOBAL g, PJSON jsp)
} // end of Merge
/***********************************************************************/
-/* Set the nth Value of the Array Value list. */
+/* Set the nth Value of the Array Value list or add it. */
/***********************************************************************/
-bool JARRAY::SetArrayValue(PGLOBAL g, PJVAL jvp, int n)
+void JARRAY::SetArrayValue(PGLOBAL g, PJVAL jvp, int n)
{
int i = 0;
PJVAL jp, *jpp = &First;
@@ -1339,7 +1380,6 @@ bool JARRAY::SetArrayValue(PGLOBAL g, PJVAL jvp, int n)
*jpp = jvp;
jvp->Next = (jp ? jp->Next : NULL);
- return false;
} // end of SetValue
/***********************************************************************/
@@ -1417,7 +1457,7 @@ bool JARRAY::IsNull(void)
/***********************************************************************/
JVALUE::JVALUE(PJSON jsp) : JSON()
{
- if (jsp->GetType() == TYPE_JVAL) {
+ if (jsp && jsp->GetType() == TYPE_JVAL) {
PJVAL jvp = (PJVAL)jsp;
// Val = ((PJVAL)jsp)->GetVal();
@@ -1434,7 +1474,7 @@ JVALUE::JVALUE(PJSON jsp) : JSON()
} else {
Jsp = jsp;
// Val = NULL;
- DataType = TYPE_JSON;
+ DataType = Jsp ? TYPE_JSON : TYPE_NULL;
Nd = 0;
} // endif Type
diff --git a/storage/connect/json.h b/storage/connect/json.h
index 3a026f5df22..53fc5f65e7b 100644
--- a/storage/connect/json.h
+++ b/storage/connect/json.h
@@ -66,6 +66,8 @@ const char* GetFmt(int type, bool un);
PJSON ParseJson(PGLOBAL g, char* s, size_t n, int* prty = NULL, bool* b = NULL);
PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty);
DllExport bool IsNum(PSZ s);
+bool IsArray(PSZ s);
+bool Stringified(PCSZ strfy, char *colname);
/***********************************************************************/
/* Class JDOC. The class for parsing and serializing json documents. */
@@ -74,7 +76,7 @@ class JDOC: public BLOCK {
friend PJSON ParseJson(PGLOBAL, char*, size_t, int*, bool*);
friend PSZ Serialize(PGLOBAL, PJSON, char*, int);
public:
- JDOC(void) : js(NULL), s(NULL), len(0), pty(NULL) {}
+ JDOC(void) : js(NULL), s(NULL), len(0), dfp(0), pty(NULL) {}
void SetJp(JOUT* jp) { js = jp; }
@@ -93,7 +95,7 @@ public:
private:
JOUT* js;
char *s;
- int len;
+ int len, dfp;
bool *pty;
}; // end of class JDOC
@@ -184,7 +186,7 @@ class JARRAY : public JSON {
// Specific
PJVAL AddArrayValue(PGLOBAL g, PJVAL jvp = NULL, int* x = NULL);
- bool SetArrayValue(PGLOBAL g, PJVAL jvp, int i);
+ void SetArrayValue(PGLOBAL g, PJVAL jvp, int i);
void InitArray(PGLOBAL g);
protected:
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index bb6b3a92688..41e73c946fb 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -1524,22 +1524,31 @@ static int *GetIntArgPtr(PGLOBAL g, UDF_ARGS *args, uint& n)
/*********************************************************************************/
int IsJson(UDF_ARGS *args, uint i, bool b)
{
- int n = 0;
+ const char *pat = args->attributes[i];
+ int n = 0;
+
+ if (*pat == '@') {
+ pat++;
+
+ if (*pat == '\'' || *pat == '"')
+ pat++;
+
+ } // endif pat
if (i >= args->arg_count || args->arg_type[i] != STRING_RESULT) {
- } else if (!strnicmp(args->attributes[i], "Json_", 5)) {
+ } else if (!strnicmp(pat, "Json_", 5)) {
if (!args->args[i] || strchr("[{ \t\r\n", *args->args[i]))
n = 1; // arg should be is a json item
else
n = 2; // A file name may have been returned
- } else if (!strnicmp(args->attributes[i], "Jbin_", 5)) {
+ } else if (!strnicmp(pat, "Jbin_", 5)) {
if (args->lengths[i] == sizeof(BSON))
n = 3; // arg is a binary json item
else
n = 2; // A file name may have been returned
- } else if (!strnicmp(args->attributes[i], "Jfile_", 6)) {
+ } else if (!strnicmp(pat, "Jfile_", 6)) {
n = 2; // arg is a json file name
} else if (b) {
char *sap;
@@ -5945,7 +5954,7 @@ char *jfile_convert(UDF_INIT* initid, UDF_ARGS* args, char* result,
str = (char*)g->Xchk;
if (!str) {
- PUSH_WARNING(g->Message ? g->Message : "Unexpected error");
+ PUSH_WARNING(*g->Message ? g->Message : "Unexpected error");
*is_null = 1;
*error = 1;
*res_length = 0;
@@ -6006,7 +6015,7 @@ char *jfile_bjson(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!g->Xchk) {
int msgid = MSGID_OPEN_MODE_STRERROR;
- FILE *fout;
+ FILE *fout = NULL;
FILE *fin;
if (!(fin = global_fopen(g, msgid, fn, "rt")))
@@ -6073,7 +6082,7 @@ char *jfile_bjson(UDF_INIT *initid, UDF_ARGS *args, char *result,
str = (char*)g->Xchk;
if (!str) {
- if (g->Message)
+ if (*g->Message)
str = strcpy(result, g->Message);
else
str = strcpy(result, "Unexpected error");
diff --git a/storage/connect/macutil.cpp b/storage/connect/macutil.cpp
index f95f3adcc6e..93cd0bcb5e1 100644
--- a/storage/connect/macutil.cpp
+++ b/storage/connect/macutil.cpp
@@ -2,11 +2,11 @@
/* MACUTIL: Author Olivier Bertrand -- 2008-2012 */
/* From the article and sample code by Khalid Shaikh. */
/***********************************************************************/
-#if defined(__WIN__)
+#if defined(_WIN32)
#include "my_global.h"
-#else // !__WIN__
+#else // !_WIN32
#error This is WINDOWS only DLL
-#endif // !__WIN__
+#endif // !_WIN32
#include "global.h"
#include "plgdbsem.h"
#include "macutil.h"
diff --git a/storage/connect/macutil.h b/storage/connect/macutil.h
index c80bd58e20a..69a785dc9da 100644
--- a/storage/connect/macutil.h
+++ b/storage/connect/macutil.h
@@ -1,10 +1,10 @@
// MACUTIL.H Olivier Bertrand 2008-2012
// Get Mac Addresses via GetAdaptersInfo
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <iphlpapi.h>
-#else // !__WIN__
+#else // !_WIN32
#error This is WINDOWS only
-#endif // !__WIN__
+#endif // !_WIN32
#include "block.h"
typedef class MACINFO *MACIP;
diff --git a/storage/connect/maputil.cpp b/storage/connect/maputil.cpp
index 9dcc564a86b..b2e55e619a9 100644
--- a/storage/connect/maputil.cpp
+++ b/storage/connect/maputil.cpp
@@ -14,7 +14,7 @@
#include "plgdbsem.h"
#include "maputil.h"
-#ifdef __WIN__
+#ifdef _WIN32
/***********************************************************************/
/* In Insert mode, just open the file for append. Otherwise */
/* create the mapping file object. The map handle can be released */
diff --git a/storage/connect/mongo.cpp b/storage/connect/mongo.cpp
index 5f10a89ee67..a9c4813684b 100644
--- a/storage/connect/mongo.cpp
+++ b/storage/connect/mongo.cpp
@@ -1,6 +1,6 @@
/************** mongo C++ Program Source Code File (.CPP) **************/
-/* PROGRAM NAME: mongo Version 1.0 */
-/* (C) Copyright to the author Olivier BERTRAND 2017 */
+/* PROGRAM NAME: mongo Version 1.1 */
+/* (C) Copyright to the author Olivier BERTRAND 2021 */
/* These programs are the MGODEF class execution routines. */
/***********************************************************************/
@@ -36,6 +36,7 @@
bool MakeSelector(PGLOBAL g, PFIL fp, PSTRG s);
bool IsNum(PSZ s);
int GetDefaultDepth(void);
+bool JsonAllPath(void);
/***********************************************************************/
/* Make selector json representation for Mongo tables. */
@@ -350,7 +351,7 @@ void MGODISC::AddColumn(PGLOBAL g, PCSZ colname, PCSZ fmt, int k)
bcp->Name = PlugDup(g, colname);
length[0] = MY_MAX(length[0], (signed)strlen(colname));
- if (k) {
+ if (k || JsonAllPath()) {
bcp->Fmt = PlugDup(g, fmt);
length[7] = MY_MAX(length[7], (signed)strlen(fmt));
} else
@@ -395,6 +396,7 @@ bool MGODEF::DefineAM(PGLOBAL g, LPCSTR, int poff)
Uri = GetStringCatInfo(g, "Connect", "mongodb://localhost:27017");
Colist = GetStringCatInfo(g, "Colist", NULL);
Filter = GetStringCatInfo(g, "Filter", NULL);
+ Strfy = GetStringCatInfo(g, "Stringify", NULL);
Base = GetIntCatInfo("Base", 0) ? 1 : 0;
Version = GetIntCatInfo("Version", 3);
diff --git a/storage/connect/mongo.h b/storage/connect/mongo.h
index dcefac372c0..7e92a7dc8e9 100644
--- a/storage/connect/mongo.h
+++ b/storage/connect/mongo.h
@@ -1,7 +1,7 @@
/**************** mongo H Declares Source Code File (.H) ***************/
-/* Name: mongo.h Version 1.0 */
+/* Name: mongo.h Version 1.1 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2021 */
/* */
/* This file contains the common MongoDB classes declares. */
/***********************************************************************/
@@ -82,6 +82,7 @@ protected:
PSZ Wrapname; /* Java wrapper name */
PCSZ Colist; /* Options list */
PCSZ Filter; /* Filtering query */
+ PCSZ Strfy; /* The stringify columns */
int Base; /* The array index base */
int Version; /* The Java driver version */
bool Pipe; /* True is Colist is a pipeline */
diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc
index e3fa00e119f..d4b182b4c64 100644
--- a/storage/connect/mycat.cc
+++ b/storage/connect/mycat.cc
@@ -62,10 +62,10 @@
#include "tabvct.h"
#endif // VCT_SUPPORT
#include "tabsys.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include "tabmac.h"
#include "tabwmi.h"
-#endif // __WIN__
+#endif // _WIN32
//#include "tabtbl.h"
#include "tabxcl.h"
#include "tabtbl.h"
@@ -105,9 +105,9 @@
/***********************************************************************/
/* Extern static variables. */
/***********************************************************************/
-#if defined(__WIN__)
+#if defined(_WIN32)
extern "C" HINSTANCE s_hModule; // Saved module handle
-#endif // !__WIN__
+#endif // !_WIN32
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
bool MongoEnabled(void);
#endif // JAVA_SUPPORT || CMGO_SUPPORT
@@ -124,6 +124,15 @@ char *GetPluginDir(void)
} // end of GetPluginDir
/***********************************************************************/
+/* Get the lc_messages_dir, it is where error messages for various */
+/* languages are installed, and by default the INSTALL_MYSQLSHAREDIR. */
+/***********************************************************************/
+char *GetMessageDir(void)
+{
+ return lc_messages_dir;
+} // end of GetMessageDir
+
+/***********************************************************************/
/* Get a unique enum table type ID. */
/***********************************************************************/
TABTYPE GetTypeID(const char *type)
@@ -152,10 +161,10 @@ TABTYPE GetTypeID(const char *type)
: (!stricmp(type, "MYSQL")) ? TAB_MYSQL
: (!stricmp(type, "MYPRX")) ? TAB_MYSQL
: (!stricmp(type, "DIR")) ? TAB_DIR
-#if defined(__WIN__)
+#if defined(_WIN32)
: (!stricmp(type, "MAC")) ? TAB_MAC
: (!stricmp(type, "WMI")) ? TAB_WMI
-#endif // __WIN__
+#endif // _WIN32
: (!stricmp(type, "TBL")) ? TAB_TBL
: (!stricmp(type, "XCOL")) ? TAB_XCL
: (!stricmp(type, "OCCUR")) ? TAB_OCCUR
@@ -374,11 +383,11 @@ uint GetFuncID(const char *func)
/***********************************************************************/
CATALOG::CATALOG(void)
{
-#if defined(__WIN__)
+#if defined(_WIN32)
//DataPath= ".\\";
-#else // !__WIN__
+#else // !_WIN32
//DataPath= "./";
-#endif // !__WIN__
+#endif // !_WIN32
memset(&Ctb, 0, sizeof(CURTAB));
Cbuf= NULL;
Cblen= 0;
@@ -472,10 +481,10 @@ PTABDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
#if defined(JAVA_SUPPORT)
case TAB_JDBC: tdp= new(g) JDBCDEF; break;
#endif // JAVA_SUPPORT
-#if defined(__WIN__)
+#if defined(_WIN32)
case TAB_MAC: tdp= new(g) MACDEF; break;
case TAB_WMI: tdp= new(g) WMIDEF; break;
-#endif // __WIN__
+#endif // _WIN32
case TAB_OEM: tdp= new(g) OEMDEF; break;
case TAB_TBL: tdp= new(g) TBLDEF; break;
case TAB_XCL: tdp= new(g) XCLDEF; break;
diff --git a/storage/connect/mycat.h b/storage/connect/mycat.h
index 6473f7a5c11..147148f4a57 100644
--- a/storage/connect/mycat.h
+++ b/storage/connect/mycat.h
@@ -78,7 +78,8 @@ struct ha_table_option_struct {
typedef class ha_connect *PHC;
-char *GetPluginDir(void);
+char *GetPluginDir(void);
+char *GetMessageDir(void);
TABTYPE GetTypeID(const char *type);
bool IsFileType(TABTYPE type);
bool IsExactType(TABTYPE type);
diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp
index e07270aff8a..76e0536633f 100644
--- a/storage/connect/myconn.cpp
+++ b/storage/connect/myconn.cpp
@@ -35,11 +35,11 @@
#include "my_sys.h"
#include "mysqld_error.h"
#endif // !MYSQL_PREPARED_STATEMENTS
-#if defined(__WIN__)
+#if defined(_WIN32)
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
#include "osutil.h"
-#endif // !__WIN__
+#endif // !_WIN32
#include "global.h"
#include "plgdbsem.h"
@@ -492,15 +492,15 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
//mysql_options(m_DB, MYSQL_OPT_READ_TIMEOUT, &nrt);
//mysql_options(m_DB, MYSQL_OPT_WRITE_TIMEOUT, ...);
-#if defined(__WIN__)
+#if defined(_WIN32)
if (!strcmp(host, ".")) {
mysql_options(m_DB, MYSQL_OPT_NAMED_PIPE, NULL);
pipe = mysqld_unix_port;
} // endif host
-#else // !__WIN__
+#else // !_WIN32
if (!strcmp(host, "localhost"))
pipe = mysqld_unix_port;
-#endif // !__WIN__
+#endif // !_WIN32
#if 0
if (pwd && !strcmp(pwd, "*")) {
diff --git a/storage/connect/myconn.h b/storage/connect/myconn.h
index 9ebd37527a6..5f64f933878 100644
--- a/storage/connect/myconn.h
+++ b/storage/connect/myconn.h
@@ -7,24 +7,24 @@
/* DO NOT define DLL_EXPORT in your application so these items are */
/* declared are imported from the Myconn DLL. */
/***********************************************************************/
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <winsock.h>
-#else // !__WIN__
+#else // !_WIN32
#include <sys/socket.h>
-#endif // !__WIN__
+#endif // !_WIN32
#include <mysql.h>
#include <errmsg.h>
#include "myutil.h"
-#if defined(__WIN__) && defined(MYCONN_EXPORTS)
+#if defined(_WIN32) && defined(MYCONN_EXPORTS)
#if defined(DLL_EXPORT)
#define DllItem _declspec(dllexport)
#else // !DLL_EXPORT
#define DllItem _declspec(dllimport)
#endif // !DLL_EXPORT
-#else // !__WIN__ || !MYCONN_EXPORTS
+#else // !_WIN32 || !MYCONN_EXPORTS
#define DllItem
-#endif // !__WIN__
+#endif // !_WIN32
#define MYSQL_ENABLED 0x00000001
#define MYSQL_LOGON 0x00000002
diff --git a/storage/connect/mysql-test/connect/r/bson_mongo_c.result b/storage/connect/mysql-test/connect/r/bson_mongo_c.result
index 83bf7cd1974..e2273be4bec 100644
--- a/storage/connect/mysql-test/connect/r/bson_mongo_c.result
+++ b/storage/connect/mysql-test/connect/r/bson_mongo_c.result
@@ -363,7 +363,7 @@ _id item prices_0 prices_1 prices_2 prices_3 prices_4
1 journal 87 45 63 12 78
2 notebook 123 456 789 NULL NULL
3 paper 5 7 3 8 NULL
-4 planner 25 71 44 27 NULL
+4 planner 25 71 NULL 44 27
5 postcard 5 7 3 8 NULL
DROP TABLE t1;
#
diff --git a/storage/connect/mysql-test/connect/r/jdbc.result b/storage/connect/mysql-test/connect/r/jdbc.result
index 0dbdf851860..b42311b8136 100644
--- a/storage/connect/mysql-test/connect/r/jdbc.result
+++ b/storage/connect/mysql-test/connect/r/jdbc.result
@@ -1,4 +1,5 @@
-SET GLOBAL time_zone='+1:00';
+SET GLOBAL time_zone='+0:00';
+SET time_zone='+0:00';
CREATE DATABASE connect;
USE connect;
CREATE TABLE t2 (
@@ -16,7 +17,7 @@ id msg tm dt dtm ts
# Testing JDBC connection to MySQL driver
#
USE test;
-CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=t2 CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root';
+CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=t2 CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root&useSSL=false';
SELECT * FROM t1;
id msg tm dt dtm ts
455000000000 A very big number 18:10:25 2016-03-16 1999-12-11 23:01:52 2015-07-24 09:32:45
@@ -26,7 +27,7 @@ Note 1105 t2: 1 affected rows
SELECT * FROM t1;
id msg tm dt dtm ts
455000000000 A very big number 18:10:25 2016-03-16 1999-12-11 23:01:52 2015-07-24 09:32:45
-786325481247 Hello! 19:45:03 1933-08-09 1985-11-12 09:02:44 2014-06-17 10:32:01
+786325481247 Hello! 19:45:03 1933-08-10 1985-11-12 09:02:44 2014-06-17 10:32:01
DELETE FROM t1 WHERE msg = 'Hello!';
Warnings:
Note 1105 t2: 1 affected rows
@@ -37,7 +38,7 @@ DROP TABLE t1;
#
# Testing JDBC view
#
-CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC SRCDEF='select id, msg, tm, dt from t2' CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root';
+CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC SRCDEF='select id, msg, tm, dt from t2' CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root&useSSL=false';
SELECT * FROM t1;
id msg tm dt
455000000000 A very big number 18:10:25 2016-03-16
@@ -74,7 +75,7 @@ SELECT * FROM t3;
name city birth hired
Donald Atlanta 1999-04-01 2016-03-31
Mick New York 1980-01-20 2002-09-11
-CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=boys CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root' OPTION_LIST='scrollable=1';
+CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=boys CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root&useSSL=false' OPTION_LIST='scrollable=1';
SELECT * FROM t1;
name city birth hired
John Boston 1986-01-25 2010-06-02
@@ -100,9 +101,9 @@ George San Jose 1981-08-10 2010-06-02
Sam Chicago 1979-11-22 2007-10-10
James Dallas 1992-05-13 2009-12-14
Bill Boston 1986-09-11 2008-02-10
-Donald Atlanta 1999-03-31 2016-03-30
-Mick New York 1980-01-20 2002-09-10
-Tom Seatle 2002-03-15 1970-01-01
+Donald Atlanta 1999-04-01 2016-03-31
+Mick New York 1980-01-20 2002-09-11
+Tom Seatle 2002-03-15 NULL
DROP TABLE t3;
#
# Testing JDBC join operations
@@ -280,3 +281,4 @@ DROP TABLE t1;
DROP TABLE connect.tx1;
DROP DATABASE connect;
SET GLOBAL time_zone=SYSTEM;
+SET time_zone=SYSTEM;
diff --git a/storage/connect/mysql-test/connect/r/jdbc_new.result b/storage/connect/mysql-test/connect/r/jdbc_new.result
index 33d8bd3b7d8..a47fb9ccaf9 100644
--- a/storage/connect/mysql-test/connect/r/jdbc_new.result
+++ b/storage/connect/mysql-test/connect/r/jdbc_new.result
@@ -2,7 +2,8 @@ connect master,127.0.0.1,root,,test,$MASTER_MYPORT,;
connect slave,127.0.0.1,root,,test,$SLAVE_MYPORT,;
connection master;
connection slave;
-SET GLOBAL time_zone='+1:00';
+SET GLOBAL time_zone='+0:00';
+SET time_zone='+0:00';
CREATE TABLE t1 (a int, b char(10));
INSERT INTO t1 VALUES (NULL,NULL),(0,'test00'),(1,'test01'),(2,'test02'),(3,'test03');
SELECT * FROM t1;
@@ -16,31 +17,32 @@ NULL NULL
# Testing errors
#
connection master;
-SET GLOBAL time_zone='+1:00';
+SET GLOBAL time_zone='+0:00';
+SET time_zone='+0:00';
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
-CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=unknown';
+CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=unknown&useSSL=false';
ERROR HY000: Connecting: java.sql.SQLException: Access denied for user 'unknown'@'localhost' (using password: NO) rc=-2
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
-CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/unknown?user=root';
+CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/unknown?user=root&useSSL=false';
ERROR HY000: Connecting: java.sql.SQLSyntaxErrorException: Unknown database 'unknown' rc=-2
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='unknown'
- CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root';
+ CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false';
ERROR HY000: Cannot get columns from unknown
SHOW CREATE TABLE t1;
ERROR 42S02: Table 'test.t1' doesn't exist
CREATE TABLE t1 (x int, y char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC
-CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root';
+CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`x` int(11) DEFAULT NULL,
`y` char(10) DEFAULT NULL
-) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false' `TABLE_TYPE`=JDBC
SELECT * FROM t1;
ERROR HY000: Got error 174 'ExecuteQuery: java.sql.SQLSyntaxErrorException: Unknown column 'x' in 'field list'' from CONNECT
DROP TABLE t1;
CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC
-CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root';
+CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false';
connection slave;
ALTER TABLE t1 RENAME t1backup;
connection master;
@@ -54,13 +56,13 @@ DROP TABLE t1;
# Testing SELECT, etc.
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
-CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root';
+CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(10) DEFAULT NULL,
`b` char(10) DEFAULT NULL
-) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC'
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false' `TABLE_TYPE`='JDBC'
SELECT * FROM t1;
a b
NULL NULL
@@ -70,13 +72,13 @@ NULL NULL
3 test03
DROP TABLE t1;
CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='t1'
- CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root';
+ CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` char(10) DEFAULT NULL
-) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC `TABNAME`='t1'
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false' `TABLE_TYPE`=JDBC `TABNAME`='t1'
SELECT * FROM t1;
a b
NULL NULL
@@ -86,13 +88,13 @@ NULL NULL
3 test03
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL, b CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=JDBC
-CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root';
+CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` char(10) NOT NULL
-) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false' `TABLE_TYPE`=JDBC
SELECT * FROM t1;
a b
0
@@ -102,13 +104,13 @@ a b
3 test03
DROP TABLE t1;
CREATE TABLE t1 (a char(10), b int) ENGINE=CONNECT TABLE_TYPE=JDBC
-CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root';
+CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` char(10) DEFAULT NULL,
`b` int(11) DEFAULT NULL
-) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false' `TABLE_TYPE`=JDBC
SELECT * FROM t1;
a b
NULL NULL
@@ -138,7 +140,7 @@ t1 CREATE TABLE `t1` (
INSERT INTO t1 VALUES(100,3333,41235,1234567890,235000000000,3.14159265,3.14159265,3141.59265);
connection master;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
-CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root';
+CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -150,7 +152,7 @@ t1 CREATE TABLE `t1` (
`f` double(14,0) DEFAULT NULL,
`g` double(24,0) DEFAULT NULL,
`h` decimal(27,5) DEFAULT NULL
-) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC'
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false' `TABLE_TYPE`='JDBC'
SELECT * FROM t1;
a b c d e f g h
100 3333 41235 1234567890 235000000000 3 3 3141.59265
@@ -173,13 +175,13 @@ a b
Welcome Hello, World
connection master;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
-CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root';
+CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` char(12) DEFAULT NULL,
`b` varchar(12) DEFAULT NULL
-) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC'
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false' `TABLE_TYPE`='JDBC'
SELECT * FROM t1;
a b
Welcome Hello, World
@@ -209,7 +211,7 @@ a b c d e
2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 2003
connection master;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
-CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root';
+CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -218,13 +220,15 @@ t1 CREATE TABLE `t1` (
`c` time DEFAULT NULL,
`d` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`e` year(4) DEFAULT NULL
-) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC'
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false' `TABLE_TYPE`='JDBC'
SELECT * FROM t1;
a b c d e
-2003-05-27 2003-05-27 11:45:23 10:45:23 2003-05-27 10:45:23 2003
+2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 2003
DROP TABLE t1;
connection slave;
DROP TABLE t1;
SET GLOBAL time_zone=SYSTEM;
+SET time_zone=SYSTEM;
connection master;
SET GLOBAL time_zone=SYSTEM;
+SET time_zone=SYSTEM;
diff --git a/storage/connect/mysql-test/connect/r/jdbc_oracle.result b/storage/connect/mysql-test/connect/r/jdbc_oracle.result
index d895a9aed87..21a2d10fef7 100644
--- a/storage/connect/mysql-test/connect/r/jdbc_oracle.result
+++ b/storage/connect/mysql-test/connect/r/jdbc_oracle.result
@@ -3,7 +3,7 @@ command varchar(128) not null,
number int(5) not null flag=1,
message varchar(255) flag=2)
ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:oracle:thin:@localhost:1521:xe'
-OPTION_LIST='User=system,Password=Choupy01,Execsrc=1';
+OPTION_LIST='User=system,Password=Biscote01,Execsrc=1';
SELECT * FROM t2 WHERE command = 'drop table employee';
command number message
drop table employee 0 Execute: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
@@ -23,14 +23,14 @@ Warnings:
Warning 1105 Affected rows
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables
CONNECTION='jdbc:oracle:thin:@localhost:1521:xe'
-OPTION_LIST='User=system,Password=Choupy01';
+OPTION_LIST='User=system,Password=Biscote01';
SELECT * FROM t1 WHERE table_name='employee';
Table_Cat Table_Schema Table_Name Table_Type Remark
NULL SYSTEM EMPLOYEE TABLE NULL
DROP TABLE t1;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='EMPLOYEE' CATFUNC=columns
CONNECTION='jdbc:oracle:thin:@localhost:1521:xe'
-OPTION_LIST='User=system,Password=Choupy01';
+OPTION_LIST='User=system,Password=Biscote01';
SELECT * FROM t1;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
NULL SYSTEM EMPLOYEE ID 3 NUMBER 38 0 0 10 0 NULL
@@ -42,7 +42,7 @@ CREATE SERVER 'oracle' FOREIGN DATA WRAPPER 'oracle.jdbc.driver.OracleDriver' OP
HOST 'jdbc:oracle:thin:@localhost:1521:xe',
DATABASE 'SYSTEM',
USER 'system',
-PASSWORD 'Choupy01',
+PASSWORD 'Biscote01',
PORT 0,
SOCKET '',
OWNER 'SYSTEM');
diff --git a/storage/connect/mysql-test/connect/r/json_java_2.result b/storage/connect/mysql-test/connect/r/json_java_2.result
index e0b08889f40..c05501013a5 100644
--- a/storage/connect/mysql-test/connect/r/json_java_2.result
+++ b/storage/connect/mysql-test/connect/r/json_java_2.result
@@ -10,7 +10,7 @@ SELECT * from t1 limit 3;
Document
{"_id":{"$oid":"58ada47de5a51ddfcd5ed51c"},"address":{"building":"1007","coord":[-73.856077,40.848447],"street":"Morris Park Ave","zipcode":"10462"},"borough":"Bronx","cuisine":"Bakery","grades":[{"date":{"$date":"2014-03-03T00:00:00.000Z"},"grade":"A","score":2},{"date":{"$date":"2013-09-11T00:00:00.000Z"},"grade":"A","score":6},{"date":{"$date":"2013-01-24T00:00:00.000Z"},"grade":"A","score":10},{"date":{"$date":"2011-11-23T00:00:00.000Z"},"grade":"A","score":9},{"date":{"$date":"2011-03-10T00:00:00.000Z"},"grade":"B","score":14}],"name":"Morris Park Bake Shop","restaurant_id":"30075445"}
{"_id":{"$oid":"58ada47de5a51ddfcd5ed51d"},"address":{"building":"469","coord":[-73.961704,40.662942],"street":"Flatbush Avenue","zipcode":"11225"},"borough":"Brooklyn","cuisine":"Hamburgers","grades":[{"date":{"$date":"2014-12-30T00:00:00.000Z"},"grade":"A","score":8},{"date":{"$date":"2014-07-01T00:00:00.000Z"},"grade":"B","score":23},{"date":{"$date":"2013-04-30T00:00:00.000Z"},"grade":"A","score":12},{"date":{"$date":"2012-05-08T00:00:00.000Z"},"grade":"A","score":12}],"name":"Wendy'S","restaurant_id":"30112340"}
-{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.98513559999999,40.7676919],"street":"West 57 Street","zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":"2014-09-06T00:00:00.000Z"},"grade":"A","score":2},{"date":{"$date":"2013-07-22T00:00:00.000Z"},"grade":"A","score":11},{"date":{"$date":"2012-07-31T00:00:00.000Z"},"grade":"A","score":12},{"date":{"$date":"2011-12-29T00:00:00.000Z"},"grade":"A","score":12}],"name":"Dj Reynolds Pub And Restaurant","restaurant_id":"30191841"}
+{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.985136,40.767692],"street":"West 57 Street","zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":"2014-09-06T00:00:00.000Z"},"grade":"A","score":2},{"date":{"$date":"2013-07-22T00:00:00.000Z"},"grade":"A","score":11},{"date":{"$date":"2012-07-31T00:00:00.000Z"},"grade":"A","score":12},{"date":{"$date":"2011-12-29T00:00:00.000Z"},"grade":"A","score":12}],"name":"Dj Reynolds Pub And Restaurant","restaurant_id":"30191841"}
DROP TABLE t1;
#
# Test catfunc
diff --git a/storage/connect/mysql-test/connect/r/json_java_3.result b/storage/connect/mysql-test/connect/r/json_java_3.result
index b9ba919507d..b74f92bfee2 100644
--- a/storage/connect/mysql-test/connect/r/json_java_3.result
+++ b/storage/connect/mysql-test/connect/r/json_java_3.result
@@ -10,7 +10,7 @@ SELECT * from t1 limit 3;
Document
{"_id":{"$oid":"58ada47de5a51ddfcd5ed51c"},"address":{"building":"1007","coord":[-73.856077,40.848447],"street":"Morris Park Ave","zipcode":"10462"},"borough":"Bronx","cuisine":"Bakery","grades":[{"date":{"$date":1393804800000},"grade":"A","score":2},{"date":{"$date":1378857600000},"grade":"A","score":6},{"date":{"$date":1358985600000},"grade":"A","score":10},{"date":{"$date":1322006400000},"grade":"A","score":9},{"date":{"$date":1299715200000},"grade":"B","score":14}],"name":"Morris Park Bake Shop","restaurant_id":"30075445"}
{"_id":{"$oid":"58ada47de5a51ddfcd5ed51d"},"address":{"building":"469","coord":[-73.961704,40.662942],"street":"Flatbush Avenue","zipcode":"11225"},"borough":"Brooklyn","cuisine":"Hamburgers","grades":[{"date":{"$date":1419897600000},"grade":"A","score":8},{"date":{"$date":1404172800000},"grade":"B","score":23},{"date":{"$date":1367280000000},"grade":"A","score":12},{"date":{"$date":1336435200000},"grade":"A","score":12}],"name":"Wendy'S","restaurant_id":"30112340"}
-{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.98513559999999,40.7676919],"street":"West 57 Street","zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":1409961600000},"grade":"A","score":2},{"date":{"$date":1374451200000},"grade":"A","score":11},{"date":{"$date":1343692800000},"grade":"A","score":12},{"date":{"$date":1325116800000},"grade":"A","score":12}],"name":"Dj Reynolds Pub And Restaurant","restaurant_id":"30191841"}
+{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.985136,40.767692],"street":"West 57 Street","zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":1409961600000},"grade":"A","score":2},{"date":{"$date":1374451200000},"grade":"A","score":11},{"date":{"$date":1343692800000},"grade":"A","score":12},{"date":{"$date":1325116800000},"grade":"A","score":12}],"name":"Dj Reynolds Pub And Restaurant","restaurant_id":"30191841"}
DROP TABLE t1;
#
# Test catfunc
diff --git a/storage/connect/mysql-test/connect/r/json_mongo_c.result b/storage/connect/mysql-test/connect/r/json_mongo_c.result
index 482ccc85b57..008e41f63d1 100644
--- a/storage/connect/mysql-test/connect/r/json_mongo_c.result
+++ b/storage/connect/mysql-test/connect/r/json_mongo_c.result
@@ -8,9 +8,9 @@ ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants CONNECTION='mongodb://localho
OPTION_LIST='Driver=C,Version=0' DATA_CHARSET=utf8;
SELECT * from t1 limit 3;
Document
-{"_id":{"$oid":"58ada47de5a51ddfcd5ed51c"},"address":{"building":"1007","coord":[-73.856076999999999089,40.848447000000000173],"street":"Morris Park Ave","zipcode":"10462"},"borough":"Bronx","cuisine":"Bakery","grades":[{"date":{"$date":1393804800000},"grade":"A","score":2},{"date":{"$date":1378857600000},"grade":"A","score":6},{"date":{"$date":1358985600000},"grade":"A","score":10},{"date":{"$date":1322006400000},"grade":"A","score":9},{"date":{"$date":1299715200000},"grade":"B","score":14}],"name":"Morris Park Bake Shop","restaurant_id":"30075445"}
-{"_id":{"$oid":"58ada47de5a51ddfcd5ed51d"},"address":{"building":"469","coord":[-73.96170399999999745,40.66294200000000103],"street":"Flatbush Avenue","zipcode":"11225"},"borough":"Brooklyn","cuisine":"Hamburgers","grades":[{"date":{"$date":1419897600000},"grade":"A","score":8},{"date":{"$date":1404172800000},"grade":"B","score":23},{"date":{"$date":1367280000000},"grade":"A","score":12},{"date":{"$date":1336435200000},"grade":"A","score":12}],"name":"Wendy'S","restaurant_id":"30112340"}
-{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.985135599999992451,40.767691900000002647],"street":"West 57 Street","zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":1409961600000},"grade":"A","score":2},{"date":{"$date":1374451200000},"grade":"A","score":11},{"date":{"$date":1343692800000},"grade":"A","score":12},{"date":{"$date":1325116800000},"grade":"A","score":12}],"name":"Dj Reynolds Pub And Restaurant","restaurant_id":"30191841"}
+{"_id":{"$oid":"58ada47de5a51ddfcd5ed51c"},"address":{"building":"1007","coord":[-73.856077,40.848447],"street":"Morris Park Ave","zipcode":"10462"},"borough":"Bronx","cuisine":"Bakery","grades":[{"date":{"$date":1393804800000},"grade":"A","score":2},{"date":{"$date":1378857600000},"grade":"A","score":6},{"date":{"$date":1358985600000},"grade":"A","score":10},{"date":{"$date":1322006400000},"grade":"A","score":9},{"date":{"$date":1299715200000},"grade":"B","score":14}],"name":"Morris Park Bake Shop","restaurant_id":"30075445"}
+{"_id":{"$oid":"58ada47de5a51ddfcd5ed51d"},"address":{"building":"469","coord":[-73.961704,40.662942],"street":"Flatbush Avenue","zipcode":"11225"},"borough":"Brooklyn","cuisine":"Hamburgers","grades":[{"date":{"$date":1419897600000},"grade":"A","score":8},{"date":{"$date":1404172800000},"grade":"B","score":23},{"date":{"$date":1367280000000},"grade":"A","score":12},{"date":{"$date":1336435200000},"grade":"A","score":12}],"name":"Wendy'S","restaurant_id":"30112340"}
+{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.985136,40.767692],"street":"West 57 Street","zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":1409961600000},"grade":"A","score":2},{"date":{"$date":1374451200000},"grade":"A","score":11},{"date":{"$date":1343692800000},"grade":"A","score":12},{"date":{"$date":1325116800000},"grade":"A","score":12}],"name":"Dj Reynolds Pub And Restaurant","restaurant_id":"30191841"}
DROP TABLE t1;
#
# Test catfunc
@@ -363,7 +363,7 @@ _id item prices_0 prices_1 prices_2 prices_3 prices_4
1 journal 87 45 63 12 78
2 notebook 123 456 789 NULL NULL
3 paper 5 7 3 8 NULL
-4 planner 25 71 44 27 NULL
+4 planner 25 71 NULL 44 27
5 postcard 5 7 3 8 NULL
DROP TABLE t1;
#
diff --git a/storage/connect/mysql-test/connect/r/mongo_c.result b/storage/connect/mysql-test/connect/r/mongo_c.result
index 8b86ce32943..5b29bb54d3a 100644
--- a/storage/connect/mysql-test/connect/r/mongo_c.result
+++ b/storage/connect/mysql-test/connect/r/mongo_c.result
@@ -8,9 +8,9 @@ ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants
OPTION_LIST='Driver=C,Version=0' DATA_CHARSET=utf8;
SELECT * from t1 limit 3;
Document
-{"_id":{"$oid":"58ada47de5a51ddfcd5ed51c"},"address":{"building":"1007","coord":[-73.856076999999999089,40.848447000000000173],"street":"Morris ParkAve", "zipcode":"10462"},"borough":"Bronx","cuisine":"Bakery","grades":[{"date":{"$date":1393804800000},"grade":"A","score":2},{"date":{"$date":1378857600000},"grade":"A","score":6},{"date":{"$date":1358985600000},"grade":"A","score":10},{"date":{"$date":1322006400000},"grade":"A","score":9},{"date":{"$date":1299715200000},"grade":"B","score":14}],"name":"Morris ParkBakeShop", "restaurant_id":"30075445"}
-{"_id":{"$oid":"58ada47de5a51ddfcd5ed51d"},"address":{"building":"469","coord":[-73.96170399999999745,40.66294200000000103],"street":"Flatbush Avenue", "zipcode":"11225"},"borough":"Brooklyn","cuisine":"Hamburgers","grades":[{"date":{"$date":1419897600000},"grade":"A","score":8},{"date":{"$date":1404172800000},"grade":"B","score":23},{"date":{"$date":1367280000000},"grade":"A","score":12},{"date":{"$date":1336435200000},"grade":"A","score":12}],"name":"Wendy'S","restaurant_id":"30112340"}
-{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.985135599999992451,40.767691900000002647],"street":"West 57Street", "zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":1409961600000},"grade":"A","score":2},{"date":{"$date":1374451200000},"grade":"A","score":11},{"date":{"$date":1343692800000},"grade":"A","score":12},{"date":{"$date":1325116800000},"grade":"A","score":12}],"name":"Dj ReynoldsPubAndRestaurant", "restaurant_id":"30191841"}
+{"_id":{"$oid":"58ada47de5a51ddfcd5ed51c"},"address":{"building":"1007","coord":[-73.856077,40.848447],"street":"Morris Park Ave","zipcode":"10462"},"borough":"Bronx","cuisine":"Bakery","grades":[{"date":{"$date":1393804800000.000000},"grade":"A","score":2},{"date":{"$date":1378857600000.000000},"grade":"A","score":6},{"date":{"$date":1358985600000.000000},"grade":"A","score":10},{"date":{"$date":1322006400000.000000},"grade":"A","score":9},{"date":{"$date":1299715200000.000000},"grade":"B","score":14}],"name":"Morris Park Bake Shop","restaurant_id":"30075445"}
+{"_id":{"$oid":"58ada47de5a51ddfcd5ed51d"},"address":{"building":"469","coord":[-73.961704,40.662942],"street":"Flatbush Avenue","zipcode":"11225"},"borough":"Brooklyn","cuisine":"Hamburgers","grades":[{"date":{"$date":1419897600000.000000},"grade":"A","score":8},{"date":{"$date":1404172800000.000000},"grade":"B","score":23},{"date":{"$date":1367280000000.000000},"grade":"A","score":12},{"date":{"$date":1336435200000.000000},"grade":"A","score":12}],"name":"Wendy'S","restaurant_id":"30112340"}
+{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.985136,40.767692],"street":"West 57 Street","zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":1409961600000.000000},"grade":"A","score":2},{"date":{"$date":1374451200000.000000},"grade":"A","score":11},{"date":{"$date":1343692800000.000000},"grade":"A","score":12},{"date":{"$date":1325116800000.000000},"grade":"A","score":12}],"name":"Dj Reynolds Pub And Restaurant","restaurant_id":"30191841"}
DROP TABLE t1;
#
# Test catfunc
@@ -64,23 +64,23 @@ SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL,
- `address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
- `address_coord` varchar(512) NOT NULL `FIELD_FORMAT`='address.coord',
- `address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
- `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
+ `address_building` char(10) NOT NULL `JPATH`='address.building',
+ `address_coord` varchar(512) NOT NULL `JPATH`='address.coord',
+ `address_street` char(38) NOT NULL `JPATH`='address.street',
+ `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL,
- `grades_0` varchar(512) DEFAULT NULL `FIELD_FORMAT`='grades.0',
+ `grades_0` varchar(512) DEFAULT NULL `JPATH`='grades.0',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `OPTION_LIST`='Depth=1,Driver=C,Version=0' `DATA_CHARSET`='utf8'
SELECT * FROM t1 LIMIT 5;
_id address_building address_coord address_street address_zipcode borough cuisine grades_0 name restaurant_id
-58ada47de5a51ddfcd5ed51c 1007 Morris Park Ave 10462 Bronx Bakery {"date":{"$date":1393804800000},"grade":"A","score":2} Morris Park Bake Shop 30075445
-58ada47de5a51ddfcd5ed51d 469 Flatbush Avenue 11225 Brooklyn Hamburgers {"date":{"$date":1419897600000},"grade":"A","score":8} Wendy'S 30112340
-58ada47de5a51ddfcd5ed51e 351 West 57 Street 10019 Manhattan Irish {"date":{"$date":1409961600000},"grade":"A","score":2} Dj Reynolds Pub And Restaurant 30191841
-58ada47de5a51ddfcd5ed51f 2780 Stillwell Avenue 11224 Brooklyn American {"date":{"$date":1402358400000},"grade":"A","score":5} Riviera Caterer 40356018
-58ada47de5a51ddfcd5ed520 97-22 63 Road 11374 Queens Jewish/Kosher {"date":{"$date":1416787200000},"grade":"Z","score":20} Tov Kosher Kitchen 40356068
+58ada47de5a51ddfcd5ed51c 1007 [-73.856077,40.848447] Morris Park Ave 10462 Bronx Bakery {"date":{"$date":1393804800000},"grade":"A","score":2} Morris Park Bake Shop 30075445
+58ada47de5a51ddfcd5ed51d 469 [-73.961704,40.662942] Flatbush Avenue 11225 Brooklyn Hamburgers {"date":{"$date":1419897600000},"grade":"A","score":8} Wendy'S 30112340
+58ada47de5a51ddfcd5ed51e 351 [-73.985136,40.767692] West 57 Street 10019 Manhattan Irish {"date":{"$date":1409961600000},"grade":"A","score":2} Dj Reynolds Pub And Restaurant 30191841
+58ada47de5a51ddfcd5ed51f 2780 [-73.982420,40.579505] Stillwell Avenue 11224 Brooklyn American {"date":{"$date":1402358400000},"grade":"A","score":5} Riviera Caterer 40356018
+58ada47de5a51ddfcd5ed520 97-22 [-73.860115,40.731174] 63 Road 11374 Queens Jewish/Kosher {"date":{"$date":1416787200000},"grade":"Z","score":20} Tov Kosher Kitchen 40356068
DROP TABLE t1;
#
# Dropping a column
@@ -89,16 +89,16 @@ CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants DATA_CHARSET
COLIST='{"projection":{"grades":0}}' OPTION_LIST='Driver=C,Version=0,level=0' ;
SELECT * FROM t1 LIMIT 10;
_id address borough cuisine name restaurant_id
-58ada47de5a51ddfcd5ed51c {"building":"1007","coord":[-73.856076999999999089,40.848447000000000173],"street":"Morris ParkAve", "zipcode":"10462"} Bronx Bakery Morris Park Bake Shop 30075445
-58ada47de5a51ddfcd5ed51d {"building":"469","coord":[-73.96170399999999745,40.66294200000000103],"street":"Flatbush Avenue", "zipcode":"11225"} Brooklyn Hamburgers Wendy'S 30112340
-58ada47de5a51ddfcd5ed51e {"building":"351","coord":[-73.985135599999992451,40.767691900000002647],"street":"West 57Street", "zipcode":"10019"} Manhattan Irish Dj Reynolds Pub And Restaurant 30191841
-58ada47de5a51ddfcd5ed51f {"building":"2780","coord":[-73.982419999999990523,40.579504999999997494],"street":"Stillwell Avenue", "zipcode":"11224"} Brooklyn American Riviera Caterer 40356018
-58ada47de5a51ddfcd5ed520 {"building":"97-22","coord":[-73.860115199999995639,40.731173900000001709],"street":"63 Road", "zipcode":"11374"} Queens Jewish/Kosher Tov Kosher Kitchen 40356068
-58ada47de5a51ddfcd5ed521 {"building":"8825","coord":[-73.880382699999998408,40.764312400000001446],"street":"Astoria Boulevard", "zipcode":"11369"} Queens American Brunos On The Boulevard 40356151
-58ada47de5a51ddfcd5ed522 {"building":"2206","coord":[-74.137728600000002643,40.611957199999999091],"street":"Victory Boulevard", "zipcode":"10314"} Staten Island Jewish/Kosher Kosher Island 40356442
-58ada47de5a51ddfcd5ed523 {"building":"7114","coord":[-73.906850599999998508,40.619903399999998328],"street":"Avenue U", "zipcode":"11234"} Brooklyn Delicatessen Wilken'S Fine Food 40356483
-58ada47de5a51ddfcd5ed524 {"building":"6409","coord":[-74.005288999999990551,40.628886000000001388],"street":"11 Avenue", "zipcode":"11219"} Brooklyn American Regina Caterers 40356649
-58ada47de5a51ddfcd5ed525 {"building":"1839","coord":[-73.948260899999993967,40.640827100000002758],"street":"Nostrand Avenue", "zipcode":"11226"} Brooklyn Ice Cream, Gelato, Yogurt, Ices Taste The Tropics Ice Cream 40356731
+58ada47de5a51ddfcd5ed51c {"building":"1007","coord":[-73.856077,40.848447],"street":"Morris Park Ave","zipcode":"10462"} Bronx Bakery Morris Park Bake Shop 30075445
+58ada47de5a51ddfcd5ed51d {"building":"469","coord":[-73.961704,40.662942],"street":"Flatbush Avenue","zipcode":"11225"} Brooklyn Hamburgers Wendy'S 30112340
+58ada47de5a51ddfcd5ed51e {"building":"351","coord":[-73.985136,40.767692],"street":"West 57 Street","zipcode":"10019"} Manhattan Irish Dj Reynolds Pub And Restaurant 30191841
+58ada47de5a51ddfcd5ed51f {"building":"2780","coord":[-73.982420,40.579505],"street":"Stillwell Avenue","zipcode":"11224"} Brooklyn American Riviera Caterer 40356018
+58ada47de5a51ddfcd5ed520 {"building":"97-22","coord":[-73.860115,40.731174],"street":"63 Road","zipcode":"11374"} Queens Jewish/Kosher Tov Kosher Kitchen 40356068
+58ada47de5a51ddfcd5ed521 {"building":"8825","coord":[-73.880383,40.764312],"street":"Astoria Boulevard","zipcode":"11369"} Queens American Brunos On The Boulevard 40356151
+58ada47de5a51ddfcd5ed522 {"building":"2206","coord":[-74.137729,40.611957],"street":"Victory Boulevard","zipcode":"10314"} Staten Island Jewish/Kosher Kosher Island 40356442
+58ada47de5a51ddfcd5ed523 {"building":"7114","coord":[-73.906851,40.619903],"street":"Avenue U","zipcode":"11234"} Brooklyn Delicatessen Wilken'S Fine Food 40356483
+58ada47de5a51ddfcd5ed524 {"building":"6409","coord":[-74.005289,40.628886],"street":"11 Avenue","zipcode":"11219"} Brooklyn American Regina Caterers 40356649
+58ada47de5a51ddfcd5ed525 {"building":"1839","coord":[-73.948261,40.640827],"street":"Nostrand Avenue","zipcode":"11226"} Brooklyn Ice Cream, Gelato, Yogurt, Ices Taste The Tropics Ice Cream 40356731
DROP TABLE t1;
#
# Specifying Jpath
@@ -249,14 +249,14 @@ SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL,
- `address_building` char(6) NOT NULL `FIELD_FORMAT`='address.building',
- `address_coord_0` double(12,6) NOT NULL `FIELD_FORMAT`='address.coord.0',
- `address_street` char(25) NOT NULL `FIELD_FORMAT`='address.street',
- `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
+ `address_building` char(6) NOT NULL `JPATH`='address.building',
+ `address_coord_0` double(12,6) NOT NULL `JPATH`='address.coord.0',
+ `address_street` char(25) NOT NULL `JPATH`='address.street',
+ `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL,
- `grades_0_date` datetime NOT NULL `FIELD_FORMAT`='grades.0.date',
- `grades_0_grade` char(14) NOT NULL `FIELD_FORMAT`='grades.0.grade',
- `grades_0_score` int(11) NOT NULL `FIELD_FORMAT`='grades.0.score',
+ `grades_0_date` datetime NOT NULL `JPATH`='grades.0.date',
+ `grades_0_grade` char(14) NOT NULL `JPATH`='grades.0.grade',
+ `grades_0_score` int(11) NOT NULL `JPATH`='grades.0.score',
`name` char(32) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `COLIST`='{"projection":{"cuisine":0}}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=C,level=2,version=0'
diff --git a/storage/connect/mysql-test/connect/r/mongo_java_2.result b/storage/connect/mysql-test/connect/r/mongo_java_2.result
index cccda2760d6..bcedd717cc4 100644
--- a/storage/connect/mysql-test/connect/r/mongo_java_2.result
+++ b/storage/connect/mysql-test/connect/r/mongo_java_2.result
@@ -64,13 +64,13 @@ SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL,
- `address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
- `address_coord` char(41) NOT NULL `FIELD_FORMAT`='address.coord',
- `address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
- `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
+ `address_building` char(10) NOT NULL `JPATH`='address.building',
+ `address_coord` char(41) NOT NULL `JPATH`='address.coord',
+ `address_street` char(38) NOT NULL `JPATH`='address.street',
+ `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL,
- `grades_0` char(99) DEFAULT NULL `FIELD_FORMAT`='grades.0',
+ `grades_0` char(99) DEFAULT NULL `JPATH`='grades.0',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `OPTION_LIST`='Depth=1,Driver=Java,Version=2' `DATA_CHARSET`='utf8'
@@ -249,14 +249,14 @@ SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL,
- `address_building` char(6) NOT NULL `FIELD_FORMAT`='address.building',
- `address_coord_0` double(18,14) NOT NULL `FIELD_FORMAT`='address.coord.0',
- `address_street` char(25) NOT NULL `FIELD_FORMAT`='address.street',
- `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
+ `address_building` char(6) NOT NULL `JPATH`='address.building',
+ `address_coord_0` double(18,14) NOT NULL `JPATH`='address.coord.0',
+ `address_street` char(25) NOT NULL `JPATH`='address.street',
+ `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL,
- `grades_0_date` datetime NOT NULL `FIELD_FORMAT`='grades.0.date',
- `grades_0_grade` char(14) NOT NULL `FIELD_FORMAT`='grades.0.grade',
- `grades_0_score` int(2) NOT NULL `FIELD_FORMAT`='grades.0.score',
+ `grades_0_date` datetime NOT NULL `JPATH`='grades.0.date',
+ `grades_0_grade` char(14) NOT NULL `JPATH`='grades.0.grade',
+ `grades_0_score` int(2) NOT NULL `JPATH`='grades.0.score',
`name` char(32) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=2'
diff --git a/storage/connect/mysql-test/connect/r/mongo_java_3.result b/storage/connect/mysql-test/connect/r/mongo_java_3.result
index ae39148a156..3183d4984d6 100644
--- a/storage/connect/mysql-test/connect/r/mongo_java_3.result
+++ b/storage/connect/mysql-test/connect/r/mongo_java_3.result
@@ -64,13 +64,13 @@ SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL,
- `address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
- `address_coord` char(39) NOT NULL `FIELD_FORMAT`='address.coord',
- `address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
- `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
+ `address_building` char(10) NOT NULL `JPATH`='address.building',
+ `address_coord` char(39) NOT NULL `JPATH`='address.coord',
+ `address_street` char(38) NOT NULL `JPATH`='address.street',
+ `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL,
- `grades_0` char(84) DEFAULT NULL `FIELD_FORMAT`='grades.0',
+ `grades_0` char(84) DEFAULT NULL `JPATH`='grades.0',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `OPTION_LIST`='Depth=1,Driver=Java,Version=3' `DATA_CHARSET`='utf8'
@@ -249,14 +249,14 @@ SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL,
- `address_building` char(6) NOT NULL `FIELD_FORMAT`='address.building',
- `address_coord_0` double(18,14) NOT NULL `FIELD_FORMAT`='address.coord.0',
- `address_street` char(25) NOT NULL `FIELD_FORMAT`='address.street',
- `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
+ `address_building` char(6) NOT NULL `JPATH`='address.building',
+ `address_coord_0` double(18,14) NOT NULL `JPATH`='address.coord.0',
+ `address_street` char(25) NOT NULL `JPATH`='address.street',
+ `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL,
- `grades_0_date` datetime NOT NULL `FIELD_FORMAT`='grades.0.date',
- `grades_0_grade` char(14) NOT NULL `FIELD_FORMAT`='grades.0.grade',
- `grades_0_score` int(2) NOT NULL `FIELD_FORMAT`='grades.0.score',
+ `grades_0_date` datetime NOT NULL `JPATH`='grades.0.date',
+ `grades_0_grade` char(14) NOT NULL `JPATH`='grades.0.grade',
+ `grades_0_score` int(2) NOT NULL `JPATH`='grades.0.score',
`name` char(32) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=3'
diff --git a/storage/connect/mysql-test/connect/r/odbc_oracle.result b/storage/connect/mysql-test/connect/r/odbc_oracle.result
index acb7d9a74c9..317aacef7a9 100644
--- a/storage/connect/mysql-test/connect/r/odbc_oracle.result
+++ b/storage/connect/mysql-test/connect/r/odbc_oracle.result
@@ -10,7 +10,7 @@ SET NAMES utf8;
# All tables in all schemas (filtered with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Tables;
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Table_Type Remark
@@ -20,7 +20,7 @@ NULL MTR V1 VIEW NULL
DROP TABLE t1;
# All tables in all schemas (filtered with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Tables TABNAME='%.%';
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Table_Type Remark
@@ -30,7 +30,7 @@ NULL MTR V1 VIEW NULL
DROP TABLE t1;
# All tables "T1" in all schemas (filtered with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Tables TABNAME='%.T1';
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Table_Type Remark
@@ -38,7 +38,7 @@ NULL MTR T1 TABLE NULL
DROP TABLE t1;
# All tables "T1" in all schemas (filtered with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Tables TABNAME='T1';
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Table_Type Remark
@@ -46,7 +46,7 @@ NULL MTR T1 TABLE NULL
DROP TABLE t1;
# Table "T1" in the schema "MTR"
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Tables TABNAME='MTR.T1';
SELECT * FROM t1 ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Table_Type Remark
@@ -54,7 +54,7 @@ NULL MTR T1 TABLE NULL
DROP TABLE t1;
# All tables in the schema "MTR"
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Tables TABNAME='MTR.%';
SELECT * FROM t1 ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Table_Type Remark
@@ -68,7 +68,7 @@ DROP TABLE t1;
# All columns in all schemas (limited with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Columns;
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
@@ -80,7 +80,7 @@ Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Bu
DROP TABLE t1;
# All columns in all schemas (limited with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Columns TABNAME='%.%';
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
@@ -91,7 +91,7 @@ Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Bu
MTR V1 B 6 NUMBER 38 40 NULL NULL 1
DROP TABLE t1;
# All tables "T1" in all schemas (limited with WHERE)
-CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' CATFUNC=Columns TABNAME='%.T1';
+CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Columns TABNAME='%.T1';
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
MTR T1 A 3 DECIMAL 38 40 0 10 1
@@ -99,7 +99,7 @@ Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Bu
DROP TABLE t1;
# Table "T1" in the schema "MTR"
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Columns TABNAME='MTR.T1';
SELECT * FROM t1 ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
@@ -108,7 +108,7 @@ Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Bu
DROP TABLE t1;
# All tables "T1" in all schemas (filtered with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Columns TABNAME='%.T1';
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
@@ -121,14 +121,14 @@ DROP TABLE t1;
# Table "T1" in the default schema ("MTR")
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
TABNAME='T1';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`A` decimal(40,0) DEFAULT NULL,
`B` double DEFAULT NULL
-) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' `TABLE_TYPE`='ODBC' `TABNAME`='T1'
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' `TABLE_TYPE`='ODBC' `TABNAME`='T1'
SELECT * FROM t1 ORDER BY A;
A B
10 1000000000
@@ -157,14 +157,14 @@ DROP VIEW v1;
DROP TABLE t1;
# Table "T1" in the schema "MTR"
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
TABNAME='MTR.T1';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`A` decimal(40,0) DEFAULT NULL,
`B` double DEFAULT NULL
-) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.T1'
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.T1'
SELECT * FROM t1;
A B
10 1000000000
@@ -173,14 +173,14 @@ A B
DROP TABLE t1;
# View "V1" in the schema "MTR"
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
TABNAME='MTR.V1';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`A` decimal(40,0) DEFAULT NULL,
`B` double DEFAULT NULL
-) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.V1'
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.V1'
SELECT * FROM t1;
A B
10 1000000000
@@ -209,13 +209,13 @@ DROP VIEW v1;
DROP TABLE t1;
# Table "T2" in the schema "MTR"
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
TABNAME='MTR.T2';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`A` varchar(64) DEFAULT NULL
-) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.T2'
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.T2'
SELECT * FROM t1;
A
test
diff --git a/storage/connect/mysql-test/connect/std_data/Mongo2.jar b/storage/connect/mysql-test/connect/std_data/Mongo2.jar
index 9be654bd4c8..d51cc5d2345 100644
--- a/storage/connect/mysql-test/connect/std_data/Mongo2.jar
+++ b/storage/connect/mysql-test/connect/std_data/Mongo2.jar
Binary files differ
diff --git a/storage/connect/mysql-test/connect/std_data/Mongo3.jar b/storage/connect/mysql-test/connect/std_data/Mongo3.jar
index 2850177a668..f84e089ef50 100644
--- a/storage/connect/mysql-test/connect/std_data/Mongo3.jar
+++ b/storage/connect/mysql-test/connect/std_data/Mongo3.jar
Binary files differ
diff --git a/storage/connect/mysql-test/connect/t/jdbc.test b/storage/connect/mysql-test/connect/t/jdbc.test
index 58a527a3e6b..79809f4eaf3 100644
--- a/storage/connect/mysql-test/connect/t/jdbc.test
+++ b/storage/connect/mysql-test/connect/t/jdbc.test
@@ -1,6 +1,7 @@
-- source windows.inc
-- source jdbconn.inc
-SET GLOBAL time_zone='+1:00';
+SET GLOBAL time_zone='+0:00';
+SET time_zone='+0:00';
let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/girls.txt $MYSQLD_DATADIR/test/girls.txt
@@ -27,7 +28,7 @@ SELECT * FROM t2;
--echo #
USE test;
--replace_result $PORT PORT
---eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=t2 CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root'
+--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=t2 CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root&useSSL=false'
SELECT * FROM t1;
INSERT INTO t1 VALUES(786325481247, 'Hello!', '19:45:03', '1933-08-10', '1985-11-12 09:02:44', '2014-06-17 10:32:01');
SELECT * FROM t1;
@@ -39,7 +40,7 @@ DROP TABLE t1;
--echo # Testing JDBC view
--echo #
--replace_result $PORT PORT
---eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC SRCDEF='select id, msg, tm, dt from t2' CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root'
+--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC SRCDEF='select id, msg, tm, dt from t2' CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root&useSSL=false'
SELECT * FROM t1;
SELECT msg, dt FROM t1;
DROP TABLE t1, connect.t2;
@@ -67,7 +68,7 @@ INSERT INTO t3 VALUES('Donald','Atlanta','1999-04-01','2016-03-31'),('Mick','New
SELECT * FROM t3;
--replace_result $PORT PORT
---eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=boys CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root' OPTION_LIST='scrollable=1'
+--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=boys CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root&useSSL=false' OPTION_LIST='scrollable=1'
SELECT * FROM t1;
UPDATE t1 SET city = 'Phoenix' WHERE name = 'Henry';
INSERT INTO t1 SELECT * FROM t3;
@@ -145,4 +146,5 @@ DROP TABLE connect.tx1;
DROP DATABASE connect;
--remove_file $MYSQLD_DATADIR/test/girls.txt
SET GLOBAL time_zone=SYSTEM;
+SET time_zone=SYSTEM;
-- source jdbconn_cleanup.inc
diff --git a/storage/connect/mysql-test/connect/t/jdbc_new.test b/storage/connect/mysql-test/connect/t/jdbc_new.test
index 36e8f36ced0..1eaafdfbf43 100644
--- a/storage/connect/mysql-test/connect/t/jdbc_new.test
+++ b/storage/connect/mysql-test/connect/t/jdbc_new.test
@@ -9,7 +9,8 @@ connection master;
-- source jdbconn.inc
connection slave;
-SET GLOBAL time_zone='+1:00';
+SET GLOBAL time_zone='+0:00';
+SET time_zone='+0:00';
CREATE TABLE t1 (a int, b char(10));
INSERT INTO t1 VALUES (NULL,NULL),(0,'test00'),(1,'test01'),(2,'test02'),(3,'test03');
@@ -19,33 +20,34 @@ SELECT * FROM t1;
--echo # Testing errors
--echo #
connection master;
-SET GLOBAL time_zone='+1:00';
+SET GLOBAL time_zone='+0:00';
+SET time_zone='+0:00';
# Bad user name
# Suppress "mysql_real_connect failed:" (printed in _DEBUG build)
--replace_result $SLAVE_MYPORT SLAVE_PORT "mysql_real_connect failed: " ""
--error ER_UNKNOWN_ERROR
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
- CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=unknown';
+ CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=unknown&useSSL=false';
# Bad database name
--replace_result $SLAVE_MYPORT SLAVE_PORT "mysql_real_connect failed: " ""
--error ER_UNKNOWN_ERROR
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
- CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/unknown?user=root';
+ CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/unknown?user=root&useSSL=false';
# Bad table name
--replace_result $SLAVE_MYPORT SLAVE_PORT
--error ER_UNKNOWN_ERROR
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='unknown'
- CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root';
+ CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false';
--error ER_NO_SUCH_TABLE
SHOW CREATE TABLE t1;
# Bad column name
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE t1 (x int, y char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC
- CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root';
+ CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false';
--replace_result $SLAVE_MYPORT SLAVE_PORT
SHOW CREATE TABLE t1;
--error ER_GET_ERRMSG
@@ -55,7 +57,7 @@ DROP TABLE t1;
# The remote table disappeared
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC
- CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root';
+ CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false';
connection slave;
ALTER TABLE t1 RENAME t1backup;
@@ -77,7 +79,7 @@ DROP TABLE t1;
# Automatic table structure
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
- CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root';
+ CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false';
--replace_result $SLAVE_MYPORT SLAVE_PORT
SHOW CREATE TABLE t1;
SELECT * FROM t1;
@@ -86,7 +88,7 @@ DROP TABLE t1;
# Explicit table structure
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='t1'
- CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root';
+ CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false';
--replace_result $SLAVE_MYPORT SLAVE_PORT
SHOW CREATE TABLE t1;
SELECT * FROM t1;
@@ -95,7 +97,7 @@ DROP TABLE t1;
# Explicit table structure: remote NULL, local NOT NULL
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE t1 (a INT NOT NULL, b CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=JDBC
- CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root';
+ CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false';
--replace_result $SLAVE_MYPORT SLAVE_PORT
SHOW CREATE TABLE t1;
SELECT * FROM t1;
@@ -104,7 +106,7 @@ DROP TABLE t1;
# Explicit table structure with wrong column types
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE t1 (a char(10), b int) ENGINE=CONNECT TABLE_TYPE=JDBC
- CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root';
+ CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false';
--replace_result $SLAVE_MYPORT SLAVE_PORT
SHOW CREATE TABLE t1;
SELECT * FROM t1;
@@ -125,7 +127,7 @@ INSERT INTO t1 VALUES(100,3333,41235,1234567890,235000000000,3.14159265,3.141592
connection master;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
- CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root';
+ CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false';
--replace_result $SLAVE_MYPORT SLAVE_PORT
SHOW CREATE TABLE t1;
SELECT * FROM t1;
@@ -146,7 +148,7 @@ SELECT * FROM t1;
connection master;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
- CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root';
+ CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false';
--replace_result $SLAVE_MYPORT SLAVE_PORT
SHOW CREATE TABLE t1;
SELECT * FROM t1;
@@ -167,7 +169,7 @@ SELECT * FROM t1;
connection master;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
- CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root';
+ CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false';
--replace_result $SLAVE_MYPORT SLAVE_PORT
SHOW CREATE TABLE t1;
SELECT * FROM t1;
@@ -176,8 +178,10 @@ DROP TABLE t1;
connection slave;
DROP TABLE t1;
SET GLOBAL time_zone=SYSTEM;
+SET time_zone=SYSTEM;
connection master;
SET GLOBAL time_zone=SYSTEM;
+SET time_zone=SYSTEM;
-- source jdbconn_cleanup.inc
diff --git a/storage/connect/mysql-test/connect/t/jdbc_oracle.test b/storage/connect/mysql-test/connect/t/jdbc_oracle.test
index 1316352d4f5..0a475102ff7 100644
--- a/storage/connect/mysql-test/connect/t/jdbc_oracle.test
+++ b/storage/connect/mysql-test/connect/t/jdbc_oracle.test
@@ -8,20 +8,20 @@ CREATE TABLE t2 (
number int(5) not null flag=1,
message varchar(255) flag=2)
ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:oracle:thin:@localhost:1521:xe'
-OPTION_LIST='User=system,Password=Choupy01,Execsrc=1';
+OPTION_LIST='User=system,Password=Biscote01,Execsrc=1';
SELECT * FROM t2 WHERE command = 'drop table employee';
SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary number(8,2))';
SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)";
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables
CONNECTION='jdbc:oracle:thin:@localhost:1521:xe'
-OPTION_LIST='User=system,Password=Choupy01';
+OPTION_LIST='User=system,Password=Biscote01';
SELECT * FROM t1 WHERE table_name='employee';
DROP TABLE t1;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='EMPLOYEE' CATFUNC=columns
CONNECTION='jdbc:oracle:thin:@localhost:1521:xe'
-OPTION_LIST='User=system,Password=Choupy01';
+OPTION_LIST='User=system,Password=Biscote01';
SELECT * FROM t1;
DROP TABLE t1;
@@ -32,7 +32,7 @@ CREATE SERVER 'oracle' FOREIGN DATA WRAPPER 'oracle.jdbc.driver.OracleDriver' OP
HOST 'jdbc:oracle:thin:@localhost:1521:xe',
DATABASE 'SYSTEM',
USER 'system',
-PASSWORD 'Choupy01',
+PASSWORD 'Biscote01',
PORT 0,
SOCKET '',
OWNER 'SYSTEM');
diff --git a/storage/connect/mysql-test/connect/t/odbc_oracle.test b/storage/connect/mysql-test/connect/t/odbc_oracle.test
index 18d29f69f1a..2a6eb5b7fce 100644
--- a/storage/connect/mysql-test/connect/t/odbc_oracle.test
+++ b/storage/connect/mysql-test/connect/t/odbc_oracle.test
@@ -78,42 +78,42 @@ SET NAMES utf8;
--echo # All tables in all schemas (filtered with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Tables;
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
DROP TABLE t1;
--echo # All tables in all schemas (filtered with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Tables TABNAME='%.%';
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
DROP TABLE t1;
--echo # All tables "T1" in all schemas (filtered with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Tables TABNAME='%.T1';
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
DROP TABLE t1;
--echo # All tables "T1" in all schemas (filtered with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Tables TABNAME='T1';
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
DROP TABLE t1;
--echo # Table "T1" in the schema "MTR"
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Tables TABNAME='MTR.T1';
SELECT * FROM t1 ORDER BY Table_Schema, Table_Name;
DROP TABLE t1;
--echo # All tables in the schema "MTR"
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Tables TABNAME='MTR.%';
SELECT * FROM t1 ORDER BY Table_Schema, Table_Name;
DROP TABLE t1;
@@ -127,7 +127,7 @@ DROP TABLE t1;
--echo # All columns in all schemas (limited with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Columns;
# Disable warnings to avoid "Result limited to 20000 lines"
--disable_warnings
@@ -137,7 +137,7 @@ DROP TABLE t1;
--echo # All columns in all schemas (limited with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Columns TABNAME='%.%';
# Disable warnings to avoid "Result limited to 20000 lines"
--disable_warnings
@@ -146,20 +146,20 @@ SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
DROP TABLE t1;
--echo # All tables "T1" in all schemas (limited with WHERE)
-CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' CATFUNC=Columns TABNAME='%.T1';
+CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Columns TABNAME='%.T1';
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
DROP TABLE t1;
--echo # Table "T1" in the schema "MTR"
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Columns TABNAME='MTR.T1';
SELECT * FROM t1 ORDER BY Table_Schema, Table_Name;
DROP TABLE t1;
--echo # All tables "T1" in all schemas (filtered with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
CATFUNC=Columns TABNAME='%.T1';
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
DROP TABLE t1;
@@ -172,7 +172,7 @@ DROP TABLE t1;
--echo # Table "T1" in the default schema ("MTR")
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
TABNAME='T1';
SHOW CREATE TABLE t1;
SELECT * FROM t1 ORDER BY A;
@@ -189,7 +189,7 @@ DROP TABLE t1;
--echo # Table "T1" in the schema "MTR"
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
TABNAME='MTR.T1';
SHOW CREATE TABLE t1;
SELECT * FROM t1;
@@ -197,7 +197,7 @@ DROP TABLE t1;
--echo # View "V1" in the schema "MTR"
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
TABNAME='MTR.V1';
SHOW CREATE TABLE t1;
SELECT * FROM t1;
@@ -214,7 +214,7 @@ DROP TABLE t1;
--echo # Table "T2" in the schema "MTR"
CREATE TABLE t1 ENGINE=CONNECT
-TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr'
+TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew'
TABNAME='MTR.T2';
SHOW CREATE TABLE t1;
SELECT * FROM t1;
diff --git a/storage/connect/myutil.cpp b/storage/connect/myutil.cpp
index e53ee1310e4..c49db48bfb3 100644
--- a/storage/connect/myutil.cpp
+++ b/storage/connect/myutil.cpp
@@ -13,11 +13,11 @@
/************************************************************************/
#include "my_global.h"
#include <mysql.h>
-#if defined(__WIN__)
+#if defined(_WIN32)
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
#include "osutil.h"
-#endif // !__WIN__
+#endif // !_WIN32
#include "global.h"
#include "plgdbsem.h"
diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp
index d08c6d1b7a5..5b20b33e240 100644
--- a/storage/connect/odbconn.cpp
+++ b/storage/connect/odbconn.cpp
@@ -11,7 +11,7 @@
/***********************************************************************/
#include <my_global.h>
#include <m_string.h>
-#if defined(__WIN__)
+#if defined(_WIN32)
//nclude <io.h>
//nclude <fcntl.h>
#include <direct.h> // for getcwd
@@ -45,13 +45,13 @@
#include "osutil.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
/***********************************************************************/
/* For dynamic load of ODBC32.DLL */
/***********************************************************************/
#pragma comment(lib, "odbc32.lib")
extern "C" HINSTANCE s_hModule; // Saved module handle
-#endif // __WIN__
+#endif // _WIN32
TYPCONV GetTypeConv();
int GetConvSize();
@@ -1280,15 +1280,15 @@ bool ODBConn::DriverConnect(DWORD Options)
SWORD nResult;
PUCHAR ConnOut = (PUCHAR)PlugSubAlloc(m_G, NULL, MAX_CONNECT_LEN);
UWORD wConnectOption = SQL_DRIVER_COMPLETE;
-#if defined(__WIN__)
+#if defined(_WIN32)
HWND hWndTop = GetForegroundWindow();
HWND hWnd = GetParent(hWndTop);
if (hWnd == NULL)
hWnd = GetDesktopWindow();
-#else // !__WIN__
+#else // !_WIN32
HWND hWnd = (HWND)1;
-#endif // !__WIN__
+#endif // !_WIN32
PGLOBAL& g = m_G;
PDBUSER dup = PlgGetUser(g);
@@ -1301,10 +1301,10 @@ bool ODBConn::DriverConnect(DWORD Options)
SQL_NTS, ConnOut, MAX_CONNECT_LEN,
&nResult, wConnectOption);
-#if defined(__WIN__)
+#if defined(_WIN32)
if (hWndTop)
EnableWindow(hWndTop, true);
-#endif // __WIN__
+#endif // _WIN32
// If user hit 'Cancel'
if (rc == SQL_NO_DATA_FOUND) {
diff --git a/storage/connect/odbconn.h b/storage/connect/odbconn.h
index f98c67bd12f..7038f06e5f3 100644
--- a/storage/connect/odbconn.h
+++ b/storage/connect/odbconn.h
@@ -29,9 +29,9 @@
//efine MAX_CURSOR_NAME 18 // Max size of a cursor name
//efine DEFAULT_FIELD_TYPE SQL_TYPE_NULL // pick "C" data type to match SQL data type
-#if !defined(__WIN__)
+#if !defined(_WIN32)
typedef unsigned char *PUCHAR;
-#endif // !__WIN__
+#endif // !_WIN32
// Field Flags, used to indicate status of fields
//efine SQL_FIELD_FLAG_DIRTY 0x1
diff --git a/storage/connect/os.h b/storage/connect/os.h
index 797692d47b2..7d0d5cabbb6 100644
--- a/storage/connect/os.h
+++ b/storage/connect/os.h
@@ -16,19 +16,19 @@ typedef off_t off64_t;
#endif
#endif
-#if defined(__WIN__)
+#if defined(_WIN32)
typedef __int64 BIGINT;
typedef _Null_terminated_ const char *PCSZ;
-#else // !__WIN__
+#else // !_WIN32
typedef longlong BIGINT;
#define FILE_BEGIN SEEK_SET
#define FILE_CURRENT SEEK_CUR
#define FILE_END SEEK_END
typedef const char *PCSZ;
-#endif // !__WIN__
+#endif // !_WIN32
-#if !defined(__WIN__)
+#if !defined(_WIN32)
typedef const void *LPCVOID;
typedef const char *LPCTSTR;
typedef const char *LPCSTR;
@@ -65,6 +65,6 @@ typedef int HANDLE;
#define _MAX_EXT FN_EXTLEN
#define INVALID_HANDLE_VALUE (-1)
#define __stdcall
-#endif /* !__WIN__ */
+#endif /* !_WIN32 */
#endif /* _OS_H_INCLUDED */
diff --git a/storage/connect/osutil.c b/storage/connect/osutil.c
index da896fec50e..278023f55a2 100644
--- a/storage/connect/osutil.c
+++ b/storage/connect/osutil.c
@@ -5,7 +5,7 @@
#include <stdio.h>
#include "osutil.h"
-#ifdef __WIN__
+#ifdef _WIN32
my_bool CloseFileHandle(HANDLE h)
{
return !CloseHandle(h);
diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h
index dd204d065ed..370bf69ffa0 100644
--- a/storage/connect/plgdbsem.h
+++ b/storage/connect/plgdbsem.h
@@ -581,11 +581,11 @@ typedef struct _colres {
char Var; /* Type added information */
} COLRES;
-#if defined(__WIN__) && !defined(NOEX)
+#if defined(_WIN32) && !defined(NOEX)
#define DllExport __declspec( dllexport )
-#else // !__WIN__
+#else // !_WIN32
#define DllExport
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Utility routines. */
diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp
index 90d3cd00d5e..3624420dfed 100644
--- a/storage/connect/plgdbutl.cpp
+++ b/storage/connect/plgdbutl.cpp
@@ -39,12 +39,12 @@
/***********************************************************************/
#include "my_global.h"
#include "my_pthread.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <io.h>
#include <fcntl.h>
#include <errno.h>
#define BIGMEM 1048576 // 1 Megabyte
-#else // !__WIN__
+#else // !_WIN32
#include <unistd.h>
#include <fcntl.h>
//#if defined(THREAD)
@@ -52,7 +52,7 @@
//#endif // THREAD
#include <stdarg.h>
#define BIGMEM 2147483647 // Max int value
-#endif // !__WIN__
+#endif // !_WIN32
#include <locale.h>
/***********************************************************************/
@@ -89,11 +89,11 @@ extern "C" {
extern char version[];
} // extern "C"
-//#if defined(__WIN__)
+//#if defined(_WIN32)
//extern CRITICAL_SECTION parsec; // Used calling the Flex parser
-//#else // !__WIN__
+//#else // !_WIN32
extern pthread_mutex_t parmut;
-//#endif // !__WIN__
+//#endif // !_WIN32
// The debug trace used by the main thread
FILE *pfile = NULL;
@@ -386,11 +386,11 @@ char *SetPath(PGLOBAL g, const char *path)
} // endif path
if (*path != '.') {
-#if defined(__WIN__)
+#if defined(_WIN32)
const char *s = "\\";
-#else // !__WIN__
+#else // !_WIN32
const char *s = "/";
-#endif // !__WIN__
+#endif // !_WIN32
strcat(strcat(strcat(strcpy(buf, "."), s), path), s);
} else
strcpy(buf, path);
@@ -409,7 +409,7 @@ char *ExtractFromPath(PGLOBAL g, char *pBuff, char *FileName, OPVAL op)
char *drive = NULL, *direc = NULL, *fname = NULL, *ftype = NULL;
switch (op) { // Determine which part to extract
-#if defined(__WIN__)
+#if defined(_WIN32)
case OP_FDISK: drive = pBuff; break;
#endif // !UNIX
case OP_FPATH: direc = pBuff; break;
@@ -1251,7 +1251,7 @@ void *PlgDBalloc(PGLOBAL g, void *area, MBLOCK& mp)
// For allocations greater than one fourth of remaining storage
// in the area, do allocate from virtual storage.
const char*v = "malloc";
-#if defined(__WIN__)
+#if defined(_WIN32)
if (mp.Size >= BIGMEM) {
v = "VirtualAlloc";
mp.Memp = VirtualAlloc(NULL, mp.Size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
@@ -1354,7 +1354,7 @@ void PlgDBfree(MBLOCK& mp)
{
if (!mp.Sub && mp.Memp) {
const char*v = "free";
-#if defined(__WIN__)
+#if defined(_WIN32)
if (mp.Size >= BIGMEM) {
v = "VirtualFree";
VirtualFree(mp.Memp, 0, MEM_RELEASE);
@@ -1556,11 +1556,11 @@ int FileComp(PGLOBAL g, char *file1, char *file2)
bp[0] = buff1; bp[1] = buff2;
for (i = 0; i < 2; i++) {
-#if defined(__WIN__)
+#if defined(_WIN32)
h[i]= global_open(g, MSGID_NONE, fn[i], _O_RDONLY | _O_BINARY);
-#else // !__WIN__
+#else // !_WIN32
h[i]= global_open(g, MSGOD_NONE, fn[i], O_RDONLY);
-#endif // !__WIN__
+#endif // !_WIN32
if (h[i] == -1) {
// if (errno != ENOENT) {
diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp
index f2887987c3f..a63eee75c1b 100644
--- a/storage/connect/plugutil.cpp
+++ b/storage/connect/plugutil.cpp
@@ -44,7 +44,7 @@
/* */
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
//#include <windows.h>
#else
#if defined(UNIX) || defined(UNIV_LINUX)
@@ -81,9 +81,9 @@
#include "rcmsg.h"
#endif // NEWMSG
-#if defined(__WIN__)
+#if defined(_WIN32)
extern HINSTANCE s_hModule; /* Saved module handle */
-#endif // __WIN__
+#endif // _WIN32
#if defined(XMSG)
extern char *msg_path;
@@ -205,7 +205,7 @@ PGLOBAL PlugExit(PGLOBAL g)
/***********************************************************************/
LPSTR PlugRemoveType(LPSTR pBuff, LPCSTR FileName)
{
-#if defined(__WIN__)
+#if defined(_WIN32)
char drive[_MAX_DRIVE];
#else
char *drive = NULL;
@@ -232,7 +232,7 @@ LPSTR PlugRemoveType(LPSTR pBuff, LPCSTR FileName)
BOOL PlugIsAbsolutePath(LPCSTR path)
{
-#if defined(__WIN__)
+#if defined(_WIN32)
return ((path[0] >= 'a' && path[0] <= 'z') ||
(path[0] >= 'A' && path[0] <= 'Z')) && path[1] == ':';
#else
@@ -250,7 +250,7 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath)
char direc[_MAX_DIR], defdir[_MAX_DIR], tmpdir[_MAX_DIR];
char fname[_MAX_FNAME];
char ftype[_MAX_EXT];
-#if defined(__WIN__)
+#if defined(_WIN32)
char drive[_MAX_DRIVE], defdrv[_MAX_DRIVE];
#else
char *drive = NULL, *defdrv = NULL;
@@ -270,7 +270,7 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath)
return pBuff;
} // endif
-#if !defined(__WIN__)
+#if !defined(_WIN32)
if (*FileName == '~') {
if (_fullpath(pBuff, FileName, _MAX_PATH)) {
if (trace(2))
@@ -281,7 +281,7 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath)
return FileName; // Error, return unchanged name
} // endif FileName
-#endif // !__WIN__
+#endif // !_WIN32
if (prefix && strcmp(prefix, ".") && !PlugIsAbsolutePath(defpath))
{
@@ -310,7 +310,7 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath)
if (trace(2)) {
htrc("after _splitpath: FileName=%-.256s\n", FileName);
-#if defined(__WIN__)
+#if defined(_WIN32)
htrc("drive=%-.256s dir=%-.256s fname=%-.256s ext=%-.256s\n", drive, direc, fname, ftype);
htrc("defdrv=%-.256s defdir=%-.256s\n", defdrv, defdir);
#else
@@ -442,7 +442,7 @@ char *PlugGetMessage(PGLOBAL g, int mid)
} // end of PlugGetMessage
#endif // NEWMSG
-#if defined(__WIN__)
+#if defined(_WIN32)
/***********************************************************************/
/* Return the line length of the console screen buffer. */
/***********************************************************************/
@@ -454,7 +454,7 @@ short GetLineLength(PGLOBAL g)
return (b) ? coninfo.dwSize.X : 0;
} // end of GetLineLength
-#endif // __WIN__
+#endif // _WIN32
/***********************************************************************/
/* Program for memory allocation of work and language areas. */
@@ -464,7 +464,7 @@ bool AllocSarea(PGLOBAL g, size_t size)
/*********************************************************************/
/* This is the allocation routine for the WIN32/UNIX/AIX version. */
/*********************************************************************/
-#if defined(__WIN__)
+#if defined(_WIN32)
if (size >= 1048576) // 1M
g->Sarea = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
else
@@ -500,7 +500,7 @@ bool AllocSarea(PGLOBAL g, size_t size)
void FreeSarea(PGLOBAL g)
{
if (g->Sarea) {
-#if defined(__WIN__)
+#if defined(_WIN32)
if (g->Sarea_Size >= 1048576) // 1M
VirtualFree(g->Sarea, 0, MEM_RELEASE);
else
diff --git a/storage/connect/rcmsg.c b/storage/connect/rcmsg.c
index 895f8f5862b..4cd443d88bb 100644
--- a/storage/connect/rcmsg.c
+++ b/storage/connect/rcmsg.c
@@ -21,9 +21,9 @@
#include "msgid.h"
#endif // NEWMSG
-#if !defined(__WIN__)
+#if !defined(_WIN32)
#define stricmp strcasecmp
-#endif // !__WIN__
+#endif // !_WIN32
char *msglang(void);
diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp
index 5b97377db97..39761fc2f18 100644
--- a/storage/connect/reldef.cpp
+++ b/storage/connect/reldef.cpp
@@ -17,7 +17,7 @@
/* Include relevant MariaDB header file. */
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <sqlext.h>
#else
//#include <dlfcn.h> // dlopen(), dlclose(), dlsym() ...
@@ -52,9 +52,9 @@
#include "ha_connect.h"
#include "mycat.h"
-#if !defined(__WIN__)
+#if !defined(_WIN32)
extern handlerton *connect_hton;
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* External function. */
@@ -71,11 +71,11 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info)
typedef PQRYRES(__stdcall* XCOLDEF) (PGLOBAL, void*, char*, char*, bool);
const char* module, * subtype;
char c, soname[_MAX_PATH], getname[40] = "Col";
-#if defined(__WIN__)
+#if defined(_WIN32)
HANDLE hdll; /* Handle to the external DLL */
-#else // !__WIN__
+#else // !_WIN32
void* hdll; /* Handle for the loaded shared library */
-#endif // !__WIN__
+#endif // !_WIN32
XCOLDEF coldef = NULL;
PQRYRES qrp = NULL;
@@ -93,8 +93,7 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info)
if (check_valid_path(module, strlen(module))) {
strcpy(g->Message, "Module cannot contain a path");
return NULL;
- }
- else
+ } else
PlugSetPath(soname, module, GetPluginDir());
// The exported name is always in uppercase
@@ -104,7 +103,7 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info)
if (!c) break;
} // endfor i
-#if defined(__WIN__)
+#if defined(_WIN32)
// Load the Dll implementing the table
if (!(hdll = LoadLibrary(soname))) {
char buf[256];
@@ -124,7 +123,7 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info)
FreeLibrary((HMODULE)hdll);
return NULL;
} // endif coldef
-#else // !__WIN__
+#else // !_WIN32
const char* error = NULL;
// Load the desired shared library
@@ -141,7 +140,7 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info)
dlclose(hdll);
return NULL;
} // endif coldef
-#endif // !__WIN__
+#endif // !_WIN32
// Just in case the external Get function does not set error messages
sprintf(g->Message, "Error getting column info from %s", subtype);
@@ -149,11 +148,11 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info)
// Get the table column definition
qrp = coldef(g, topt, tab, db, info);
-#if defined(__WIN__)
+#if defined(_WIN32)
FreeLibrary((HMODULE)hdll);
-#else // !__WIN__
+#else // !_WIN32
dlclose(hdll);
-#endif // !__WIN__
+#endif // !_WIN32
return qrp;
} // end of OEMColumns
@@ -406,13 +405,13 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
// Take care of the column definitions
i= poff= nof= nlg= 0;
-#if defined(__WIN__)
+#if defined(_WIN32)
// Offsets of HTML and DIR tables start from 0, DBF at 1
loff= (trf == RECFM_DBF) ? 1 : (trf == RECFM_XML || trf == RECFM_DIR) ? -1 : 0;
-#else // !__WIN__
+#else // !_WIN32
// Offsets of HTML tables start from 0, DIR and DBF at 1
loff = (trf == RECFM_DBF || trf == RECFM_DIR) ? 1 : (trf == RECFM_XML) ? -1 : 0;
-#endif // !__WIN__
+#endif // !_WIN32
while (true) {
// Default Offset depends on table format
@@ -625,7 +624,7 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
strncat(strcpy(soname, GetPluginDir()), Module,
sizeof(soname) - strlen(soname) - 1);
-#if defined(__WIN__)
+#if defined(_WIN32)
// Is the DLL already loaded?
if (!Hdll && !(Hdll = GetModuleHandle(soname)))
// No, load the Dll implementing the function
@@ -661,7 +660,7 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
FreeLibrary((HMODULE)Hdll);
return NULL;
} // endif getdef
-#else // !__WIN__
+#else // !_WIN32
const char *error = NULL;
#if 0 // Don't know what all this stuff does
@@ -703,7 +702,7 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
dlclose(Hdll);
return NULL;
} // endif getdef
-#endif // !__WIN__
+#endif // !_WIN32
// Just in case the external Get function does not set error messages
sprintf(g->Message, MSG(DEF_ALLOC_ERROR), Subtype);
diff --git a/storage/connect/reldef.h b/storage/connect/reldef.h
index 73e178ed51c..1b81ae9e3b3 100644
--- a/storage/connect/reldef.h
+++ b/storage/connect/reldef.h
@@ -146,11 +146,11 @@ class DllExport OEMDEF : public TABDEF { /* OEM table */
PTABDEF GetXdef(PGLOBAL g);
// Members
-#if defined(__WIN__)
+#if defined(_WIN32)
HANDLE Hdll; /* Handle to the external DLL */
-#else // !__WIN__
+#else // !_WIN32
void *Hdll; /* Handle for the loaded shared library */
-#endif // !__WIN__
+#endif // !_WIN32
PTABDEF Pxdef; /* Pointer to the external TABDEF class */
char *Module; /* Path/Name of the DLL implenting it */
char *Subtype; /* The name of the OEM table sub type */
diff --git a/storage/connect/tabbson.cpp b/storage/connect/tabbson.cpp
index 8477d22d364..3b1f1c84d1a 100644
--- a/storage/connect/tabbson.cpp
+++ b/storage/connect/tabbson.cpp
@@ -1,5 +1,5 @@
/************* tabbson C++ Program Source Code File (.CPP) *************/
-/* PROGRAM NAME: tabbson Version 1.1 */
+/* PROGRAM NAME: tabbson Version 1.2 */
/* (C) Copyright to the author Olivier BERTRAND 2020 - 2021 */
/* This program are the BSON class DB execution routines. */
/***********************************************************************/
@@ -53,6 +53,7 @@ USETEMP UseTemp(void);
bool JsonAllPath(void);
int GetDefaultDepth(void);
char *GetJsonNull(void);
+bool Stringified(PCSZ, char*);
/***********************************************************************/
/* BSONColumns: construct the result blocks containing the description */
@@ -173,7 +174,7 @@ int BSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
lvl = GetIntegerTableOption(g, topt, "Depth", lvl);
sep = GetStringTableOption(g, topt, "Separator", ".");
sz = GetIntegerTableOption(g, topt, "Jsize", 1024);
- limit = GetIntegerTableOption(g, topt, "Limit", 10);
+ limit = GetIntegerTableOption(g, topt, "Limit", 50);
strfy = GetStringTableOption(g, topt, "Stringify", NULL);
/*********************************************************************/
@@ -193,7 +194,11 @@ int BSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
if (!(tdp->Database = SetPath(g, db)))
return 0;
- tdp->Objname = GetStringTableOption(g, topt, "Object", NULL);
+ if ((tdp->Objname = GetStringTableOption(g, topt, "Object", NULL))) {
+ if (*tdp->Objname == '$') tdp->Objname++;
+ if (*tdp->Objname == '.') tdp->Objname++;
+ } // endif Objname
+
tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0;
tdp->Pretty = GetIntegerTableOption(g, topt, "Pretty", 2);
tdp->Xcol = GetStringTableOption(g, topt, "Expand", NULL);
@@ -218,8 +223,7 @@ int BSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
if (tdp->Uri) {
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
- tdp->Collname = GetStringTableOption(g, topt, "Name", NULL);
- tdp->Collname = GetStringTableOption(g, topt, "Tabname", tdp->Collname);
+ tdp->Collname = GetStringTableOption(g, topt, "Tabname", NULL);
tdp->Schema = GetStringTableOption(g, topt, "Dbname", "test");
tdp->Options = (PSZ)GetStringTableOption(g, topt, "Colist", "all");
tdp->Pipe = GetBooleanTableOption(g, topt, "Pipeline", false);
@@ -433,7 +437,7 @@ bool BSONDISC::Find(PGLOBAL g, PBVAL jvp, PCSZ key, int j)
jcol.Type = TYPE_UNKNOWN;
jcol.Len = jcol.Scale = 0;
jcol.Cbn = true;
- } else if (j < lvl && !(strfy && !stricmp(strfy, colname))) {
+ } else if (j < lvl && !Stringified(strfy, colname)) {
if (!fmt[bf])
strcat(fmt, colname);
@@ -504,7 +508,7 @@ bool BSONDISC::Find(PGLOBAL g, PBVAL jvp, PCSZ key, int j)
} // endswitch Type
} else if (lvl >= 0) {
- if (strfy && !stricmp(strfy, colname)) {
+ if (Stringified(strfy, colname)) {
if (!fmt[bf])
strcat(fmt, colname);
@@ -604,33 +608,51 @@ void BSONDISC::AddColumn(PGLOBAL g)
/***********************************************************************/
PBVAL BTUTIL::FindRow(PGLOBAL g)
{
- char *p, *objpath;
+ char *p, *objpath = PlugDup(g, Tp->Objname);
+ char *sep = (char*)(Tp->Sep == ':' ? ":[" : ".[");
+ bool bp = false, b = false;
PBVAL jsp = Tp->Row;
PBVAL val = NULL;
- for (objpath = PlugDup(g, Tp->Objname); jsp && objpath; objpath = p) {
- if ((p = strchr(objpath, Tp->Sep)))
+ for (; jsp && objpath; objpath = p, bp = b) {
+ if ((p = strpbrk(objpath + 1, sep))) {
+ b = (*p == '[');
*p++ = 0;
+ } // endif p
- if (*objpath != '[' && !IsNum(objpath)) { // objpass is a key
+ if (!bp && *objpath != '[' && !IsNum(objpath)) { // objpass is a key
val = (jsp->Type == TYPE_JOB) ?
GetKeyValue(jsp, objpath) : NULL;
} else {
- if (*objpath == '[') {
- if (objpath[strlen(objpath) - 1] == ']')
- objpath++;
- else
+ if (bp || *objpath == '[') { // Old style
+ if (objpath[strlen(objpath) - 1] != ']') {
+ sprintf(g->Message, "Invalid Table path %s", Tp->Objname);
return NULL;
- } // endif [
+ } else if (!bp)
+ objpath++;
+
+ } // endif bp
val = (jsp->Type == TYPE_JAR) ?
- GetArrayValue(GetArray(jsp), atoi(objpath) - Tp->B) : NULL;
+ GetArrayValue(jsp, atoi(objpath) - Tp->B) : NULL;
} // endif objpath
// jsp = (val) ? val->GetJson() : NULL;
jsp = val;
} // endfor objpath
+ if (jsp && jsp->Type != TYPE_JOB) {
+ if (jsp->Type == TYPE_JAR) {
+ jsp = GetArrayValue(jsp, Tp->B);
+
+ if (jsp->Type != TYPE_JOB)
+ jsp = NULL;
+
+ } else
+ jsp = NULL;
+
+ } // endif Type
+
return jsp;
} // end of FindRow
@@ -654,17 +676,22 @@ PBVAL BTUTIL::MakeTopTree(PGLOBAL g, int type)
if (Tp->Objname) {
if (!Tp->Row) {
// Parse and allocate Objpath item(s)
- char* p;
- char *objpath = PlugDup(g, Tp->Objname);
+ char *p, *objpath = PlugDup(g, Tp->Objname);
+ char *sep = (char*)(Tp->Sep == ':' ? ":[" : ".[");
int i;
+ bool bp = false, b = false;
PBVAL objp = NULL;
PBVAL arp = NULL;
- for (; objpath; objpath = p) {
- if ((p = strchr(objpath, Tp->Sep)))
+ for (; objpath; objpath = p, bp = b) {
+ if ((p = strpbrk(objpath + 1, sep))) {
+ b = (*p == '[');
*p++ = 0;
+ } // endif p
+
- if (*objpath != '[' && !IsNum(objpath)) {
+ if (!bp && *objpath != '[' && !IsNum(objpath)) {
+ // objpass is a key
objp = NewVal(TYPE_JOB);
if (!top)
@@ -676,15 +703,15 @@ PBVAL BTUTIL::MakeTopTree(PGLOBAL g, int type)
val = NewVal();
SetKeyValue(objp, MOF(val), objpath);
} else {
- if (*objpath == '[') {
+ if (bp || *objpath == '[') {
// Old style
if (objpath[strlen(objpath) - 1] != ']') {
sprintf(g->Message, "Invalid Table path %s", Tp->Objname);
return NULL;
- } else
+ } else if (!bp)
objpath++;
- } // endif objpath
+ } // endif bp
if (!top)
top = NewVal(TYPE_JAR);
@@ -756,10 +783,16 @@ void BCUTIL::SetJsonValue(PGLOBAL g, PVAL vp, PBVAL jvp)
break;
case TYPE_DATE:
if (jvp->Type == TYPE_STRG) {
- if (!((DTVAL*)vp)->IsFormatted())
- ((DTVAL*)vp)->SetFormat(g, "YYYY-MM-DDThh:mm:ssZ", 20, 0);
+ PSZ dat = GetString(jvp);
+
+ if (!IsNum(dat)) {
+ if (!((DTVAL*)vp)->IsFormatted())
+ ((DTVAL*)vp)->SetFormat(g, "YYYY-MM-DDThh:mm:ssZ", 20, 0);
+
+ vp->SetValue_psz(dat);
+ } else
+ vp->SetValue(atoi(dat));
- vp->SetValue_psz(GetString(jvp));
} else
vp->SetValue(GetInteger(jvp));
@@ -1157,10 +1190,15 @@ bool BSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
G = g;
Schema = GetStringCatInfo(g, "DBname", Schema);
Jmode = (JMODE)GetIntCatInfo("Jmode", MODE_OBJECT);
- Objname = GetStringCatInfo(g, "Object", NULL);
+
+ if ((Objname = GetStringCatInfo(g, "Object", NULL))) {
+ if (*Objname == '$') Objname++;
+ if (*Objname == '.') Objname++;
+ } // endif Objname
+
Xcol = GetStringCatInfo(g, "Expand", NULL);
Pretty = GetIntCatInfo("Pretty", 2);
- Limit = GetIntCatInfo("Limit", 10);
+ Limit = GetIntCatInfo("Limit", 50);
Base = GetIntCatInfo("Base", 0) ? 1 : 0;
Sep = *GetStringCatInfo(g, "Separator", ".");
Accept = GetBoolCatInfo("Accept", false);
@@ -1171,7 +1209,7 @@ bool BSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Collname = GetStringCatInfo(g, "Name",
(Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
Collname = GetStringCatInfo(g, "Tabname", Collname);
- Options = GetStringCatInfo(g, "Colist", NULL);
+ Options = GetStringCatInfo(g, "Colist", Xcol ? "all" : NULL);
Filter = GetStringCatInfo(g, "Filter", NULL);
Pipe = GetBoolCatInfo("Pipeline", false);
Driver = GetStringCatInfo(g, "Driver", NULL);
@@ -1215,7 +1253,7 @@ PTDB BSONDEF::GetTable(PGLOBAL g, MODE m)
if (Lrecl) {
// Allocate the parse work memory
- G = PlugInit(NULL, (size_t)Lrecl * (Pretty < 0 ? 2 : 4));
+ G = PlugInit(NULL, (size_t)Lrecl * (Pretty < 0 ? 3 : 5));
} else {
strcpy(g->Message, "LRECL is not defined");
return NULL;
@@ -1249,6 +1287,7 @@ PTDB BSONDEF::GetTable(PGLOBAL g, MODE m)
#endif // !MONGO_SUPPORT
} // endif Driver
+ Pretty = 4; // Not a file
} else if (Zipped) {
#if defined(ZIP_SUPPORT)
if (m == MODE_READ || m == MODE_ANY || m == MODE_ALTER) {
@@ -1454,7 +1493,7 @@ int TDBBSN::EstimatedLength(void)
} // end of Estimated Length
/***********************************************************************/
-/* OpenDB: Data Base open routine for JSN access method. */
+/* OpenDB: Data Base open routine for BSN access method. */
/***********************************************************************/
bool TDBBSN::OpenDB(PGLOBAL g)
{
@@ -1676,6 +1715,7 @@ BSONCOL::BSONCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
Xpd = false;
Parsed = false;
Warned = false;
+ Sgfy = false;
} // end of BSONCOL constructor
/***********************************************************************/
@@ -1695,6 +1735,7 @@ BSONCOL::BSONCOL(BSONCOL* col1, PTDB tdbp) : DOSCOL(col1, tdbp)
Xpd = col1->Xpd;
Parsed = col1->Parsed;
Warned = col1->Warned;
+ Sgfy = col1->Sgfy;
} // end of BSONCOL copy constructor
/***********************************************************************/
@@ -1933,6 +1974,10 @@ bool BSONCOL::ParseJpath(PGLOBAL g)
// Analyse intermediate array processing
if (SetArrayOptions(g, p, i, Nodes[i - 1].Key))
return true;
+ else if (Xpd && Tbp->Mode == MODE_DELETE) {
+ strcpy(g->Message, "Cannot delete expanded columns");
+ return true;
+ } // endif Xpd
} else if (*p == '*') {
// Return JSON
@@ -1966,8 +2011,10 @@ PSZ BSONCOL::GetJpath(PGLOBAL g, bool proj)
if (*p1 == '$') p1++;
if (*p1 == '.') p1++;
mgopath = PlugDup(g, p1);
- } else
+ } else {
+ Sgfy = true;
return NULL;
+ } // endif
for (p1 = p2 = mgopath; *p1; p1++)
if (i) { // Inside []
@@ -2005,6 +2052,7 @@ PSZ BSONCOL::GetJpath(PGLOBAL g, bool proj)
case '*':
if (*(p2 - 1) == '.' && !*(p1 + 1)) {
p2--; // Suppress last :*
+ Sgfy = true;
break;
} // endif p2
@@ -2013,6 +2061,9 @@ PSZ BSONCOL::GetJpath(PGLOBAL g, bool proj)
break;
} // endswitch p1;
+ if (*(p2 - 1) == '.')
+ p2--;
+
*p2 = 0;
return mgopath;
} else
@@ -2229,8 +2280,6 @@ int TDBBSON::MakeDocument(PGLOBAL g)
return RC_FX;
if ((objpath = PlugDup(g, Objname))) {
- if (*objpath == '$') objpath++;
- if (*objpath == '.') objpath++;
p1 = (*objpath == '[') ? objpath++ : NULL;
/*********************************************************************/
diff --git a/storage/connect/tabbson.h b/storage/connect/tabbson.h
index e9c5cc6477f..7f41bba6bd9 100644
--- a/storage/connect/tabbson.h
+++ b/storage/connect/tabbson.h
@@ -1,7 +1,7 @@
/*************** tabbson H Declares Source Code File (.H) **************/
-/* Name: tabbson.h Version 1.0 */
+/* Name: tabbson.h Version 1.1 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2020 */
+/* (C) Copyright to the author Olivier BERTRAND 2020 - 2021 */
/* */
/* This file contains the BSON classes declares. */
/***********************************************************************/
@@ -242,7 +242,8 @@ public:
BSONCOL(BSONCOL* colp, PTDB tdbp); // Constructor used in copy process
// Implementation
- virtual int GetAmType(void) { return Tbp->GetAmType(); }
+ virtual int GetAmType(void) { return Tbp->GetAmType(); }
+ virtual bool Stringify(void) { return Sgfy; }
// Methods
virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
@@ -270,6 +271,7 @@ protected:
bool Xpd; // True for expandable column
bool Parsed; // True when parsed
bool Warned; // True when warning issued
+ bool Sgfy; // True if stringified
}; // end of class BSONCOL
/* -------------------------- TDBBSON class -------------------------- */
diff --git a/storage/connect/tabcmg.cpp b/storage/connect/tabcmg.cpp
index f2ff721627c..56d705f42ca 100644
--- a/storage/connect/tabcmg.cpp
+++ b/storage/connect/tabcmg.cpp
@@ -1,6 +1,6 @@
/************** tabcmg C++ Program Source Code File (.CPP) *************/
-/* PROGRAM NAME: tabcmg Version 1.1 */
-/* (C) Copyright to the author Olivier BERTRAND 2017 */
+/* PROGRAM NAME: tabcmg Version 1.3 */
+/* (C) Copyright to the author Olivier BERTRAND 2017 - 2021 */
/* This program are the C MongoDB class DB execution routines. */
/***********************************************************************/
@@ -27,6 +27,7 @@
#include "filter.h"
PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt, bool info);
+bool Stringified(PCSZ, char*);
/* -------------------------- Class CMGDISC -------------------------- */
@@ -84,69 +85,80 @@ bool CMGDISC::FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
bcol.Cbn = false;
- if (BSON_ITER_HOLDS_UTF8(iter)) {
- bcol.Type = TYPE_STRING;
- bcol.Len = strlen(bson_iter_utf8(iter, NULL));
- } else if (BSON_ITER_HOLDS_INT32(iter)) {
- bcol.Type = TYPE_INT;
- bcol.Len = 11; // bson_iter_int32(iter)
- } else if (BSON_ITER_HOLDS_INT64(iter)) {
- bcol.Type = TYPE_BIGINT;
- bcol.Len = 22; // bson_iter_int64(iter)
- } else if (BSON_ITER_HOLDS_DOUBLE(iter)) {
- bcol.Type = TYPE_DOUBLE;
- bcol.Len = 12;
- bcol.Scale = 6; // bson_iter_double(iter)
- } else if (BSON_ITER_HOLDS_DATE_TIME(iter)) {
- bcol.Type = TYPE_DATE;
- bcol.Len = 19; // bson_iter_date_time(iter)
- } else if (BSON_ITER_HOLDS_BOOL(iter)) {
- bcol.Type = TYPE_TINY;
- bcol.Len = 1;
- } else if (BSON_ITER_HOLDS_OID(iter)) {
- bcol.Type = TYPE_STRING;
- bcol.Len = 24; // bson_iter_oid(iter)
- } else if (BSON_ITER_HOLDS_DECIMAL128(iter)) {
- bcol.Type = TYPE_DECIM;
- bcol.Len = 32; // bson_iter_decimal128(iter, &dec)
- } else if (BSON_ITER_HOLDS_DOCUMENT(iter)) {
- if (lvl < 0)
- continue;
- else if (lvl <= k) {
+ switch (bson_iter_type(iter)) {
+ case BSON_TYPE_UTF8:
bcol.Type = TYPE_STRING;
- bcol.Len = 512;
- } else {
- bson_iter_t child;
-
- if (bson_iter_recurse(iter, &child))
- if (FindInDoc(g, &child, NULL, colname, fmt, k + 1, false))
- return true;
-
- newcol = false;
- } // endif lvl
-
- } else if (BSON_ITER_HOLDS_ARRAY(iter)) {
- if (lvl < 0)
- continue;
- else if (lvl <= k) {
+ bcol.Len = strlen(bson_iter_utf8(iter, NULL));
+ break;
+ case BSON_TYPE_INT32:
+ bcol.Type = TYPE_INT;
+ bcol.Len = 11; // bson_iter_int32(iter)
+ break;
+ case BSON_TYPE_INT64:
+ bcol.Type = TYPE_BIGINT;
+ bcol.Len = 22; // bson_iter_int64(iter)
+ break;
+ case BSON_TYPE_DOUBLE:
+ bcol.Type = TYPE_DOUBLE;
+ bcol.Len = 12;
+ bcol.Scale = 6; // bson_iter_double(iter)
+ break;
+ case BSON_TYPE_DATE_TIME:
+ bcol.Type = TYPE_DATE;
+ bcol.Len = 19; // bson_iter_date_time(iter)
+ break;
+ case BSON_TYPE_BOOL:
+ bcol.Type = TYPE_TINY;
+ bcol.Len = 1;
+ break;
+ case BSON_TYPE_OID:
bcol.Type = TYPE_STRING;
- bcol.Len = 512;
- } else {
- bson_t *arr;
- bson_iter_t itar;
- const uint8_t *data = NULL;
- uint32_t len = 0;
-
- bson_iter_array(iter, &len, &data);
- arr = bson_new_from_data(data, len);
-
- if (FindInDoc(g, &itar, arr, colname, fmt, k + 1, !all))
- return true;
+ bcol.Len = 24; // bson_iter_oid(iter)
+ break;
+ case BSON_TYPE_DECIMAL128:
+ bcol.Type = TYPE_DECIM;
+ bcol.Len = 32; // bson_iter_decimal128(iter, &dec)
+ break;
+ case BSON_TYPE_DOCUMENT:
+ if (lvl < 0)
+ continue;
+ else if (lvl <= k) {
+ bcol.Type = TYPE_STRING;
+ bcol.Len = 512;
+ } else {
+ bson_iter_t child;
+
+ if (bson_iter_recurse(iter, &child))
+ if (FindInDoc(g, &child, NULL, colname, fmt, k + 1, false))
+ return true;
+
+ newcol = false;
+ } // endif lvl
+
+ break;
+ case BSON_TYPE_ARRAY:
+ if (lvl < 0)
+ continue;
+ else if (lvl <= k) {
+ bcol.Type = TYPE_STRING;
+ bcol.Len = 512;
+ } else {
+ bson_t* arr;
+ bson_iter_t itar;
+ const uint8_t* data = NULL;
+ uint32_t len = 0;
+
+ bson_iter_array(iter, &len, &data);
+ arr = bson_new_from_data(data, len);
+
+ if (FindInDoc(g, &itar, arr, colname, fmt, k + 1, !all))
+ return true;
- newcol = false;
- } // endif lvl
+ newcol = false;
+ } // endif lvl
- } // endif's
+ break;
+ } // endswitch iter
if (newcol)
AddColumn(g, colname, fmt, k);
@@ -178,15 +190,19 @@ TDBCMG::TDBCMG(MGODEF *tdp) : TDBEXT(tdp)
Pcg.Coll_name = tdp->Tabname;
Pcg.Options = tdp->Colist;
Pcg.Filter = tdp->Filter;
+ Pcg.Line = NULL;
Pcg.Pipe = tdp->Pipe && tdp->Colist != NULL;
B = tdp->Base ? 1 : 0;
+ Strfy = tdp->Strfy;
} else {
Pcg.Uristr = NULL;
Pcg.Db_name = NULL;
Pcg.Coll_name = NULL;
Pcg.Options = NULL;
Pcg.Filter = NULL;
+ Pcg.Line = NULL;
Pcg.Pipe = false;
+ Strfy = NULL;
B = 0;
} // endif tdp
@@ -200,6 +216,7 @@ TDBCMG::TDBCMG(TDBCMG *tdbp) : TDBEXT(tdbp)
Cmgp = tdbp->Cmgp;
Cnd = tdbp->Cnd;
Pcg = tdbp->Pcg;
+ Strfy = tdbp->Strfy;
B = tdbp->B;
Fpos = tdbp->Fpos;
N = tdbp->N;
@@ -381,7 +398,21 @@ MGOCOL::MGOCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
: EXTCOL(cdp, tdbp, cprec, i, "MGO")
{
Tmgp = (PTDBCMG)(tdbp->GetOrig() ? tdbp->GetOrig() : tdbp);
- Jpath = cdp->GetFmt() ? cdp->GetFmt() : cdp->GetName();
+ Sgfy = Stringified(Tmgp->Strfy, Name);
+
+ if ((Jpath = cdp->GetFmt())) {
+ int n = strlen(Jpath) - 1;
+
+ if (Jpath[n] == '*') {
+ Jpath = PlugDup(g, cdp->GetFmt());
+ if (Jpath[n - 1] == '.') n--;
+ Jpath[n] = 0;
+ Sgfy = true;
+ } // endif Jpath
+
+ } else
+ Jpath = cdp->GetName();
+
} // end of MGOCOL constructor
/***********************************************************************/
@@ -392,6 +423,7 @@ MGOCOL::MGOCOL(MGOCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp)
{
Tmgp = col1->Tmgp;
Jpath = col1->Jpath;
+ Sgfy = col1->Sgfy;
} // end of MGOCOL copy constructor
/***********************************************************************/
@@ -419,6 +451,9 @@ PSZ MGOCOL::GetJpath(PGLOBAL g, bool proj)
} else
*p2++ = *p1;
+ if (*(p2 - 1) == '.')
+ p2--;
+
*p2 = 0;
return projpath;
} else
diff --git a/storage/connect/tabcmg.h b/storage/connect/tabcmg.h
index 260f2def8a2..9effe714fdd 100644
--- a/storage/connect/tabcmg.h
+++ b/storage/connect/tabcmg.h
@@ -1,7 +1,7 @@
/**************** tabcmg H Declares Source Code File (.H) **************/
-/* Name: tabcmg.h Version 1.2 */
+/* Name: tabcmg.h Version 1.3 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2017 - 2021 */
/* */
/* This file contains the MongoDB classes declares. */
/***********************************************************************/
@@ -75,6 +75,7 @@ protected:
CMgoConn *Cmgp; // Points to a C Mongo connection class
CMGOPARM Pcg; // Parms passed to Cmgp
const Item *Cnd; // The first condition
+ PCSZ Strfy; // The stringified columns
int Fpos; // The current row index
int N; // The current Rownum
int B; // Array index base
@@ -96,6 +97,7 @@ public:
// Implementation
virtual int GetAmType(void) { return Tmgp->GetAmType(); }
+ virtual bool Stringify(void) { return Sgfy; }
// Methods
virtual PSZ GetJpath(PGLOBAL g, bool proj);
@@ -109,6 +111,7 @@ protected:
// Members
TDBCMG *Tmgp; // To the MGO table block
char *Jpath; // The json path
+ bool Sgfy; // True if stringified
}; // end of class MGOCOL
/***********************************************************************/
diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp
index fa764b1f84d..cb6154c45e3 100644
--- a/storage/connect/tabdos.cpp
+++ b/storage/connect/tabdos.cpp
@@ -17,7 +17,7 @@
/* Include relevant sections of the System header files. */
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <io.h>
#include <sys\timeb.h> // For testing only
#include <fcntl.h>
@@ -26,7 +26,7 @@
#define __MFC_COMPAT__ // To define min/max as macro
#endif // __BORLANDC__
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
#if defined(UNIX)
#include <errno.h>
#include <unistd.h>
@@ -34,7 +34,7 @@
#include <io.h>
#endif // !UNIX
#include <fcntl.h>
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Include application header files: */
@@ -233,11 +233,11 @@ void DOSDEF::RemoveOptValues(PGLOBAL g)
// Delete any eventually ill formed non matching optimization file
if (!GetOptFileName(g, filename))
-#if defined(__WIN__)
+#if defined(_WIN32)
DeleteFile(filename);
#else // UNIX
remove(filename);
-#endif // __WIN__
+#endif // _WIN32
Optimized = 0;
} // end of RemoveOptValues
@@ -279,7 +279,7 @@ bool DOSDEF::DeleteIndexFile(PGLOBAL g, PIXDEF pxdf)
/*********************************************************************/
if (sep) {
// Indexes are save in separate files
-#if defined(__WIN__)
+#if defined(_WIN32)
char drive[_MAX_DRIVE];
#else
char *drive = NULL;
@@ -296,7 +296,7 @@ bool DOSDEF::DeleteIndexFile(PGLOBAL g, PIXDEF pxdf)
strcat(strcat(fname, "_"), pxdf->GetName());
_makepath(filename, drive, direc, fname, ftype);
PlugSetPath(filename, filename, GetPath());
-#if defined(__WIN__)
+#if defined(_WIN32)
if (!DeleteFile(filename))
rc |= (GetLastError() != ERROR_FILE_NOT_FOUND);
#else // UNIX
@@ -313,7 +313,7 @@ bool DOSDEF::DeleteIndexFile(PGLOBAL g, PIXDEF pxdf)
// Drop all indexes, delete the common file
PlugSetPath(filename, Ofn, GetPath());
strcat(PlugRemoveType(filename, filename), ftype);
-#if defined(__WIN__)
+#if defined(_WIN32)
if (!DeleteFile(filename))
rc = (GetLastError() != ERROR_FILE_NOT_FOUND);
#else // UNIX
@@ -1024,7 +1024,7 @@ bool TDBDOS::GetBlockValues(PGLOBAL g)
#if 0
if (Mode == MODE_INSERT && Txfp->GetAmType() == TYPE_AM_DOS)
return false;
-#endif // __WIN__
+#endif // _WIN32
if (defp->Optimized || !(dup->Check & CHK_OPT))
return false; // Already done or to be redone
@@ -2532,6 +2532,7 @@ void DOSCOL::ReadColumn(PGLOBAL g)
char *p = NULL;
int i, rc;
int field;
+ bool err = false;
double dval;
PTDBDOS tdbp = (PTDBDOS)To_Tdb;
@@ -2575,33 +2576,39 @@ void DOSCOL::ReadColumn(PGLOBAL g)
case TYPE_SHORT:
case TYPE_TINY:
case TYPE_BIGINT:
- if (Value->SetValue_char(p, field - Dcm)) {
- sprintf(g->Message, "Out of range value for column %s at row %d",
- Name, tdbp->RowNumber(g));
- PushWarning(g, tdbp);
- } // endif SetValue_char
-
+ err = Value->SetValue_char(p, field - Dcm);
break;
case TYPE_DOUBLE:
- Value->SetValue_char(p, field);
- dval = Value->GetFloatValue();
+ if (!(err = Value->SetValue_char(p, field))) {
+ dval = Value->GetFloatValue();
+
+ for (i = 0; i < Dcm; i++)
+ dval /= 10.0;
- for (i = 0; i < Dcm; i++)
- dval /= 10.0;
+ Value->SetValue(dval);
+ } // endif err
- Value->SetValue(dval);
break;
default:
- Value->SetValue_char(p, field);
+ err = Value->SetValue_char(p, field);
+
+ if (!err && Buf_Type == TYPE_DECIM) {
+ char* s = Value->GetCharValue();
+
+ if (!(err = ((i = strlen(s)) >= Value->GetClen()))) {
+ for (int d = Dcm + 1; d; i--, d--)
+ s[i + 1] = s[i];
+
+ s[i + 1] = '.';
+ } // endif err
+
+ } // endif DECIM
+
break;
- } // endswitch Buf_Type
+ } // endswitch Buf_Type
else
- if (Value->SetValue_char(p, field)) {
- sprintf(g->Message, "Out of range value for column %s at row %d",
- Name, tdbp->RowNumber(g));
- PushWarning(g, tdbp);
- } // endif SetValue_char
+ err = Value->SetValue_char(p, field);
break;
default:
@@ -2609,6 +2616,12 @@ void DOSCOL::ReadColumn(PGLOBAL g)
throw 34;
} // endswitch Ftype
+ if (err) {
+ sprintf(g->Message, "Out of range value for column %s at row %d",
+ Name, tdbp->RowNumber(g));
+ PushWarning(g, tdbp);
+ } // endif err
+
// Set null when applicable
if (Nullable)
Value->SetNull(Value->IsZero());
@@ -2699,7 +2712,7 @@ void DOSCOL::WriteColumn(PGLOBAL g)
case TYPE_DECIM:
strcpy(fmt, (Ldz) ? "%0*.*lf" : "%*.*lf");
len = field + ((Nod && Dcm) ? 1 : 0);
- snprintf(Buf, len, fmt, len, Dcm, Value->GetFloatValue());
+ snprintf(Buf, len + 1, fmt, len, Dcm, Value->GetFloatValue());
len = strlen(Buf);
if (Nod && Dcm)
diff --git a/storage/connect/tabext.cpp b/storage/connect/tabext.cpp
index aaf14f123c6..53a0d2aa2c7 100644
--- a/storage/connect/tabext.cpp
+++ b/storage/connect/tabext.cpp
@@ -14,7 +14,7 @@
#include "sql_class.h"
#include "sql_servers.h"
#include "sql_string.h"
-#if !defined(__WIN__)
+#if !defined(_WIN32)
#include "osutil.h"
#endif
diff --git a/storage/connect/tabfix.cpp b/storage/connect/tabfix.cpp
index 4a0a75460cd..5deb5fd0d40 100644
--- a/storage/connect/tabfix.cpp
+++ b/storage/connect/tabfix.cpp
@@ -17,7 +17,7 @@
/* Include relevant section of system dependant header files. */
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <io.h>
#include <fcntl.h>
#include <errno.h>
@@ -25,7 +25,7 @@
#define __MFC_COMPAT__ // To define min/max as macro
#endif // __BORLANDC__
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
#if defined(UNIX)
#include <sys/types.h>
#include <sys/stat.h>
@@ -35,7 +35,7 @@
#include <io.h>
#endif // !UNIX
#include <fcntl.h>
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Include application header files: */
diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp
index 37d28b96517..53af8d84053 100644
--- a/storage/connect/tabfmt.cpp
+++ b/storage/connect/tabfmt.cpp
@@ -20,7 +20,7 @@
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <io.h>
#include <fcntl.h>
#include <errno.h>
@@ -156,14 +156,14 @@ PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info)
p = (char*)GetStringTableOption(g, topt, "Separator", ",");
tdp->Sep = (strlen(p) == 2 && p[0] == '\\' && p[1] == 't') ? '\t' : *p;
-#if defined(__WIN__)
+#if defined(_WIN32)
if (tdp->Sep == ',' || strnicmp(setlocale(LC_NUMERIC, NULL), "French", 6))
dechar = '.';
else
dechar = ',';
-#else // !__WIN__
+#else // !_WIN32
dechar = '.';
-#endif // !__WIN__
+#endif // !_WIN32
sep = tdp->Sep;
tdp->Quoted = GetIntegerTableOption(g, topt, "Quoted", -1);
diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp
index 06b6b3a9730..9721c62be7d 100644
--- a/storage/connect/tabjdbc.cpp
+++ b/storage/connect/tabjdbc.cpp
@@ -38,7 +38,7 @@
#include "my_global.h"
#include "sql_class.h"
#include "sql_servers.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <io.h>
#include <fcntl.h>
#if defined(__BORLANDC__)
@@ -188,6 +188,9 @@ int JDBCDEF::ParseURL(PGLOBAL g, char *url, bool b)
} else // host is a URL
Url = PlugDup(g, server->host);
+ if (!Tabschema && server->db)
+ Tabschema = PlugDup(g, server->db);
+
if (!Username && server->username)
Username = PlugDup(g, server->username);
diff --git a/storage/connect/tabjmg.cpp b/storage/connect/tabjmg.cpp
index 850d9e5fa9b..983ee39d65f 100644
--- a/storage/connect/tabjmg.cpp
+++ b/storage/connect/tabjmg.cpp
@@ -1,6 +1,6 @@
/************** tabjmg C++ Program Source Code File (.CPP) *************/
-/* PROGRAM NAME: tabjmg Version 1.2 */
-/* (C) Copyright to the author Olivier BERTRAND 2017 */
+/* PROGRAM NAME: tabjmg Version 1.3 */
+/* (C) Copyright to the author Olivier BERTRAND 2021 */
/* This file contains the MongoDB classes using the Java Driver. */
/***********************************************************************/
@@ -30,6 +30,7 @@
#define nullptr 0
PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt, bool info);
+bool Stringified(PCSZ, char*);
/* -------------------------- Class JMGDISC -------------------------- */
@@ -166,6 +167,7 @@ TDBJMG::TDBJMG(PMGODEF tdp) : TDBEXT(tdp)
Coll_name = tdp->Tabname;
Options = tdp->Colist;
Filter = tdp->Filter;
+ Strfy = tdp->Strfy;
B = tdp->Base ? 1 : 0;
Pipe = tdp->Pipe && Options != NULL;
} else {
@@ -177,6 +179,7 @@ TDBJMG::TDBJMG(PMGODEF tdp) : TDBEXT(tdp)
Coll_name = NULL;
Options = NULL;
Filter = NULL;
+ Strfy = NULL;
B = 0;
Pipe = false;
} // endif tdp
@@ -197,6 +200,7 @@ TDBJMG::TDBJMG(TDBJMG *tdbp) : TDBEXT(tdbp)
Coll_name = tdbp->Coll_name;
Options = tdbp->Options;
Filter = tdbp->Filter;
+ Strfy = tdbp->Strfy;
B = tdbp->B;
Fpos = tdbp->Fpos;
N = tdbp->N;
@@ -384,7 +388,7 @@ int TDBJMG::WriteDB(PGLOBAL g)
int rc = RC_OK;
if (Mode == MODE_INSERT) {
- rc = Jcp->DocWrite(g);
+ rc = Jcp->DocWrite(g, NULL);
} else if (Mode == MODE_DELETE) {
rc = Jcp->DocDelete(g, false);
} else if (Mode == MODE_UPDATE) {
@@ -420,8 +424,25 @@ JMGCOL::JMGCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
: EXTCOL(cdp, tdbp, cprec, i, "MGO")
{
Tmgp = (PTDBJMG)(tdbp->GetOrig() ? tdbp->GetOrig() : tdbp);
- Jpath = cdp->GetFmt() ? cdp->GetFmt() : cdp->GetName();
-//Mbuf = NULL;
+ Sgfy = Stringified(Tmgp->Strfy, Name);
+
+ if ((Jpath = cdp->GetFmt())) {
+ int n = strlen(Jpath);
+
+ if (n && Jpath[n - 1] == '*') {
+ Jpath = PlugDup(g, cdp->GetFmt());
+
+ if (--n) {
+ if (Jpath[n - 1] == '.') n--;
+ Jpath[n] = 0;
+ } // endif n
+
+ Sgfy = true;
+ } // endif Jpath
+
+ } else
+ Jpath = cdp->GetName();
+
} // end of JMGCOL constructor
/***********************************************************************/
@@ -432,7 +453,7 @@ JMGCOL::JMGCOL(JMGCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp)
{
Tmgp = col1->Tmgp;
Jpath = col1->Jpath;
-//Mbuf = col1->Mbuf;
+ Sgfy = col1->Sgfy;
} // end of JMGCOL copy constructor
/***********************************************************************/
@@ -442,7 +463,7 @@ PSZ JMGCOL::GetJpath(PGLOBAL g, bool proj)
{
if (Jpath) {
if (proj) {
- char *p1, *p2, *projpath = PlugDup(g, Jpath);
+ char* p1, * p2, * projpath = PlugDup(g, Jpath);
int i = 0;
for (p1 = p2 = projpath; *p1; p1++)
@@ -460,6 +481,9 @@ PSZ JMGCOL::GetJpath(PGLOBAL g, bool proj)
} else
*p2++ = *p1;
+ if (*(p2 - 1) == '.')
+ p2--;
+
*p2 = 0;
return projpath;
} else
@@ -489,6 +513,7 @@ char *JMGCOL::Mini(PGLOBAL g, const bson_t *bson, bool b)
switch (s[i]) {
case ' ':
if (ok) continue;
+ break;
case '"':
ok = !ok;
default:
diff --git a/storage/connect/tabjmg.h b/storage/connect/tabjmg.h
index 5a637145cff..cf7cff83b68 100644
--- a/storage/connect/tabjmg.h
+++ b/storage/connect/tabjmg.h
@@ -1,7 +1,7 @@
/**************** tabjmg H Declares Source Code File (.H) **************/
-/* Name: tabjmg.h Version 1.1 */
+/* Name: tabjmg.h Version 1.3 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2017 - 2021 */
/* */
/* This file contains the MongoDB classes using the Java Driver. */
/***********************************************************************/
@@ -83,6 +83,7 @@ protected:
PCSZ Coll_name;
PCSZ Options; // The MongoDB options
PCSZ Filter; // The filtering query
+ PCSZ Strfy; // The stringified columns
PSZ Wrapname; // Java wrapper name
int Fpos; // The current row index
int N; // The current Rownum
@@ -106,6 +107,7 @@ public:
// Implementation
virtual int GetAmType(void) {return Tmgp->GetAmType();}
+ virtual bool Stringify(void) { return Sgfy; }
// Methods
//virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
@@ -123,7 +125,7 @@ protected:
// Members
TDBJMG *Tmgp; // To the MGO table block
char *Jpath; // The json path
-//char *Mbuf; // The Mini buffer
+ bool Sgfy; // True if stringified
}; // end of class JMGCOL
/***********************************************************************/
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index 07c54e8a0fb..56f22fa91ec 100644
--- a/storage/connect/tabjson.cpp
+++ b/storage/connect/tabjson.cpp
@@ -1,5 +1,5 @@
/************* tabjson C++ Program Source Code File (.CPP) *************/
-/* PROGRAM NAME: tabjson Version 1.8 */
+/* PROGRAM NAME: tabjson Version 1.9 */
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2021 */
/* This program are the JSON class DB execution routines. */
/***********************************************************************/
@@ -58,6 +58,7 @@ USETEMP UseTemp(void);
bool JsonAllPath(void);
int GetDefaultDepth(void);
char *GetJsonNull(void);
+bool Stringified(PCSZ, char*);
/***********************************************************************/
/* JSONColumns: construct the result blocks containing the description */
@@ -178,8 +179,8 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
lvl = GetIntegerTableOption(g, topt, "Depth", lvl);
sep = GetStringTableOption(g, topt, "Separator", ".");
strfy = GetStringTableOption(g, topt, "Stringify", NULL);
- sz = GetIntegerTableOption(g, topt, "Jsize", 250);
- limit = GetIntegerTableOption(g, topt, "Limit", 10);
+ sz = GetIntegerTableOption(g, topt, "Jsize", 1024);
+ limit = GetIntegerTableOption(g, topt, "Limit", 50);
/*********************************************************************/
/* Open the input file. */
@@ -191,13 +192,19 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
#endif // ZIP_SUPPORT
tdp->Fn = GetStringTableOption(g, topt, "Filename", NULL);
- if (!tdp->Fn && topt->http)
+ if (!tdp->Fn && topt->http) {
tdp->Fn = GetStringTableOption(g, topt, "Subtype", NULL);
+ topt->subtype = NULL;
+ } // endif fn
if (!(tdp->Database = SetPath(g, db)))
return 0;
- tdp->Objname = GetStringTableOption(g, topt, "Object", NULL);
+ if ((tdp->Objname = GetStringTableOption(g, topt, "Object", NULL))) {
+ if (*tdp->Objname == '$') tdp->Objname++;
+ if (*tdp->Objname == '.') tdp->Objname++;
+ } // endif Objname
+
tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0;
tdp->Pretty = GetIntegerTableOption(g, topt, "Pretty", 2);
tdp->Xcol = GetStringTableOption(g, topt, "Expand", NULL);
@@ -222,8 +229,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
if (tdp->Uri) {
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
- tdp->Collname = GetStringTableOption(g, topt, "Name", NULL);
- tdp->Collname = GetStringTableOption(g, topt, "Tabname", tdp->Collname);
+ tdp->Collname = GetStringTableOption(g, topt, "Tabname", NULL);
tdp->Schema = GetStringTableOption(g, topt, "Dbname", "test");
tdp->Options = (PSZ)GetStringTableOption(g, topt, "Colist", "all");
tdp->Pipe = GetBooleanTableOption(g, topt, "Pipeline", false);
@@ -442,7 +448,7 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j)
jcol.Type = TYPE_UNKNOWN;
jcol.Len = jcol.Scale = 0;
jcol.Cbn = true;
- } else if (j < lvl && !(strfy && !stricmp(strfy, colname))) {
+ } else if (j < lvl && !Stringified(strfy, colname)) {
if (!fmt[bf])
strcat(fmt, colname);
@@ -512,7 +518,7 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j)
} // endswitch Type
} else if (lvl >= 0) {
- if (strfy && !stricmp(strfy, colname)) {
+ if (Stringified(strfy, colname)) {
if (!fmt[bf])
strcat(fmt, colname);
@@ -633,10 +639,15 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
Schema = GetStringCatInfo(g, "DBname", Schema);
Jmode = (JMODE)GetIntCatInfo("Jmode", MODE_OBJECT);
- Objname = GetStringCatInfo(g, "Object", NULL);
+
+ if ((Objname = GetStringCatInfo(g, "Object", NULL))) {
+ if (*Objname == '$') Objname++;
+ if (*Objname == '.') Objname++;
+ } // endif Objname
+
Xcol = GetStringCatInfo(g, "Expand", NULL);
Pretty = GetIntCatInfo("Pretty", 2);
- Limit = GetIntCatInfo("Limit", 10);
+ Limit = GetIntCatInfo("Limit", 50);
Base = GetIntCatInfo("Base", 0) ? 1 : 0;
Sep = *GetStringCatInfo(g, "Separator", ".");
Accept = GetBoolCatInfo("Accept", false);
@@ -647,7 +658,7 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Collname = GetStringCatInfo(g, "Name",
(Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
Collname = GetStringCatInfo(g, "Tabname", Collname);
- Options = GetStringCatInfo(g, "Colist", NULL);
+ Options = GetStringCatInfo(g, "Colist", Xcol ? "all" : NULL);
Filter = GetStringCatInfo(g, "Filter", NULL);
Pipe = GetBoolCatInfo("Pipeline", false);
Driver = GetStringCatInfo(g, "Driver", NULL);
@@ -716,6 +727,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
#endif // !MONGO_SUPPORT
} // endif Driver
+ Pretty = 4; // Not a file
} else if (Zipped) {
#if defined(ZIP_SUPPORT)
if (m == MODE_READ || m == MODE_ANY || m == MODE_ALTER) {
@@ -761,7 +773,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
G->jump_level = 0;
((TDBJSN*)tdbp)->G = G;
#endif // 0
- ((TDBJSN*)tdbp)->G = PlugInit(NULL, (size_t)Lrecl * (Pretty >= 0 ? 10 : 2));
+ ((TDBJSN*)tdbp)->G = PlugInit(NULL, (size_t)Lrecl * (Pretty >= 0 ? 12 : 4));
} else {
strcpy(g->Message, "LRECL is not defined");
return NULL;
@@ -950,23 +962,29 @@ int TDBJSN::EstimatedLength(void)
/***********************************************************************/
PJSON TDBJSN::FindRow(PGLOBAL g)
{
- char *p, *objpath;
+ char *p, *objpath = PlugDup(g, Objname);
+ char *sep = (char*)(Sep == ':' ? ":[" : ".[");
+ bool bp = false, b = false;
PJSON jsp = Row;
PJVAL val = NULL;
- for (objpath = PlugDup(g, Objname); jsp && objpath; objpath = p) {
- if ((p = strchr(objpath, Sep)))
+ for (; jsp && objpath; objpath = p, bp = b) {
+ if ((p = strpbrk(objpath + 1, sep))) {
+ b = (*p == '[');
*p++ = 0;
+ } // endif p
- if (*objpath != '[' && !IsNum(objpath)) { // objpass is a key
+ if (!bp && *objpath != '[' && !IsNum(objpath)) { // objpass is a key
val = (jsp->GetType() == TYPE_JOB) ?
jsp->GetObject()->GetKeyValue(objpath) : NULL;
} else {
- if (*objpath == '[') {
- if (objpath[strlen(objpath) - 1] == ']')
- objpath++;
- else
+ if (bp || *objpath == '[') {
+ if (objpath[strlen(objpath) - 1] != ']') {
+ sprintf(g->Message, "Invalid Table path %s", Objname);
return NULL;
+ } else if (!bp)
+ objpath++;
+
} // endif [
val = (jsp->GetType() == TYPE_JAR) ?
@@ -976,6 +994,18 @@ PJSON TDBJSN::FindRow(PGLOBAL g)
jsp = (val) ? val->GetJson() : NULL;
} // endfor objpath
+ if (jsp && jsp->GetType() != TYPE_JOB) {
+ if (jsp->GetType() == TYPE_JAR) {
+ jsp = jsp->GetArray()->GetArrayValue(B);
+
+ if (jsp->GetType() != TYPE_JOB)
+ jsp = NULL;
+
+ } else
+ jsp = NULL;
+
+ } // endif Type
+
return jsp;
} // end of FindRow
@@ -1144,25 +1174,28 @@ int TDBJSN::ReadDB(PGLOBAL g) {
/***********************************************************************/
/* Make the top tree from the object path. */
/***********************************************************************/
-int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp)
+bool TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp)
{
if (Objname) {
if (!Val) {
// Parse and allocate Objname item(s)
- char *p;
- char *objpath = PlugDup(g, Objname);
+ char *p, *objpath = PlugDup(g, Objname);
+ char *sep = (char*)(Sep == ':' ? ":[" : ".[");
int i;
+ bool bp = false, b = false;
PJOB objp;
PJAR arp;
PJVAL val = NULL;
Top = NULL;
- for (; objpath; objpath = p) {
- if ((p = strchr(objpath, Sep)))
+ for (; objpath; objpath = p, bp = b) {
+ if ((p = strpbrk(objpath + 1, sep))) {
+ b = (*p == '[');
*p++ = 0;
+ } // endif p
- if (*objpath != '[' && !IsNum(objpath)) {
+ if (!bp && *objpath != '[' && !IsNum(objpath)) {
objp = new(g) JOBJECT;
if (!Top)
@@ -1174,15 +1207,15 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp)
val = new(g) JVALUE;
objp->SetKeyValue(g, val, objpath);
} else {
- if (*objpath == '[') {
+ if (bp || *objpath == '[') {
// Old style
if (objpath[strlen(objpath) - 1] != ']') {
sprintf(g->Message, "Invalid Table path %s", Objname);
- return RC_FX;
- } else
+ return true;
+ } else if (!bp)
objpath++;
- } // endif objpath
+ } // endif bp
arp = new(g) JARRAY;
@@ -1207,7 +1240,7 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp)
} else
Top = jsp;
- return RC_OK;
+ return false;
} // end of MakeTopTree
/***********************************************************************/
@@ -1277,6 +1310,7 @@ JSONCOL::JSONCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
Xpd = false;
Parsed = false;
Warned = false;
+ Sgfy = false;
} // end of JSONCOL constructor
/***********************************************************************/
@@ -1296,6 +1330,7 @@ JSONCOL::JSONCOL(JSONCOL *col1, PTDB tdbp) : DOSCOL(col1, tdbp)
Xpd = col1->Xpd;
Parsed = col1->Parsed;
Warned = col1->Warned;
+ Sgfy = col1->Sgfy;
} // end of JSONCOL copy constructor
/***********************************************************************/
@@ -1535,6 +1570,10 @@ bool JSONCOL::ParseJpath(PGLOBAL g)
// Analyse intermediate array processing
if (SetArrayOptions(g, p, i, Nodes[i - 1].Key))
return true;
+ else if (Xpd && Tjp->Mode == MODE_DELETE) {
+ strcpy(g->Message, "Cannot delete expanded columns");
+ return true;
+ } // endif Xpd
} else if (*p == '*') {
// Return JSON
@@ -1568,8 +1607,10 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj)
if (*p1 == '$') p1++;
if (*p1 == '.') p1++;
mgopath = PlugDup(g, p1);
- } else
+ } else {
+ Sgfy = true;
return NULL;
+ } // endif
for (p1 = p2 = mgopath; *p1; p1++)
{
@@ -1608,6 +1649,7 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj)
case '*':
if (*(p2 - 1) == '.' && !*(p1 + 1)) {
p2--; // Suppress last :*
+ Sgfy = true;
break;
} // endif p2
/* falls through */
@@ -1616,6 +1658,10 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj)
break;
} // endswitch p1;
}
+
+ if (*(p2 - 1) == '.')
+ p2--;
+
*p2 = 0;
return mgopath;
} else
@@ -1745,10 +1791,16 @@ void JSONCOL::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL jvp)
break;
case TYPE_DATE:
if (jvp->GetValType() == TYPE_STRG) {
- if (!((DTVAL*)vp)->IsFormatted())
- ((DTVAL*)vp)->SetFormat(g, "YYYY-MM-DDThh:mm:ssZ", 20, 0);
+ PSZ dat = jvp->GetString(g);
+
+ if (!IsNum(dat)) {
+ if (!((DTVAL*)vp)->IsFormatted())
+ ((DTVAL*)vp)->SetFormat(g, "YYYY-MM-DDThh:mm:ssZ", 20, 0);
+
+ vp->SetValue_psz(dat);
+ } else
+ vp->SetValue(atoi(dat));
- vp->SetValue_psz(jvp->GetString(g));
} else
vp->SetValue(jvp->GetInteger());
@@ -2128,10 +2180,14 @@ void JSONCOL::WriteColumn(PGLOBAL g)
if (Nodes[Nod-1].Op == OP_XX) {
s = Value->GetCharValue();
- if (!(jsp = ParseJson(G, s, strlen(s)))) {
- strcpy(g->Message, s);
- throw 666;
- } // endif jsp
+ if (s && *s) {
+ if (!(jsp = ParseJson(G, s, strlen(s)))) {
+ strcpy(g->Message, s);
+ throw 666;
+ } // endif jsp
+
+ } else
+ jsp = NULL;
if (arp) {
if (Nod > 1 && Nodes[Nod-2].Op == OP_EQ)
@@ -2560,8 +2616,8 @@ int TDBJSON::WriteDB(PGLOBAL g)
if (Mode == MODE_INSERT) {
Doc->AddArrayValue(g, vp);
Row = new(g) JOBJECT;
- } else if (Doc->SetArrayValue(g, vp, Fpos))
- return RC_FX;
+ } else
+ Doc->SetArrayValue(g, vp, Fpos);
} else if (Jmode == MODE_ARRAY) {
PJVAL vp = new(g) JVALUE(Row);
@@ -2569,15 +2625,15 @@ int TDBJSON::WriteDB(PGLOBAL g)
if (Mode == MODE_INSERT) {
Doc->AddArrayValue(g, vp);
Row = new(g) JARRAY;
- } else if (Doc->SetArrayValue(g, vp, Fpos))
- return RC_FX;
+ } else
+ Doc->SetArrayValue(g, vp, Fpos);
} else { // if (Jmode == MODE_VALUE)
if (Mode == MODE_INSERT) {
Doc->AddArrayValue(g, (PJVAL)Row);
Row = new(g) JVALUE;
- } else if (Doc->SetArrayValue(g, (PJVAL)Row, Fpos))
- return RC_FX;
+ } else
+ Doc->SetArrayValue(g, (PJVAL)Row, Fpos);
} // endif Jmode
diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h
index 1062928d410..623e5b6d509 100644
--- a/storage/connect/tabjson.h
+++ b/storage/connect/tabjson.h
@@ -170,7 +170,7 @@ public:
protected:
PJSON FindRow(PGLOBAL g);
- int MakeTopTree(PGLOBAL g, PJSON jsp);
+ bool MakeTopTree(PGLOBAL g, PJSON jsp);
// Members
PGLOBAL G; // Support of parse memory
@@ -216,7 +216,8 @@ public:
JSONCOL(JSONCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
- virtual int GetAmType(void) {return Tjp->GetAmType();}
+ virtual int GetAmType(void) {return Tjp->GetAmType();}
+ virtual bool Stringify(void) { return Sgfy; }
// Methods
virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
@@ -251,6 +252,7 @@ public:
bool Xpd; // True for expandable column
bool Parsed; // True when parsed
bool Warned; // True when warning issued
+ bool Sgfy; // True if stringified
}; // end of class JSONCOL
/* -------------------------- TDBJSON class -------------------------- */
diff --git a/storage/connect/tabmac.cpp b/storage/connect/tabmac.cpp
index 8260ab65391..ed161ac4be1 100644
--- a/storage/connect/tabmac.cpp
+++ b/storage/connect/tabmac.cpp
@@ -3,12 +3,12 @@
/* From the article and sample code by Khalid Shaikh. */
/* TABMAC: virtual table to get the list of MAC addresses. */
/***********************************************************************/
-#if defined(__WIN__)
+#if defined(_WIN32)
#include "my_global.h"
//#include <iphlpapi.h>
-#else // !__WIN__
+#else // !_WIN32
#error This is a WINDOWS only table type
-#endif // !__WIN__
+#endif // !_WIN32
#include "global.h"
#include "plgdbsem.h"
//#include "catalog.h"
diff --git a/storage/connect/tabmac.h b/storage/connect/tabmac.h
index 47565bb2541..68135edb95f 100644
--- a/storage/connect/tabmac.h
+++ b/storage/connect/tabmac.h
@@ -1,11 +1,11 @@
// TABMAC.H Olivier Bertrand 2011-2012
// MAC: virtual table to Get Mac Addresses via GetAdaptersInfo
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <windows.h>
#include <iphlpapi.h>
-#else // !__WIN__
+#else // !_WIN32
#error This is a WINDOWS only table TYPE
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Definitions. */
diff --git a/storage/connect/tabmul.cpp b/storage/connect/tabmul.cpp
index 7997a999b56..131b96ffbf5 100644
--- a/storage/connect/tabmul.cpp
+++ b/storage/connect/tabmul.cpp
@@ -37,7 +37,7 @@
/* Include relevant section of system dependant header files. */
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <stdlib.h>
#include <stdio.h>
#if defined(__BORLANDC__)
@@ -166,11 +166,11 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
while (true)
if ((rc = dirp->ReadDB(g)) == RC_OK) {
-#if defined(__WIN__)
+#if defined(_WIN32)
strcat(strcpy(filename, dirp->Drive), dirp->Direc);
-#else // !__WIN__
+#else // !_WIN32
strcpy(filename, dirp->Direc);
-#endif // !__WIN__
+#endif // !_WIN32
strcat(strcat(filename, dirp->Fname), dirp->Ftype);
pfn[n++] = PlugDup(g, filename);
} else
@@ -199,7 +199,7 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
p = filename + strlen(filename) - 1;
-#if !defined(__WIN__)
+#if !defined(_WIN32)
// Data files can be imported from Windows (having CRLF)
if (*p == '\n' || *p == '\r') {
// is this enough for Unix ???
@@ -566,11 +566,11 @@ bool TDBMSD::InitFileNames(PGLOBAL g)
while (true)
if ((rc = dirp->ReadDB(g)) == RC_OK) {
-#if defined(__WIN__)
+#if defined(_WIN32)
strcat(strcpy(filename, dirp->Drive), dirp->Direc);
-#else // !__WIN__
+#else // !_WIN32
strcpy(filename, dirp->Direc);
-#endif // !__WIN__
+#endif // !_WIN32
strcat(strcat(filename, dirp->Fname), dirp->Ftype);
pfn[n++] = PlugDup(g, filename);
} else
@@ -634,18 +634,18 @@ PTDB DIRDEF::GetTable(PGLOBAL g, MODE)
void TDBDIR::Init(void)
{
iFile = 0;
-#if defined(__WIN__)
+#if defined(_WIN32)
Dvalp = NULL;
memset(&FileData, 0, sizeof(_finddata_t));
hSearch = INVALID_HANDLE_VALUE;
*Drive = '\0';
-#else // !__WIN__
+#else // !_WIN32
memset(&Fileinfo, 0, sizeof(struct stat));
Entry = NULL;
Dir = NULL;
Done = false;
*Pattern = '\0';
-#endif // !__WIN__
+#endif // !_WIN32
*Fpath = '\0';
*Direc = '\0';
*Fname = '\0';
@@ -674,7 +674,7 @@ char* TDBDIR::Path(PGLOBAL g)
PCATLG cat __attribute__((unused))= PlgGetCatalog(g);
PTABDEF defp = (PTABDEF)To_Def;
-#if defined(__WIN__)
+#if defined(_WIN32)
if (!*Drive) {
PlugSetPath(Fpath, To_File, defp ? defp->GetPath() : NULL);
_splitpath(Fpath, Drive, Direc, Fname, Ftype);
@@ -682,7 +682,7 @@ char* TDBDIR::Path(PGLOBAL g)
_makepath(Fpath, Drive, Direc, Fname, Ftype); // Usefull for TDBSDR
return Fpath;
-#else // !__WIN__
+#else // !_WIN32
if (!Done) {
PlugSetPath(Fpath, To_File, defp ? defp->GetPath() : NULL);
_splitpath(Fpath, NULL, Direc, Fname, Ftype);
@@ -691,7 +691,7 @@ char* TDBDIR::Path(PGLOBAL g)
} // endif Done
return Pattern;
-#endif // !__WIN__
+#endif // !_WIN32
} // end of Path
/***********************************************************************/
@@ -709,7 +709,7 @@ int TDBDIR::GetMaxSize(PGLOBAL g)
{
if (MaxSize < 0) {
int n = -1;
-#if defined(__WIN__)
+#if defined(_WIN32)
int rc;
// Start searching files in the target directory.
@@ -751,7 +751,7 @@ int TDBDIR::GetMaxSize(PGLOBAL g)
// Close the search handle.
FindClose(hSearch);
-#else // !__WIN__
+#else // !_WIN32
Path(g);
// Start searching files in the target directory.
@@ -775,7 +775,7 @@ int TDBDIR::GetMaxSize(PGLOBAL g)
// Close the DIR handle.
closedir(Dir);
-#endif // !__WIN__
+#endif // !_WIN32
MaxSize = n;
} // endif MaxSize
@@ -801,10 +801,10 @@ bool TDBDIR::OpenDB(PGLOBAL g)
} // endif use
Use = USE_OPEN;
-#if !defined(__WIN__)
+#if !defined(_WIN32)
Path(g); // Be sure it is done
Dir = NULL; // For ReadDB
-#endif // !__WIN__
+#endif // !_WIN32
return false;
} // end of OpenDB
@@ -815,7 +815,7 @@ int TDBDIR::ReadDB(PGLOBAL g)
{
int rc = RC_OK;
-#if defined(__WIN__)
+#if defined(_WIN32)
do {
if (hSearch == INVALID_HANDLE_VALUE) {
/*****************************************************************/
@@ -878,7 +878,7 @@ int TDBDIR::ReadDB(PGLOBAL g)
rc = RC_EF;
} // endif Entry
-#endif // !__WIN__
+#endif // !_WIN32
return rc;
} // end of ReadDB
@@ -906,17 +906,17 @@ int TDBDIR::DeleteDB(PGLOBAL g, int)
/***********************************************************************/
void TDBDIR::CloseDB(PGLOBAL)
{
-#if defined(__WIN__)
+#if defined(_WIN32)
// Close the search handle.
FindClose(hSearch);
hSearch = INVALID_HANDLE_VALUE;
-#else // !__WIN__
+#else // !_WIN32
// Close the DIR handle
if (Dir) {
closedir(Dir);
Dir = NULL;
} // endif dir
-#endif // !__WIN__
+#endif // !_WIN32
iFile = 0;
} // end of CloseDB
@@ -951,7 +951,7 @@ DIRCOL::DIRCOL(DIRCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
N = col1->N;
} // end of DIRCOL copy constructor
-#if defined(__WIN__)
+#if defined(_WIN32)
/***********************************************************************/
/* Retrieve time information from FileData. */
/***********************************************************************/
@@ -978,7 +978,7 @@ void DIRCOL::SetTimeValue(PGLOBAL g, FILETIME& ftime)
Value->Reset();
} // end of SetTimeValue
-#endif // __WIN__
+#endif // _WIN32
/***********************************************************************/
/* ReadColumn: what this routine does is to access the information */
@@ -994,19 +994,19 @@ void DIRCOL::ReadColumn(PGLOBAL g)
/* Retrieve the information corresponding to the column number. */
/*********************************************************************/
switch (N) {
-#if defined(__WIN__)
+#if defined(_WIN32)
case 0: Value->SetValue_psz(Tdbp->Drive); break;
-#endif // __WIN__
+#endif // _WIN32
case 1: Value->SetValue_psz(Tdbp->Direc); break;
case 2: Value->SetValue_psz(Tdbp->Fname); break;
case 3: Value->SetValue_psz(Tdbp->Ftype); break;
-#if defined(__WIN__)
+#if defined(_WIN32)
case 4: Value->SetValue((int)Tdbp->FileData.dwFileAttributes); break;
case 5: Value->SetValue((int)Tdbp->FileData.nFileSizeLow); break;
case 6: SetTimeValue(g, Tdbp->FileData.ftLastWriteTime); break;
case 7: SetTimeValue(g, Tdbp->FileData.ftCreationTime); break;
case 8: SetTimeValue(g, Tdbp->FileData.ftLastAccessTime); break;
-#else // !__WIN__
+#else // !_WIN32
case 4: Value->SetValue((int)Tdbp->Fileinfo.st_mode); break;
case 5: Value->SetValue((int)Tdbp->Fileinfo.st_size); break;
case 6: Value->SetValue((int)Tdbp->Fileinfo.st_mtime); break;
@@ -1014,7 +1014,7 @@ void DIRCOL::ReadColumn(PGLOBAL g)
case 8: Value->SetValue((int)Tdbp->Fileinfo.st_atime); break;
case 9: Value->SetValue((int)Tdbp->Fileinfo.st_uid); break;
case 10: Value->SetValue((int)Tdbp->Fileinfo.st_gid); break;
-#endif // !__WIN__
+#endif // !_WIN32
default:
sprintf(g->Message, MSG(INV_DIRCOL_OFST), N);
throw GetAmType();
@@ -1046,7 +1046,7 @@ int TDBSDR::FindInDir(PGLOBAL g)
size_t m = strlen(Direc);
// Start searching files in the target directory.
-#if defined(__WIN__)
+#if defined(_WIN32)
HANDLE h;
int rc;
@@ -1157,7 +1157,7 @@ int TDBSDR::FindInDir(PGLOBAL g)
// Close the search handle.
FindClose(h);
-#else // !__WIN__
+#else // !_WIN32
int k;
DIR *dir = opendir(Direc);
@@ -1191,7 +1191,7 @@ int TDBSDR::FindInDir(PGLOBAL g)
// Close the DIR handle.
closedir(dir);
-#endif // !__WIN__
+#endif // !_WIN32
return n;
} // end of FindInDir
@@ -1207,13 +1207,13 @@ bool TDBSDR::OpenDB(PGLOBAL g)
Sub = (PSUBDIR)PlugSubAlloc(g, NULL, sizeof(SUBDIR));
Sub->Next = NULL;
Sub->Prev = NULL;
-#if defined(__WIN__)
+#if defined(_WIN32)
Sub->H = INVALID_HANDLE_VALUE;
Sub->Len = strlen(Direc);
-#else // !__WIN__
+#else // !_WIN32
Sub->D = NULL;
Sub->Len = 0;
-#endif // !__WIN__
+#endif // !_WIN32
} // endif To_Sub
return TDBDIR::OpenDB(g);
@@ -1226,7 +1226,7 @@ int TDBSDR::ReadDB(PGLOBAL g)
{
int rc;
-#if defined(__WIN__)
+#if defined(_WIN32)
again:
rc = TDBDIR::ReadDB(g);
@@ -1282,7 +1282,7 @@ int TDBSDR::ReadDB(PGLOBAL g)
} // endif H
} // endif rc
-#else // !__WIN__
+#else // !_WIN32
rc = RC_NF;
again:
@@ -1340,7 +1340,7 @@ int TDBSDR::ReadDB(PGLOBAL g)
} // endif Entry
-#endif // !__WIN__
+#endif // !_WIN32
return rc;
} // end of ReadDB
diff --git a/storage/connect/tabmul.h b/storage/connect/tabmul.h
index 8a95a772c41..a9d3f88cc44 100644
--- a/storage/connect/tabmul.h
+++ b/storage/connect/tabmul.h
@@ -6,14 +6,14 @@
/* */
/* This file contains the TDBMUL and TDBDIR classes declares. */
/***********************************************************************/
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <io.h>
-#else // !__WIN__
+#else // !_WIN32
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <dirent.h>
-#endif // !__WIN__
+#endif // !_WIN32
//#include "osutil.h"
#include "block.h"
@@ -160,18 +160,18 @@ public:
// Members
PSZ To_File; // Points to file search pathname
int iFile; // Index of currently retrieved file
-#if defined(__WIN__)
+#if defined(_WIN32)
PVAL Dvalp; // Used to retrieve file date values
WIN32_FIND_DATA FileData; // Find data structure
HANDLE hSearch; // Search handle
char Drive[_MAX_DRIVE]; // Drive name
-#else // !__WIN__
+#else // !_WIN32
struct stat Fileinfo; // File info structure
struct dirent *Entry; // Point to directory entry structure
DIR *Dir; // To searched directory structure
bool Done; // true when _splipath is done
char Pattern[_MAX_FNAME+_MAX_EXT];
-#endif // !__WIN__
+#endif // !_WIN32
char Fpath[_MAX_PATH]; // Absolute file search pattern
char Direc[_MAX_DIR]; // Search path
char Fname[_MAX_FNAME]; // File name
@@ -207,11 +207,11 @@ class TDBSDR : public TDBDIR {
typedef struct _Sub_Dir {
struct _Sub_Dir *Next;
struct _Sub_Dir *Prev;
-#if defined(__WIN__)
+#if defined(_WIN32)
HANDLE H; // Search handle
-#else // !__WIN__
+#else // !_WIN32
DIR *D;
-#endif // !__WIN__
+#endif // !_WIN32
size_t Len; // Initial directory name length
} SUBDIR, *PSUBDIR;
@@ -238,9 +238,9 @@ class DIRCOL : public COLBLK {
protected:
// Default constructor not to be used
DIRCOL(void) {}
-#if defined(__WIN__)
+#if defined(_WIN32)
void SetTimeValue(PGLOBAL g, FILETIME& ftime);
-#endif // __WIN__
+#endif // _WIN32
// Members
PTDBDIR Tdbp; // To DIR table
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index 440fdb583f1..674580535a5 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -35,9 +35,9 @@
#include "my_global.h"
#include "sql_class.h"
#include "sql_servers.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
//#include <fnmatch.h>
//#include <errno.h>
#include <stdlib.h>
@@ -46,7 +46,7 @@
#include "osutil.h"
//#include <io.h>
//#include <fcntl.h>
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Include application header files: */
diff --git a/storage/connect/taboccur.cpp b/storage/connect/taboccur.cpp
index 20d4c0cb032..c3cb5be2e8d 100644
--- a/storage/connect/taboccur.cpp
+++ b/storage/connect/taboccur.cpp
@@ -1,7 +1,7 @@
/************ TabOccur CPP Declares Source Code File (.CPP) ************/
/* Name: TABOCCUR.CPP Version 1.2 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2013 - 2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2013 - 2021 */
/* */
/* OCCUR: Table that provides a view of a source table where the */
/* contain of several columns of the source table is placed in only */
@@ -13,7 +13,7 @@
/***********************************************************************/
#include "my_global.h"
#include "table.h" // MySQL table definitions
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <stdlib.h>
#include <stdio.h>
#if defined(__BORLANDC__)
@@ -49,11 +49,13 @@
#include "tabmysql.h"
#include "ha_connect.h"
+int PrepareColist(char *colist);
+
/***********************************************************************/
/* Prepare and count columns in the column list. */
/***********************************************************************/
-static int PrepareColist(char *colist)
- {
+int PrepareColist(char *colist)
+{
char *p, *pn;
int n = 0;
@@ -71,7 +73,7 @@ static int PrepareColist(char *colist)
} // endif p
return n;
- } // end of PrepareColist
+} // end of PrepareColist
/************************************************************************/
/* OcrColumns: constructs the result blocks containing all the columns */
@@ -79,7 +81,7 @@ static int PrepareColist(char *colist)
/************************************************************************/
bool OcrColumns(PGLOBAL g, PQRYRES qrp, const char *col,
const char *ocr, const char *rank)
- {
+{
char *pn, *colist;
int i, k, m, n = 0, c = 0, j = qrp->Nblin;
bool rk, b = false;
@@ -168,7 +170,7 @@ bool OcrColumns(PGLOBAL g, PQRYRES qrp, const char *col,
/**********************************************************************/
qrp->Nblin = j;
return false;
- } // end of OcrColumns
+} // end of OcrColumns
/************************************************************************/
/* OcrSrcCols: constructs the result blocks containing all the columns */
@@ -176,7 +178,7 @@ bool OcrColumns(PGLOBAL g, PQRYRES qrp, const char *col,
/************************************************************************/
bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col,
const char *ocr, const char *rank)
- {
+{
char *pn, *colist;
int i, k, m, n = 0, c = 0;
bool rk, b = false;
@@ -249,7 +251,7 @@ bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col,
/**********************************************************************/
qrp->Nblin = i;
return false;
- } // end of OcrSrcCols
+} // end of OcrSrcCols
/* -------------- Implementation of the OCCUR classes ---------------- */
@@ -257,24 +259,24 @@ bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col,
/* DefineAM: define specific AM block values from OCCUR table. */
/***********************************************************************/
bool OCCURDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
- {
+{
Rcol = GetStringCatInfo(g, "RankCol", "");
Colist = GetStringCatInfo(g, "Colist", "");
Xcol = GetStringCatInfo(g, "OccurCol", Colist);
return PRXDEF::DefineAM(g, am, poff);
- } // end of DefineAM
+} // end of DefineAM
/***********************************************************************/
/* GetTable: makes a new TDB of the proper type. */
/***********************************************************************/
PTDB OCCURDEF::GetTable(PGLOBAL g, MODE)
- {
+{
if (Catfunc != FNC_COL)
return new(g) TDBOCCUR(this);
else
return new(g) TDBTBC(this);
- } // end of GetTable
+} // end of GetTable
/* ------------------------------------------------------------------- */
@@ -282,7 +284,7 @@ PTDB OCCURDEF::GetTable(PGLOBAL g, MODE)
/* Implementation of the TDBOCCUR class. */
/***********************************************************************/
TDBOCCUR::TDBOCCUR(POCCURDEF tdp) : TDBPRX(tdp)
- {
+{
//Tdbp = NULL; // Source table (in TDBPRX)
Tabname = tdp->Tablep->GetName(); // Name of source table
Colist = tdp->Colist; // List of source columns
@@ -294,13 +296,13 @@ TDBOCCUR::TDBOCCUR(POCCURDEF tdp) : TDBPRX(tdp)
N = 0; // The current table index
M = 0; // The occurence rank
RowFlag = 0; // 0: Ok, 1: Same, 2: Skip
- } // end of TDBOCCUR constructor
+} // end of TDBOCCUR constructor
/***********************************************************************/
/* Allocate OCCUR/SRC column description block. */
/***********************************************************************/
PCOL TDBOCCUR::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
- {
+{
PCOL colp = NULL;
if (!stricmp(cdp->GetName(), Rcolumn)) {
@@ -321,13 +323,13 @@ PCOL TDBOCCUR::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
} // endif cprec
return colp;
- } // end of MakeCol
+} // end of MakeCol
/***********************************************************************/
/* Initializes the table. */
/***********************************************************************/
bool TDBOCCUR::InitTable(PGLOBAL g)
- {
+{
if (!Tdbp)
// Get the table description block of this table
if (!(Tdbp = GetSubTable(g, ((POCCURDEF)To_Def)->Tablep, TRUE)))
@@ -338,13 +340,13 @@ bool TDBOCCUR::InitTable(PGLOBAL g)
return TRUE;
return FALSE;
- } // end of InitTable
+} // end of InitTable
/***********************************************************************/
/* Allocate OCCUR column description block. */
/***********************************************************************/
bool TDBOCCUR::MakeColumnList(PGLOBAL g)
- {
+{
char *pn;
int i;
PCOL colp;
@@ -371,13 +373,13 @@ bool TDBOCCUR::MakeColumnList(PGLOBAL g)
} // endfor i
return false;
- } // end of MakeColumnList
+} // end of MakeColumnList
/***********************************************************************/
/* Allocate OCCUR column description block for a view. */
/***********************************************************************/
bool TDBOCCUR::ViewColumnList(PGLOBAL g)
- {
+{
char *pn;
int i;
PCOL colp, cp;
@@ -412,13 +414,13 @@ bool TDBOCCUR::ViewColumnList(PGLOBAL g)
} // endif Col
return false;
- } // end of ViewColumnList
+} // end of ViewColumnList
/***********************************************************************/
/* OCCUR GetMaxSize: returns the maximum number of rows in the table. */
/***********************************************************************/
int TDBOCCUR::GetMaxSize(PGLOBAL g)
- {
+{
if (MaxSize < 0) {
if (!(Tdbp = GetSubTable(g, ((POCCURDEF)To_Def)->Tablep, TRUE)))
return 0;
@@ -427,22 +429,22 @@ int TDBOCCUR::GetMaxSize(PGLOBAL g)
} // endif MaxSize
return MaxSize;
- } // end of GetMaxSize
+} // end of GetMaxSize
/***********************************************************************/
/* In this sample, ROWID will be the (virtual) row number, */
/* while ROWNUM will be the occurence rank in the multiple column. */
/***********************************************************************/
int TDBOCCUR::RowNumber(PGLOBAL, bool b)
- {
+{
return (b) ? M : N;
- } // end of RowNumber
+} // end of RowNumber
/***********************************************************************/
/* OCCUR Access Method opening routine. */
/***********************************************************************/
bool TDBOCCUR::OpenDB(PGLOBAL g)
- {
+{
if (Use == USE_OPEN) {
/*******************************************************************/
/* Table already open, just replace it at its beginning. */
@@ -491,13 +493,13 @@ bool TDBOCCUR::OpenDB(PGLOBAL g)
Use = USE_OPEN;
return ViewColumnList(g);
- } // end of OpenDB
+} // end of OpenDB
/***********************************************************************/
/* Data Base read routine for OCCUR access method. */
/***********************************************************************/
int TDBOCCUR::ReadDB(PGLOBAL g)
- {
+{
int rc = RC_OK;
/*********************************************************************/
@@ -518,7 +520,7 @@ int TDBOCCUR::ReadDB(PGLOBAL g)
N++;
return rc;
- } // end of ReadDB
+} // end of ReadDB
// ------------------------ OCCURCOL functions ----------------------------
@@ -527,17 +529,17 @@ int TDBOCCUR::ReadDB(PGLOBAL g)
/***********************************************************************/
OCCURCOL::OCCURCOL(PCOLDEF cdp, PTDBOCCUR tdbp, int n)
: COLBLK(cdp, tdbp, n)
- {
+{
// Set additional OCCUR access method information for column.
I = 0;
- } // end of OCCURCOL constructor
+} // end of OCCURCOL constructor
/***********************************************************************/
/* ReadColumn: what this routine does is to access the columns of */
/* list, extract their value and convert it to buffer type. */
/***********************************************************************/
void OCCURCOL::ReadColumn(PGLOBAL g)
- {
+{
PTDBOCCUR tdbp = (PTDBOCCUR)To_Tdb;
PCOL *col = tdbp->Col;
@@ -559,7 +561,7 @@ void OCCURCOL::ReadColumn(PGLOBAL g)
// Set the OCCUR column value from the Ith source column value
Value->SetValue_pval(col[I++]->GetValue());
tdbp->RowFlag = 1;
- } // end of ReadColumn
+} // end of ReadColumn
// ------------------------ RANKCOL functions ---------------------------
@@ -569,7 +571,7 @@ void OCCURCOL::ReadColumn(PGLOBAL g)
/* list, extract its name and set to it the rank column value. */
/***********************************************************************/
void RANKCOL::ReadColumn(PGLOBAL)
- {
+{
PTDBOCCUR tdbp = (PTDBOCCUR)To_Tdb;
PCOL *col = tdbp->Col;
@@ -584,4 +586,4 @@ void RANKCOL::ReadColumn(PGLOBAL)
} // endelse
- } // end of ReadColumn
+} // end of ReadColumn
diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp
index ba5c65e2c94..bede19f7344 100644
--- a/storage/connect/tabodbc.cpp
+++ b/storage/connect/tabodbc.cpp
@@ -36,7 +36,7 @@
/***********************************************************************/
#include "my_global.h"
#include "sql_class.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <io.h>
#include <fcntl.h>
#if defined(__BORLANDC__)
diff --git a/storage/connect/tabpivot.cpp b/storage/connect/tabpivot.cpp
index b8e61f259e4..1047a139f3b 100644
--- a/storage/connect/tabpivot.cpp
+++ b/storage/connect/tabpivot.cpp
@@ -17,7 +17,7 @@
/***********************************************************************/
#include "my_global.h"
#include "table.h" // MySQL table definitions
-#if defined(__WIN__)
+#if defined(_WIN32)
#if defined(__BORLANDC__)
#define __MFC_COMPAT__ // To define min/max as macro
#endif
diff --git a/storage/connect/tabrest.cpp b/storage/connect/tabrest.cpp
index 6679ccd55b0..c66d8d76f3d 100644
--- a/storage/connect/tabrest.cpp
+++ b/storage/connect/tabrest.cpp
@@ -1,5 +1,5 @@
/************** tabrest C++ Program Source Code File (.CPP) ************/
-/* PROGRAM NAME: tabrest Version 2.0 */
+/* PROGRAM NAME: tabrest Version 2.1 */
/* (C) Copyright to the author Olivier BERTRAND 2018 - 2021 */
/* This program is the REST Web API support for MariaDB. */
/* The way Connect handles NOSQL data returned by REST queries is */
@@ -13,10 +13,10 @@
#include <my_global.h> // All MariaDB stuff
#include <mysqld.h>
#include <sql_error.h>
-#if !defined(__WIN__) && !defined(_WINDOWS)
+#if !defined(_WIN32) && !defined(_WINDOWS)
#include <sys/types.h>
#include <sys/wait.h>
-#endif // !__WIN__ && !_WINDOWS
+#endif // !_WIN32 && !_WINDOWS
/***********************************************************************/
/* Include application header files: */
@@ -37,7 +37,7 @@
#include "tabrest.h"
#if defined(connect_EXPORTS)
-#define PUSH_WARNING(M) push_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, 0, M)
+#define PUSH_WARNING(M) push_warning(current_thd, Sql_condition::WARN_LEVEL_NOTE, 0, M)
#else
#define PUSH_WARNING(M) htrc(M)
#endif
@@ -65,9 +65,9 @@ int Xcurl(PGLOBAL g, PCSZ Http, PCSZ Uri, PCSZ filename)
my_snprintf(buf, sizeof(buf)-1, "%s/%s", Http, Uri);
} else
- my_snprintf(buf, sizeof(buf)-1, "%s", Http);
+ my_snprintf(buf, sizeof(buf)-1, "%s", Http);
-#if defined(__WIN__)
+#if defined(_WIN32)
char cmd[1024];
STARTUPINFO si;
PROCESS_INFORMATION pi;
@@ -90,7 +90,7 @@ int Xcurl(PGLOBAL g, PCSZ Http, PCSZ Uri, PCSZ filename)
sprintf(g->Message, "CreateProcess curl failed (%d)", GetLastError());
rc = 1;
} // endif CreateProcess
-#else // !__WIN__
+#else // !_WIN32
char fn[600];
pid_t pID;
@@ -130,7 +130,7 @@ int Xcurl(PGLOBAL g, PCSZ Http, PCSZ Uri, PCSZ filename)
// Parent process
wait(NULL); // Wait for the child to terminate
} // endif pID
-#endif // !__WIN__
+#endif // !_WIN32
return rc;
} // end of Xcurl
@@ -147,7 +147,7 @@ XGETREST GetRestFunction(PGLOBAL g)
if (trace(515))
htrc("Looking for GetRest library\n");
-#if defined(__WIN__) || defined(_WINDOWS)
+#if defined(_WIN32) || defined(_WINDOWS)
HANDLE Hdll;
const char* soname = "GetRest.dll"; // Module name
@@ -176,7 +176,7 @@ XGETREST GetRestFunction(PGLOBAL g)
FreeLibrary((HMODULE)Hdll);
return NULL;
} // endif getRestFnc
-#else // !__WIN__
+#else // !_WIN32
void* Hso;
const char* error = NULL;
const char* soname = "GetRest.so"; // Module name
@@ -195,7 +195,7 @@ XGETREST GetRestFunction(PGLOBAL g)
dlclose(Hso);
return NULL;
} // endif getdef
-#endif // !__WIN__
+#endif // !_WIN32
#else // REST_SOURCE
getRestFnc = restGetFile;
#endif // REST_SOURCE
diff --git a/storage/connect/tabrest.h b/storage/connect/tabrest.h
index 9cf2d10a6b8..9066a89b306 100644
--- a/storage/connect/tabrest.h
+++ b/storage/connect/tabrest.h
@@ -5,12 +5,12 @@
/***********************************************************************/
#pragma once
-#if defined(__WIN__)
+#if defined(_WIN32)
static PCSZ slash = "\\";
-#else // !__WIN__
+#else // !_WIN32
static PCSZ slash = "/";
#define stricmp strcasecmp
-#endif // !__WIN__
+#endif // !_WIN32
typedef int(__stdcall* XGETREST) (char*, bool, PCSZ, PCSZ, PCSZ);
diff --git a/storage/connect/tabsys.cpp b/storage/connect/tabsys.cpp
index f73a2b6578d..9a8e4a9c562 100644
--- a/storage/connect/tabsys.cpp
+++ b/storage/connect/tabsys.cpp
@@ -12,12 +12,12 @@
/* Include relevant sections of the System header files. */
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#if defined(__BORLANDC__)
#define __MFC_COMPAT__ // To define min/max as macro
#endif // __BORLANDC__
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
#if defined(UNIX)
#include <errno.h>
#include <unistd.h>
@@ -25,7 +25,7 @@
#include <io.h>
#endif // !UNIX
#include <fcntl.h>
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Include application header files: */
@@ -36,9 +36,9 @@
#include "global.h"
#include "plgdbsem.h"
#include "reldef.h"
-#if !defined(__WIN__)
+#if !defined(_WIN32)
#include "osutil.h"
-#endif // !__WIN__
+#endif // !_WIN32
#include "filamtxt.h"
#include "tabdos.h"
#include "tabsys.h"
@@ -48,10 +48,10 @@
#define CSZ 36 // Column section name length
#define CDZ 256 // Column definition length
-#if !defined(__WIN__)
+#if !defined(_WIN32)
#define GetPrivateProfileSectionNames(S,L,I) \
GetPrivateProfileString(NULL,NULL,"",S,L,I)
-#endif // !__WIN__
+#endif // !_WIN32
/* -------------- Implementation of the INI classes ------------------ */
@@ -123,7 +123,7 @@ bool INIDEF::DeleteTableFile(PGLOBAL g)
// Delete the INI table file if not protected
if (!IsReadOnly()) {
PlugSetPath(filename, Fn, GetPath());
-#if defined(__WIN__)
+#if defined(_WIN32)
rc = !DeleteFile(filename);
#else // UNIX
rc = remove(filename);
@@ -345,9 +345,9 @@ int TDBINI::DeleteDB(PGLOBAL g, int irc)
/***********************************************************************/
void TDBINI::CloseDB(PGLOBAL)
{
-#if !defined(__WIN__)
+#if !defined(_WIN32)
PROFILE_Close(Ifile);
-#endif // !__WIN__
+#endif // !_WIN32
} // end of CloseDB
// ------------------------ INICOL functions ----------------------------
diff --git a/storage/connect/tabtbl.cpp b/storage/connect/tabtbl.cpp
index 1150824464f..b6277088bac 100644
--- a/storage/connect/tabtbl.cpp
+++ b/storage/connect/tabtbl.cpp
@@ -36,7 +36,7 @@
//#include "sql_base.h"
#include "my_global.h"
#include "table.h" // MySQL table definitions
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <stdlib.h>
#include <stdio.h>
#if defined(__BORLANDC__)
@@ -71,15 +71,15 @@
#include "tabmysql.h"
#include "ha_connect.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#if defined(__BORLANDC__)
#define SYSEXIT void _USERENTRY
#else
#define SYSEXIT void
#endif
-#else // !__WIN__
+#else // !_WIN32
#define SYSEXIT void *
-#endif // !__WIN__
+#endif // !_WIN32
extern pthread_mutex_t tblmut;
diff --git a/storage/connect/tabutil.cpp b/storage/connect/tabutil.cpp
index 0a91f36afa7..e23ada8cde9 100644
--- a/storage/connect/tabutil.cpp
+++ b/storage/connect/tabutil.cpp
@@ -14,7 +14,7 @@
#include "sql_class.h"
#include "table.h"
#include "field.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <stdlib.h>
#include <stdio.h>
#if defined(__BORLANDC__)
diff --git a/storage/connect/tabvct.cpp b/storage/connect/tabvct.cpp
index 0ed466f6ffb..9cf5f41d1fe 100644
--- a/storage/connect/tabvct.cpp
+++ b/storage/connect/tabvct.cpp
@@ -35,7 +35,7 @@
/* Include relevant MariaDB header file. */
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <io.h>
#include <fcntl.h>
#if defined(__BORLANDC__)
@@ -149,7 +149,7 @@ bool VCTDEF::Erase(char *filename)
for (i = 1, cdp = To_Cols; cdp; i++, cdp = cdp->GetNext()) {
sprintf(filename, fpat, i);
-//#if defined(__WIN__)
+//#if defined(_WIN32)
// rc |= !DeleteFile(filename);
//#else // UNIX
rc |= remove(filename);
@@ -178,7 +178,7 @@ bool VCTDEF::Erase(char *filename)
int VCTDEF::MakeFnPattern(char *fpat)
{
char pat[16];
-#if defined(__WIN__)
+#if defined(_WIN32)
char drive[_MAX_DRIVE];
#else
char *drive = NULL;
diff --git a/storage/connect/tabwmi.cpp b/storage/connect/tabwmi.cpp
index 8a8e1bcbcb6..a6aab7d2563 100644
--- a/storage/connect/tabwmi.cpp
+++ b/storage/connect/tabwmi.cpp
@@ -2,9 +2,9 @@
/* TABWMI: Author Olivier Bertrand -- PlugDB -- 2012 - 2017 */
/* TABWMI: Virtual table to get WMI information. */
/***********************************************************************/
-#if !defined(__WIN__)
+#if !defined(_WIN32)
#error This is a WINDOWS only table type
-#endif // !__WIN__
+#endif // !_WIN32
#include "my_global.h"
#include <stdio.h>
diff --git a/storage/connect/tabxcl.cpp b/storage/connect/tabxcl.cpp
index 4634f6a4ded..5b1cf57cebb 100644
--- a/storage/connect/tabxcl.cpp
+++ b/storage/connect/tabxcl.cpp
@@ -17,7 +17,7 @@
/***********************************************************************/
#include "my_global.h"
#include "table.h" // MySQL table definitions
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <stdlib.h>
#include <stdio.h>
#if defined(__BORLANDC__)
diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp
index 195a9418f93..6990fa4abba 100644
--- a/storage/connect/tabxml.cpp
+++ b/storage/connect/tabxml.cpp
@@ -15,12 +15,12 @@
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <io.h>
#include <winsock2.h>
//#include <windows.h>
#include <comdef.h>
-#else // !__WIN__
+#else // !_WIN32
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -28,7 +28,7 @@
//#include <ctype.h>
#include "osutil.h"
#define _O_RDONLY O_RDONLY
-#endif // !__WIN__
+#endif // !_WIN32
#include "resource.h" // for IDS_COLUMNS
#define INCLUDE_TDBXML
@@ -53,11 +53,11 @@
extern "C" char version[];
-#if defined(__WIN__) && defined(DOMDOC_SUPPORT)
+#if defined(_WIN32) && defined(DOMDOC_SUPPORT)
#define XMLSUP "MS-DOM"
-#else // !__WIN__
+#else // !_WIN32
#define XMLSUP "libxml2"
-#endif // !__WIN__
+#endif // !_WIN32
#define TYPE_UNKNOWN 12 /* Must be greater than other types */
#define XLEN(M) sizeof(M) - strlen(M) - 1 /* To avoid overflow*/
@@ -180,11 +180,11 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
tdp->Skip = GetBooleanTableOption(g, topt, "Skipnull", false);
if (!(op = GetStringTableOption(g, topt, "Xmlsup", NULL)))
-#if defined(__WIN__)
+#if defined(_WIN32)
tdp->Usedom = true;
-#else // !__WIN__
+#else // !_WIN32
tdp->Usedom = false;
-#endif // !__WIN__
+#endif // !_WIN32
else
tdp->Usedom = (toupper(*op) == 'M' || toupper(*op) == 'D');
@@ -529,7 +529,7 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
XmlDB = GetStringCatInfo(g, "XmlDB", NULL);
Nslist = GetStringCatInfo(g, "Nslist", NULL);
DefNs = GetStringCatInfo(g, "DefNs", NULL);
- Limit = GetIntCatInfo("Limit", 10);
+ Limit = GetIntCatInfo("Limit", 50);
Xpand = GetBoolCatInfo("Expand", false);
Header = GetIntCatInfo("Header", 0);
GetCharCatInfo("Xmlsup", "*", buf, sizeof(buf));
@@ -537,11 +537,11 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
// Note that if no support is specified, the default is MS-DOM
// on Windows and libxml2 otherwise
if (*buf == '*')
-#if defined(__WIN__)
+#if defined(_WIN32)
Usedom = true;
-#else // !__WIN__
+#else // !_WIN32
Usedom = false;
-#endif // !__WIN__
+#endif // !_WIN32
else
Usedom = (toupper(*buf) == 'M' || toupper(*buf) == 'D');
@@ -974,7 +974,7 @@ bool TDBXML::Initialize(PGLOBAL g)
Docp->SetNofree(true); // For libxml2
-#if defined(__WIN__)
+#if defined(_WIN32)
} catch (_com_error e) {
// We come here if a DOM command threw an error
char buf[128];
@@ -988,7 +988,7 @@ bool TDBXML::Initialize(PGLOBAL g)
sprintf(g->Message, "%s hr=%x", MSG(COM_ERROR), e.Error());
goto error;
-#endif // __WIN__
+#endif // _WIN32
#if !defined(UNIX)
} catch(...) {
// Other errors
diff --git a/storage/connect/valblk.cpp b/storage/connect/valblk.cpp
index 2ae9382609d..40d9751721e 100644
--- a/storage/connect/valblk.cpp
+++ b/storage/connect/valblk.cpp
@@ -23,7 +23,7 @@
/* Include relevant MariaDB header file. */
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
//#include <windows.h>
#else
#include "osutil.h"
diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp
index 412cb808936..a34133a9b72 100644
--- a/storage/connect/value.cpp
+++ b/storage/connect/value.cpp
@@ -30,11 +30,11 @@
#include "sql_class.h"
#include "sql_time.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
#include <string.h>
-#endif // !__WIN__
+#endif // !_WIN32
#include <math.h>
@@ -77,12 +77,12 @@ int DTVAL::Shift = 0;
/***********************************************************************/
bool PlugEvalLike(PGLOBAL, LPCSTR, LPCSTR, bool);
-#if !defined(__WIN__)
+#if !defined(_WIN32)
extern "C" {
PSZ strupr(PSZ s);
PSZ strlwr(PSZ s);
}
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Get a long long number from its character representation. */
@@ -1648,10 +1648,10 @@ int TYPVAL<PSZ>::CompareValue(PVAL vp)
else
n = strcmp(Strp, vp->GetCharValue());
-#if defined(__WIN__)
+#if defined(_WIN32)
if (n == _NLSCMPERROR)
return n; // Here we should raise an error
-#endif // __WIN__
+#endif // _WIN32
return (n > 0) ? 1 : (n < 0) ? -1 : 0;
} // end of CompareValue
@@ -2644,9 +2644,9 @@ bool DTVAL::SetValue_pval(PVAL valp, bool chktype)
} else if (valp->GetType() == TYPE_BIGINT &&
!(valp->GetBigintValue() % 1000)) {
// Assuming that this timestamp is in milliseconds
- Tval = (int)(valp->GetBigintValue() / 1000);
+ SetValue((int)(valp->GetBigintValue() / 1000));
} else
- Tval = valp->GetIntValue();
+ SetValue(valp->GetIntValue());
} else
Reset();
@@ -2738,20 +2738,38 @@ void DTVAL::SetValue_pvblk(PVBLK blk, int n)
} // end of SetValue
/***********************************************************************/
+/* DTVAL SetValue: get date as an integer. */
+/***********************************************************************/
+void DTVAL::SetValue(int n)
+{
+ Tval = n;
+
+ if (Pdtp) {
+ size_t slen = (size_t)Len + 1;
+ struct tm tm, *ptm= GetGmTime(&tm);
+
+ if (ptm)
+ strftime(Sdate, slen, Pdtp->OutFmt, ptm);
+
+ } // endif Pdtp
+
+} // end of SetValue
+
+/***********************************************************************/
/* DTVAL GetCharString: get string representation of a date value. */
/***********************************************************************/
char *DTVAL::GetCharString(char *p)
{
if (Pdtp) {
- size_t n = 0;
+ size_t n = 0, slen = (size_t)Len + 1;
struct tm tm, *ptm= GetGmTime(&tm);
if (ptm)
- n = strftime(Sdate, Len + 1, Pdtp->OutFmt, ptm);
+ n = strftime(Sdate, slen, Pdtp->OutFmt, ptm);
if (!n) {
*Sdate = '\0';
- strncat(Sdate, "Error", Len + 1);
+ strncat(Sdate, "Error", slen);
} // endif n
return Sdate;
diff --git a/storage/connect/value.h b/storage/connect/value.h
index df6a55501b6..a0d947347c3 100644
--- a/storage/connect/value.h
+++ b/storage/connect/value.h
@@ -412,13 +412,15 @@ class DllExport DTVAL : public TYPVAL<int> {
// Constructors
DTVAL(PGLOBAL g, int n, int p, PCSZ fmt);
DTVAL(int n);
+ using TYPVAL<int>::SetValue;
// Implementation
virtual bool SetValue_pval(PVAL valp, bool chktype);
virtual bool SetValue_char(const char *p, int n);
virtual void SetValue_psz(PCSZ s);
virtual void SetValue_pvblk(PVBLK blk, int n);
- virtual PSZ GetCharValue(void) { return Sdate; }
+ virtual void SetValue(int n);
+ virtual PSZ GetCharValue(void) { return Sdate; }
virtual char *GetCharString(char *p);
virtual int ShowValue(char *buf, int len);
virtual bool FormatValue(PVAL vp, PCSZ fmt);
diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp
index 8dcaa186bc9..f4a5b1fe1fa 100644
--- a/storage/connect/xindex.cpp
+++ b/storage/connect/xindex.cpp
@@ -10,12 +10,12 @@
/* Include relevant sections of the System header files. */
/***********************************************************************/
#include "my_global.h"
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <io.h>
#include <fcntl.h>
#include <errno.h>
//#include <windows.h>
-#else // !__WIN__
+#else // !_WIN32
#if defined(UNIX)
#include <sys/types.h>
#include <sys/stat.h>
@@ -25,7 +25,7 @@
#include <io.h>
#endif // !UNIX
#include <fcntl.h>
-#endif // !__WIN__
+#endif // !_WIN32
/***********************************************************************/
/* Include required application header files */
@@ -848,7 +848,7 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp)
if ((sep = defp->GetBoolCatInfo("SepIndex", false))) {
// Index is saved in a separate file
-#if defined(__WIN__)
+#if defined(_WIN32)
char drive[_MAX_DRIVE];
#else
char *drive = NULL;
@@ -1002,7 +1002,7 @@ bool XINDEX::Init(PGLOBAL g)
if (defp->SepIndex()) {
// Index was saved in a separate file
-#if defined(__WIN__)
+#if defined(_WIN32)
char drive[_MAX_DRIVE];
#else
char *drive = NULL;
@@ -1256,7 +1256,7 @@ bool XINDEX::MapInit(PGLOBAL g)
if (defp->SepIndex()) {
// Index was save in a separate file
-#if defined(__WIN__)
+#if defined(_WIN32)
char drive[_MAX_DRIVE];
#else
char *drive = NULL;
@@ -1471,7 +1471,7 @@ bool XINDEX::GetAllSizes(PGLOBAL g,/* int &ndif,*/ int &numk)
if (defp->SepIndex()) {
// Index was saved in a separate file
-#if defined(__WIN__)
+#if defined(_WIN32)
char drive[_MAX_DRIVE];
#else
char *drive = NULL;
@@ -2520,7 +2520,7 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
if (trace(1))
htrc(" Xopen: filename=%s id=%d mode=%d\n", filename, id, mode);
-#if defined(__WIN__)
+#if defined(_WIN32)
LONG high = 0;
DWORD rc, drc, access, share, creation;
@@ -2696,7 +2696,7 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
/***********************************************************************/
bool XHUGE::Seek(PGLOBAL g, int low, int high, int origin)
{
-#if defined(__WIN__)
+#if defined(_WIN32)
LONG hi = high;
DWORD rc = SetFilePointer(Hfile, low, &hi, origin);
@@ -2732,7 +2732,7 @@ bool XHUGE::Read(PGLOBAL g, void *buf, int n, int size)
{
bool rc = false;
-#if defined(__WIN__)
+#if defined(_WIN32)
bool brc;
DWORD nbr, count = (DWORD)(n * size);
@@ -2778,7 +2778,7 @@ bool XHUGE::Read(PGLOBAL g, void *buf, int n, int size)
/***********************************************************************/
int XHUGE::Write(PGLOBAL g, void *buf, int n, int size, bool& rc)
{
-#if defined(__WIN__)
+#if defined(_WIN32)
bool brc;
DWORD nbw, count = (DWORD)n * (DWORD) size;
@@ -2820,7 +2820,7 @@ void XHUGE::Close(char *fn, int id)
if (trace(1))
htrc("XHUGE::Close: fn=%s id=%d NewOff=%lld\n", fn, id, NewOff.Val);
-#if defined(__WIN__)
+#if defined(_WIN32)
if (id >= 0 && fn) {
CloseFileHandle(Hfile);
Hfile = CreateFile(fn, GENERIC_READ | GENERIC_WRITE, 0, NULL,
@@ -2835,7 +2835,7 @@ void XHUGE::Close(char *fn, int id)
} // endif SetFilePointer
} // endif id
-#else // !__WIN__
+#else // !_WIN32
if (id >= 0 && fn) {
if (Hfile != INVALID_HANDLE_VALUE) {
if (lseek64(Hfile, id * sizeof(IOFF), SEEK_SET) >= 0) {
@@ -2851,7 +2851,7 @@ void XHUGE::Close(char *fn, int id)
htrc("(XHUGE)error reopening %s: %s\n", fn, strerror(errno));
} // endif id
-#endif // !__WIN__
+#endif // !_WIN32
XLOAD::Close();
} // end of Close
diff --git a/storage/connect/xindex.h b/storage/connect/xindex.h
index 339d7e68b75..ce62f0591c1 100644
--- a/storage/connect/xindex.h
+++ b/storage/connect/xindex.h
@@ -350,7 +350,7 @@ class DllExport XLOAD : public BLOCK {
protected:
// Members
-#if defined(__WIN__)
+#if defined(_WIN32)
HANDLE Hfile; // Handle to file or map
#else // UNIX
int Hfile; // Descriptor to file or map
diff --git a/storage/innobase/btr/btr0scrub.cc b/storage/innobase/btr/btr0scrub.cc
index 5f89391d280..c25d2e42555 100644
--- a/storage/innobase/btr/btr0scrub.cc
+++ b/storage/innobase/btr/btr0scrub.cc
@@ -1,5 +1,5 @@
// Copyright (c) 2014, Google Inc.
-// Copyright (c) 2017, 2019, MariaDB Corporation.
+// Copyright (c) 2017, 2021, MariaDB Corporation.
/**************************************************//**
@file btr/btr0scrub.cc
@@ -830,22 +830,12 @@ btr_scrub_page(
/**************************************************************//**
Start iterating a space */
-UNIV_INTERN
-bool
-btr_scrub_start_space(
-/*===================*/
- ulint space, /*!< in: space */
- btr_scrub_t* scrub_data) /*!< in/out: scrub data */
+bool btr_scrub_start_space(const fil_space_t &space, btr_scrub_t *scrub_data)
{
- scrub_data->space = space;
+ scrub_data->space = space.id;
scrub_data->current_table = NULL;
scrub_data->current_index = NULL;
- if (fil_space_t* s = fil_space_acquire_silent(space)) {
- scrub_data->compressed = s->zip_size();
- s->release();
- } else {
- scrub_data->compressed = 0;
- }
+ scrub_data->compressed = FSP_FLAGS_GET_ZIP_SSIZE(space.flags) != 0;
scrub_data->scrubbing = check_scrub_setting(scrub_data);
return scrub_data->scrubbing;
}
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 85bf8f2a059..771e273e8ea 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -1,8 +1,8 @@
/*****************************************************************************
-Copyright (c) 1995, 2018, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2021, Oracle and/or its affiliates.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2013, 2020, MariaDB Corporation.
+Copyright (c) 2013, 2021, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -775,8 +775,8 @@ buf_page_is_checksum_valid_crc32(
#ifdef UNIV_INNOCHECKSUM
if (log_file
&& srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32) {
- fprintf(log_file, "page::%llu;"
- " crc32 calculated = %u;"
+ fprintf(log_file, "page::" UINT32PF ";"
+ " crc32 calculated = " UINT32PF ";"
" recorded checksum field1 = " ULINTPF " recorded"
" checksum field2 =" ULINTPF "\n", cur_page_num,
crc32, checksum_field1, checksum_field2);
@@ -817,26 +817,26 @@ buf_page_is_checksum_valid_innodb(
#ifdef UNIV_INNOCHECKSUM
if (log_file
&& srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_INNODB) {
- fprintf(log_file, "page::%llu;"
+ fprintf(log_file, "page::" UINT32PF ";"
" old style: calculated ="
" " ULINTPF "; recorded = " ULINTPF "\n",
cur_page_num, old_checksum,
checksum_field2);
- fprintf(log_file, "page::%llu;"
+ fprintf(log_file, "page::" UINT32PF ";"
" new style: calculated ="
- " " ULINTPF "; crc32 = %u; recorded = " ULINTPF "\n",
+ " " ULINTPF "; crc32 = " UINT32PF "; recorded = " ULINTPF "\n",
cur_page_num, new_checksum,
buf_calc_page_crc32(read_buf), checksum_field1);
}
if (log_file
&& srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB) {
- fprintf(log_file, "page::%llu;"
+ fprintf(log_file, "page::" UINT32PF ";"
" old style: calculated ="
" " ULINTPF "; recorded checksum = " ULINTPF "\n",
cur_page_num, old_checksum,
checksum_field2);
- fprintf(log_file, "page::%llu;"
+ fprintf(log_file, "page::" UINT32PF ";"
" new style: calculated ="
" " ULINTPF "; recorded checksum = " ULINTPF "\n",
cur_page_num, new_checksum,
@@ -904,7 +904,7 @@ buf_page_is_checksum_valid_none(
if (log_file
&& srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_NONE) {
fprintf(log_file,
- "page::%llu; none checksum: calculated"
+ "page::" UINT32PF "; none checksum: calculated"
" = %lu; recorded checksum_field1 = " ULINTPF
" recorded checksum_field2 = " ULINTPF "\n",
cur_page_num, BUF_NO_CHECKSUM_MAGIC,
@@ -1127,15 +1127,15 @@ buf_page_is_corrupted(
checksum_field1, checksum_field2)) {
#ifdef UNIV_INNOCHECKSUM
if (log_file) {
- fprintf(log_file, "page::%llu;"
+ fprintf(log_file, "page::" UINT32PF ";"
" old style: calculated = %u;"
" recorded = " ULINTPF ";\n",
cur_page_num,
buf_calc_page_old_checksum(read_buf),
checksum_field2);
- fprintf(log_file, "page::%llu;"
- " new style: calculated = %u;"
- " crc32 = %u; recorded = " ULINTPF ";\n",
+ fprintf(log_file, "page::" UINT32PF ";"
+ " new style: calculated = " UINT32PF ";"
+ " crc32 = " UINT32PF "; recorded = " ULINTPF ";\n",
cur_page_num,
buf_calc_page_new_checksum(read_buf),
buf_calc_page_crc32(read_buf),
@@ -1943,8 +1943,6 @@ buf_pool_init_instance(
LATCH_ID_HASH_TABLE_RW_LOCK,
srv_n_page_hash_locks, MEM_HEAP_FOR_PAGE_HASH);
- buf_pool->page_hash_old = NULL;
-
buf_pool->zip_hash = hash_create(2 * buf_pool->curr_size);
buf_pool->last_printout_time = time(NULL);
@@ -2578,8 +2576,6 @@ buf_pool_resize_hash(
{
hash_table_t* new_hash_table;
- ut_ad(buf_pool->page_hash_old == NULL);
-
/* recreate page_hash */
new_hash_table = ib_recreate(
buf_pool->page_hash, 2 * buf_pool->curr_size);
@@ -2611,8 +2607,14 @@ buf_pool_resize_hash(
}
}
- buf_pool->page_hash_old = buf_pool->page_hash;
- buf_pool->page_hash = new_hash_table;
+ /* Concurrent threads may be accessing
+ buf_pool->page_hash->n_cells, n_sync_obj and try to latch
+ sync_obj[i] while we are resizing. Therefore we never
+ deallocate page_hash, instead we overwrite n_cells (and other
+ fields) with the new values. The n_sync_obj and sync_obj are
+ actually same in both. */
+ std::swap(*buf_pool->page_hash, *new_hash_table);
+ hash_table_free(new_hash_table);
/* recreate zip_hash */
new_hash_table = hash_create(2 * buf_pool->curr_size);
@@ -3066,11 +3068,6 @@ calc_buf_pool_size:
hash_unlock_x_all(buf_pool->page_hash);
buf_pool_mutex_exit(buf_pool);
-
- if (buf_pool->page_hash_old != NULL) {
- hash_table_free(buf_pool->page_hash_old);
- buf_pool->page_hash_old = NULL;
- }
}
UT_DELETE(chunk_map_old);
diff --git a/storage/innobase/bzip2.cmake b/storage/innobase/bzip2.cmake
index 26fd703120e..91dd2bf0fcd 100644
--- a/storage/innobase/bzip2.cmake
+++ b/storage/innobase/bzip2.cmake
@@ -22,12 +22,15 @@ MACRO (MYSQL_CHECK_BZIP2)
CHECK_LIBRARY_EXISTS(bz2 BZ2_bzBuffToBuffDecompress "" HAVE_BZLIB2_DECOMPRESS)
IF (HAVE_BZLIB2_COMPRESS AND HAVE_BZLIB2_DECOMPRESS AND HAVE_BZLIB2_H)
+ SET(HAVE_INNODB_BZLIB2 TRUE)
ADD_DEFINITIONS(-DHAVE_BZIP2=1)
LINK_LIBRARIES(bz2)
ELSE()
IF (WITH_INNODB_BZIP2 STREQUAL "ON")
- MESSAGE(FATAL_ERROR "Required bzip2 library is not found")
+ MESSAGE(FATAL_ERROR "Required bzip2 library is not found")
ENDIF()
ENDIF()
ENDIF()
+ ADD_FEATURE_INFO(INNODB_BZIP2 HAVE_INNODB_BZLIB2
+ "BZIP2 compression in the InnoDB storage engine")
ENDMACRO()
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index 1b7ec82d912..81ecdbf0481 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
-Copyright (c) 2014, 2020, MariaDB Corporation.
+Copyright (c) 2014, 2021, 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
@@ -1290,6 +1290,33 @@ struct rotate_thread_t {
}
};
+/** Avoid the removal of the tablespace from
+default_encrypt_list only when
+1) Another active encryption thread working on tablespace
+2) Eligible for tablespace key rotation
+3) Tablespace is in flushing phase
+@return true if tablespace should be removed from
+default encrypt */
+static bool fil_crypt_must_remove(const fil_space_t &space)
+{
+ ut_ad(space.purpose == FIL_TYPE_TABLESPACE);
+ fil_space_crypt_t *crypt_data = space.crypt_data;
+ ut_ad(mutex_own(&fil_system.mutex));
+ const ulong encrypt_tables= srv_encrypt_tables;
+ if (!crypt_data)
+ return !encrypt_tables;
+ if (!crypt_data->is_key_found())
+ return true;
+
+ mutex_enter(&crypt_data->mutex);
+ const bool remove= (space.is_stopping() || crypt_data->not_encrypted()) &&
+ (!crypt_data->rotate_state.flushing &&
+ !encrypt_tables == !!crypt_data->min_key_version &&
+ !crypt_data->rotate_state.active_threads);
+ mutex_exit(&crypt_data->mutex);
+ return remove;
+}
+
/***********************************************************************
Check if space needs rotation given a key_state
@param[in,out] state Key rotation state
@@ -1371,7 +1398,7 @@ fil_crypt_space_needs_rotation(
key_state->rotate_key_age);
crypt_data->rotate_state.scrubbing.is_active =
- btr_scrub_start_space(space->id, &state->scrub_data);
+ btr_scrub_start_space(*space, &state->scrub_data);
time_t diff = time(0) - crypt_data->rotate_state.scrubbing.
last_scrub_completed;
@@ -1627,8 +1654,7 @@ inline fil_space_t *fil_system_t::default_encrypt_next(
If there is a change in innodb_encrypt_tables variables
value then don't remove the last processed tablespace
from the default encrypt list. */
- if (released && (!recheck || space->crypt_data) &&
- !encrypt == !srv_encrypt_tables)
+ if (released && !recheck && fil_crypt_must_remove(*space))
{
ut_a(!default_encrypt_tables.empty());
default_encrypt_tables.remove(*space);
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 35d3d0edd34..6d1ac1b9300 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2011, 2021, Oracle and/or its affiliates.
Copyright (c) 2016, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -1298,6 +1298,9 @@ fts_cache_node_add_positions(
ptr = ilist + node->ilist_size;
node->ilist_size_alloc = new_size;
+ if (cache) {
+ cache->total_size += new_size;
+ }
}
ptr_start = ptr;
@@ -1324,6 +1327,9 @@ fts_cache_node_add_positions(
if (node->ilist_size > 0) {
memcpy(ilist, node->ilist, node->ilist_size);
ut_free(node->ilist);
+ if (cache) {
+ cache->total_size -= node->ilist_size;
+ }
}
node->ilist = ilist;
@@ -1331,10 +1337,6 @@ fts_cache_node_add_positions(
node->ilist_size += enc_len;
- if (cache) {
- cache->total_size += enc_len;
- }
-
if (node->first_doc_id == FTS_NULL_DOC_ID) {
node->first_doc_id = doc_id;
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 25e2468770e..ac066be7b42 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -4435,7 +4435,7 @@ innobase_commit_low(
if (trx_is_started(trx)) {
trx_commit_for_mysql(trx);
} else {
- trx->will_lock = 0;
+ trx->will_lock = false;
#ifdef WITH_WSREP
trx->wsrep = false;
#endif /* WITH_WSREP */
@@ -4806,7 +4806,7 @@ innobase_rollback_trx(
lock_unlock_table_autoinc(trx);
if (!trx->has_logged()) {
- trx->will_lock = 0;
+ trx->will_lock = false;
#ifdef WITH_WSREP
trx->wsrep= false;
trx->lock.was_chosen_as_wsrep_victim= false;
@@ -8063,7 +8063,7 @@ ha_innobase::write_row(
ut_a(m_prebuilt->trx == trx);
if (!trx_is_started(trx)) {
- ++trx->will_lock;
+ trx->will_lock = true;
}
ins_mode_t vers_set_fields;
@@ -8833,7 +8833,7 @@ ha_innobase::update_row(
ib_senderrf(ha_thd(), IB_LOG_LEVEL_WARN, ER_READ_ONLY_MODE);
DBUG_RETURN(HA_ERR_TABLE_READONLY);
} else if (!trx_is_started(trx)) {
- ++trx->will_lock;
+ trx->will_lock = true;
}
if (m_upd_buf == NULL) {
@@ -9015,7 +9015,7 @@ ha_innobase::delete_row(
ib_senderrf(ha_thd(), IB_LOG_LEVEL_WARN, ER_READ_ONLY_MODE);
DBUG_RETURN(HA_ERR_TABLE_READONLY);
} else if (!trx_is_started(trx)) {
- ++trx->will_lock;
+ trx->will_lock = true;
}
if (!m_prebuilt->upd_node) {
@@ -9894,7 +9894,7 @@ ha_innobase::ft_init()
them as regular read only transactions for now. */
if (!trx_is_started(trx)) {
- ++trx->will_lock;
+ trx->will_lock = true;
}
DBUG_RETURN(rnd_init(false));
@@ -9960,7 +9960,7 @@ ha_innobase::ft_init_ext(
them as regular read only transactions for now. */
if (!trx_is_started(trx)) {
- ++trx->will_lock;
+ trx->will_lock = true;
}
dict_table_t* ft_table = m_prebuilt->table;
@@ -12915,7 +12915,7 @@ create_table_info_t::allocate_trx()
{
m_trx = innobase_trx_allocate(m_thd);
- m_trx->will_lock++;
+ m_trx->will_lock = true;
m_trx->ddl = true;
}
@@ -13229,13 +13229,7 @@ inline int ha_innobase::delete_table(const char* name, enum_sql_command sqlcom)
ut_a(name_len < 1000);
- /* Either the transaction is already flagged as a locking transaction
- or it hasn't been started yet. */
-
- ut_a(!trx_is_started(trx) || trx->will_lock > 0);
-
- /* We are doing a DDL operation. */
- ++trx->will_lock;
+ trx->will_lock = true;
/* Drop the table in InnoDB */
@@ -13412,14 +13406,7 @@ innobase_drop_database(
#endif /* _WIN32 */
trx_t* trx = innobase_trx_allocate(thd);
-
- /* Either the transaction is already flagged as a locking transaction
- or it hasn't been started yet. */
-
- ut_a(!trx_is_started(trx) || trx->will_lock > 0);
-
- /* We are doing a DDL operation. */
- ++trx->will_lock;
+ trx->will_lock = true;
ulint dummy;
@@ -13463,7 +13450,7 @@ inline dberr_t innobase_rename_table(trx_t *trx, const char *from,
DEBUG_SYNC_C("innodb_rename_table_ready");
trx_start_if_not_started(trx, true);
- ut_ad(trx->will_lock > 0);
+ ut_ad(trx->will_lock);
if (commit) {
/* Serialize data dictionary operations with dictionary mutex:
@@ -13612,8 +13599,7 @@ int ha_innobase::truncate()
heap, ib_table->name.m_name, ib_table->id);
const char* name = mem_heap_strdup(heap, ib_table->name.m_name);
trx_t* trx = innobase_trx_allocate(m_user_thd);
-
- ++trx->will_lock;
+ trx->will_lock = true;
trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
row_mysql_lock_data_dictionary(trx);
dict_stats_wait_bg_to_stop_using_table(ib_table, trx);
@@ -13698,9 +13684,7 @@ ha_innobase::rename_table(
}
trx_t* trx = innobase_trx_allocate(thd);
-
- /* We are doing a DDL operation. */
- ++trx->will_lock;
+ trx->will_lock = true;
trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
dberr_t error = innobase_rename_table(trx, from, to, true);
@@ -15511,7 +15495,7 @@ ha_innobase::start_stmt(
innobase_register_trx(ht, thd, trx);
if (!trx_is_started(trx)) {
- ++trx->will_lock;
+ trx->will_lock = true;
}
DBUG_RETURN(0);
@@ -15737,7 +15721,7 @@ ha_innobase::external_lock(
&& (m_prebuilt->select_lock_type != LOCK_NONE
|| m_prebuilt->stored_select_lock_type != LOCK_NONE)) {
- ++trx->will_lock;
+ trx->will_lock = true;
}
DBUG_RETURN(0);
@@ -15778,7 +15762,7 @@ ha_innobase::external_lock(
&& (m_prebuilt->select_lock_type != LOCK_NONE
|| m_prebuilt->stored_select_lock_type != LOCK_NONE)) {
- ++trx->will_lock;
+ trx->will_lock = true;
}
DBUG_RETURN(0);
@@ -16460,7 +16444,7 @@ ha_innobase::store_lock(
&& (m_prebuilt->select_lock_type != LOCK_NONE
|| m_prebuilt->stored_select_lock_type != LOCK_NONE)) {
- ++trx->will_lock;
+ trx->will_lock = true;
}
return(to);
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 5ce5360e14a..9a718915752 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -2391,7 +2391,7 @@ innodb_instant_alter_column_allowed_reason:
}
}
- m_prebuilt->trx->will_lock++;
+ m_prebuilt->trx->will_lock = true;
/* When changing a NULL column to NOT NULL and specifying a
DEFAULT value, ensure that the DEFAULT expression is a constant.
@@ -7621,7 +7621,6 @@ ha_innobase::prepare_inplace_alter_table(
mem_heap_t* heap;
const char** col_names;
int error;
- ulint max_col_len;
ulint add_autoinc_col_no = ULINT_UNDEFINED;
ulonglong autoinc_col_max_value = 0;
ulint fts_doc_col_no = ULINT_UNDEFINED;
@@ -7659,12 +7658,6 @@ ha_innobase::prepare_inplace_alter_table(
if (!(ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE)) {
/* Nothing to do */
DBUG_ASSERT(m_prebuilt->trx->dict_operation_lock_mode == 0);
- if (ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE) {
-
- online_retry_drop_indexes(
- m_prebuilt->table, m_user_thd);
-
- }
DBUG_RETURN(false);
}
@@ -7830,7 +7823,13 @@ check_if_ok_to_rename:
& 1U << DICT_TF_POS_DATA_DIR);
}
- max_col_len = DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(info.flags());
+
+ /* ALGORITHM=INPLACE without rebuild (10.3+ ALGORITHM=NOCOPY)
+ must use the current ROW_FORMAT of the table. */
+ const ulint max_col_len = DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(
+ innobase_need_rebuild(ha_alter_info, this->table)
+ ? info.flags()
+ : m_prebuilt->table->flags);
/* Check each index's column length to make sure they do not
exceed limit */
@@ -11616,7 +11615,6 @@ foreign_fail:
m_prebuilt = ctx->prebuilt;
}
trx_start_if_not_started(user_trx, true);
- user_trx->will_lock++;
m_prebuilt->trx = user_trx;
}
DBUG_INJECT_CRASH("ib_commit_inplace_crash",
diff --git a/storage/innobase/include/btr0scrub.h b/storage/innobase/include/btr0scrub.h
index feaf61784d0..0f17467fb70 100644
--- a/storage/innobase/include/btr0scrub.h
+++ b/storage/innobase/include/btr0scrub.h
@@ -141,12 +141,7 @@ btr_scrub_skip_page(
/****************************************************************
Start iterating a space
* @return true if scrubbing is turned on */
-UNIV_INTERN
-bool
-btr_scrub_start_space(
-/*===================*/
- ulint space, /*!< in: space */
- btr_scrub_t* scrub_data); /*!< in/out: scrub data */
+bool btr_scrub_start_space(const fil_space_t &space, btr_scrub_t *scrub_data);
/** Complete iterating a space.
@param[in,out] scrub_data scrub data */
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index 28060ec601e..1aba6adeb83 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2020, MariaDB Corporation.
+Copyright (c) 1995, 2021, Oracle and/or its affiliates.
+Copyright (c) 2013, 2021, 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
@@ -2081,8 +2081,6 @@ struct buf_pool_t{
page_hash mutex. Lookups can happen
while holding the buf_pool->mutex or
the relevant page_hash mutex. */
- hash_table_t* page_hash_old; /*!< old pointer to page_hash to be
- freed after resizing buffer pool */
hash_table_t* zip_hash; /*!< hash table of buf_block_t blocks
whose frames are allocated to the
zip buddy system,
diff --git a/storage/innobase/include/trx0i_s.h b/storage/innobase/include/trx0i_s.h
index 65c7d321597..ea2f9a18fcc 100644
--- a/storage/innobase/include/trx0i_s.h
+++ b/storage/innobase/include/trx0i_s.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2021, 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
@@ -164,8 +164,8 @@ struct i_s_trx_row_t {
/*!< detailed_error in trx_t */
ulint trx_is_read_only;
/*!< trx_t::read_only */
- ulint trx_is_autocommit_non_locking;
- /*!< trx_is_autocommit_non_locking(trx)
+ bool trx_is_autocommit_non_locking;
+ /*!< trx:t::is_autocommit_non_locking()
*/
};
diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h
index 5812c87feeb..323994fa14f 100644
--- a/storage/innobase/include/trx0sys.h
+++ b/storage/innobase/include/trx0sys.h
@@ -506,7 +506,7 @@ class rw_trx_hash_t
static void validate_element(trx_t *trx)
{
ut_ad(!trx->read_only || !trx->rsegs.m_redo.rseg);
- ut_ad(!trx_is_autocommit_non_locking(trx));
+ ut_ad(!trx->is_autocommit_non_locking());
/* trx->state can be anything except TRX_STATE_NOT_STARTED */
mutex_enter(&trx->mutex);
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE) ||
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 647a8d2c8a0..fa5ad1422e5 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -395,64 +395,6 @@ from innodb_lock_wait_timeout via trx_t::mysql_thd.
? thd_lock_wait_timeout((t)->mysql_thd) \
: 0)
-/**
-Determine if the transaction is a non-locking autocommit select
-(implied read-only).
-@param t transaction
-@return true if non-locking autocommit select transaction. */
-#define trx_is_autocommit_non_locking(t) \
-((t)->auto_commit && (t)->will_lock == 0)
-
-/**
-Determine if the transaction is a non-locking autocommit select
-with an explicit check for the read-only status.
-@param t transaction
-@return true if non-locking autocommit read-only transaction. */
-#define trx_is_ac_nl_ro(t) \
-((t)->read_only && trx_is_autocommit_non_locking((t)))
-
-/**
-Check transaction state */
-#define check_trx_state(t) do { \
- ut_ad(!trx_is_autocommit_non_locking((t))); \
- switch ((t)->state) { \
- case TRX_STATE_PREPARED: \
- case TRX_STATE_PREPARED_RECOVERED: \
- case TRX_STATE_ACTIVE: \
- case TRX_STATE_COMMITTED_IN_MEMORY: \
- continue; \
- case TRX_STATE_NOT_STARTED: \
- break; \
- } \
- ut_error; \
-} while (0)
-
-#ifdef UNIV_DEBUG
-/*******************************************************************//**
-Assert that an autocommit non-locking select cannot be in the
-rw_trx_hash and that it is a read-only transaction.
-The transaction must have mysql_thd assigned. */
-# define assert_trx_nonlocking_or_in_list(t) \
- do { \
- if (trx_is_autocommit_non_locking(t)) { \
- trx_state_t t_state = (t)->state; \
- ut_ad((t)->read_only); \
- ut_ad(!(t)->is_recovered); \
- ut_ad((t)->mysql_thd); \
- ut_ad(t_state == TRX_STATE_NOT_STARTED \
- || t_state == TRX_STATE_ACTIVE); \
- } else { \
- check_trx_state(t); \
- } \
- } while (0)
-#else /* UNIV_DEBUG */
-/*******************************************************************//**
-Assert that an autocommit non-locking slect cannot be in the
-rw_trx_hash and that it is a read-only transaction.
-The transaction must have mysql_thd assigned. */
-# define assert_trx_nonlocking_or_in_list(trx) ((void)0)
-#endif /* UNIV_DEBUG */
-
typedef std::vector<ib_lock_t*, ut_allocator<ib_lock_t*> > lock_list;
/*******************************************************************//**
@@ -965,16 +907,15 @@ public:
/*------------------------------*/
bool read_only; /*!< true if transaction is flagged
as a READ-ONLY transaction.
- if auto_commit && will_lock == 0
+ if auto_commit && !will_lock
then it will be handled as a
AC-NL-RO-SELECT (Auto Commit Non-Locking
Read Only Select). A read only
transaction will not be assigned an
UNDO log. */
bool auto_commit; /*!< true if it is an autocommit */
- ib_uint32_t will_lock; /*!< Will acquire some locks. Increment
- each time we determine that a lock will
- be acquired by the MySQL layer. */
+ bool will_lock; /*!< set to inform trx_start_low() that
+ the transaction may acquire locks */
/*------------------------------*/
fts_trx_t* fts_trx; /*!< FTS information, or NULL if
transaction hasn't modified tables
@@ -1129,10 +1070,13 @@ public:
}
+ /** @return whether this is a non-locking autocommit transaction */
+ bool is_autocommit_non_locking() const { return auto_commit && !will_lock; }
+
private:
- /** Assign a rollback segment for modifying temporary tables.
- @return the assigned rollback segment */
- trx_rseg_t* assign_temp_rseg();
+ /** Assign a rollback segment for modifying temporary tables.
+ @return the assigned rollback segment */
+ trx_rseg_t *assign_temp_rseg();
};
/**
diff --git a/storage/innobase/include/trx0trx.ic b/storage/innobase/include/trx0trx.ic
index f51d5368022..72310cbba06 100644
--- a/storage/innobase/include/trx0trx.ic
+++ b/storage/innobase/include/trx0trx.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2021, 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
@@ -49,11 +49,15 @@ trx_state_eq(
case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY:
- ut_ad(!trx_is_autocommit_non_locking(trx));
+ ut_ad(!trx->is_autocommit_non_locking());
return(trx->state == state);
case TRX_STATE_ACTIVE:
- assert_trx_nonlocking_or_in_list(trx);
+ if (trx->is_autocommit_non_locking()) {
+ ut_ad(!trx->is_recovered);
+ ut_ad(trx->read_only);
+ ut_ad(trx->mysql_thd);
+ }
return(state == trx->state);
case TRX_STATE_NOT_STARTED:
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index b66ea937ec2..ab9d4d296ad 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -423,7 +423,7 @@ in both 32-bit and 64-bit environments. */
#ifdef UNIV_INNOCHECKSUM
extern bool strict_verify;
extern FILE* log_file;
-extern unsigned long long cur_page_num;
+extern uint32_t cur_page_num;
#endif /* UNIV_INNOCHECKSUM */
typedef int64_t ib_int64_t;
diff --git a/storage/innobase/innodb.cmake b/storage/innobase/innodb.cmake
index 07ed7ed67ab..929b17ef52d 100644
--- a/storage/innobase/innodb.cmake
+++ b/storage/innobase/innodb.cmake
@@ -81,6 +81,7 @@ MARK_AS_ADVANCED(INNODB_COMPILER_HINTS)
IF(INNODB_COMPILER_HINTS)
ADD_DEFINITIONS("-DCOMPILER_HINTS")
ENDIF()
+ADD_FEATURE_INFO(INNODB_COMPILER_HINTS INNODB_COMPILER_HINTS "InnoDB compiled with compiler hints")
SET(MUTEXTYPE "event" CACHE STRING "Mutex type: event, sys or futex")
@@ -116,15 +117,21 @@ IF(WITH_INNODB_AHI)
ADD_DEFINITIONS(-DBTR_CUR_HASH_ADAPT -DBTR_CUR_ADAPT)
IF(NOT WITH_INNODB_ROOT_GUESS)
MESSAGE(WARNING "WITH_INNODB_AHI implies WITH_INNODB_ROOT_GUESS")
+ SET(WITH_INNODB_ROOT_GUESS ON)
ENDIF()
ELSEIF(WITH_INNODB_ROOT_GUESS)
ADD_DEFINITIONS(-DBTR_CUR_ADAPT)
ENDIF()
+ADD_FEATURE_INFO(INNODB_AHI WITH_INNODB_AHI "InnoDB Adaptive Hash Index")
+ADD_FEATURE_INFO(INNODB_ROOT_GUESS WITH_INNODB_ROOT_GUESS
+ "Cache index root block descriptors in InnoDB")
OPTION(WITH_INNODB_EXTRA_DEBUG "Enable extra InnoDB debug checks" OFF)
IF(WITH_INNODB_EXTRA_DEBUG)
ADD_DEFINITIONS(-DUNIV_ZIP_DEBUG)
ENDIF()
+ADD_FEATURE_INFO(INNODB_EXTRA_DEBUG WITH_INNODB_EXTRA_DEBUG "Extra InnoDB debug checks")
+
CHECK_FUNCTION_EXISTS(sched_getcpu HAVE_SCHED_GETCPU)
IF(HAVE_SCHED_GETCPU)
@@ -209,6 +216,7 @@ OPTION(WITH_INNODB_DISALLOW_WRITES "InnoDB freeze writes patch from Google" ${WI
IF (WITH_INNODB_DISALLOW_WRITES)
ADD_DEFINITIONS(-DWITH_INNODB_DISALLOW_WRITES)
ENDIF()
+ADD_FEATURE_INFO(INNODB_DISALLOW_WRITES WITH_INNODB_DISALLOW_WRITES "Expose innodb_disallow_writes switch to stop innodb from writing to disk")
# Include directories under innobase
@@ -244,8 +252,8 @@ IF(MSVC)
SET_SOURCE_FILES_PROPERTIES(${_SRC_DIR}/pars/lexyy.c
PROPERTIES COMPILE_FLAGS "/wd4003")
ENDIF()
-
+
# Include directories under innobase
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/innobase/include
- ${CMAKE_SOURCE_DIR}/storage/innobase/handler
+ ${CMAKE_SOURCE_DIR}/storage/innobase/handler
${CMAKE_SOURCE_DIR}/libbinlogevents/include )
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 47178a768bc..f08788b7748 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -1306,6 +1306,19 @@ wsrep_print_wait_locks(
}
#endif /* WITH_WSREP */
+#ifdef UNIV_DEBUG
+/** Check transaction state */
+static void check_trx_state(const trx_t *trx)
+{
+ ut_ad(!trx->auto_commit || trx->will_lock);
+ const auto state= trx->state;
+ ut_ad(state == TRX_STATE_ACTIVE ||
+ state == TRX_STATE_PREPARED_RECOVERED ||
+ state == TRX_STATE_PREPARED ||
+ state == TRX_STATE_COMMITTED_IN_MEMORY);
+}
+#endif
+
/** Create a new record lock and inserts it to the lock queue,
without checking for deadlocks or conflicts.
@param[in] type_mode lock mode and wait flag; type will be replaced
@@ -3446,8 +3459,8 @@ lock_table_create(
ut_ad(table && trx);
ut_ad(lock_mutex_own());
ut_ad(trx_mutex_own(trx));
-
- check_trx_state(trx);
+ ut_ad(trx->is_recovered || trx->state == TRX_STATE_ACTIVE);
+ ut_ad(!trx->auto_commit || trx->will_lock);
if ((type_mode & LOCK_MODE_MASK) == LOCK_AUTO_INC) {
++table->n_waiting_or_granted_auto_inc_locks;
@@ -4836,7 +4849,8 @@ lock_rec_queue_validate(
ut_ad(!index || lock->index == index);
trx_mutex_enter(lock->trx);
- ut_ad(!trx_is_ac_nl_ro(lock->trx));
+ ut_ad(!lock->trx->read_only
+ || !lock->trx->is_autocommit_non_locking());
ut_ad(trx_state_eq(lock->trx,
TRX_STATE_COMMITTED_IN_MEMORY)
|| !lock_get_wait(lock)
@@ -4922,8 +4936,8 @@ func_exit:
for (lock = lock_rec_get_first(lock_sys.rec_hash, block, heap_no);
lock != NULL;
lock = lock_rec_get_next_const(heap_no, lock)) {
-
- ut_ad(!trx_is_ac_nl_ro(lock->trx));
+ ut_ad(!lock->trx->read_only
+ || !lock->trx->is_autocommit_non_locking());
ut_ad(!page_rec_is_metadata(rec));
if (index) {
@@ -5013,7 +5027,8 @@ loop:
}
}
- ut_ad(!trx_is_ac_nl_ro(lock->trx));
+ ut_ad(!lock->trx->read_only
+ || !lock->trx->is_autocommit_non_locking());
/* Only validate the record queues when this thread is not
holding a space->latch. */
@@ -5080,7 +5095,8 @@ lock_rec_validate(
ib_uint64_t current;
- ut_ad(!trx_is_ac_nl_ro(lock->trx));
+ ut_ad(!lock->trx->read_only
+ || !lock->trx->is_autocommit_non_locking());
ut_ad(lock_get_type(lock) == LOCK_REC);
current = ut_ull_create(
@@ -6774,7 +6790,8 @@ DeadlockChecker::search()
ut_ad(m_start != NULL);
ut_ad(m_wait_lock != NULL);
- check_trx_state(m_wait_lock->trx);
+ ut_ad(!m_wait_lock->trx->auto_commit || m_wait_lock->trx->will_lock);
+ ut_d(check_trx_state(m_wait_lock->trx));
ut_ad(m_mark_start <= s_lock_mark_counter);
/* Look at the locks ahead of wait_lock in the lock queue. */
@@ -6939,7 +6956,8 @@ DeadlockChecker::check_and_resolve(const lock_t* lock, trx_t* trx)
{
ut_ad(lock_mutex_own());
ut_ad(trx_mutex_own(trx));
- check_trx_state(trx);
+ ut_ad(trx->state == TRX_STATE_ACTIVE);
+ ut_ad(!trx->auto_commit || trx->will_lock);
ut_ad(!srv_read_only_mode);
if (!innobase_deadlock_detect) {
diff --git a/storage/innobase/lz4.cmake b/storage/innobase/lz4.cmake
index e901378eafc..a908dd3b73e 100644
--- a/storage/innobase/lz4.cmake
+++ b/storage/innobase/lz4.cmake
@@ -22,35 +22,17 @@ MACRO (MYSQL_CHECK_LZ4)
CHECK_LIBRARY_EXISTS(lz4 LZ4_compress_default "" HAVE_LZ4_COMPRESS_DEFAULT)
IF (HAVE_LZ4_SHARED_LIB AND HAVE_LZ4_H)
+ SET(HAVE_INNODB_LZ4 TRUE)
ADD_DEFINITIONS(-DHAVE_LZ4=1)
IF (HAVE_LZ4_COMPRESS_DEFAULT)
- ADD_DEFINITIONS(-DHAVE_LZ4_COMPRESS_DEFAULT=1)
+ ADD_DEFINITIONS(-DHAVE_LZ4_COMPRESS_DEFAULT=1)
ENDIF()
LINK_LIBRARIES(lz4)
ELSE()
IF (WITH_INNODB_LZ4 STREQUAL "ON")
- MESSAGE(FATAL_ERROR "Required lz4 library is not found")
+ MESSAGE(FATAL_ERROR "Required lz4 library is not found")
ENDIF()
ENDIF()
ENDIF()
-ENDMACRO()
-
-MACRO (MYSQL_CHECK_LZ4_STATIC)
- IF (WITH_INNODB_LZ4 STREQUAL "ON" OR WITH_INNODB_LZ4 STREQUAL "AUTO")
- CHECK_INCLUDE_FILES(lz4.h HAVE_LZ4_H)
- CHECK_LIBRARY_EXISTS(liblz4.a LZ4_compress_limitedOutput "" HAVE_LZ4_LIB)
- CHECK_LIBRARY_EXISTS(liblz3.a LZ4_compress_default "" HAVE_LZ4_COMPRESS_DEFAULT)
-
- IF(HAVE_LZ4_LIB AND HAVE_LZ4_H)
- ADD_DEFINITIONS(-DHAVE_LZ4=1)
- IF (HAVE_LZ4_COMPRESS_DEFAULT)
- ADD_DEFINITIONS(-DHAVE_LZ4_COMPRESS_DEFAULT=1)
- ENDIF()
- LINK_LIBRARIES(liblz4.a)
- ELSE()
- IF (WITH_INNODB_LZ4 STREQUAL "ON")
- MESSAGE(FATAL_ERROR "Required lz4 library is not found")
- ENDIF()
- ENDIF()
- ENDIF()
+ ADD_FEATURE_INFO(INNODB_LZ4 HAVE_INNODB_LZ4 "LZ4 compression in the InnoDB storage engine")
ENDMACRO()
diff --git a/storage/innobase/lzma.cmake b/storage/innobase/lzma.cmake
index 93de0a2934d..3060139c27c 100644
--- a/storage/innobase/lzma.cmake
+++ b/storage/innobase/lzma.cmake
@@ -22,12 +22,14 @@ MACRO (MYSQL_CHECK_LZMA)
CHECK_LIBRARY_EXISTS(lzma lzma_easy_buffer_encode "" HAVE_LZMA_ENCODE)
IF (HAVE_LZMA_DECODE AND HAVE_LZMA_ENCODE AND HAVE_LZMA_H)
+ SET(HAVE_INNODB_LZMA TRUE)
ADD_DEFINITIONS(-DHAVE_LZMA=1)
LINK_LIBRARIES(lzma)
ELSE()
IF (WITH_INNODB_LZMA STREQUAL "ON")
- MESSAGE(FATAL_ERROR "Required lzma library is not found")
+ MESSAGE(FATAL_ERROR "Required lzma library is not found")
ENDIF()
ENDIF()
ENDIF()
+ ADD_FEATURE_INFO(INNODB_LZMA HAVE_INNODB_LZMA "LZMA compression in the InnoDB storage engine")
ENDMACRO()
diff --git a/storage/innobase/lzo.cmake b/storage/innobase/lzo.cmake
index 236eac2d1e5..ca2de6ab1c5 100644
--- a/storage/innobase/lzo.cmake
+++ b/storage/innobase/lzo.cmake
@@ -15,34 +15,20 @@
SET(WITH_INNODB_LZO AUTO CACHE STRING
"Build with lzo. Possible values are 'ON', 'OFF', 'AUTO' and default is 'AUTO'")
-MACRO (MYSQL_CHECK_LZO_STATIC)
- IF (WITH_INNODB_LZO STREQUAL "ON" OR WITH_INNODB_LZO STREQUAL "AUTO")
- CHECK_INCLUDE_FILES(lzo/lzo1x.h HAVE_LZO_H)
- CHECK_LIBRARY_EXISTS(liblzo2.a lzo1x_1_compress "" HAVE_LZO_LIB)
-
- IF(HAVE_LZO_LIB AND HAVE_LZO_H)
- ADD_DEFINITIONS(-DHAVE_LZO=1)
- LINK_LIBRARIES(liblzo2.a)
- ELSE()
- IF (WITH_INNODB_LZO STREQUAL "ON")
- MESSAGE(FATAL_ERROR "Required lzo library is not found")
- ENDIF()
- ENDIF()
- ENDIF()
-ENDMACRO()
-
MACRO (MYSQL_CHECK_LZO)
IF (WITH_INNODB_LZO STREQUAL "ON" OR WITH_INNODB_LZO STREQUAL "AUTO")
CHECK_INCLUDE_FILES(lzo/lzo1x.h HAVE_LZO_H)
CHECK_LIBRARY_EXISTS(lzo2 lzo1x_1_compress "" HAVE_LZO_SHARED_LIB)
IF(HAVE_LZO_SHARED_LIB AND HAVE_LZO_H)
+ SET(HAVE_INNODB_LZO TRUE)
ADD_DEFINITIONS(-DHAVE_LZO=1)
LINK_LIBRARIES(lzo2)
ELSE()
IF (WITH_INNODB_LZO STREQUAL "ON")
- MESSAGE(FATAL_ERROR "Required lzo library is not found")
+ MESSAGE(FATAL_ERROR "Required lzo library is not found")
ENDIF()
ENDIF()
ENDIF()
+ ADD_FEATURE_INFO(INNODB_LZO HAVE_INNODB_LZO "LZO compression in the InnoDB storage engine")
ENDMACRO()
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index 08ff856e888..f08aa7e025f 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -999,6 +999,10 @@ os_file_lock(
int fd,
const char* name)
{
+ if (my_disable_locking) {
+ return 0;
+ }
+
struct flock lk;
lk.l_type = F_WRLCK;
diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc
index 111a400ec92..73d9b0d1fcd 100644
--- a/storage/innobase/page/page0zip.cc
+++ b/storage/innobase/page/page0zip.cc
@@ -4992,9 +4992,9 @@ bool page_zip_verify_checksum(const byte *data, size_t size)
#ifdef UNIV_INNOCHECKSUM
if (log_file) {
- fprintf(log_file, "page::%llu;"
- " %s checksum: calculated = %u;"
- " recorded = %u\n", cur_page_num,
+ fprintf(log_file, "page::" UINT32PF ";"
+ " %s checksum: calculated = " UINT32PF ";"
+ " recorded = " UINT32PF "\n", cur_page_num,
buf_checksum_algorithm_name(
static_cast<srv_checksum_algorithm_t>(
srv_checksum_algorithm)),
@@ -5006,11 +5006,11 @@ bool page_zip_verify_checksum(const byte *data, size_t size)
data, size, SRV_CHECKSUM_ALGORITHM_CRC32);
if (log_file) {
- fprintf(log_file, "page::%llu: crc32 checksum:"
- " calculated = %u; recorded = %u\n",
+ fprintf(log_file, "page::" UINT32PF ": crc32 checksum:"
+ " calculated = " UINT32PF "; recorded = " UINT32PF "\n",
cur_page_num, crc32, stored);
- fprintf(log_file, "page::%llu: none checksum:"
- " calculated = %lu; recorded = %u\n",
+ fprintf(log_file, "page::" UINT32PF ": none checksum:"
+ " calculated = %lu; recorded = " UINT32PF "\n",
cur_page_num, BUF_NO_CHECKSUM_MAGIC, stored);
}
}
diff --git a/storage/innobase/read/read0read.cc b/storage/innobase/read/read0read.cc
index 1cc88f4b758..9ad2eaa1ebe 100644
--- a/storage/innobase/read/read0read.cc
+++ b/storage/innobase/read/read0read.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2018, 2019, MariaDB Corporation.
+Copyright (c) 2018, 2021, 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
@@ -235,7 +235,7 @@ void ReadView::open(trx_t *trx)
may get started, committed and purged meanwhile. It is acceptable as
well, since this view doesn't see it.
*/
- if (trx_is_autocommit_non_locking(trx) && m_ids.empty() &&
+ if (trx->is_autocommit_non_locking() && m_ids.empty() &&
m_low_limit_id == trx_sys.get_max_trx_id())
goto reopen;
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 3d3407e3a88..6f7b9dde3e1 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -932,8 +932,8 @@ row_ins_foreign_fill_virtual(
upd_field = update->fields + n_diff;
upd_field->old_v_val = static_cast<dfield_t*>(
- mem_heap_alloc(cascade->heap,
- sizeof *upd_field->old_v_val));
+ mem_heap_alloc(update->heap,
+ sizeof *upd_field->old_v_val));
dfield_copy(upd_field->old_v_val, vfield);
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index b594f8a8020..c8b098be5fa 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -52,6 +52,11 @@ Created 12/27/1996 Heikki Tuuri
#include <algorithm>
#include <mysql/plugin.h>
#include <mysql/service_wsrep.h>
+#ifdef WITH_WSREP
+#include "log.h"
+#include "wsrep.h"
+#endif /* WITH_WSREP */
+
/* What kind of latch and lock can we assume when the control comes to
-------------------------------------------------------------------
@@ -2449,34 +2454,30 @@ row_upd_sec_index_entry(
err = DB_SUCCESS;
break;
case DB_LOCK_WAIT:
- if (UNIV_UNLIKELY(wsrep_debug)) {
- ib::warn() << "WSREP: sec index FK lock wait"
- << " index " << index->name
- << " table " << index->table->name
- << " query " << wsrep_thd_query(trx->mysql_thd);
- }
- break;
case DB_DEADLOCK:
- if (UNIV_UNLIKELY(wsrep_debug)) {
- ib::warn() << "WSREP: sec index FK check fail for deadlock"
- << " index " << index->name
- << " table " << index->table->name
- << " query " << wsrep_thd_query(trx->mysql_thd);
- }
+ case DB_LOCK_WAIT_TIMEOUT:
+ WSREP_DEBUG("Foreign key check fail: "
+ "%s on table %s index %s query %s",
+ ut_strerr(err), index->name(), index->table->name.m_name,
+ wsrep_thd_query(trx->mysql_thd));
break;
default:
- ib::error() << "WSREP: referenced FK check fail: " << err
- << " index " << index->name
- << " table " << index->table->name
- << " query " << wsrep_thd_query(trx->mysql_thd);
-
+ WSREP_ERROR("Foreign key check fail: "
+ "%s on table %s index %s query %s",
+ ut_strerr(err), index->name(), index->table->name.m_name,
+ wsrep_thd_query(trx->mysql_thd));
break;
}
}
#endif /* WITH_WSREP */
}
+#ifdef WITH_WSREP
+ ut_ad(err == DB_SUCCESS || err == DB_LOCK_WAIT
+ || err == DB_DEADLOCK || err == DB_LOCK_WAIT_TIMEOUT);
+#else
ut_ad(err == DB_SUCCESS);
+#endif
if (referenced) {
rec_offs* offsets = rec_get_offsets(
@@ -2798,17 +2799,21 @@ check_fk:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
+ case DB_LOCK_WAIT:
case DB_DEADLOCK:
- if (UNIV_UNLIKELY(wsrep_debug)) {
- ib::warn() << "WSREP: sec index FK check fail for deadlock"
- << " index " << index->name
- << " table " << index->table->name;
- }
+ case DB_LOCK_WAIT_TIMEOUT:
+ WSREP_DEBUG("Foreign key check fail: "
+ "%s on table %s index %s query %s",
+ ut_strerr(err), index->name(), index->table->name.m_name,
+ wsrep_thd_query(trx->mysql_thd));
+
goto err_exit;
default:
- ib::error() << "WSREP: referenced FK check fail: " << err
- << " index " << index->name
- << " table " << index->table->name;
+ WSREP_ERROR("Foreign key check fail: "
+ "%s on table %s index %s query %s",
+ ut_strerr(err), index->name(), index->table->name.m_name,
+ wsrep_thd_query(trx->mysql_thd));
+
goto err_exit;
}
#endif /* WITH_WSREP */
@@ -3025,18 +3030,19 @@ row_upd_del_mark_clust_rec(
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
+ case DB_LOCK_WAIT:
case DB_DEADLOCK:
- if (UNIV_UNLIKELY(wsrep_debug)) {
- ib::warn() << "WSREP: sec index FK check fail for deadlock"
- << " index " << index->name
- << " table " << index->table->name;
- }
+ case DB_LOCK_WAIT_TIMEOUT:
+ WSREP_DEBUG("Foreign key check fail: "
+ "%d on table %s index %s query %s",
+ err, index->name(), index->table->name.m_name,
+ wsrep_thd_query(trx->mysql_thd));
break;
default:
- ib::error() << "WSREP: referenced FK check fail: " << err
- << " index " << index->name
- << " table " << index->table->name;
-
+ WSREP_ERROR("Foreign key check fail: "
+ "%d on table %s index %s query %s",
+ err, index->name(), index->table->name.m_name,
+ wsrep_thd_query(trx->mysql_thd));
break;
}
#endif /* WITH_WSREP */
diff --git a/storage/innobase/snappy.cmake b/storage/innobase/snappy.cmake
index 2810472cef6..3a2d828ee5c 100644
--- a/storage/innobase/snappy.cmake
+++ b/storage/innobase/snappy.cmake
@@ -21,12 +21,14 @@ MACRO (MYSQL_CHECK_SNAPPY)
CHECK_LIBRARY_EXISTS(snappy snappy_uncompress "" HAVE_SNAPPY_SHARED_LIB)
IF(HAVE_SNAPPY_SHARED_LIB AND HAVE_SNAPPY_H)
+ SET(HAVE_INNODB_SNAPPY TRUE)
ADD_DEFINITIONS(-DHAVE_SNAPPY=1)
LINK_LIBRARIES(snappy)
ELSE()
IF (WITH_INNODB_SNAPPY STREQUAL "ON")
- MESSAGE(FATAL_ERROR "Required snappy library is not found")
+ MESSAGE(FATAL_ERROR "Required snappy library is not found")
ENDIF()
ENDIF()
ENDIF()
+ ADD_FEATURE_INFO(INNODB_SNAPPY HAVE_INNODB_SNAPPY "Snappy compression in the InnoDB storage engine")
ENDMACRO()
diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc
index b25476861a5..e38522cbbab 100644
--- a/storage/innobase/trx/trx0i_s.cc
+++ b/storage/innobase/trx/trx0i_s.cc
@@ -575,7 +575,7 @@ thd_done:
row->trx_is_read_only = trx->read_only;
- row->trx_is_autocommit_non_locking = trx_is_autocommit_non_locking(trx);
+ row->trx_is_autocommit_non_locking = trx->is_autocommit_non_locking();
return(TRUE);
}
@@ -1229,7 +1229,24 @@ static void fetch_data_into_cache_low(trx_i_s_cache_t *cache, const trx_t *trx)
{
i_s_locks_row_t *requested_lock_row;
- assert_trx_nonlocking_or_in_list(trx);
+#ifdef UNIV_DEBUG
+ {
+ const auto state= trx->state;
+
+ if (trx->is_autocommit_non_locking())
+ {
+ ut_ad(trx->read_only);
+ ut_ad(!trx->is_recovered);
+ ut_ad(trx->mysql_thd);
+ ut_ad(state == TRX_STATE_NOT_STARTED || state == TRX_STATE_ACTIVE);
+ }
+ else
+ ut_ad(state == TRX_STATE_ACTIVE ||
+ state == TRX_STATE_PREPARED ||
+ state == TRX_STATE_PREPARED_RECOVERED ||
+ state == TRX_STATE_COMMITTED_IN_MEMORY);
+ }
+#endif /* UNIV_DEBUG */
if (add_trx_relevant_locks_to_cache(cache, trx, &requested_lock_row))
{
diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc
index 0d05eff46bc..841827b0709 100644
--- a/storage/innobase/trx/trx0roll.cc
+++ b/storage/innobase/trx/trx0roll.cc
@@ -104,12 +104,18 @@ trx_rollback_to_savepoint_low(
heap = mem_heap_create(512);
roll_node = roll_node_create(heap);
+ ut_ad(!trx->in_rollback);
if (savept != NULL) {
roll_node->savept = savept;
- check_trx_state(trx);
+ ut_ad(trx->mysql_thd);
+ ut_ad(!trx->is_recovered);
+ ut_ad(trx->state == TRX_STATE_ACTIVE);
} else {
- assert_trx_nonlocking_or_in_list(trx);
+ ut_d(trx_state_t state = trx->state);
+ ut_ad(state == TRX_STATE_ACTIVE
+ || state == TRX_STATE_PREPARED
+ || state == TRX_STATE_PREPARED_RECOVERED);
}
trx->error_state = DB_SUCCESS;
@@ -220,7 +226,7 @@ dberr_t trx_rollback_for_mysql(trx_t* trx)
switch (trx->state) {
case TRX_STATE_NOT_STARTED:
- trx->will_lock = 0;
+ trx->will_lock = false;
ut_ad(trx->mysql_thd);
#ifdef WITH_WSREP
trx->wsrep= false;
@@ -230,13 +236,14 @@ dberr_t trx_rollback_for_mysql(trx_t* trx)
case TRX_STATE_ACTIVE:
ut_ad(trx->mysql_thd);
- assert_trx_nonlocking_or_in_list(trx);
+ ut_ad(!trx->is_recovered);
+ ut_ad(!trx->is_autocommit_non_locking() || trx->read_only);
return(trx_rollback_for_mysql_low(trx));
case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
- ut_ad(!trx_is_autocommit_non_locking(trx));
- if (trx->rsegs.m_redo.undo) {
+ ut_ad(!trx->is_autocommit_non_locking());
+ if (trx->has_logged_persistent()) {
/* The XA ROLLBACK of a XA PREPARE transaction
will consist of multiple mini-transactions.
@@ -274,7 +281,7 @@ dberr_t trx_rollback_for_mysql(trx_t* trx)
return(trx_rollback_for_mysql_low(trx));
case TRX_STATE_COMMITTED_IN_MEMORY:
- check_trx_state(trx);
+ ut_ad(!trx->is_autocommit_non_locking());
break;
}
@@ -303,7 +310,9 @@ trx_rollback_last_sql_stat_for_mysql(
return(DB_SUCCESS);
case TRX_STATE_ACTIVE:
- assert_trx_nonlocking_or_in_list(trx);
+ ut_ad(trx->mysql_thd);
+ ut_ad(!trx->is_recovered);
+ ut_ad(!trx->is_autocommit_non_locking() || trx->read_only);
trx->op_info = "rollback of SQL statement";
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index afc48cc7b71..770c675c14f 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -140,7 +140,7 @@ trx_init(
trx->auto_commit = false;
- trx->will_lock = 0;
+ trx->will_lock = false;
trx->ddl = false;
@@ -355,7 +355,7 @@ trx_t *trx_create()
ib_alloc_t* alloc;
/* We just got trx from pool, it should be non locking */
- ut_ad(trx->will_lock == 0);
+ ut_ad(!trx->will_lock);
ut_ad(!trx->rw_trx_hash_pins);
DBUG_LOG("trx", "Create: " << trx);
@@ -571,7 +571,7 @@ void trx_disconnect_prepared(trx_t *trx)
trx->is_recovered= true;
trx->mysql_thd= NULL;
/* todo/fixme: suggest to do it at innodb prepare */
- trx->will_lock= 0;
+ trx->will_lock= false;
}
/****************************************************************//**
@@ -916,11 +916,10 @@ void trx_t::remove_flush_observer()
/** Assign a rollback segment for modifying temporary tables.
@return the assigned rollback segment */
-trx_rseg_t*
-trx_t::assign_temp_rseg()
+trx_rseg_t *trx_t::assign_temp_rseg()
{
ut_ad(!rsegs.m_noredo.rseg);
- ut_ad(!trx_is_autocommit_non_locking(this));
+ ut_ad(!is_autocommit_non_locking());
compile_time_assert(ut_is_2pow(TRX_SYS_N_RSEGS));
/* Choose a temporary rollback segment between 0 and 127
@@ -967,8 +966,8 @@ trx_start_low(
&& thd_trx_is_read_only(trx->mysql_thd));
if (!trx->auto_commit) {
- ++trx->will_lock;
- } else if (trx->will_lock == 0) {
+ trx->will_lock = true;
+ } else if (!trx->will_lock) {
trx->read_only = true;
}
@@ -1011,7 +1010,7 @@ trx_start_low(
trx_sys.register_rw(trx);
} else {
- if (!trx_is_autocommit_non_locking(trx)) {
+ if (!trx->is_autocommit_non_locking()) {
/* If this is a read-only transaction that is writing
to a temporary table then it needs a transaction id
@@ -1199,12 +1198,12 @@ trx_flush_log_if_needed_low(
bool flush = srv_file_flush_method != SRV_NOSYNC;
switch (srv_flush_log_at_trx_commit) {
- case 3:
case 2:
/* Write the log but do not flush it to disk */
flush = false;
/* fall through */
case 1:
+ case 3:
/* Write the log and optionally flush it to disk */
log_write_up_to(lsn, flush);
return;
@@ -1304,12 +1303,15 @@ inline void trx_t::commit_in_memory(const mtr_t *mtr)
must_flush_log_later= false;
read_view.close();
- if (trx_is_autocommit_non_locking(this))
+ if (is_autocommit_non_locking())
{
ut_ad(id == 0);
ut_ad(read_only);
+ ut_ad(!will_lock);
ut_a(!is_recovered);
ut_ad(!rsegs.m_redo.rseg);
+ ut_ad(mysql_thd);
+ ut_ad(state == TRX_STATE_ACTIVE);
/* Note: We are asserting without holding the lock mutex. But
that is OK because this transaction is not waiting and cannot
@@ -1323,12 +1325,11 @@ inline void trx_t::commit_in_memory(const mtr_t *mtr)
However, the trx_sys_t::mutex will protect the trx_t instance
and it cannot be removed from the trx_list and freed
without first acquiring the trx_sys_t::mutex. */
- ut_ad(trx_state_eq(this, TRX_STATE_ACTIVE));
+ state= TRX_STATE_NOT_STARTED;
MONITOR_INC(MONITOR_TRX_NL_RO_COMMIT);
DBUG_LOG("trx", "Autocommit in memory: " << this);
- state= TRX_STATE_NOT_STARTED;
}
else
{
@@ -1475,8 +1476,6 @@ inline void trx_t::commit_in_memory(const mtr_t *mtr)
@param mtr mini-transaction (if there are any persistent modifications) */
void trx_t::commit_low(mtr_t *mtr)
{
- assert_trx_nonlocking_or_in_list(this);
- ut_ad(!trx_state_eq(this, TRX_STATE_COMMITTED_IN_MEMORY));
ut_ad(!mtr || mtr->is_active());
ut_d(bool aborted = in_rollback && error_state == DB_DEADLOCK);
ut_ad(!mtr == (aborted || !has_logged()));
@@ -1485,13 +1484,13 @@ void trx_t::commit_low(mtr_t *mtr)
/* undo_no is non-zero if we're doing the final commit. */
if (fts_trx && undo_no)
{
- ut_a(!trx_is_autocommit_non_locking(this));
- dberr_t error= fts_commit(this);
+ ut_a(!is_autocommit_non_locking());
/* FTS-FIXME: Temporarily tolerate DB_DUPLICATE_KEY instead of
dying. This is a possible scenario if there is a crash between
insert to DELETED table committing and transaction committing. The
fix would be able to return error from this function */
- ut_a(error == DB_SUCCESS || error == DB_DUPLICATE_KEY);
+ if (dberr_t error= fts_commit(this))
+ ut_a(error == DB_DUPLICATE_KEY);
}
#ifndef DBUG_OFF
@@ -1751,7 +1750,6 @@ trx_print_low(
/*!< in: mem_heap_get_size(trx->lock.lock_heap) */
{
ibool newline;
- const char* op_info;
fprintf(f, "TRANSACTION " TRX_ID_FMT, trx_get_id_for_print(trx));
@@ -1778,9 +1776,7 @@ trx_print_low(
fprintf(f, ", state %lu", (ulong) trx->state);
ut_ad(0);
state_ok:
-
- /* prevent a race condition */
- op_info = trx->op_info;
+ const char* op_info = trx->op_info;
if (*op_info) {
putc(' ', f);
@@ -2251,7 +2247,7 @@ trx_start_internal_low(
/* Ensure it is not flagged as an auto-commit-non-locking
transaction. */
- trx->will_lock = 1;
+ trx->will_lock = true;
trx->internal = true;
@@ -2267,7 +2263,7 @@ trx_start_internal_read_only_low(
/* Ensure it is not flagged as an auto-commit-non-locking
transaction. */
- trx->will_lock = 1;
+ trx->will_lock = true;
trx->internal = true;
@@ -2288,13 +2284,7 @@ trx_start_for_ddl_low(
the data dictionary will be locked in crash recovery. */
trx_set_dict_operation(trx, op);
-
- /* Ensure it is not flagged as an auto-commit-non-locking
- transation. */
- trx->will_lock = 1;
-
trx->ddl= true;
-
trx_start_internal_low(trx);
return;
@@ -2321,7 +2311,7 @@ trx_set_rw_mode(
trx_t* trx) /*!< in/out: transaction that is RW */
{
ut_ad(trx->rsegs.m_redo.rseg == 0);
- ut_ad(!trx_is_autocommit_non_locking(trx));
+ ut_ad(!trx->is_autocommit_non_locking());
ut_ad(!trx->read_only);
ut_ad(trx->id == 0);
diff --git a/storage/mroonga/CMakeLists.txt b/storage/mroonga/CMakeLists.txt
index 0898bd82011..4dd36a65708 100644
--- a/storage/mroonga/CMakeLists.txt
+++ b/storage/mroonga/CMakeLists.txt
@@ -80,7 +80,7 @@ else()
set(MRN_SOURCE_DIR ${CMAKE_SOURCE_DIR})
endif()
-file(READ ${MRN_SOURCE_DIR}/version MRN_VERSION)
+file(READ ${MRN_SOURCE_DIR}/version_full MRN_VERSION)
file(READ ${MRN_SOURCE_DIR}/version_major MRN_VERSION_MAJOR)
file(READ ${MRN_SOURCE_DIR}/version_minor MRN_VERSION_MINOR)
file(READ ${MRN_SOURCE_DIR}/version_micro MRN_VERSION_MICRO)
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/CMakeLists.txt b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/CMakeLists.txt
index d1ca2a8a0d8..ae083028038 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/CMakeLists.txt
@@ -28,7 +28,7 @@ endif()
set(GROONGA_NORMALIZER_MYSQL_EMBED ${GROONGA_NORMALIZER_MYSQL_EMBED_DEFAULT}
CACHE BOOL "Build as a static library to embed into an application")
-file(READ "${CMAKE_CURRENT_SOURCE_DIR}/version" VERSION)
+file(READ "${CMAKE_CURRENT_SOURCE_DIR}/version_full" VERSION)
if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
set(GROONGA_NORMALIZER_MYSQL_BUNDLED FALSE)
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version_full
index 8cfbc905b39..8cfbc905b39 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version_full
diff --git a/storage/mroonga/version b/storage/mroonga/version_full
index 5b1f56847ae..5b1f56847ae 100644
--- a/storage/mroonga/version
+++ b/storage/mroonga/version_full
diff --git a/storage/oqgraph/CMakeLists.txt b/storage/oqgraph/CMakeLists.txt
index 901acc6a8ca..a41b864d15b 100644
--- a/storage/oqgraph/CMakeLists.txt
+++ b/storage/oqgraph/CMakeLists.txt
@@ -3,6 +3,10 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
MACRO(CHECK_OQGRAPH)
MESSAGE(STATUS "Configuring OQGraph")
FIND_PACKAGE(Boost 1.40.0)
+SET_PACKAGE_PROPERTIES(Boost PROPERTIES
+ PURPOSE "Required for the OQGraph storage engine"
+ TYPE OPTIONAL
+)
IF(NOT Boost_FOUND)
MESSAGE(STATUS "Boost not found. OQGraph will not be compiled")
SET(OQGRAPH_OK 0 CACHE INTERNAL "")
@@ -11,6 +15,10 @@ ENDIF()
INCLUDE_DIRECTORIES(BEFORE ${Boost_INCLUDE_DIRS})
FIND_PACKAGE(Judy)
+SET_PACKAGE_PROPERTIES(Judy PROPERTIES
+ PURPOSE "Required for the OQGraph storage engine"
+ TYPE OPTIONAL
+)
IF(NOT Judy_FOUND)
MESSAGE(STATUS "Judy not found. OQGraph will not be compiled")
SET(OQGRAPH_OK 0 CACHE INTERNAL "")
diff --git a/storage/oqgraph/mysql-test/oqgraph/social.test b/storage/oqgraph/mysql-test/oqgraph/social.test
index 69eb7698bb9..a71b160cc1d 100644
--- a/storage/oqgraph/mysql-test/oqgraph/social.test
+++ b/storage/oqgraph/mysql-test/oqgraph/social.test
@@ -1,3 +1,6 @@
+# The test can take very long time with valgrind
+--source include/not_valgrind.inc
+
--disable_warnings
DROP TABLE IF EXISTS rsb, rsb_graph;
--enable_warnings
diff --git a/storage/rocksdb/CMakeLists.txt b/storage/rocksdb/CMakeLists.txt
index 931aaeb5c64..5dfd94c6212 100644
--- a/storage/rocksdb/CMakeLists.txt
+++ b/storage/rocksdb/CMakeLists.txt
@@ -2,6 +2,7 @@
MACRO(SKIP_ROCKSDB_PLUGIN msg)
MESSAGE_ONCE(SKIP_ROCKSDB_PLUGIN "Can't build rocksdb engine - ${msg}")
+ ADD_FEATURE_INFO(ROCKSDB "OFF" "Storage Engine")
RETURN()
ENDMACRO()
diff --git a/storage/rocksdb/build_rocksdb.cmake b/storage/rocksdb/build_rocksdb.cmake
index 5f1566edcf5..e23862ee659 100644
--- a/storage/rocksdb/build_rocksdb.cmake
+++ b/storage/rocksdb/build_rocksdb.cmake
@@ -42,6 +42,7 @@ macro(check_lib package var)
IF (NOT ${WITH_ROCKSDB_${package}} STREQUAL "OFF")
FIND_PACKAGE(${package} QUIET)
+ SET(HAVE_ROCKSDB_${PACKAGE_NAME} TRUE)
IF (${${PACKAGE_NAME}_FOUND})
IF(${ARGC} GREATER 2)
SET(CMAKE_REQUIRED_LIBRARIES ${${var}_LIBRARIES})
@@ -52,6 +53,7 @@ macro(check_lib package var)
ENDIF()
ENDIF()
ENDIF()
+ ADD_FEATURE_INFO(ROCKSDB_${PACKAGE_NAME} HAVE_ROCKSDB_${PACKAGE_NAME} "${package} Compression in the RocksDB storage engine")
IF(${${var}_VALID})
MESSAGE_ONCE(rocksdb_${var} "Found ${package}: ${${var}_LIBRARIES}")
@@ -78,6 +80,7 @@ check_lib(ZSTD ZSTD ZDICT_trainFromBuffer)
add_definitions(-DZLIB)
list(APPEND THIRDPARTY_LIBS ${ZLIB_LIBRARY})
+ADD_FEATURE_INFO(ROCKSDB_ZLIB "ON" "zlib Compression in the RocksDB storage engine")
if(CMAKE_SYSTEM_NAME MATCHES "Cygwin")
add_definitions(-fno-builtin-memcmp -DCYGWIN)
diff --git a/storage/spider/mysql-test/spider/bugfix/include/mdev_24020_deinit.inc b/storage/spider/mysql-test/spider/bugfix/include/mdev_24020_deinit.inc
new file mode 100644
index 00000000000..1880a1c7bba
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/include/mdev_24020_deinit.inc
@@ -0,0 +1,11 @@
+--let $MASTER_1_COMMENT_P_2_1= $MASTER_1_COMMENT_P_2_1_BACKUP
+--let $CHILD2_1_DROP_TABLES= $CHILD2_1_DROP_TABLES_BACKUP
+--let $CHILD2_1_CREATE_TABLES= $CHILD2_1_CREATE_TABLES_BACKUP
+--let $CHILD2_1_SELECT_TABLES= $CHILD2_1_SELECT_TABLES_BACKUP
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_deinit.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
diff --git a/storage/spider/mysql-test/spider/bugfix/include/mdev_24020_init.inc b/storage/spider/mysql-test/spider/bugfix/include/mdev_24020_init.inc
new file mode 100644
index 00000000000..63fd70a4b49
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/include/mdev_24020_init.inc
@@ -0,0 +1,43 @@
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_init.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
+--let $MASTER_1_COMMENT_P_2_1_BACKUP= $MASTER_1_COMMENT_P_2_1
+let $MASTER_1_COMMENT_P_2_1=
+ PARTITION BY LIST(a % 3) (
+ PARTITION pt1 VALUES IN (0) COMMENT='srv "s_2_1", table "ta_r2"',
+ PARTITION pt2 VALUES IN (1) COMMENT='srv "s_2_1", table "ta_r3"',
+ PARTITION pt3 VALUES IN (2) COMMENT='srv "s_2_1", table "ta_r4"'
+ );
+--let $CHILD2_1_DROP_TABLES_BACKUP= $CHILD2_1_DROP_TABLES
+let $CHILD2_1_DROP_TABLES=
+ DROP TABLE IF EXISTS ta_r2 $STR_SEMICOLON
+ DROP TABLE IF EXISTS ta_r3 $STR_SEMICOLON
+ DROP TABLE IF EXISTS ta_r4;
+--let $CHILD2_1_CREATE_TABLES_BACKUP= $CHILD2_1_CREATE_TABLES
+let $CHILD2_1_CREATE_TABLES=
+ CREATE TABLE ta_r2 (
+ a INT,
+ b VARCHAR(30),
+ PRIMARY KEY(a)
+ ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET $STR_SEMICOLON
+ CREATE TABLE ta_r3 (
+ a INT,
+ b VARCHAR(30),
+ PRIMARY KEY(a)
+ ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET $STR_SEMICOLON
+ CREATE TABLE ta_r4 (
+ a INT,
+ b VARCHAR(30),
+ PRIMARY KEY(a)
+ ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
+--let $CHILD2_1_SELECT_TABLES_BACKUP= $CHILD2_1_SELECT_TABLES
+let $CHILD2_1_SELECT_TABLES=
+ SELECT a, b FROM ta_r2 ORDER BY a $STR_SEMICOLON
+ SELECT a, b FROM ta_r3 ORDER BY a $STR_SEMICOLON
+ SELECT a, b FROM ta_r4 ORDER BY a;
+let $CHILD2_1_SELECT_ARGUMENT1=
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
diff --git a/storage/spider/mysql-test/spider/bugfix/include/mdev_24517_deinit.inc b/storage/spider/mysql-test/spider/bugfix/include/mdev_24517_deinit.inc
new file mode 100644
index 00000000000..1880a1c7bba
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/include/mdev_24517_deinit.inc
@@ -0,0 +1,11 @@
+--let $MASTER_1_COMMENT_P_2_1= $MASTER_1_COMMENT_P_2_1_BACKUP
+--let $CHILD2_1_DROP_TABLES= $CHILD2_1_DROP_TABLES_BACKUP
+--let $CHILD2_1_CREATE_TABLES= $CHILD2_1_CREATE_TABLES_BACKUP
+--let $CHILD2_1_SELECT_TABLES= $CHILD2_1_SELECT_TABLES_BACKUP
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_deinit.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
diff --git a/storage/spider/mysql-test/spider/bugfix/include/mdev_24517_init.inc b/storage/spider/mysql-test/spider/bugfix/include/mdev_24517_init.inc
new file mode 100644
index 00000000000..b5b77a53798
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/include/mdev_24517_init.inc
@@ -0,0 +1,43 @@
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_init.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
+--let $MASTER_1_COMMENT_P_2_1_BACKUP= $MASTER_1_COMMENT_P_2_1
+let $MASTER_1_COMMENT_P_2_1=
+ PARTITION BY RANGE(i) (
+ PARTITION pt1 VALUES LESS THAN (5) COMMENT='srv "s_2_1", table "ta_r2"',
+ PARTITION pt2 VALUES LESS THAN (10) COMMENT='srv "s_2_1", table "ta_r3"',
+ PARTITION pt3 VALUES LESS THAN MAXVALUE COMMENT='srv "s_2_1", table "ta_r4"'
+ );
+--let $CHILD2_1_DROP_TABLES_BACKUP= $CHILD2_1_DROP_TABLES
+let $CHILD2_1_DROP_TABLES=
+ DROP TABLE IF EXISTS ta_r2 $STR_SEMICOLON
+ DROP TABLE IF EXISTS ta_r3 $STR_SEMICOLON
+ DROP TABLE IF EXISTS ta_r4;
+--let $CHILD2_1_CREATE_TABLES_BACKUP= $CHILD2_1_CREATE_TABLES
+let $CHILD2_1_CREATE_TABLES=
+ CREATE TABLE ta_r2 (
+ i INT,
+ j JSON,
+ PRIMARY KEY(i)
+ ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET $STR_SEMICOLON
+ CREATE TABLE ta_r3 (
+ i INT,
+ j JSON,
+ PRIMARY KEY(i)
+ ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET $STR_SEMICOLON
+ CREATE TABLE ta_r4 (
+ i INT,
+ j JSON,
+ PRIMARY KEY(i)
+ ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
+--let $CHILD2_1_SELECT_TABLES_BACKUP= $CHILD2_1_SELECT_TABLES
+let $CHILD2_1_SELECT_TABLES=
+ SELECT i, j FROM ta_r2 ORDER BY i $STR_SEMICOLON
+ SELECT i, j FROM ta_r3 ORDER BY i $STR_SEMICOLON
+ SELECT i, j FROM ta_r4 ORDER BY i;
+let $CHILD2_1_SELECT_ARGUMENT1=
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_24020.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_24020.result
new file mode 100644
index 00000000000..164c68fbc0c
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_24020.result
@@ -0,0 +1,97 @@
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+
+this test is for MDEV-24020
+
+drop and create databases
+connection master_1;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+connection child2_1;
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+
+create table and insert
+connection child2_1;
+CHILD2_1_CREATE_TABLES
+connection master_1;
+CREATE TABLE tbl_a (
+a INT,
+b VARCHAR(30),
+PRIMARY KEY(a)
+) ENGINE=Spider PARTITION BY LIST(a % 3) (
+PARTITION pt1 VALUES IN (0) COMMENT='srv "s_2_1", table "ta_r2"',
+PARTITION pt2 VALUES IN (1) COMMENT='srv "s_2_1", table "ta_r3"',
+PARTITION pt3 VALUES IN (2) COMMENT='srv "s_2_1", table "ta_r4"'
+ )
+INSERT INTO tbl_a VALUES(10000, " abcd ");
+INSERT INTO tbl_a VALUES(10001, " abcd ");
+INSERT INTO tbl_a VALUES(10002, " abcd ");
+INSERT INTO tbl_a VALUES(10003, "[[[abcd][[");
+INSERT INTO tbl_a VALUES(10004, "[[[abcd][[");
+INSERT INTO tbl_a VALUES(10005, "[[[abcd][[");
+INSERT INTO tbl_a VALUES(10006, "[[[abcd]]");
+INSERT INTO tbl_a VALUES(10007, "[[[abcd]]");
+INSERT INTO tbl_a VALUES(10008, "[[[abcd]]");
+INSERT INTO tbl_a VALUES(10009, "[[[**abcd****]]");
+
+test 1
+connection master_1;
+UPDATE tbl_a SET b = trim(b) WHERE a = 10000;
+SELECT * FROM tbl_a WHERE a = 10000;
+a b
+10000 abcd
+UPDATE tbl_a SET b = ltrim(b) WHERE a = 10001;
+SELECT * FROM tbl_a WHERE a = 10001;
+a b
+10001 abcd
+UPDATE tbl_a SET b = rtrim(b) WHERE a = 10002;
+SELECT * FROM tbl_a WHERE a = 10002;
+a b
+10002 abcd
+UPDATE tbl_a SET b = trim(BOTH '[' FROM b) WHERE a = 10003;
+SELECT * FROM tbl_a WHERE a = 10003;
+a b
+10003 abcd]
+UPDATE tbl_a SET b = trim(LEADING '[' FROM b) WHERE a = 10004;
+SELECT * FROM tbl_a WHERE a = 10004;
+a b
+10004 abcd][[
+UPDATE tbl_a SET b = trim(TRAILING '[' FROM b) WHERE a = 10005;
+SELECT * FROM tbl_a WHERE a = 10005;
+a b
+10005 [[[abcd]
+UPDATE tbl_a SET b = trim(LEADING '[' FROM trim(TRAILING ']' FROM b)) WHERE a = 10006;
+SELECT * FROM tbl_a WHERE a = 10006;
+a b
+10006 abcd
+UPDATE tbl_a SET b = trim(TRAILING '[' FROM trim(LEADING ']' FROM b)) WHERE a = 10007;
+SELECT * FROM tbl_a WHERE a = 10007;
+a b
+10007 [[[abcd]]
+UPDATE tbl_a SET b = trim(TRAILING ']' FROM trim(LEADING '[' FROM b)) WHERE a = 10008;
+SELECT * FROM tbl_a WHERE a = 10008;
+a b
+10008 abcd
+UPDATE tbl_a SET b = trim(BOTH '*' FROM trim(TRAILING ']' FROM trim(LEADING '[' FROM b))) WHERE a = 10009;
+SELECT * FROM tbl_a WHERE a = 10009;
+a b
+10009 abcd
+
+deinit
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+connection child2_1;
+DROP DATABASE IF EXISTS auto_test_remote;
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+
+end of test
diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_24517.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_24517.result
new file mode 100644
index 00000000000..f084c967435
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_24517.result
@@ -0,0 +1,78 @@
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+
+this test is for MDEV-24517
+
+drop and create databases
+connection master_1;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+connection child2_1;
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = 'TABLE,FILE';
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+
+create table and insert
+connection child2_1;
+CHILD2_1_CREATE_TABLES
+TRUNCATE TABLE mysql.general_log;
+connection master_1;
+CREATE TABLE tbl_a (
+i INT,
+j JSON,
+PRIMARY KEY(i)
+) ENGINE=Spider PARTITION BY RANGE(i) (
+PARTITION pt1 VALUES LESS THAN (5) COMMENT='srv "s_2_1", table "ta_r2"',
+PARTITION pt2 VALUES LESS THAN (10) COMMENT='srv "s_2_1", table "ta_r3"',
+PARTITION pt3 VALUES LESS THAN MAXVALUE COMMENT='srv "s_2_1", table "ta_r4"'
+ )
+INSERT INTO tbl_a (i, j) VALUES
+(1, '{"ID": "3", "Name": "Barney", "Age": 18}'),
+(2, '{"ID": "4", "Name": "Betty", "Age": 19}'),
+(3, '{"ID": "2", "Name": "Wilma", "Age": 20}'),
+(4, '[10, 20, [30, 40]]');
+
+test 1
+connection child2_1;
+TRUNCATE TABLE mysql.general_log;
+connection master_1;
+SELECT * FROM tbl_a WHERE JSON_EXTRACT(j, '$.Age')=19;
+i j
+2 {"ID": "4", "Name": "Betty", "Age": 19}
+SELECT * FROM tbl_a WHERE JSON_EXTRACT(j, '$.Name')="Betty";
+i j
+2 {"ID": "4", "Name": "Betty", "Age": 19}
+SELECT i, JSON_EXTRACT(j, "$.ID")
+FROM tbl_a
+WHERE JSON_EXTRACT(j, "$.ID") > 1 AND i < 4
+ORDER BY JSON_EXTRACT(j, "$.Name");
+i JSON_EXTRACT(j, "$.ID")
+1 "3"
+2 "4"
+3 "2"
+SELECT * FROM tbl_a WHERE JSON_EXTRACT(j, '$[1]') = 20;
+i j
+4 [10, 20, [30, 40]]
+SELECT * FROM tbl_a WHERE JSON_EXTRACT(j, '$[2][0]') = 30;
+i j
+4 [10, 20, [30, 40]]
+
+deinit
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+connection child2_1;
+DROP DATABASE IF EXISTS auto_test_remote;
+SET GLOBAL log_output = @old_log_output;
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+
+end of test
diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_24760.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_24760.result
new file mode 100644
index 00000000000..08481cd15f9
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_24760.result
@@ -0,0 +1,49 @@
+#
+# MDEV-24760 SELECT..CASE statement syntax error at Spider Engine table
+#
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+connection child2_1;
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+DROP TABLE IF EXISTS tbl_a;
+Warnings:
+Note 1051 Unknown table 'auto_test_remote.tbl_a'
+CREATE TABLE tbl_a (
+id int NOT NULL AUTO_INCREMENT,
+name varchar(255) DEFAULT NULL,
+PRIMARY KEY (id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+INSERT INTO tbl_a (name) VALUES ('Alice'), ('Bob');
+connection master_1;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+CREATE TABLE tbl_a (
+id int NOT NULL AUTO_INCREMENT,
+name varchar(255) DEFAULT NULL,
+PRIMARY KEY (id)
+) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a"'
+PARTITION BY HASH(id) (
+PARTITION pt1 COMMENT='srv "s_2_1"'
+);
+SELECT id, CASE WHEN name='Alice' THEN "A" WHEN name='Bob' THEN "B" END FROM tbl_a;
+id CASE WHEN name='Alice' THEN "A" WHEN name='Bob' THEN "B" END
+1 A
+2 B
+SELECT id, CASE name WHEN 'Alice' THEN "A" WHEN 'Bob' THEN "B" END FROM tbl_a;
+id CASE name WHEN 'Alice' THEN "A" WHEN 'Bob' THEN "B" END
+1 A
+2 B
+DROP DATABASE auto_test_local;
+connection child2_1;
+DROP DATABASE auto_test_remote;
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_24020.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_24020.cnf
new file mode 100644
index 00000000000..05dfd8a0bce
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_24020.cnf
@@ -0,0 +1,3 @@
+!include include/default_mysqld.cnf
+!include ../my_1_1.cnf
+!include ../my_2_1.cnf
diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_24020.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_24020.test
new file mode 100644
index 00000000000..ac06d86052b
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_24020.test
@@ -0,0 +1,90 @@
+--source ../include/mdev_24020_init.inc
+--echo
+--echo this test is for MDEV-24020
+--echo
+--echo drop and create databases
+
+--connection master_1
+--disable_warnings
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+
+--connection child2_1
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+--enable_warnings
+
+--echo
+--echo create table and insert
+
+--connection child2_1
+--disable_query_log
+--disable_ps_protocol
+echo CHILD2_1_CREATE_TABLES;
+eval $CHILD2_1_CREATE_TABLES;
+--enable_ps_protocol
+--enable_query_log
+
+--connection master_1
+--disable_query_log
+echo CREATE TABLE tbl_a (
+ a INT,
+ b VARCHAR(30),
+ PRIMARY KEY(a)
+) $MASTER_1_ENGINE $MASTER_1_COMMENT_P_2_1;
+eval CREATE TABLE tbl_a (
+ a INT,
+ b VARCHAR(30),
+ PRIMARY KEY(a)
+) $MASTER_1_ENGINE $MASTER_1_COMMENT_P_2_1;
+--enable_query_log
+INSERT INTO tbl_a VALUES(10000, " abcd ");
+INSERT INTO tbl_a VALUES(10001, " abcd ");
+INSERT INTO tbl_a VALUES(10002, " abcd ");
+INSERT INTO tbl_a VALUES(10003, "[[[abcd][[");
+INSERT INTO tbl_a VALUES(10004, "[[[abcd][[");
+INSERT INTO tbl_a VALUES(10005, "[[[abcd][[");
+INSERT INTO tbl_a VALUES(10006, "[[[abcd]]");
+INSERT INTO tbl_a VALUES(10007, "[[[abcd]]");
+INSERT INTO tbl_a VALUES(10008, "[[[abcd]]");
+INSERT INTO tbl_a VALUES(10009, "[[[**abcd****]]");
+
+--echo
+--echo test 1
+
+--connection master_1
+UPDATE tbl_a SET b = trim(b) WHERE a = 10000;
+SELECT * FROM tbl_a WHERE a = 10000;
+UPDATE tbl_a SET b = ltrim(b) WHERE a = 10001;
+SELECT * FROM tbl_a WHERE a = 10001;
+UPDATE tbl_a SET b = rtrim(b) WHERE a = 10002;
+SELECT * FROM tbl_a WHERE a = 10002;
+UPDATE tbl_a SET b = trim(BOTH '[' FROM b) WHERE a = 10003;
+SELECT * FROM tbl_a WHERE a = 10003;
+UPDATE tbl_a SET b = trim(LEADING '[' FROM b) WHERE a = 10004;
+SELECT * FROM tbl_a WHERE a = 10004;
+UPDATE tbl_a SET b = trim(TRAILING '[' FROM b) WHERE a = 10005;
+SELECT * FROM tbl_a WHERE a = 10005;
+UPDATE tbl_a SET b = trim(LEADING '[' FROM trim(TRAILING ']' FROM b)) WHERE a = 10006;
+SELECT * FROM tbl_a WHERE a = 10006;
+UPDATE tbl_a SET b = trim(TRAILING '[' FROM trim(LEADING ']' FROM b)) WHERE a = 10007;
+SELECT * FROM tbl_a WHERE a = 10007;
+UPDATE tbl_a SET b = trim(TRAILING ']' FROM trim(LEADING '[' FROM b)) WHERE a = 10008;
+SELECT * FROM tbl_a WHERE a = 10008;
+UPDATE tbl_a SET b = trim(BOTH '*' FROM trim(TRAILING ']' FROM trim(LEADING '[' FROM b))) WHERE a = 10009;
+SELECT * FROM tbl_a WHERE a = 10009;
+
+--echo
+--echo deinit
+--disable_warnings
+
+--connection master_1
+DROP DATABASE IF EXISTS auto_test_local;
+
+--connection child2_1
+DROP DATABASE IF EXISTS auto_test_remote;
+
+--enable_warnings
+--source ../include/mdev_24020_deinit.inc
+--echo
+--echo end of test
diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_24517.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_24517.cnf
new file mode 100644
index 00000000000..05dfd8a0bce
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_24517.cnf
@@ -0,0 +1,3 @@
+!include include/default_mysqld.cnf
+!include ../my_1_1.cnf
+!include ../my_2_1.cnf
diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_24517.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_24517.test
new file mode 100644
index 00000000000..21b9dda4f12
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_24517.test
@@ -0,0 +1,80 @@
+--source ../include/mdev_24517_init.inc
+--echo
+--echo this test is for MDEV-24517
+--echo
+--echo drop and create databases
+
+--connection master_1
+--disable_warnings
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+
+--connection child2_1
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = 'TABLE,FILE';
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+--enable_warnings
+
+--echo
+--echo create table and insert
+
+--connection child2_1
+--disable_query_log
+--disable_ps_protocol
+echo CHILD2_1_CREATE_TABLES;
+eval $CHILD2_1_CREATE_TABLES;
+--enable_ps_protocol
+--enable_query_log
+TRUNCATE TABLE mysql.general_log;
+
+--connection master_1
+--disable_query_log
+echo CREATE TABLE tbl_a (
+ i INT,
+ j JSON,
+ PRIMARY KEY(i)
+) $MASTER_1_ENGINE $MASTER_1_COMMENT_P_2_1;
+eval CREATE TABLE tbl_a (
+ i INT,
+ j JSON,
+ PRIMARY KEY(i)
+) $MASTER_1_ENGINE $MASTER_1_COMMENT_P_2_1;
+--enable_query_log
+INSERT INTO tbl_a (i, j) VALUES
+ (1, '{"ID": "3", "Name": "Barney", "Age": 18}'),
+ (2, '{"ID": "4", "Name": "Betty", "Age": 19}'),
+ (3, '{"ID": "2", "Name": "Wilma", "Age": 20}'),
+ (4, '[10, 20, [30, 40]]');
+
+--echo
+--echo test 1
+
+--connection child2_1
+TRUNCATE TABLE mysql.general_log;
+
+--connection master_1
+SELECT * FROM tbl_a WHERE JSON_EXTRACT(j, '$.Age')=19;
+SELECT * FROM tbl_a WHERE JSON_EXTRACT(j, '$.Name')="Betty";
+SELECT i, JSON_EXTRACT(j, "$.ID")
+ FROM tbl_a
+ WHERE JSON_EXTRACT(j, "$.ID") > 1 AND i < 4
+ ORDER BY JSON_EXTRACT(j, "$.Name");
+SELECT * FROM tbl_a WHERE JSON_EXTRACT(j, '$[1]') = 20;
+SELECT * FROM tbl_a WHERE JSON_EXTRACT(j, '$[2][0]') = 30;
+
+--echo
+--echo deinit
+--disable_warnings
+
+--connection master_1
+DROP DATABASE IF EXISTS auto_test_local;
+
+--connection child2_1
+DROP DATABASE IF EXISTS auto_test_remote;
+SET GLOBAL log_output = @old_log_output;
+
+--enable_warnings
+--source ../include/mdev_24517_deinit.inc
+--echo
+--echo end of test
diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_24760.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_24760.cnf
new file mode 100644
index 00000000000..05dfd8a0bce
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_24760.cnf
@@ -0,0 +1,3 @@
+!include include/default_mysqld.cnf
+!include ../my_1_1.cnf
+!include ../my_2_1.cnf
diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_24760.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_24760.test
new file mode 100644
index 00000000000..149b057d003
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_24760.test
@@ -0,0 +1,49 @@
+--echo #
+--echo # MDEV-24760 SELECT..CASE statement syntax error at Spider Engine table
+--echo #
+
+--disable_query_log
+--disable_result_log
+--source ../t/test_init.inc
+--enable_query_log
+--enable_result_log
+
+--connection child2_1
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+
+DROP TABLE IF EXISTS tbl_a;
+eval CREATE TABLE tbl_a (
+ id int NOT NULL AUTO_INCREMENT,
+ name varchar(255) DEFAULT NULL,
+ PRIMARY KEY (id)
+) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
+
+INSERT INTO tbl_a (name) VALUES ('Alice'), ('Bob');
+
+--connection master_1
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+
+eval CREATE TABLE tbl_a (
+ id int NOT NULL AUTO_INCREMENT,
+ name varchar(255) DEFAULT NULL,
+ PRIMARY KEY (id)
+) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a"'
+PARTITION BY HASH(id) (
+ PARTITION pt1 COMMENT='srv "s_2_1"'
+);
+
+SELECT id, CASE WHEN name='Alice' THEN "A" WHEN name='Bob' THEN "B" END FROM tbl_a;
+SELECT id, CASE name WHEN 'Alice' THEN "A" WHEN 'Bob' THEN "B" END FROM tbl_a;
+
+DROP DATABASE auto_test_local;
+
+--connection child2_1
+DROP DATABASE auto_test_remote;
+
+--disable_query_log
+--disable_result_log
+--source ../t/test_deinit.inc
+--enable_query_log
+--enable_result_log
diff --git a/storage/spider/mysql-test/spider/include/init_master_1.inc b/storage/spider/mysql-test/spider/include/init_master_1.inc
index 2c45d0bd65d..460142b9c7d 100644
--- a/storage/spider/mysql-test/spider/include/init_master_1.inc
+++ b/storage/spider/mysql-test/spider/include/init_master_1.inc
@@ -152,6 +152,11 @@ let $MASTER_1_COMMENT_TEXT_PK1_1=
COMMENT 'tbl "t1", srv "s_2_1"';
let $MASTER_1_COMMENT_TEXT_KEY1_1=
COMMENT 'tbl "t1", srv "s_2_1"';
+let $MASTER_1_COMMENT_MDEV_25985=
+ COMMENT='table "t1"'
+ PARTITION BY LIST COLUMNS(`a`) (
+ PARTITION `pt1` DEFAULT COMMENT = 'srv "s_2_1"'
+ );
let $MASTER_1_CHECK_DIRECT_UPDATE_STATUS=
SHOW STATUS LIKE 'Spider_direct_update';
let $MASTER_1_CHECK_DIRECT_DELETE_STATUS=
diff --git a/storage/spider/mysql-test/spider/r/spider_fixes_part.result b/storage/spider/mysql-test/spider/r/spider_fixes_part.result
index 234d52fed0d..571af94c1f2 100644
--- a/storage/spider/mysql-test/spider/r/spider_fixes_part.result
+++ b/storage/spider/mysql-test/spider/r/spider_fixes_part.result
@@ -262,6 +262,40 @@ a b c d e f
56B68DA68D6D4A04A08B453D09AD7B70 821E71E6ABB4404EBAA349BB681089F8 51041110620310 2018-08-02 13:48:28 510411 0
51ECF2C0CD3C48D99C91792E99D3C1A0 017B8A460DBC444682B791305EF75356 51041110620308 2018-08-02 13:48:29 510411 0
093B37A93A534DF883787AF5F6799674 996C7F14989D480589A553717D735E3E 51041110620302 2018-08-02 13:48:30 510411 0
+#
+# MDEV-25985 Spider handle ">=" as ">" in some cases
+#
+connection child2_1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a int,
+b int,
+c int,
+PRIMARY KEY (a),
+KEY (b,c)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+INSERT INTO t1 VALUES (1, 1, 1), (2, 2, 1);
+connection master_1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a int,
+b int,
+c int,
+PRIMARY KEY (a),
+KEY (b,c)
+) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "t1"'
+ PARTITION BY LIST COLUMNS(`a`) (
+PARTITION `pt1` DEFAULT COMMENT = 'srv "s_2_1"'
+ );
+connection master_1;
+SELECT * FROM t1 WHERE c > 0 AND b >= 1 AND b <= 2;
+a b c
+1 1 1
+2 2 1
+SELECT * FROM t1 WHERE c < 3 AND b <= 2;
+a b c
+1 1 1
+2 2 1
Crash from b4a2baffa82e5c07b96a1c752228560dcac1359b (MDEV-11084)
Fixed with 4968049799193394d442f26b4e3a8d95b185be72
diff --git a/storage/spider/mysql-test/spider/t/spider_fixes_part.test b/storage/spider/mysql-test/spider/t/spider_fixes_part.test
index b0b9ce86588..d2be62a6d31 100644
--- a/storage/spider/mysql-test/spider/t/spider_fixes_part.test
+++ b/storage/spider/mysql-test/spider/t/spider_fixes_part.test
@@ -726,6 +726,41 @@ if ($HAVE_PARTITION)
}
}
+
+--echo #
+--echo # MDEV-25985 Spider handle ">=" as ">" in some cases
+--echo #
+
+--connection child2_1
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+eval CREATE TABLE t1 (
+ a int,
+ b int,
+ c int,
+ PRIMARY KEY (a),
+ KEY (b,c)
+) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
+
+INSERT INTO t1 VALUES (1, 1, 1), (2, 2, 1);
+
+--connection master_1
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+eval CREATE TABLE t1 (
+ a int,
+ b int,
+ c int,
+ PRIMARY KEY (a),
+ KEY (b,c)
+) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_MDEV_25985;
+
+--connection master_1
+SELECT * FROM t1 WHERE c > 0 AND b >= 1 AND b <= 2;
+SELECT * FROM t1 WHERE c < 3 AND b <= 2;
+
--echo
--echo Crash from b4a2baffa82e5c07b96a1c752228560dcac1359b (MDEV-11084)
--echo Fixed with 4968049799193394d442f26b4e3a8d95b185be72
diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc
index 264f85d74cb..be9ee324ee1 100644
--- a/storage/spider/spd_db_conn.cc
+++ b/storage/spider/spd_db_conn.cc
@@ -2008,12 +2008,20 @@ int spider_db_append_key_where_internal(
case HA_READ_AFTER_KEY:
if (sql_kind == SPIDER_SQL_KIND_SQL)
{
+ const char* op_str;
+ uint32 op_len;
+ if (start_key_part_map == 1) {
+ op_str = SPIDER_SQL_GT_STR;
+ op_len = SPIDER_SQL_GT_LEN;
+ } else {
+ op_str = SPIDER_SQL_GTEQUAL_STR;
+ op_len = SPIDER_SQL_GTEQUAL_LEN;
+ }
if (str->reserve(store_length + key_name_length +
- /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 +
- SPIDER_SQL_GT_LEN))
+ /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + op_len))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
dbton_share->append_column_name(str, field->field_index);
- str->q_append(SPIDER_SQL_GT_STR, SPIDER_SQL_GT_LEN);
+ str->q_append(op_str, op_len);
if (spider_dbton[dbton_id].db_util->
append_column_value(spider, str, field, ptr,
share->access_charset))
@@ -2081,12 +2089,20 @@ int spider_db_append_key_where_internal(
result_list->desc_flg = TRUE;
if (sql_kind == SPIDER_SQL_KIND_SQL)
{
+ const char* op_str;
+ uint32 op_len;
+ if (start_key_part_map == 1) {
+ op_str = SPIDER_SQL_LT_STR;
+ op_len = SPIDER_SQL_LT_LEN;
+ } else {
+ op_str = SPIDER_SQL_LTEQUAL_STR;
+ op_len = SPIDER_SQL_LTEQUAL_LEN;
+ }
if (str->reserve(store_length + key_name_length +
- /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 +
- SPIDER_SQL_LT_LEN))
+ /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + op_len))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
dbton_share->append_column_name(str, field->field_index);
- str->q_append(SPIDER_SQL_LT_STR, SPIDER_SQL_LT_LEN);
+ str->q_append(op_str, op_len);
if (spider_dbton[dbton_id].db_util->
append_column_value(spider, str, field, ptr,
share->access_charset))
@@ -2499,12 +2515,20 @@ int spider_db_append_key_where_internal(
case HA_READ_BEFORE_KEY:
if (sql_kind == SPIDER_SQL_KIND_SQL)
{
+ const char* op_str;
+ uint32 op_len;
+ if (end_key_part_map == 1) {
+ op_str = SPIDER_SQL_LT_STR;
+ op_len = SPIDER_SQL_LT_LEN;
+ } else {
+ op_str = SPIDER_SQL_LTEQUAL_STR;
+ op_len = SPIDER_SQL_LTEQUAL_LEN;
+ }
if (str->reserve(store_length + key_name_length +
- /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 +
- SPIDER_SQL_LT_LEN))
+ /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + op_len))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
dbton_share->append_column_name(str, field->field_index);
- str->q_append(SPIDER_SQL_LT_STR, SPIDER_SQL_LT_LEN);
+ str->q_append(op_str, op_len);
if (spider_dbton[dbton_id].db_util->
append_column_value(spider, str, field, ptr,
share->access_charset))
diff --git a/storage/spider/spd_db_conn.h b/storage/spider/spd_db_conn.h
index 6fdb4b694ae..e820851d257 100644
--- a/storage/spider/spd_db_conn.h
+++ b/storage/spider/spd_db_conn.h
@@ -253,6 +253,15 @@
#define SPIDER_SQL_B_STR "b"
#define SPIDER_SQL_B_LEN (sizeof(SPIDER_SQL_B_STR) - 1)
+#define SPIDER_SQL_TRIM_STR "trim"
+#define SPIDER_SQL_TRIM_LEN sizeof(SPIDER_SQL_TRIM_STR) - 1
+#define SPIDER_SQL_TRIM_BOTH_STR "both "
+#define SPIDER_SQL_TRIM_BOTH_LEN sizeof(SPIDER_SQL_TRIM_BOTH_STR) - 1
+#define SPIDER_SQL_TRIM_LEADING_STR "leading "
+#define SPIDER_SQL_TRIM_LEADING_LEN sizeof(SPIDER_SQL_TRIM_LEADING_STR) - 1
+#define SPIDER_SQL_TRIM_TRAILING_STR "trailing "
+#define SPIDER_SQL_TRIM_TRAILING_LEN sizeof(SPIDER_SQL_TRIM_TRAILING_STR) - 1
+
#define SPIDER_SQL_INDEX_IGNORE_STR " IGNORE INDEX "
#define SPIDER_SQL_INDEX_IGNORE_LEN (sizeof(SPIDER_SQL_INDEX_IGNORE_STR) - 1)
#define SPIDER_SQL_INDEX_USE_STR " USE INDEX "
diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc
index 86ce0c530b1..cfe2fecf9d6 100644
--- a/storage/spider/spd_db_mysql.cc
+++ b/storage/spider/spd_db_mysql.cc
@@ -5687,72 +5687,106 @@ int spider_db_mbase_util::open_item_func(
DBUG_RETURN(spider_db_open_item_int(item_func, NULL, spider, str,
alias, alias_length, dbton_id, use_fields, fields));
} else if (
- !strncasecmp("case", func_name, func_name_length)
+ !strncasecmp("trim", func_name, func_name_length) &&
+ item_count == 2
) {
-#ifdef ITEM_FUNC_CASE_PARAMS_ARE_PUBLIC
- Item_func_case *item_func_case = (Item_func_case *) item_func;
- if (str)
- {
- if (str->reserve(SPIDER_SQL_CASE_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CASE_STR, SPIDER_SQL_CASE_LEN);
- }
- if (item_func_case->first_expr_num != -1)
- {
- if ((error_num = spider_db_print_item_type(
- item_list[item_func_case->first_expr_num], NULL, spider, str,
- alias, alias_length, dbton_id, use_fields, fields)))
- DBUG_RETURN(error_num);
- }
- for (roop_count = 0; roop_count < item_func_case->ncases;
- roop_count += 2)
+ /* item_count == 1 means this TRIM() is without a remove_str */
+ item = item_list[0];
+ Item *item_tmp = item_list[1];
+ if (str)
{
- if (str)
+ if (item_tmp->is_of_type(Item::CONST_ITEM, STRING_RESULT))
{
- if (str->reserve(SPIDER_SQL_WHEN_LEN))
+ /* 1. append 'TRIM(BOTH ' */
+ if (str->reserve(SPIDER_SQL_TRIM_LEN + SPIDER_SQL_OPEN_PAREN_LEN +
+ SPIDER_SQL_TRIM_BOTH_LEN))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_WHEN_STR, SPIDER_SQL_WHEN_LEN);
- }
- if ((error_num = spider_db_print_item_type(
- item_list[roop_count], NULL, spider, str,
- alias, alias_length, dbton_id, use_fields, fields)))
- DBUG_RETURN(error_num);
- if (str)
- {
- if (str->reserve(SPIDER_SQL_THEN_LEN))
+ str->q_append(SPIDER_SQL_TRIM_STR, SPIDER_SQL_TRIM_LEN);
+ str->q_append(SPIDER_SQL_OPEN_PAREN_STR,
+ SPIDER_SQL_OPEN_PAREN_LEN);
+ str->q_append(SPIDER_SQL_TRIM_BOTH_STR, SPIDER_SQL_TRIM_BOTH_LEN);
+ /* 2. append "remove_str"*/
+ if ((error_num = spider_db_print_item_type(
+ item_tmp, NULL, spider, str, alias, alias_length, dbton_id,
+ use_fields, fields)))
+ DBUG_RETURN(error_num);
+ /* 3. append ' FROM ' */
+ if (str->reserve(SPIDER_SQL_FROM_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_FROM_STR, SPIDER_SQL_FROM_LEN);
+ /* 4. append `field` */
+ if ((error_num = spider_db_print_item_type(
+ item, NULL, spider, str, alias, alias_length, dbton_id,
+ use_fields, fields)))
+ DBUG_RETURN(error_num);
+ /* 5. append ')' */
+ if (str->reserve(SPIDER_SQL_CLOSE_PAREN_LEN))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_THEN_STR, SPIDER_SQL_THEN_LEN);
+ str->q_append(SPIDER_SQL_CLOSE_PAREN_STR,
+ SPIDER_SQL_CLOSE_PAREN_LEN);
}
- if ((error_num = spider_db_print_item_type(
- item_list[roop_count + 1], NULL, spider, str,
- alias, alias_length, dbton_id, use_fields, fields)))
- DBUG_RETURN(error_num);
}
- if (item_func_case->else_expr_num != -1)
+ item_count -= 2;
+ break;
+ }
+ } else if (func_name_length == 5)
+ {
+ if (
+ (!strncasecmp("ltrim", func_name, func_name_length) ||
+ !strncasecmp("rtrim", func_name, func_name_length)) &&
+ (item_count == 2)
+ ) {
+ /* the func_name for TRIM(LEADING ...) is LTRIM, for TRIM(TRAILING) is RTRIM */
+ /* item_count == 2 means this TRIM(LEADING/TRAILING ...) is with a remove_str */
+ item = item_list[0];
+ Item *item_tmp = item_list[1];
+ if (str)
{
- if (str)
+ if (item_tmp->is_of_type(Item::CONST_ITEM, STRING_RESULT))
{
- if (str->reserve(SPIDER_SQL_ELSE_LEN))
+ /* 1. append 'TRIM(LEADING ' or 'TRIM(TRAILING ' */
+ if (func_name[0] == 'l' || func_name[0] == 'L')
+ { /* ltrim */
+ if (str->reserve(SPIDER_SQL_TRIM_LEN + SPIDER_SQL_OPEN_PAREN_LEN +
+ SPIDER_SQL_TRIM_LEADING_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_TRIM_STR, SPIDER_SQL_TRIM_LEN);
+ str->q_append(SPIDER_SQL_OPEN_PAREN_STR,
+ SPIDER_SQL_OPEN_PAREN_LEN);
+ str->q_append(SPIDER_SQL_TRIM_LEADING_STR, SPIDER_SQL_TRIM_LEADING_LEN);
+ } else
+ { /* rtrim */
+ if (str->reserve(SPIDER_SQL_TRIM_LEN + SPIDER_SQL_OPEN_PAREN_LEN +
+ SPIDER_SQL_TRIM_TRAILING_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_TRIM_STR, SPIDER_SQL_TRIM_LEN);
+ str->q_append(SPIDER_SQL_OPEN_PAREN_STR,
+ SPIDER_SQL_OPEN_PAREN_LEN);
+ str->q_append(SPIDER_SQL_TRIM_TRAILING_STR, SPIDER_SQL_TRIM_TRAILING_LEN);
+ }
+ /* 2. append "remove_str"*/
+ if ((error_num = spider_db_print_item_type(
+ item_tmp, NULL, spider, str, alias, alias_length, dbton_id,
+ use_fields, fields)))
+ DBUG_RETURN(error_num);
+ /* 3. append ' FROM ' */
+ if (str->reserve(SPIDER_SQL_FROM_LEN))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_ELSE_STR, SPIDER_SQL_ELSE_LEN);
+ str->q_append(SPIDER_SQL_FROM_STR, SPIDER_SQL_FROM_LEN);
+ /* 4. append `field` */
+ if ((error_num = spider_db_print_item_type(
+ item, NULL, spider, str, alias, alias_length, dbton_id,
+ use_fields, fields)))
+ DBUG_RETURN(error_num);
+ /* 5. append ')' */
+ if (str->reserve(SPIDER_SQL_CLOSE_PAREN_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CLOSE_PAREN_STR,
+ SPIDER_SQL_CLOSE_PAREN_LEN);
}
- if ((error_num = spider_db_print_item_type(
- item_list[item_func_case->else_expr_num], NULL, spider, str,
- alias, alias_length, dbton_id, use_fields, fields)))
- DBUG_RETURN(error_num);
- }
- if (str)
- {
- if (str->reserve(SPIDER_SQL_END_LEN + SPIDER_SQL_CLOSE_PAREN_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_END_STR, SPIDER_SQL_END_LEN);
- str->q_append(SPIDER_SQL_CLOSE_PAREN_STR,
- SPIDER_SQL_CLOSE_PAREN_LEN);
}
- DBUG_RETURN(0);
-#else
- DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
-#endif
+ item_count -= 2;
+ break;
}
} else if (func_name_length == 6 &&
!strncasecmp("istrue", func_name, func_name_length)
@@ -6583,6 +6617,89 @@ int spider_db_mbase_util::open_item_func(
#else
DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
#endif
+ case Item_func::CASE_SEARCHED_FUNC:
+ case Item_func::CASE_SIMPLE_FUNC:
+#ifdef ITEM_FUNC_CASE_PARAMS_ARE_PUBLIC
+ Item_func_case *item_func_case = (Item_func_case *) item_func;
+ if (str)
+ {
+ if (str->reserve(SPIDER_SQL_CASE_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CASE_STR, SPIDER_SQL_CASE_LEN);
+ }
+ if (item_func_case->first_expr_num != -1)
+ {
+ if ((error_num = spider_db_print_item_type(
+ item_list[item_func_case->first_expr_num], NULL, spider, str,
+ alias, alias_length, dbton_id, use_fields, fields)))
+ DBUG_RETURN(error_num);
+ }
+ for (roop_count = 0; roop_count < item_func_case->ncases;
+ roop_count += 2)
+ {
+ if (str)
+ {
+ if (str->reserve(SPIDER_SQL_WHEN_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_WHEN_STR, SPIDER_SQL_WHEN_LEN);
+ }
+ if ((error_num = spider_db_print_item_type(
+ item_list[roop_count], NULL, spider, str,
+ alias, alias_length, dbton_id, use_fields, fields)))
+ DBUG_RETURN(error_num);
+ if (str)
+ {
+ if (str->reserve(SPIDER_SQL_THEN_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_THEN_STR, SPIDER_SQL_THEN_LEN);
+ }
+ if ((error_num = spider_db_print_item_type(
+ item_list[roop_count + 1], NULL, spider, str,
+ alias, alias_length, dbton_id, use_fields, fields)))
+ DBUG_RETURN(error_num);
+ }
+ if (item_func_case->else_expr_num != -1)
+ {
+ if (str)
+ {
+ if (str->reserve(SPIDER_SQL_ELSE_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_ELSE_STR, SPIDER_SQL_ELSE_LEN);
+ }
+ if ((error_num = spider_db_print_item_type(
+ item_list[item_func_case->else_expr_num], NULL, spider, str,
+ alias, alias_length, dbton_id, use_fields, fields)))
+ DBUG_RETURN(error_num);
+ }
+ if (str)
+ {
+ if (str->reserve(SPIDER_SQL_END_LEN + SPIDER_SQL_CLOSE_PAREN_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_END_STR, SPIDER_SQL_END_LEN);
+ str->q_append(SPIDER_SQL_CLOSE_PAREN_STR,
+ SPIDER_SQL_CLOSE_PAREN_LEN);
+ }
+ DBUG_RETURN(0);
+#else
+ DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
+#endif
+ case Item_func::JSON_EXTRACT_FUNC:
+ func_name = (char*) item_func->func_name();
+ func_name_length = strlen(func_name);
+ if (str)
+ {
+ if (str->reserve(func_name_length + SPIDER_SQL_OPEN_PAREN_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(func_name, func_name_length);
+ str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN);
+ }
+ func_name = SPIDER_SQL_COMMA_STR;
+ func_name_length = SPIDER_SQL_COMMA_LEN;
+ separator_str = SPIDER_SQL_COMMA_STR;
+ separator_str_length = SPIDER_SQL_COMMA_LEN;
+ last_str = SPIDER_SQL_CLOSE_PAREN_STR;
+ last_str_length = SPIDER_SQL_CLOSE_PAREN_LEN;
+ break;
default:
THD *thd = spider->trx->thd;
SPIDER_SHARE *share = spider->share;
diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc
index d36f7624adf..f706ab86fc9 100644
--- a/storage/tokudb/ha_tokudb.cc
+++ b/storage/tokudb/ha_tokudb.cc
@@ -7266,7 +7266,7 @@ int ha_tokudb::create(
// in the database directory, so automatic filename-based
// discover_table_names() doesn't work either. So, it must force .frm
// file to disk.
- form->s->write_frm_image();
+ error= form->s->write_frm_image();
#endif
#if defined(TOKU_INCLUDE_OPTION_STRUCTS) && TOKU_INCLUDE_OPTION_STRUCTS
@@ -7298,8 +7298,8 @@ int ha_tokudb::create(
#endif // defined(TOKU_INCLUDE_OPTION_STRUCTS) && TOKU_INCLUDE_OPTION_STRUCTS
const toku_compression_method compression_method =
row_format_to_toku_compression_method(row_format);
-
bool create_from_engine = (create_info->table_options & HA_OPTION_CREATE_FROM_ENGINE);
+ if (error) { goto cleanup; }
if (create_from_engine) {
// table already exists, nothing to do
error = 0;
diff --git a/storage/tokudb/mysql-test/tokudb/r/bug-23786.result b/storage/tokudb/mysql-test/tokudb/r/bug-23786.result
new file mode 100644
index 00000000000..1b21758b85a
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb/r/bug-23786.result
@@ -0,0 +1,10 @@
+#
+# 10.2 Test
+#
+# MDEV-23786: Assertion `!is_set() || (m_status == DA_OK_BULK &&
+# is_bulk_op())'failed for TokuDB engine CREATE TABLE
+#
+set default_storage_engine='tokudb';
+CREATE TABLE _uppercase.t (a INT) ENGINE=TokuDB;
+ERROR 42000: Unknown database '_uppercase'
+# End of 10.2 Test
diff --git a/storage/tokudb/mysql-test/tokudb/t/bug-23786.test b/storage/tokudb/mysql-test/tokudb/t/bug-23786.test
new file mode 100644
index 00000000000..a8a0c4a1577
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb/t/bug-23786.test
@@ -0,0 +1,14 @@
+source include/have_tokudb.inc;
+
+--echo #
+--echo # 10.2 Test
+--echo #
+--echo # MDEV-23786: Assertion `!is_set() || (m_status == DA_OK_BULK &&
+--echo # is_bulk_op())'failed for TokuDB engine CREATE TABLE
+--echo #
+
+set default_storage_engine='tokudb';
+--error ER_BAD_DB_ERROR
+CREATE TABLE _uppercase.t (a INT) ENGINE=TokuDB;
+
+--echo # End of 10.2 Test
diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt
index 2a17cf6d0d8..ccbd24d30f9 100644
--- a/support-files/CMakeLists.txt
+++ b/support-files/CMakeLists.txt
@@ -79,7 +79,7 @@ IF(UNIX)
INSTALL(FILES ${out} DESTINATION ${inst_location}/policy/selinux COMPONENT SupportFiles)
ENDFOREACH()
IF(RPM)
- EXECUTE_PROCESS(COMMAND rpm -q --qf "%{VERSION}-%{RELEASE}" libsepol
+ EXECUTE_PROCESS(COMMAND rpm -q --qf "%{VERSION}" libsepol
OUTPUT_VARIABLE LIBSEPOL_VERSION RESULT_VARIABLE err)
IF (NOT err)
SET(CPACK_RPM_server_PACKAGE_REQUIRES
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 31c71c705a2..32681ac20a1 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -20601,6 +20601,71 @@ static void test_ps_params_in_ctes()
myquery(rc);
}
+void display_result_metadata(MYSQL_FIELD *field,
+ uint num_fields)
+{
+ MYSQL_FIELD* field_end;
+
+ mct_log("Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
+ "Column_alias\tType\tLength\tMax length\tIs_null\t"
+ "Flags\tDecimals\tCharsetnr\n");
+ for (field_end= field+num_fields; field < field_end; field++)
+ {
+ mct_log("%s\t", field->catalog);
+ mct_log("%s\t", field->db);
+ mct_log("%s\t", field->org_table);
+ mct_log("%s\t", field->table);
+ mct_log("%s\t", field->org_name);
+ mct_log("%s\t", field->name);
+ mct_log("%u\t", field->type);
+ mct_log("%lu\t", field->length);
+ mct_log("%lu\t", field->max_length);
+ mct_log("%s\t", (IS_NOT_NULL(field->flags) ? "N" : "Y"));
+ mct_log("%u\t", field->flags);
+ mct_log("%u\t", field->decimals);
+ mct_log("%u\n", field->charsetnr);
+ }
+}
+
+static void test_mdev_26145()
+{
+ MYSQL_STMT *stmt;
+ MYSQL_RES *result;
+ MYSQL_FIELD *fields;
+ int rc, num_fields;
+
+ myheader("test_mdev_26145");
+
+ rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "CREATE TABLE t1(a INT)");
+ myquery(rc);
+
+ stmt= mysql_simple_prepare(
+ mysql, "(SELECT MAX(a) FROM t1) UNION (SELECT MAX(a) FROM t1)");
+ check_stmt(stmt);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ result= mysql_stmt_result_metadata(stmt);
+ DIE_UNLESS(result);
+
+ num_fields= mysql_stmt_field_count(stmt);
+ fields= mysql_fetch_fields(result);
+
+ mct_start_logging("test_mdev26145");
+ display_result_metadata(fields, num_fields);
+ mct_close_log();
+
+ mysql_free_result(result);
+ mysql_stmt_close(stmt);
+
+ rc= mysql_query(mysql, "DROP TABLE t1");
+
+ myquery(rc);
+}
static void print_metadata(MYSQL_RES *rs_metadata, int num_fields)
{
@@ -21138,6 +21203,7 @@ static void test_mdev20261()
static struct my_tests_st my_tests[]= {
+ { "test_mdev_26145", test_mdev_26145 },
{ "disable_query_logs", disable_query_logs },
{ "test_view_sp_list_fields", test_view_sp_list_fields },
{ "client_query", client_query },